Merge commit 'a7d64bac1248a8ad2fba9bfd0e96efd6574f5d92' as 'php-langspec'
This commit is contained in:
Коммит
a6d4e312e5
|
@ -0,0 +1 @@
|
|||
/.commit-template
|
|
@ -0,0 +1,10 @@
|
|||
## Contributing to the Specification for PHP
|
||||
|
||||
We'd love your help in improving, correcting, adding to the specification.
|
||||
Please [file an issue](https://bugs.php.net/) or [submit a pull request](https://wiki.php.net/vcs/gitworkflow)
|
||||
at the [spec git repo](https://github.com/php/php-langspec).
|
||||
|
||||
## License for your Contributions
|
||||
|
||||
Any contribution you provide to the Specification for PHP must adhere to the
|
||||
same license as stated in the [LICENSE](LICENSE).
|
|
@ -0,0 +1,20 @@
|
|||
# Formatting rules
|
||||
|
||||
1. The format of the PHP Language Specification is
|
||||
[Markdown](http://daringfireball.net/projects/markdown/).
|
||||
2. Everything in the actual specification document must be ASCII only.
|
||||
3. The only allowed extensions to original Markdown are tables and code blocks
|
||||
(indicated by three backticks).
|
||||
4. Style
|
||||
* Use spaces to indent, not tabs.
|
||||
* For headings, use prefixed hash symbols `# Example`, not underlining it
|
||||
with `===`.
|
||||
* Use of *inline* links `[example](http://example.org)` is preferred over
|
||||
*reference* links `[example][xmpl]` unless used multiple times in a
|
||||
paragraph or section. This is to allow for easier splitting and
|
||||
reorganization of the document.
|
||||
* Do not embed external images not hosted on [php.net](http://php.net)
|
||||
infrastructure.
|
||||
* Try to stick to 80 chars wide, if possible. This is not as strict as
|
||||
in coding standard rules, but still easier to read most of the times.
|
||||
This does only apply to text, not to code examples or tables.
|
|
@ -0,0 +1,9 @@
|
|||
Facebook has dedicated all copyright to this specification to the public
|
||||
domain worldwide under the CC0 Public Domain Dedication located at
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
The first draft of this specification was initially written in 2014 by
|
||||
Facebook, Inc.
|
||||
|
||||
This specification is distributed without any warranty.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# PHP Language Specifications
|
||||
|
||||
This repo will contain the WIP PHP Language Specifications.
|
||||
|
||||
To join the conversation, send blank email to:
|
||||
|
||||
> [standards-subscribe@lists.php.net](mailto:standards-subscribe@lists.php.net)
|
||||
|
||||
Bug reports can be filed at:
|
||||
|
||||
> [https://bugs.php.net/report.php?package_name=PHP+Language+Specification](https://bugs.php.net/report.php?package_name=PHP+Language+Specification)
|
||||
|
||||
and browsed at:
|
||||
|
||||
> [https://bugs.php.net/search.php?cmd=display&status=Open&package_name%5B%5D=PHP+Language+Specification](https://bugs.php.net/search.php?cmd=display&status=Open&package_name%5B%5D=PHP+Language+Specification)
|
||||
|
||||
|
||||
The upstream url of this repo is:
|
||||
|
||||
git@git.php.net:/php-langspec.git
|
||||
|
||||
It is also mirrored on GitHub:
|
||||
|
||||
> [https://github.com/php/php-langspec](https://github.com/php/php-langspec)
|
||||
|
||||
The PHP specification is community-owned and open-source. Pull requests,
|
||||
issue filings and comments are extremely welcome.
|
||||
|
||||
Make sure you understand the [*contribution process*](CONTRIBUTING.md).
|
|
@ -0,0 +1,316 @@
|
|||
<!-- This file is autogenerated, do not edit it manually -->
|
||||
<!-- Run tools/toc.php instead -->
|
||||
|
||||
#Specification for PHP
|
||||
Facebook has dedicated all copyright to this specification to the public
|
||||
domain worldwide under the CC0 Public Domain Dedication located at
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>. This specification
|
||||
is distributed without any warranty.
|
||||
|
||||
(Initially written in 2014 by Facebook, Inc., July 2014)
|
||||
|
||||
**Table of Contents**
|
||||
- [Introduction](01-introduction.md#introduction)
|
||||
- [Conformance](02-conformance.md#conformance)
|
||||
- [Terms and Definitions](03-terms-and-definitions.md#terms-and-definitions)
|
||||
- [Basic Concepts](04-basic-concepts.md#basic-concepts)
|
||||
- [Program Structure](04-basic-concepts.md#program-structure)
|
||||
- [Program Start-Up](04-basic-concepts.md#program-start-up)
|
||||
- [Program Termination](04-basic-concepts.md#program-termination)
|
||||
- [__halt_compiler](04-basic-concepts.md#__halt_compiler)
|
||||
- [The Memory Model](04-basic-concepts.md#the-memory-model)
|
||||
- [General](04-basic-concepts.md#general)
|
||||
- [Reclamation and Automatic Memory Management](04-basic-concepts.md#reclamation-and-automatic-memory-management)
|
||||
- [Assignment](04-basic-concepts.md#assignment)
|
||||
- [General](04-basic-concepts.md#general-1)
|
||||
- [Value Assignment of Scalar Types to a Local Variable](04-basic-concepts.md#value-assignment-of-scalar-types-to-a-local-variable)
|
||||
- [Value Assignment of Objects to a Local Variable](04-basic-concepts.md#value-assignment-of-objects-to-a-local-variable)
|
||||
- [ByRef Assignment for Scalar Types with Local Variables](04-basic-concepts.md#byref-assignment-for-scalar-types-with-local-variables)
|
||||
- [ByRef Assignment of Non-Scalar Types with Local Variables](04-basic-concepts.md#byref-assignment-of-non-scalar-types-with-local-variables)
|
||||
- [Value Assignment of Array Types to Local Variables](04-basic-concepts.md#value-assignment-of-array-types-to-local-variables)
|
||||
- [Deferred Array Copying](04-basic-concepts.md#deferred-array-copying)
|
||||
- [General Value Assignment](04-basic-concepts.md#general-value-assignment)
|
||||
- [General ByRef Assignment](04-basic-concepts.md#general-byref-assignment)
|
||||
- [Argument Passing](04-basic-concepts.md#argument-passing)
|
||||
- [Value Returning](04-basic-concepts.md#value-returning)
|
||||
- [Cloning objects](04-basic-concepts.md#cloning-objects)
|
||||
- [Scope](04-basic-concepts.md#scope)
|
||||
- [Storage Duration](04-basic-concepts.md#storage-duration)
|
||||
- [Types](05-types.md#types)
|
||||
- [General](05-types.md#general)
|
||||
- [Scalar Types](05-types.md#scalar-types)
|
||||
- [General](05-types.md#general-1)
|
||||
- [The Boolean Type](05-types.md#the-boolean-type)
|
||||
- [The Integer Type](05-types.md#the-integer-type)
|
||||
- [The Floating-Point Type](05-types.md#the-floating-point-type)
|
||||
- [The String Type](05-types.md#the-string-type)
|
||||
- [The Null Type](05-types.md#the-null-type)
|
||||
- [Composite Types](05-types.md#composite-types)
|
||||
- [The Array Type](05-types.md#the-array-type)
|
||||
- [Objects](05-types.md#objects)
|
||||
- [Resources](05-types.md#resources)
|
||||
- [Constants](06-constants.md#constants)
|
||||
- [General](06-constants.md#general)
|
||||
- [Context-Dependent Constants](06-constants.md#context-dependent-constants)
|
||||
- [Core Predefined Constants](06-constants.md#core-predefined-constants)
|
||||
- [User-Defined Constants](06-constants.md#user-defined-constants)
|
||||
- [Variables](07-variables.md#variables)
|
||||
- [General](07-variables.md#general)
|
||||
- [Kinds of Variables](07-variables.md#kinds-of-variables)
|
||||
- [Constants](07-variables.md#constants)
|
||||
- [Local Variables](07-variables.md#local-variables)
|
||||
- [Array Elements](07-variables.md#array-elements)
|
||||
- [Function Statics](07-variables.md#function-statics)
|
||||
- [Global Variables](07-variables.md#global-variables)
|
||||
- [Instance Properties](07-variables.md#instance-properties)
|
||||
- [Static Properties](07-variables.md#static-properties)
|
||||
- [Class and Interface Constants](07-variables.md#class-and-interface-constants)
|
||||
- [Predefined Variables](07-variables.md#predefined-variables)
|
||||
- [Conversions](08-conversions.md#conversions)
|
||||
- [General](08-conversions.md#general)
|
||||
- [Converting to Boolean Type](08-conversions.md#converting-to-boolean-type)
|
||||
- [Converting to Integer Type](08-conversions.md#converting-to-integer-type)
|
||||
- [Converting to Floating-Point Type](08-conversions.md#converting-to-floating-point-type)
|
||||
- [Converting to String Type](08-conversions.md#converting-to-string-type)
|
||||
- [Converting to Array Type](08-conversions.md#converting-to-array-type)
|
||||
- [Converting to Object Type](08-conversions.md#converting-to-object-type)
|
||||
- [Lexical Structure](09-lexical-structure.md#lexical-structure)
|
||||
- [Scripts](09-lexical-structure.md#scripts)
|
||||
- [Grammars](09-lexical-structure.md#grammars)
|
||||
- [Lexical analysis](09-lexical-structure.md#lexical-analysis)
|
||||
- [General](09-lexical-structure.md#general)
|
||||
- [Comments](09-lexical-structure.md#comments)
|
||||
- [White Space](09-lexical-structure.md#white-space)
|
||||
- [Tokens](09-lexical-structure.md#tokens)
|
||||
- [General](09-lexical-structure.md#general-1)
|
||||
- [Names](09-lexical-structure.md#names)
|
||||
- [Keywords](09-lexical-structure.md#keywords)
|
||||
- [Literals](09-lexical-structure.md#literals)
|
||||
- [General](09-lexical-structure.md#general-2)
|
||||
- [Integer Literals](09-lexical-structure.md#integer-literals)
|
||||
- [Floating-Point Literals](09-lexical-structure.md#floating-point-literals)
|
||||
- [String Literals](09-lexical-structure.md#string-literals)
|
||||
- [Single-Quoted String Literals](09-lexical-structure.md#single-quoted-string-literals)
|
||||
- [Double-Quoted String Literals](09-lexical-structure.md#double-quoted-string-literals)
|
||||
- [Heredoc String Literals](09-lexical-structure.md#heredoc-string-literals)
|
||||
- [Nowdoc String Literals](09-lexical-structure.md#nowdoc-string-literals)
|
||||
- [Operators and Punctuators](09-lexical-structure.md#operators-and-punctuators)
|
||||
- [Expressions](10-expressions.md#expressions)
|
||||
- [General](10-expressions.md#general)
|
||||
- [Primary Expressions](10-expressions.md#primary-expressions)
|
||||
- [General](10-expressions.md#general-1)
|
||||
- [Intrinsics](10-expressions.md#intrinsics)
|
||||
- [General](10-expressions.md#general-2)
|
||||
- [array](10-expressions.md#array)
|
||||
- [echo](10-expressions.md#echo)
|
||||
- [empty](10-expressions.md#empty)
|
||||
- [eval](10-expressions.md#eval)
|
||||
- [exit/die](10-expressions.md#exitdie)
|
||||
- [isset](10-expressions.md#isset)
|
||||
- [list](10-expressions.md#list)
|
||||
- [print](10-expressions.md#print)
|
||||
- [unset](10-expressions.md#unset)
|
||||
- [Anonymous Function Creation](10-expressions.md#anonymous-function-creation)
|
||||
- [Postfix Operators](10-expressions.md#postfix-operators)
|
||||
- [General](10-expressions.md#general-3)
|
||||
- [The `clone` Operator](10-expressions.md#the-clone-operator)
|
||||
- [The `new` Operator](10-expressions.md#the-new-operator)
|
||||
- [Array Creation Operator](10-expressions.md#array-creation-operator)
|
||||
- [Subscript Operator](10-expressions.md#subscript-operator)
|
||||
- [Function Call Operator](10-expressions.md#function-call-operator)
|
||||
- [Member-Selection Operator](10-expressions.md#member-selection-operator)
|
||||
- [Postfix Increment and Decrement Operators](10-expressions.md#postfix-increment-and-decrement-operators)
|
||||
- [Scope-Resolution Operator](10-expressions.md#scope-resolution-operator)
|
||||
- [Exponentiation Operator](10-expressions.md#exponentiation-operator)
|
||||
- [Unary Operators](10-expressions.md#unary-operators)
|
||||
- [General](10-expressions.md#general-4)
|
||||
- [Prefix Increment and Decrement Operators](10-expressions.md#prefix-increment-and-decrement-operators)
|
||||
- [Unary Arithmetic Operators](10-expressions.md#unary-arithmetic-operators)
|
||||
- [Error Control Operator](10-expressions.md#error-control-operator)
|
||||
- [Shell Command Operator](10-expressions.md#shell-command-operator)
|
||||
- [Cast Operator](10-expressions.md#cast-operator)
|
||||
- [Variable-Name Creation Operator](10-expressions.md#variable-name-creation-operator)
|
||||
- [`instanceof` Operator](10-expressions.md#instanceof-operator)
|
||||
- [Multiplicative Operators](10-expressions.md#multiplicative-operators)
|
||||
- [Additive Operators](10-expressions.md#additive-operators)
|
||||
- [Bitwise Shift Operators](10-expressions.md#bitwise-shift-operators)
|
||||
- [Relational Operators](10-expressions.md#relational-operators)
|
||||
- [Equality Operators](10-expressions.md#equality-operators)
|
||||
- [Bitwise AND Operator](10-expressions.md#bitwise-and-operator)
|
||||
- [Bitwise Exclusive OR Operator](10-expressions.md#bitwise-exclusive-or-operator)
|
||||
- [Bitwise Inclusive OR Operator](10-expressions.md#bitwise-inclusive-or-operator)
|
||||
- [Logical AND Operator (form 1)](10-expressions.md#logical-and-operator-form-1)
|
||||
- [Logical Inclusive OR Operator (form 1)](10-expressions.md#logical-inclusive-or-operator-form-1)
|
||||
- [Conditional Operator](10-expressions.md#conditional-operator)
|
||||
- [Coalesce Operator](10-expressions.md#coalesce-operator)
|
||||
- [Assignment Operators](10-expressions.md#assignment-operators)
|
||||
- [General](10-expressions.md#general-5)
|
||||
- [Simple Assignment](10-expressions.md#simple-assignment)
|
||||
- [byRef Assignment](10-expressions.md#byref-assignment)
|
||||
- [Compound Assignment](10-expressions.md#compound-assignment)
|
||||
- [Logical AND Operator (form 2)](10-expressions.md#logical-and-operator-form-2)
|
||||
- [Logical Exclusive OR Operator](10-expressions.md#logical-exclusive-or-operator)
|
||||
- [Logical Inclusive OR Operator (form 2)](10-expressions.md#logical-inclusive-or-operator-form-2)
|
||||
- [`yield` Operator](10-expressions.md#yield-operator)
|
||||
- [Script Inclusion Operators](10-expressions.md#script-inclusion-operators)
|
||||
- [General](10-expressions.md#general-6)
|
||||
- [The `include` Operator](10-expressions.md#the-include-operator)
|
||||
- [The `include_once` Operator](10-expressions.md#the-include_once-operator)
|
||||
- [The `require` Operator](10-expressions.md#the-require-operator)
|
||||
- [The `require_once` Operator](10-expressions.md#the-require_once-operator)
|
||||
- [Constant Expressions](10-expressions.md#constant-expressions)
|
||||
- [Statements](11-statements.md#statements)
|
||||
- [General](11-statements.md#general)
|
||||
- [Compound Statements](11-statements.md#compound-statements)
|
||||
- [Labeled Statements](11-statements.md#labeled-statements)
|
||||
- [Expression Statements](11-statements.md#expression-statements)
|
||||
- [Selection Statements](11-statements.md#selection-statements)
|
||||
- [General](11-statements.md#general-1)
|
||||
- [The `if` Statement](11-statements.md#the-if-statement)
|
||||
- [The `switch` Statement](11-statements.md#the-switch-statement)
|
||||
- [Iteration Statements](11-statements.md#iteration-statements)
|
||||
- [General](11-statements.md#general-2)
|
||||
- [The `while` Statement](11-statements.md#the-while-statement)
|
||||
- [The `do` Statement](11-statements.md#the-do-statement)
|
||||
- [The `for` Statement](11-statements.md#the-for-statement)
|
||||
- [The `foreach` Statement](11-statements.md#the-foreach-statement)
|
||||
- [Jump Statements](11-statements.md#jump-statements)
|
||||
- [General](11-statements.md#general-3)
|
||||
- [The `goto` Statement](11-statements.md#the-goto-statement)
|
||||
- [The `continue` Statement](11-statements.md#the-continue-statement)
|
||||
- [The `break` Statement](11-statements.md#the-break-statement)
|
||||
- [The `return` Statement](11-statements.md#the-return-statement)
|
||||
- [The `throw` Statement](11-statements.md#the-throw-statement)
|
||||
- [The `try` Statement](11-statements.md#the-try-statement)
|
||||
- [The `declare` Statement](11-statements.md#the-declare-statement)
|
||||
- [Arrays](12-arrays.md#arrays)
|
||||
- [General](12-arrays.md#general)
|
||||
- [Array Creation and Initialization](12-arrays.md#array-creation-and-initialization)
|
||||
- [Element Access and Insertion](12-arrays.md#element-access-and-insertion)
|
||||
- [Functions](13-functions.md#functions)
|
||||
- [General](13-functions.md#general)
|
||||
- [Function Calls](13-functions.md#function-calls)
|
||||
- [Function Definitions](13-functions.md#function-definitions)
|
||||
- [Return typing](13-functions.md#return-typing)
|
||||
- [Type check modes](13-functions.md#type-check-modes)
|
||||
- [Variable Functions](13-functions.md#variable-functions)
|
||||
- [Anonymous Functions](13-functions.md#anonymous-functions)
|
||||
- [Classes](14-classes.md#classes)
|
||||
- [General](14-classes.md#general)
|
||||
- [Class Declarations](14-classes.md#class-declarations)
|
||||
- [Class Members](14-classes.md#class-members)
|
||||
- [Dynamic Members](14-classes.md#dynamic-members)
|
||||
- [Constants](14-classes.md#constants)
|
||||
- [Properties](14-classes.md#properties)
|
||||
- [Methods](14-classes.md#methods)
|
||||
- [Constructors](14-classes.md#constructors)
|
||||
- [Destructors](14-classes.md#destructors)
|
||||
- [Inheritance](14-classes.md#inheritance)
|
||||
- [Methods with Special Semantics](14-classes.md#methods-with-special-semantics)
|
||||
- [General](14-classes.md#general-1)
|
||||
- [Method `__call`](14-classes.md#method-__call)
|
||||
- [Method `__callStatic`](14-classes.md#method-__callstatic)
|
||||
- [Method `__clone`](14-classes.md#method-__clone)
|
||||
- [Method `__debugInfo`](14-classes.md#method-__debuginfo)
|
||||
- [Method `__get`](14-classes.md#method-__get)
|
||||
- [Method `__invoke`](14-classes.md#method-__invoke)
|
||||
- [Method `__isset`](14-classes.md#method-__isset)
|
||||
- [Method `__set`](14-classes.md#method-__set)
|
||||
- [Method `__set_state`](14-classes.md#method-__set_state)
|
||||
- [Method `__sleep`](14-classes.md#method-__sleep)
|
||||
- [Method `__toString`](14-classes.md#method-__tostring)
|
||||
- [Method `__unset`](14-classes.md#method-__unset)
|
||||
- [Method `__wakeup`](14-classes.md#method-__wakeup)
|
||||
- [Serialization](14-classes.md#serialization)
|
||||
- [Predefined Classes](14-classes.md#predefined-classes)
|
||||
- [Class `Closure`](14-classes.md#class-closure)
|
||||
- [Class `Generator`](14-classes.md#class-generator)
|
||||
- [Class `__PHP_Incomplete_Class`](14-classes.md#class-__php_incomplete_class)
|
||||
- [Class `stdClass`](14-classes.md#class-stdclass)
|
||||
- [Predefined Error Classes](14-classes.md#predefined-error-classes)
|
||||
- [Class `Error`](14-classes.md#class-error)
|
||||
- [Class `ArithmeticError`](14-classes.md#class-arithmeticerror)
|
||||
- [Class `AssertionError`](14-classes.md#class-assertionerror)
|
||||
- [Class `DivisionByZeroError`](14-classes.md#class-divisionbyzeroerror)
|
||||
- [Class `ParseError`](14-classes.md#class-parseerror)
|
||||
- [Class `TypeError`](14-classes.md#class-typeerror)
|
||||
- [Interfaces](15-interfaces.md#interfaces)
|
||||
- [General](15-interfaces.md#general)
|
||||
- [Interface Declarations](15-interfaces.md#interface-declarations)
|
||||
- [Interface Members](15-interfaces.md#interface-members)
|
||||
- [Constants](15-interfaces.md#constants)
|
||||
- [Methods](15-interfaces.md#methods)
|
||||
- [Predefined Interfaces](15-interfaces.md#predefined-interfaces)
|
||||
- [Interface `ArrayAccess`](15-interfaces.md#interface-arrayaccess)
|
||||
- [Interface `Iterator`](15-interfaces.md#interface-iterator)
|
||||
- [Interface `IteratorAggregate`](15-interfaces.md#interface-iteratoraggregate)
|
||||
- [Interface `Throwable`](15-interfaces.md#interface-throwable)
|
||||
- [Interface `Traversable`](15-interfaces.md#interface-traversable)
|
||||
- [Interface `Serializable`](15-interfaces.md#interface--serializable)
|
||||
- [Traits](16-traits.md#traits)
|
||||
- [General](16-traits.md#general)
|
||||
- [Trait Declarations](16-traits.md#trait-declarations)
|
||||
- [Trait Uses](16-traits.md#trait-uses)
|
||||
- [Exception Handling](17-exception-handling.md#exception-handling)
|
||||
- [General](17-exception-handling.md#general)
|
||||
- [Class `Exception`](17-exception-handling.md#class-exception)
|
||||
- [Tracing Exceptions](17-exception-handling.md#tracing-exceptions)
|
||||
- [User-Defined Exception Classes](17-exception-handling.md#user-defined-exception-classes)
|
||||
- [Namespaces](18-namespaces.md#namespaces)
|
||||
- [General](18-namespaces.md#general)
|
||||
- [Defining Namespaces](18-namespaces.md#defining-namespaces)
|
||||
- [Namespace Use Declarations](18-namespaces.md#namespace-use-declarations)
|
||||
- [Name Lookup](18-namespaces.md#name-lookup)
|
||||
- [Grammar](19-grammar.md#grammar)
|
||||
- [General](19-grammar.md#general)
|
||||
- [Lexical Grammar](19-grammar.md#lexical-grammar)
|
||||
- [General](19-grammar.md#general-1)
|
||||
- [Comments](19-grammar.md#comments)
|
||||
- [White Space](19-grammar.md#white-space)
|
||||
- [Tokens](19-grammar.md#tokens)
|
||||
- [General](19-grammar.md#general-2)
|
||||
- [Names](19-grammar.md#names)
|
||||
- [Keywords](19-grammar.md#keywords)
|
||||
- [Literals](19-grammar.md#literals)
|
||||
- [General](19-grammar.md#general-3)
|
||||
- [Integer Literals](19-grammar.md#integer-literals)
|
||||
- [Floating-Point Literals](19-grammar.md#floating-point-literals)
|
||||
- [String Literals](19-grammar.md#string-literals)
|
||||
- [Operators and Punctuators](19-grammar.md#operators-and-punctuators)
|
||||
- [Syntactic Grammar](19-grammar.md#syntactic-grammar)
|
||||
- [Program Structure](19-grammar.md#program-structure)
|
||||
- [Variables](19-grammar.md#variables)
|
||||
- [Expressions](19-grammar.md#expressions)
|
||||
- [Primary Expressions](19-grammar.md#primary-expressions)
|
||||
- [Postfix Operators](19-grammar.md#postfix-operators)
|
||||
- [Unary Operators](19-grammar.md#unary-operators)
|
||||
- [instanceof Operator](19-grammar.md#instanceof-operator)
|
||||
- [Multiplicative Operators](19-grammar.md#multiplicative-operators)
|
||||
- [Additive Operators](19-grammar.md#additive-operators)
|
||||
- [Bitwise Shift Operators](19-grammar.md#bitwise-shift-operators)
|
||||
- [Relational Operators](19-grammar.md#relational-operators)
|
||||
- [Equality Operators](19-grammar.md#equality-operators)
|
||||
- [Bitwise Logical Operators](19-grammar.md#bitwise-logical-operators)
|
||||
- [Logical Operators (form 1)](19-grammar.md#logical-operators-form-1)
|
||||
- [Conditional Operator](19-grammar.md#conditional-operator)
|
||||
- [Coalesce Operator](19-grammar.md#coalesce-operator)
|
||||
- [Assignment Operators](19-grammar.md#assignment-operators)
|
||||
- [Logical Operators (form 2)](19-grammar.md#logical-operators-form-2)
|
||||
- [yield Operator](19-grammar.md#yield-operator)
|
||||
- [Script Inclusion Operators](19-grammar.md#script-inclusion-operators)
|
||||
- [Constant Expressions](19-grammar.md#constant-expressions)
|
||||
- [Statements](19-grammar.md#statements)
|
||||
- [General](19-grammar.md#general-4)
|
||||
- [Compound Statements](19-grammar.md#compound-statements)
|
||||
- [Labeled Statements](19-grammar.md#labeled-statements)
|
||||
- [Expression Statements](19-grammar.md#expression-statements)
|
||||
- [Iteration Statements](19-grammar.md#iteration-statements)
|
||||
- [Jump Statements](19-grammar.md#jump-statements)
|
||||
- [The try Statement](19-grammar.md#the-try-statement)
|
||||
- [The declare Statement](19-grammar.md#the-declare-statement)
|
||||
- [Functions](19-grammar.md#functions)
|
||||
- [Classes](19-grammar.md#classes)
|
||||
- [Interfaces](19-grammar.md#interfaces)
|
||||
- [Traits](19-grammar.md#traits)
|
||||
- [Namespaces](19-grammar.md#namespaces)
|
||||
- [Bibliography](20-bibliography.md#bibliography)
|
|
@ -0,0 +1,13 @@
|
|||
#Introduction
|
||||
This specification is intended to provide a complete and concise
|
||||
definition of the syntax and semantics of the PHP language, suitable for
|
||||
use by the following:
|
||||
|
||||
- Implementers of a PHP compiler.
|
||||
- Implementers of a test suite for the PHP language.
|
||||
- Programmers writing PHP code.
|
||||
|
||||
For now, the runtime library has been excluded, as that is documented at
|
||||
[www.php.net](http://www.php.net). However, the document can contain references
|
||||
to the library functions, usually in the form of links to http://www.php.net.
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#Conformance
|
||||
In this specification, "must" is to be interpreted as a requirement on
|
||||
an implementation or on a program; conversely, "must not" is to be
|
||||
interpreted as a prohibition.
|
||||
|
||||
If a "must" or "must not" requirement that appears outside of a
|
||||
constraint is violated, the behavior is undefined. Undefined behavior is
|
||||
otherwise indicated in this specification by the words "undefined
|
||||
behavior" or by the omission of any explicit definition of behavior.
|
||||
There is no difference in emphasis among these three; they all describe
|
||||
"behavior that is undefined".
|
||||
|
||||
The word "may" indicates "permission", and is never used to mean
|
||||
"might".
|
||||
|
||||
A *strictly conforming program* must use only those features of the
|
||||
language described in this specification. In particular, it must not
|
||||
produce output or exhibit behavior dependent on any unspecified,
|
||||
undefined, or implementation-defined behavior.
|
||||
|
||||
A *conforming implementation* must accept any strictly conforming
|
||||
program. A conforming implementation may have extensions, provided they
|
||||
do not alter the behavior of any strictly conforming program.
|
||||
|
||||
A *conforming program* is one that is acceptable to a conforming
|
||||
implementation.
|
||||
|
||||
A conforming implementation must be accompanied by a document that
|
||||
defines all implementation-defined characteristics and all extensions.
|
||||
|
||||
Some Syntax sections are followed by a Constraints section, which
|
||||
further restricts the grammar. After issuing a diagnostic for a
|
||||
constraint violation, a conforming implementation may continue program
|
||||
execution. In some cases, such continuation behavior is documented (for
|
||||
example, what happens when passing too few arguments to a function).
|
||||
Making such things constraint violations simply forces the issuance of a
|
||||
diagnostic; it does not require that program execution terminate.
|
||||
|
||||
This specification contains explanatory material—called *informative* or
|
||||
*non-normative* text—that, strictly speaking, is not necessary in a
|
||||
formal language specification. Examples are provided to illustrate
|
||||
possible forms of the constructions described. References are used to
|
||||
refer to related clauses. Notes and Implementer Notes are provided to
|
||||
give advice or guidance to implementers or programmers. Informative
|
||||
annexes provide additional information and summarize the information
|
||||
contained in this specification. All text not marked as informative is
|
||||
*normative*.
|
||||
|
||||
Certain features are marked as *deprecated*. While these are normative
|
||||
for the current edition of this specification, they are not guaranteed
|
||||
to exist in future revisions. Usually, they are old approaches that have
|
||||
been superseded by new ones, and use of the old approach is discouraged.
|
||||
(Examples of this include the use of braces ({ }) for subscripting, and
|
||||
the use of old-style constructor names).
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#Terms and Definitions
|
||||
For the purposes of this document, the following terms and definitions
|
||||
apply:
|
||||
|
||||
<dl>
|
||||
<dt>argument</dt>
|
||||
<dd>a value passed to a function, that is intended to map to a
|
||||
corresponding parameter.</dd>
|
||||
|
||||
<dt>behavior</dt>
|
||||
<dd>external appearance or action.</dd>
|
||||
|
||||
<dt>behavior, implementation-defined</dt>
|
||||
<dd>behavior specific to an implementation, where that implementation
|
||||
must document that behavior.</dd>
|
||||
|
||||
<dt>behavior, undefined</dt>
|
||||
<dd>behavior which is not guaranteed to produce any specific result.
|
||||
Usually follows an erroneous program construct or data.</dd>
|
||||
|
||||
<dt>behavior, unspecified</dt>
|
||||
<dd>behavior for which this specification provides no requirements.</dd>
|
||||
|
||||
<dt>constraint</dt>
|
||||
<dd>restriction, either syntactic or semantic, on how language elements
|
||||
can be used.</dd>
|
||||
|
||||
<dt>error, fatal</dt>
|
||||
<dd>a condition in which the engine cannot continue executing the script
|
||||
and must terminate.</dd>
|
||||
|
||||
<dt>error, fatal, catchable</dt>
|
||||
<dd>a fatal error that can be caught by a user-defined handler.</dd>
|
||||
|
||||
<dt>error, non-fatal</dt>
|
||||
<dd>an error that is not a fatal error and allows for the engine to
|
||||
continue execution.</dd>
|
||||
|
||||
<dt>lvalue</dt>
|
||||
<dd>an expression that designates a location that can store a value.</dd>
|
||||
|
||||
<dt>lvalue, modifiable</dt>
|
||||
<dd>an lvalue whose value can be changed.</dd>
|
||||
|
||||
<dt>lvalue, non-modifiable</dt>
|
||||
<dd>an lvalue whose value cannot be changed.</dd>
|
||||
|
||||
<dt>notice</dt>
|
||||
<dd>an informational message informing user of the code that may not work as intended.</dd>
|
||||
|
||||
<dt>parameter</dt>
|
||||
<dd>a variable declared in the parameter list of a function that is
|
||||
intended to map to a corresponding argument in a call to that
|
||||
function.</dd>
|
||||
|
||||
<dt>PHP Run-Time Engine</dt>
|
||||
<dd>the software that executes a PHP program. Referred to as <em>the
|
||||
Engine</em> throughout this specification.</dd>
|
||||
|
||||
<dt>value</dt>
|
||||
<dd>a primitive unit of data operated by the Engine having a type
|
||||
and potentially other content depending on the type.</dd>
|
||||
</dl>
|
||||
|
||||
Other terms are defined throughout this specification, as needed, with
|
||||
the first usage being typeset *like this*.
|
||||
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,202 @@
|
|||
#Types
|
||||
|
||||
##General
|
||||
|
||||
The meaning of a value is determined by its *type*. PHP's types are
|
||||
categorized as *scalar types* and *composite types*. The scalar types
|
||||
are [Boolean](#the-boolean-type), [integer](#the-integer-type), [floating point](#the-floating-point-type), [string](#the-string-type), and [null](#the-null-type). The composite types are [array](#the-array-type),
|
||||
and [object](#objects). The [resource](#resources) is an opaque type whose internal structure is not specified and depends
|
||||
on the implementation.
|
||||
|
||||
The scalar types are *value types*. That is, a variable of scalar type
|
||||
behaves as though it contains its own value.
|
||||
|
||||
The composite types can contain other variables, besides the variable itself, e.g.
|
||||
array contains its elements and object contains its properties.
|
||||
|
||||
The objects and resources are *handle types*. The type contains information — in a *handle* —
|
||||
that leads to the value. The differences between value and handle types become apparent
|
||||
when it comes to understanding the [semantics](04-basic-concepts.md#the-memory-model) of assignment, and passing
|
||||
arguments to, and returning values from, functions.
|
||||
|
||||
Variables are not declared to have a particular type. Instead, a
|
||||
variable's type is determined at runtime by the value it contains.
|
||||
The same variable can contain values of different types at different times.
|
||||
|
||||
Useful library functions for interrogating and using type information
|
||||
include [`gettype`](http://www.php.net/gettype), [`is_type`](http://www.php.net/is_type), [`settype`](http://www.php.net/settype), and [`var_dump`](http://www.php.net/var_dump).
|
||||
|
||||
##Scalar Types
|
||||
|
||||
###General
|
||||
|
||||
The integer and floating-point types are collectively known as
|
||||
*arithmetic types*. The library function [`is_numeric`](http://www.php.net/is_numeric) indicates if
|
||||
a given value is a number or a numeric [string](#the-string-type).
|
||||
|
||||
The library function [`is_scalar`](http://www.php.net/is_scalar) indicates if a given value has a
|
||||
scalar type. However, that function does not consider `NULL` to be scalar.
|
||||
To test for `NULL`, use [`is_null`](http://www.php.net/is_null).
|
||||
|
||||
Some objects may support arithmetic and other scalar operations and/or be
|
||||
convertible to scalar types (this is currently available only to internal classes).
|
||||
Such object types together with scalar types are called *scalar-compatible types*.
|
||||
Note that the same object type may be scalar-compatible for one operation but not for another.
|
||||
|
||||
###The Boolean Type
|
||||
|
||||
The Boolean type is `bool`, for which the name `boolean` is a synonym. This
|
||||
type is capable of storing two distinct values, which correspond to the
|
||||
Boolean values [`true` and `false`](06-constants.md#core-predefined-constants), respectively.
|
||||
The internal representation of this type and its values is unspecified.
|
||||
|
||||
The library function [`is_bool`](http://www.php.net/is_bool) indicates if a given value has type
|
||||
`bool`.
|
||||
|
||||
###The Integer Type
|
||||
|
||||
There is one integer type, `int`, for which the name `integer` is a synonym.
|
||||
This type is binary, signed, and uses twos-complement representation for
|
||||
negative values. The range of values that can be stored is
|
||||
implementation-defined; however, the range [-2147483648, 2147483647],
|
||||
must be supported. This range must be finite.
|
||||
|
||||
Certain operations on integer values produce a mathematical result that
|
||||
cannot be represented as an integer. Examples include the following:
|
||||
|
||||
- Incrementing the largest value or decrementing the smallest value.
|
||||
- Applying the unary minus to the smallest value.
|
||||
- Multiplying, adding, or subtracting two values.
|
||||
|
||||
In such cases, the computation is done as though the types of the values were
|
||||
`float` with the result having that type.
|
||||
|
||||
The constants [`PHP_INT_SIZE`, `PHP_INT_MIN` and `PHP_INT_MAX`](06-constants.md#core-predefined-constants) define certain
|
||||
characteristics about type `int`.
|
||||
|
||||
The library function [`is_int`](http://www.php.net/is_int) indicates if a given value has type
|
||||
`int`.
|
||||
|
||||
###The Floating-Point Type
|
||||
|
||||
There is one floating-point type, `float`, for which the names `double` and
|
||||
`real` are synonyms. The `float` type must support at least the range and
|
||||
precision of IEEE 754 64-bit double-precision representation.
|
||||
|
||||
The library function [`is_float`](http://www.php.net/is_float) indicates if a given value has type
|
||||
`float`. The library function [`is_finite`](http://www.php.net/is_finite) indicates if a given
|
||||
floating-point value is finite. The library function [`is_infinite`](http://www.php.net/is_infinite)
|
||||
indicates if a given floating-point value is infinite. The library
|
||||
function [`is_nan`](http://www.php.net/is_nan) indicates if a given floating-point value is a
|
||||
`NaN`.
|
||||
|
||||
###The String Type
|
||||
|
||||
A string is a set of contiguous bytes that represents a sequence of zero
|
||||
or more characters.
|
||||
|
||||
Conceptually, a string can be considered as an [array](#array-types) of
|
||||
bytes—the *elements*—whose keys are the `int` values starting at zero. The
|
||||
type of each element is `string`. However, a string is *not* considered a
|
||||
collection, so it cannot be iterated over.
|
||||
|
||||
A string whose length is zero is an *empty string*.
|
||||
|
||||
As to how the bytes in a string translate into characters is
|
||||
unspecified.
|
||||
|
||||
Although a user of a string might choose to ascribe special semantics to
|
||||
bytes having the value `\0`, from PHP's perspective, such *null bytes*
|
||||
have no special meaning. PHP does not assume strings contain any specific
|
||||
data or assign special values to any bytes or sequences. However, many
|
||||
library functions assume the strings they receive as arguments are UTF-8
|
||||
encoded, often without explicitly mentioning that fact.
|
||||
|
||||
A *numeric string* is a string whose content exactly matches the pattern
|
||||
defined by the *str-numeric* production below.
|
||||
A *leading-numeric string* is a string whose initial characters follow
|
||||
the requirements of a numeric string, and whose trailing characters are
|
||||
non-numeric. A *non-numeric string* is a string that is not a numeric
|
||||
string.
|
||||
|
||||
<pre>
|
||||
<i>str-numeric::</i>
|
||||
<i>str-whitespace<sub>opt</sub> sign<sub>opt</sub> str-number</i>
|
||||
|
||||
<i>str-whitespace::</i>
|
||||
<i>str-whitespace<sub>opt</sub> str-whitespace-char</i>
|
||||
|
||||
<i>str-whitespace-char::</i>
|
||||
<i>new-line</i>
|
||||
Space character (U+0020)
|
||||
Horizontal-tab character (U+0009)
|
||||
Vertical-tab character (U+000B)
|
||||
Form-feed character (U+000C)
|
||||
|
||||
<i>str-number::</i>
|
||||
<i>digit-sequence</i>
|
||||
<i>floating-literal</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*digit-sequence*](09-lexical-structure.md#floating-point-literals)
|
||||
* [*floating-literal*](09-lexical-structure.md#floating-point-literals)
|
||||
* [*new-line*](09-lexical-structure.md#comments)
|
||||
* [*sign*](09-lexical-structure.md#floating-point-literals)
|
||||
|
||||
Note that *digit-sequence* is interpreted as having base-10 (so `"0377"` is treated as 377 decimal with a redundant
|
||||
leading zero, rather than as octal 377).
|
||||
|
||||
Only one mutation operation may be performed on a string, offset
|
||||
assignment, which involves the simple assignment [operator =](10-expressions.md#simple-assignment).
|
||||
|
||||
The library function [`is_string`](http://www.php.net/is_string) indicates if a given value has
|
||||
type string.
|
||||
|
||||
###The Null Type
|
||||
|
||||
The null type has only one possible value, [`NULL`](06-constants.md#core-predefined-constants). The representation
|
||||
of this type and its value is unspecified.
|
||||
|
||||
The library function [`is_null`](http://www.php.net/is_null) indicates if a given value is `NULL`.
|
||||
|
||||
##Composite Types
|
||||
|
||||
###The Array Type
|
||||
|
||||
An array is a data structure that contains a collection of zero or more
|
||||
elements whose values are accessed through keys that are of type `int` or
|
||||
`string`. See more details in [arrays chapter](12-arrays.md#arrays).
|
||||
|
||||
The library function [`is_array`](http://www.php.net/is_array) indicates if a given value is an
|
||||
array.
|
||||
|
||||
###Objects
|
||||
|
||||
An *object* is an instance of a [class](14-classes.md#classes). Each distinct
|
||||
[]*class-declaration*](14-classes.md#class-declarations) defines a new class type, and each class
|
||||
type is an object type. The representation of object types is unspecified.
|
||||
|
||||
The library function [`is_object`](http://www.php.net/is_object) indicates if a given value is an
|
||||
object, and the library function
|
||||
[`get_class`](http://php.net/manual/function.get-class.php) indicates the name of an object's class.
|
||||
|
||||
###Resources
|
||||
|
||||
A [*resource*](http://php.net/manual/language.types.resource.php)
|
||||
is a descriptor to some sort of external entity. Examples include
|
||||
files, databases, and network sockets.
|
||||
|
||||
A resource is an abstract entity whose representation is unspecified.
|
||||
Resources are only created or consumed by the implementation; they are
|
||||
never created or consumed by PHP code.
|
||||
|
||||
Each distinct resource has a unique identity of some unspecified form.
|
||||
|
||||
The library function [`is_resource`](http://www.php.net/is_resource) indicates if a given value is a
|
||||
resource, and the library function
|
||||
[`get_resource_type`](http://php.net/manual/function.get-resource-type.php) indicates the type of a resource.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
#Constants
|
||||
|
||||
##General
|
||||
|
||||
A *constant* is a [named](09-lexical-structure.md#names) value. Once defined, the value
|
||||
of the constant can not be changed.
|
||||
|
||||
A constant can be defined in one of two ways: as a *c-constant* using a
|
||||
[*const-declaration*](14-classes.md#constants), or as a *d-constant* by calling the library
|
||||
function [`define`](http://www.php.net/define). However, the two approaches differ slightly.
|
||||
Specifically:
|
||||
|
||||
- The name of a c-constant must comply with the lexical grammar for a
|
||||
name while that for a d-constant can contain any source character.
|
||||
- The name of a c-constant is case-sensitive while that for a
|
||||
d-constant can be case-sensitive or case-insensitive based on the
|
||||
value of the third argument passed to `define`.
|
||||
- If `define` is able to define the given name, it returns `TRUE`;
|
||||
otherwise, it returns `FALSE`.
|
||||
|
||||
The constants can only hold a value of a [scalar type](05-types.md#scalar-types), an array or a [resource](05-types.md#resource-types).
|
||||
|
||||
The library function [`defined`](http://www.php.net/defined) reports if a given name (specified as
|
||||
a string) is defined as a constant. The library function [`constant`](http://www.php.net/constant)
|
||||
returns the value of a given constant whose name is specified as a
|
||||
string.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
const MAX_HEIGHT = 10.5; // define two (case-sensitive) c-constants
|
||||
const UPPER_LIMIT = MAX_HEIGHT;
|
||||
define('COEFFICIENT_1', 2.345, TRUE); // define a case-insensitive d-constant
|
||||
define('FAILURE', FALSE, FALSE); // define a case-sensitive d-constant
|
||||
```
|
||||
|
||||
##Context-Dependent Constants
|
||||
|
||||
The following constants—sometimes referred to as *magic constants*—are
|
||||
automatically available to all scripts; their values are not fixed and they are case-insensitive:
|
||||
|
||||
Constant Name | Description
|
||||
----------------- | ---------
|
||||
`__CLASS__` | `string`; The name of the current class. From within a trait method, the name of the class in which that trait is used. If the current namespace is other than the default, the namespace name and `\` are prepended, in that order. If used outside all classes, the value is the empty string.
|
||||
`__COMPILER_HALT_OFFSET__` | `int`; When the [`__halt_compiler();`](04-basic-concepts.md#__halt_compiler) construct is used, this constant contains the byte offset in the source file immediately following the `__halt_compiler();` token in this file.
|
||||
`__DIR__` | `string`; The directory name of the script. A directory separator is only appended for the root directory.
|
||||
`__FILE__` | `string`; The full name of the script.
|
||||
`__FUNCTION__` | `string`; Inside a function, the name of the current function exactly as it was declared, with the following prepended: If a named namespace exists, that namespace name followed by "\". If used outside all functions, the result is the empty string. For a method, no parent-class prefix is present. (See `__METHOD__` and [anonymous functions](13-functions.md#anonymous-functions)).
|
||||
`__LINE__` | `int`; the number of the current source line.
|
||||
`__METHOD__` | `string`; Inside a method, the name of the current method exactly as it was declared, with the following prepended, in order: If a named namespace exists, that namespace name followed by `\`; the parent class name or trait name followed by `::`. If used outside all methods, the result is the same as for `__FUNCTION__`.
|
||||
`__NAMESPACE__` | `string`; The name of the current namespace exactly as it was declared. For the default namespace, the result is the empty string.
|
||||
`__TRAIT__` | `string`; The name of the current trait. From within a trait method, the name of the current trait. If used outside all traits, the result is the empty string.
|
||||
|
||||
Constant names beginning with __ are reserved for future use by the Engine.
|
||||
|
||||
##Core Predefined Constants
|
||||
|
||||
The following constants are automatically available to all scripts; they are case-sensitive with the exception of `NULL`, `TRUE` and `FALSE`:
|
||||
|
||||
Constant Name | Description
|
||||
------------- | -----------
|
||||
`DEFAULT_INCLUDE_PATH` | `string`; the [`fopen`](http://www.php.net/fopen) library function include path is used if it is not overridden by the `php.ini` setting `include_path`.
|
||||
`E_ALL` | `int`; All errors and warnings, as supported.
|
||||
`E_COMPILE_ERROR` | `int`; Fatal compile-time errors. This is like an `E_ERROR`, except that `E_COMPILE_ERROR` is generated by the scripting engine.
|
||||
`E_COMPILE_WARNING` | `int`; Compile-time warnings (non-fatal errors). This is like an `E_WARNING`, except that `E_COMPILE_WARNING` is generated by the scripting engine.
|
||||
`E_CORE_ERROR` | `int`; Fatal errors that occur during PHP's initial start-up. This is like an `E_ERROR`, except that `E_CORE_ERROR` is generated by the core of PHP.
|
||||
`E_CORE_WARNING` | `int`; Warnings (non-fatal errors) that occur during PHP's initial start-up. This is like an `E_WARNING`, except that `E_CORE_WARNING` is generated by the core of PHP.
|
||||
`E_DEPRECATED` | `int`; Deprecation notices. Enable this to receive warnings about code that will not work in future versions.
|
||||
`E_ERROR` | `int`; Fatal run-time errors. These indicate errors that cannot be recovered from, such as a memory allocation problem. Execution of the script is halted.
|
||||
`E_NOTICE` | `int`; Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.
|
||||
`E_PARSE` | `int`; Compile-time parse errors.
|
||||
`E_RECOVERABLE_ERROR` | `int`; Catchable fatal error. It indicates that a probably dangerous error occurred, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handler (see the library function [`set_error_handler`](http://www.php.net/set_error_handler)), the application aborts as it was an `E_ERROR`.
|
||||
`E_STRICT` | `int`; Have PHP suggest changes to the source code to ensure the best interoperability.
|
||||
`E_USER_DEPRECATED` | `int`; User-generated error message. This is like an `E_DEPRECATED`, except that `E_USER_DEPRECATED` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
|
||||
`E_USER_ERROR` | `int`; User-generated error message. This is like an `E_ERROR`, except that `E_USER_ERROR` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
|
||||
`E_USER_NOTICE` | `int`; User-generated warning message. This is like an `E_NOTICE`, except that `E_USER_NOTICE` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
|
||||
`E_USER_WARNING` | `int`; User-generated warning message. This is like an `E_WARNING`, except that `E_USER_WARNING` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
|
||||
`E_WARNING` | `int`; Run-time warnings (non-fatal errors). Execution of the script is not halted.
|
||||
`E_USER_DEPRECATED` | `int`; User-generated warning message. This is like an `E_DEPRECATED`, except that `E_USER_DEPRECATED` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
|
||||
`FALSE` | `bool`; the case-insensitive Boolean value `FALSE`.
|
||||
`INF` | `float`; Infinity
|
||||
`M_1_PI` | `float`; 1/pi
|
||||
`M_2_PI` | `float`; 2/pi
|
||||
`M_2_SQRTPI` | `float`; 2/sqrt(pi)
|
||||
`M_E` | `float`; e
|
||||
`M_EULER` | `float`; Euler constant
|
||||
`M_LN10` | `float`; log_e 10
|
||||
`M_LN2` | `float`; log_e 2
|
||||
`M_LNPI` | `float`; log_e(pi)
|
||||
`M_LOG10E` | `float`; log_10 e
|
||||
`M_LOG2E` | `float`; log_2 e
|
||||
`M_PI` | `float`; Pi
|
||||
`M_PI_2` | `floa`t; pi/2
|
||||
`M_PI_4` | `float`; pi/4
|
||||
`M_SQRT1_2` | `float`; 1/sqrt(2)
|
||||
`M_SQRT2` | `float`; sqrt(2)
|
||||
`M_SQRT3` | `float`; sqrt(3)
|
||||
`M_SQRTPI` | `float`; sqrt(pi)
|
||||
`NAN` | `float`; Not-a-Number
|
||||
`NULL` | `null`; the case-insensitive value `NULL`.
|
||||
`PHP_BINARY` | `string`; the PHP binary path during script execution.
|
||||
`PHP_BINDIR` | `string`; the installation location of the binaries.
|
||||
`PHP_CONFIG_FILE_PATH` | `string`; location from which php.ini values were parsed
|
||||
`PHP_CONFIG_FILE_SCAN_DIR` | `string`; The directory containing multiple INI files, all of which were parsed on start-up.
|
||||
`PHP_DEBUG` | `int`; Indicates whether the engine was built with debugging enabled.
|
||||
`PHP_EOL` | `string`; the end-of-line terminator for this platform.
|
||||
`PHP_EXTENSION_DIR` | `string`; The directory to be searched by the library function [`dl`](http://www.pph.net/dl) when looking for runtime extensions.
|
||||
`PHP_EXTRA_VERSION` | `string`; the current PHP extra version.
|
||||
`PHP_INT_MAX` | `int`; the maximum representable value for an integer.
|
||||
`PHP_INT_MIN` | `int`; the minimum representable value for an integer.
|
||||
`PHP_INT_SIZE` | `int`; the number of bytes used to represent an integer.
|
||||
`PHP_MAJOR_VERSION` | `int`; the current PHP major version
|
||||
`PHP_MANDIR` | `string`; the installation location of the manual pages.
|
||||
`PHP_MAXPATHLEN` | `int`; the maximum length of a fully qualified filename supported by this build.
|
||||
`PHP_MINOR_VERSION` | `int`; the current PHP minor version.
|
||||
`PHP_OS` | `string`; the current operating system.
|
||||
`PHP_PREFIX` | `string`; the value to which "--prefix" was set when configured.
|
||||
`PHP_RELEASE_VERSION` | `int`; the current PHP release version.
|
||||
`PHP_ROUND_HALF_DOWN` | `int`; Round halves down.
|
||||
`PHP_ROUND_HALF_EVEN` | `int`; Round halves to even numbers.
|
||||
`PHP_ROUND_HALF_ODD` | `int`; Round halves to odd numbers.
|
||||
`PHP_ROUND_HALF_UP` | `int`; Round halves up.
|
||||
`PHP_SAPI` | `string`; the Server API for this build.
|
||||
`PHP_SHLIB_SUFFIX` | `string`; build-platform's shared library suffix.
|
||||
`PHP_SYSCONFDIR` | `string`; the PHP system configuration directory.
|
||||
`PHP_VERSION` | `string`; the current PHP version in the form "major.minor.release[extra]".
|
||||
`PHP_VERSION_ID` | `int`; the current PHP version.
|
||||
`PHP_ZTS` | `int`; Indicates whether the compiler was built with thread safety enabled.
|
||||
`STDIN` | `resource`; File resource that maps to standard input (`php://stdin`).
|
||||
`STDOUT` | `resource`; File resource that maps to standard output (`php://stdout`).
|
||||
`STDERR` | `resource`; File resource that maps to standard error (`php://stderr`).
|
||||
`TRUE` | `bool`; the case-insensitive Boolean value `TRUE`.
|
||||
|
||||
The members of the `E_*` family have values that are powers of 2, so
|
||||
they can be combined meaningfully using bitwise operators.
|
||||
|
||||
##User-Defined Constants
|
||||
|
||||
A constant may be defined inside or outside of functions, inside
|
||||
a [class](14-classes.md#constants), or inside an [interface](15-interfaces.md#constants).
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,482 @@
|
|||
#Variables
|
||||
|
||||
##General
|
||||
|
||||
A *variable* is a named area of data storage that contains a PHP value. A variable is represented by a [VSlot](04-basic-concepts.md#general). A variable is created by [assigning a value](04-basic-concepts.md#assignment) to it.
|
||||
A variable is destroyed by *unsetting* it, either by an explicit call to the intrinsic [`unset`](10-expressions.md#unset), or by the Engine. The intrinsic [`isset`](10-expressions.md#isset) tests if a given variable exists and is not set to `NULL`.
|
||||
If a variable, which is not defined so far, is used in an expression, then different strategies are applied which determine whether the variable is defined implicitly or a substitution value is used instead and whether a notice is emitted or not. The strategies depend on the kind of the variable as well as on the context where the undefined variable is being used. The strategies are elaborated in the sub-sections of the different [kinds of variables](#kinds-of-variables) below.
|
||||
|
||||
Variables have [names](09-lexical-structure.md#names). Distinct variables may have
|
||||
the same name provided they are in different [scopes](04-basic-concepts.md#scope).
|
||||
|
||||
A [constant](06-constants.md#general) is a variable that, once initialized, its value cannot
|
||||
be changed.
|
||||
|
||||
Based on the context in which it is declared, a variable has a [scope](04-basic-concepts.md#scope) and a [storage duration](04-basic-concepts.md#storage-duration).
|
||||
|
||||
A *superglobal* variable is a global variable that is accessible in all scopes without
|
||||
the need for a [*global-declaration*](#global-variables).
|
||||
|
||||
The following kinds of variable may exist in a script:
|
||||
|
||||
- [Constant](#constants).
|
||||
- [Local variable](#local-variables).
|
||||
- [Array element](#array-elements).
|
||||
- [Function static](#function-statics).
|
||||
- [Global variable](#global-variables).
|
||||
- [Instance property](#instance-properties).
|
||||
- [Static class property](#static-properties).
|
||||
- [Class and interface constant](#class-and-interface-constants).
|
||||
|
||||
##Kinds of Variables
|
||||
|
||||
###Constants
|
||||
|
||||
**Syntax**
|
||||
|
||||
See [constants section](06-constants.md#general).
|
||||
|
||||
**Constraints**
|
||||
|
||||
Outside of a class or interface, a c-constant can be defined only at the
|
||||
top level of a script.
|
||||
|
||||
**Semantics**
|
||||
|
||||
See [constants](06-constants.md#general) and [class constants](14-classes.md#constants).
|
||||
|
||||
A constant defined outside of a class or interface is a [superglobal](#general). A constant has static [storage duration](04-basic-concepts.md#storage-duration)
|
||||
and is a non-modifiable lvalue.
|
||||
|
||||
**Undefined Constants**
|
||||
|
||||
Undefined constants are not defined implicitly -- forward usages of constants are also classified as undefined constants here. A distinction between class/interface constants and top level constants is made.
|
||||
|
||||
For top level constants: For unqualified usages, the name of the undefined constant (as string) is used as substitution value. Moreover, a notice is emitted stating that the corresponding constant was undefined. For qualified usages, an exception of type [`Error`](14-classes.md#class-error) is thrown.
|
||||
|
||||
For class/interface constants: An exception of type [`Error`](14-classes.md#class-error) is thrown, stating that the corresponding constant was undefined.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
const MAX_HEIGHT = 10.5; // define two c-constants
|
||||
const UPPER_LIMIT = MAX_HEIGHT;
|
||||
define('COEFFICIENT_1', 2.345); // define two d-constants
|
||||
define('FAILURE', TRUE);
|
||||
|
||||
// Examples of undefined constants
|
||||
echo NON_EXISTING_CONSTANT; // uses 'NON_EXISTING_CONSTANT' as substitution
|
||||
// value and emits a notice stating that the
|
||||
// constant was undefined.
|
||||
|
||||
echo NON_EXISTING_CONSTANT; // same here, the constant is still undefined
|
||||
// and 'NON_EXISTING_CONSTANT' is used as
|
||||
// substitution value and a notice is emitted
|
||||
// again.
|
||||
|
||||
echo MAX_LENGTH; // same here due to a forward usage
|
||||
// (MAX_LENGTH is defined further below).
|
||||
// 'MAX_LENGTH' is used as substitution
|
||||
// value and an notice is emitted.
|
||||
|
||||
echo \NON_EXISTING_CONSTANT; // qualified use of undefined constant. Throws
|
||||
// an exception of type Error.
|
||||
|
||||
const MAX_LENGTH = 7.5;
|
||||
|
||||
echo Exception::MESSAGE; // undefined class constant. Throws an exception
|
||||
// of type Error.
|
||||
|
||||
```
|
||||
|
||||
###Local Variables
|
||||
|
||||
**Syntax**
|
||||
|
||||
See Semantics below.
|
||||
|
||||
**Semantics**
|
||||
|
||||
Except for a parameter, a local variable is never defined explicitly;
|
||||
instead, it is created when it is first assigned a value. A local
|
||||
variable can be assigned to as a parameter in the parameter list of a
|
||||
[function definition](13-functions.md#function-definitions) or inside any [compound statement](11-statements.md#compound-statements). It
|
||||
has function [scope](04-basic-concepts.md#scope) and automatic [storage duration](04-basic-concepts.md#storage-duration). A local
|
||||
variable is a modifiable lvalue.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
function doit($p1) // assigned the value TRUE when called
|
||||
{
|
||||
$count = 10;
|
||||
...
|
||||
if ($p1)
|
||||
{
|
||||
$message = "Can't open master file.";
|
||||
...
|
||||
}
|
||||
...
|
||||
}
|
||||
doit(TRUE);
|
||||
// -----------------------------------------
|
||||
function f()
|
||||
{
|
||||
$lv = 1;
|
||||
echo "\$lv = $lv\n";
|
||||
++$lv;
|
||||
}
|
||||
for ($i = 1; $i <= 3; ++$i)
|
||||
f();
|
||||
```
|
||||
|
||||
Unlike the [function static equivalent](#function-statics), function `f` outputs
|
||||
"`$lv = 1`" each time.
|
||||
|
||||
See the recursive function example in [storage duration section](04-basic-concepts.md#storage-duration).
|
||||
|
||||
<a name="undefined-local-variables"></a>
|
||||
**Undefined Local Variables**
|
||||
|
||||
A distinction is made based on the context where an undefined local variable is used.
|
||||
|
||||
*byVal Context*
|
||||
|
||||
PHP does not implicitly define an undefined local variable and uses `NULL` as substitution value instead. Furthermore, a notice is emitted, stating that the corresponding variable was undefined, unless the variable is used
|
||||
|
||||
1. as the single expression in a statement.
|
||||
2. as argument of [isset](10-expressions.md#isset).
|
||||
3. as argument of [empty](10-expressions.md#empty).
|
||||
4. as the left hand side of the [coalesce operator `??`](10-expressions.md#coalesce-operator).
|
||||
|
||||
Since undefined local variables are not defined implicitly, they stay undefined. In general, a VSlot is not created for undefined variables used in a byValue context.
|
||||
|
||||
*byRef Context*
|
||||
|
||||
If the undefined variable is used in a [byRef context](04-basic-concepts#byRef) then PHP defines the variable implicitly. Hence, a VSlot is created for it and `NULL` is stored in it. A notice is *not* emitted in such a case.
|
||||
|
||||
*Examples of Undefined Variables*
|
||||
|
||||
Following some examples which outlines the behaviour with undefined local variables.
|
||||
|
||||
```PHP
|
||||
// The following 4 cases outline the exceptions of undefined variables
|
||||
// used in byValue context where no notice is emitted.
|
||||
$a;
|
||||
isset($a);
|
||||
empty($a);
|
||||
$a ?? 'default Value';
|
||||
|
||||
$a = 1; // a VSlot for $a was created and 1 was assigned.
|
||||
|
||||
$b = $c; // a VSlot for $b was created and the value of $c was assigned to
|
||||
// it. But because $c in turn was undefined, NULL was used as
|
||||
// substitution value instead. In addition, a notice was
|
||||
// emitted stating that $c was undefined.
|
||||
|
||||
$d = $c; // a VSlot for $d was created and the value of $c was assigned to
|
||||
// it. But since $c is still undefined, NULL was used as
|
||||
// substitution value instead and another notice was emitted
|
||||
// stating $c was undefined.
|
||||
|
||||
$d + $e; // $e was undefined and `NULL` was used as substitution value
|
||||
// instead. In addition, a notice was emitted stating that
|
||||
// $e was undefined.
|
||||
|
||||
$f = &$g; // a VSlot for $f was created which points to the VSlot of $g.
|
||||
// $g in turn was undefined but was defined implicitly because the
|
||||
// assignment was byRef. Thus a VSlot for $g was created and `NULL`
|
||||
// was assigned to it. A notice was *not* emitted.
|
||||
|
||||
$h = $g; // a VSlot for $h was created and the value of $g (which is NULL)
|
||||
// was assigned to it.
|
||||
|
||||
function foo($x){}
|
||||
|
||||
foo($i); // $i was undefined and NULL was used as substitution value
|
||||
// instead. In addition, a notice was emitted stating that $i
|
||||
// was undefined.
|
||||
|
||||
$j = $i; // a VSlot for $j was created and the value of $i was assigned to
|
||||
// it. But because $i in turn was still undefined, NULL was used
|
||||
// as substitution value instead. Another notice was emitted
|
||||
// stating that $i was undefined.
|
||||
|
||||
function bar(&$x){}
|
||||
|
||||
bar($k); // $k was undefined but implicitly defined because it was passed to
|
||||
// the function bar byRef. Thus a VSlot for $k was created and
|
||||
// NULL was assigned to it. A notice was *not* emitted.
|
||||
|
||||
$l = $k; // a VSlot for $l was created and the value of $k (which is NULL)
|
||||
// was assigned to it.
|
||||
|
||||
```
|
||||
|
||||
###Array Elements
|
||||
|
||||
**Syntax**
|
||||
|
||||
[Arrays](12-arrays.md#arrays) are created via the [array-creation operator](10-expressions.md#array-creation-operator) or
|
||||
the intrinsic [`array`](10-expressions.md#array). At the same time, one or more elements
|
||||
may be created for that array. New elements are inserted into an
|
||||
existing array via the [simple-assignment operator](10-expressions.md#simple-assignment) in
|
||||
conjunction with the subscript [operator `[]`](10-expressions.md#subscript-operator). Elements can be
|
||||
removed by calling the [`unset` intrinsic](10-expressions.md#unset).
|
||||
|
||||
**Semantics**
|
||||
|
||||
The [scope](04-basic-concepts.md#scope) of an array element is the same as the scope of that
|
||||
array's name. An array element has allocated [storage duration](04-basic-concepts.md#storage-duration).
|
||||
|
||||
**Undefined Array Elements**
|
||||
|
||||
Similar to [undefined local variables](#undefined-local-variables), a distinction is made based on the context where an undefined array element is used.
|
||||
|
||||
*byValue Context*
|
||||
|
||||
If one tries to access an undefined array element, then `NULL` is used as substitution value and a notice is emitted, stating that an undefined offset was used. The undefined offset is not created implicitly and a subsequent access results in another notice.
|
||||
|
||||
*byRef Context*
|
||||
|
||||
PHP defines implicitly an undefined array element when it is accessed byRef, a VSlot for the corresponding undefined offset is created and `NULL` is assigned to it. A notice is *not* emitted in this case.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
$colors = ["red", "white", "blue"]; // create array with 3 elements
|
||||
$colors[] = "green"; // insert a new element
|
||||
|
||||
echo $colors[100]; // element with offset 100 is undefined and NULL is
|
||||
// used as substitution value. Moreover, a notice is
|
||||
// emitted stating that an undefined offset was used.
|
||||
|
||||
echo $colors[100]; // element with offset 100 is still undefined and NULL
|
||||
// is used as substitution value instead. Another
|
||||
// notice is emitted.
|
||||
|
||||
$b = &colors[100]; // a VSlot for $b is created which points to the array
|
||||
// element with the offset 100. An array element with
|
||||
// offset 100 was undefined but implicitly defined
|
||||
// because the assignment is byRef. Thus a VSlot for
|
||||
// the array element with offset 100 is created and
|
||||
// NULL is assigned to it. A notice is *not* emitted.
|
||||
```
|
||||
|
||||
###Function Statics
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>function-static-declaration:</i>
|
||||
static <i>static-variable-name-list</i> ;
|
||||
|
||||
<i>static-variable-name-list:</i>
|
||||
<i>static-variable-declaration</i>
|
||||
<i>static-variable-name-list</i> , <i>static-variable-declaration</i>
|
||||
|
||||
<i>static-variable-declaration:</i>
|
||||
<i>variable-name</i> <i>function-static-initializer<sub>opt</sub></i>
|
||||
|
||||
<i>function-static-initializer:</i>
|
||||
= <i>constant-expression</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*variable-name*](09-lexical-structure.md#names)
|
||||
* [*constant-expression*](10-expressions.md#constant-expressions)
|
||||
|
||||
**Constraints**
|
||||
|
||||
A function static must be defined inside a function.
|
||||
|
||||
**Semantics**
|
||||
|
||||
A function static may be defined inside any [compound statement](11-statements.md#compound-statements).
|
||||
It is a modifiable lvalue.
|
||||
|
||||
A function static has function [scope](04-basic-concepts.md#scope) and static [storage duration](04-basic-concepts.md#storage-duration).
|
||||
|
||||
The value of a function static is retained across calls to its parent
|
||||
function. Each time the function containing a function static
|
||||
declaration is called, that execution is dealing with an [alias](04-basic-concepts.md#general)
|
||||
to that static variable. If that alias is passed to the [`unset` intrinsic](10-expressions.md#unset),
|
||||
only that alias is destroyed. The next time that function is called, a new alias is created.
|
||||
|
||||
**Undefined Function Statics**
|
||||
|
||||
Function statics are explicitly defined and thus cannot be undefined.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
function f()
|
||||
{
|
||||
static $fs = 1;
|
||||
echo "\$fs = $fs\n";
|
||||
++$fs;
|
||||
}
|
||||
for ($i = 1; $i <= 3; ++$i)
|
||||
f();
|
||||
```
|
||||
|
||||
Unlike the [local variable equivalent](#local-variables), function `f` outputs "`$fs
|
||||
= 1`", "`$fs = 2`", and "`$fs = 3`", as `$fs` retains its value across
|
||||
calls.
|
||||
|
||||
<a name="hidingNotice"></a>
|
||||
Be also aware that declaring a function static can hide a local variable and/or a global variable withe the same name. The value of the local or global variable is not taken over as initial value of the function static. Subsequent modifications of the variable only modify the function static and do not affect the local nor the global variable. An example:
|
||||
|
||||
```PHP
|
||||
function f(){
|
||||
$fs = 10; // assign 10 to the local variable $fs
|
||||
static $fs; // define a function static with name $fs
|
||||
echo "\$fs = $fs\n"; // $fs =
|
||||
$fs = 5; // assign 5 to the function static $fs (local variable is not modified)
|
||||
echo "\$fs = $fs\n"; // $fs = 5
|
||||
global $fs; // define a global variabel with name $fs
|
||||
echo "\$fs = $fs\n"; // $fs =
|
||||
$fs = 3; // assign 3 to the global variable $fs (function static and local variabel is not modified
|
||||
echo "\$fs = $fs\n"; // $fs = 3
|
||||
static $fs;
|
||||
++$fs; // increment function static $fs
|
||||
echo "\$fs = $fs\n"; // $fs = 6
|
||||
}
|
||||
f();
|
||||
echo "\$fs = $fs\n"; // $fs = 3
|
||||
```
|
||||
|
||||
###Global Variables
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>global-declaration:</i>
|
||||
global <i>variable-name-list</i> ;
|
||||
|
||||
<i>variable-name-list:</i>
|
||||
<i>global-variable</i>
|
||||
<i>variable-name-list</i> , <i>global-variable</i>
|
||||
|
||||
<i>global-variable:</i>
|
||||
<i>variable-name</i>
|
||||
<i>variable-name-creation-expression</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*expression*](10-expressions.md#general-6)
|
||||
* [*variable-name*](09-lexical-structure.md#names)
|
||||
* [*variable-name-creation-expression*](10-expressions.md#variable-name-creation-operator)
|
||||
|
||||
**Constraints**
|
||||
|
||||
Each *variable-name-creation-expression* must designate a simple variable name, i.e. it can not include array elements,
|
||||
property accesses, etc. that are not inside braced expression.
|
||||
|
||||
**Semantics**
|
||||
|
||||
A global variable is never defined explicitly; instead, it is created
|
||||
when it is first assigned a value. That may be done at the top level of
|
||||
a script, or from within a block in which that variable has been
|
||||
declared (*imported*, that is) using the `global` keyword.
|
||||
|
||||
One of the [predefined variables](#predefined-variables),
|
||||
[`$GLOBALS`](http://php.net/manual/reserved.variables.globals.php) is
|
||||
a [superglobal](#general) array whose elements' key/value pairs contain the
|
||||
name and value, respectively, of each global variable currently defined.
|
||||
As such, a global variable `gv` can be initialized with the value `v`,
|
||||
and possibly be created, using the following form of assignment:
|
||||
|
||||
`$GLOBALS['gv'] = v`
|
||||
|
||||
As `$GLOBALS` is a superglobal, `gv` need not first be the subject of a
|
||||
*global-declaration*.
|
||||
|
||||
A global variable has global [scope](04-basic-concepts.md#scope) and static
|
||||
[storage duration](04-basic-concepts.md#storage-duration). A global variable is a modifiable lvalue.
|
||||
|
||||
When a global value is imported into a function, each time the function
|
||||
is called, that execution is dealing with an [alias](04-basic-concepts.md#general) to that
|
||||
global variable. If that alias is passed to the [`unset` intrinsic](10-expressions.md#unset),
|
||||
only that alias is destroyed. The next time that function
|
||||
is called, a new alias is created with the current value of the global variable.
|
||||
|
||||
**Undefined Global Variables**
|
||||
|
||||
The same rules as for [undefined local variables](#undefined-local-variables) apply.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
$colors = array("red", "white", "blue");
|
||||
$GLOBALS['done'] = FALSE;
|
||||
// -----------------------------------------
|
||||
$min = 10; $max = 100; $average = NULL;
|
||||
global $min, $max; // allowed, but serves no purpose
|
||||
function compute($p)
|
||||
{
|
||||
global $min, $max;
|
||||
global $average;
|
||||
$average = ($max + $min)/2;
|
||||
|
||||
if ($p)
|
||||
{
|
||||
global $result;
|
||||
$result = 3.456; // initializes a global, creating it, if necessary
|
||||
}
|
||||
}
|
||||
compute(TRUE);
|
||||
echo "\$average = $average\n"; // $average = 55
|
||||
echo "\$result = $result\n"; // $result = 3.456
|
||||
// -----------------------------------------
|
||||
$g = 100;
|
||||
function f()
|
||||
{
|
||||
$v = 'g';
|
||||
global $$v; // import global $g
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Be also aware that declaring a variable global can hide a local variable and/or a function static with the same name. See [static variables section](#hidingNotice) for an example.
|
||||
|
||||
###Instance Properties
|
||||
|
||||
These are described in [class instance properties section](14-classes.md#properties).
|
||||
They have class [scope](04-basic-concepts.md#scope) of the defining class and
|
||||
allocated [storage duration](04-basic-concepts.md#storage-duration).
|
||||
Access to the instance properties is governed by [visibility rules](14-classes.md#general).
|
||||
|
||||
###Static Properties
|
||||
|
||||
These are described in [class static properties section](14-classes.md#properties).
|
||||
They have class [scope](04-basic-concepts.md#scope) of the defining class
|
||||
and static [storage duration](04-basic-concepts.md#storage-duration).
|
||||
Access to the static properties is governed by [visibility rules](14-classes.md#general).
|
||||
|
||||
###Class and Interface Constants
|
||||
|
||||
These are described in [class constants section](14-classes.md#constants) and [interface constants section](15-interfaces.md#constants). They have class [scope](04-basic-concepts.md#scope) of the defining class or interface
|
||||
and static [storage duration](04-basic-concepts.md#storage-duration).
|
||||
|
||||
##Predefined Variables
|
||||
|
||||
The following global variables are available to all scripts:
|
||||
|
||||
Variable Name | Description
|
||||
------------- | -----------
|
||||
`$argc` | `int`; The number of command-line arguments passed to the script. This is at least 1. (See `$argv` below). This may not be available in non-command-line builds of the Engine.
|
||||
`$argv` | `array`; An array of `$argc` elements containing the command-line arguments passed to the script as strings. Each element has an `int` key with the keys being numbered sequentially starting at zero through `$argc-1`. `$argv[0]` is the name of the script. It is implementation-defined as to how white space on command lines is handled, whether letter casing is preserved, which characters constitute quotes, or how `$argv[0]`'s string is formatted. As to how command-line arguments are defined, is unspecified. This may not be available in non-command-line builds of the Engine.
|
||||
`$_COOKIE` | `array`; The variables passed to the current script via HTTP Cookies.
|
||||
`$_ENV` | `array`; An array in which the environment variable names are element keys, and the environment variable value strings are element values. As to how an environment variable is defined, is unspecified.
|
||||
`$_FILES` | `array`; The items uploaded to the current script via the HTTP POST method.
|
||||
`$_GET` | `array`; The variables passed to the current script via the URL parameters.
|
||||
`$GLOBALS` | `array`; A [superglobal](#general) array containing the names of all variables that are currently defined in the global scope of the script. The variable names are the element keys, and the variable values are the element values.
|
||||
`$_POST` | `array`; The variables passed to the current script via the HTTP POST method.
|
||||
`$_REQUEST` | `array`; By default contains the contents of `$_COOKIE`, `$_GET`, and `$_POST`. The exact contents may depend on the Engine settings.
|
||||
`$_SERVER` | `array`; Server and execution environment information, such as headers, paths, and script locations. The entries in this array are taken from the Engine environment, e.g. the webserver.
|
||||
`$_SESSION` | `array`; The session variables available to the current script. This global is defined only if a [session](http://php.net/manual/en/book.session.php) is active.
|
||||
|
||||
All `$_*` variables above are superglobals. The exact set of the variables available may depend on the implementation, the Engine build and the environment.
|
|
@ -0,0 +1,182 @@
|
|||
#Conversions
|
||||
|
||||
##General
|
||||
|
||||
Explicit type conversion is performed using the [cast operator](10-expressions.md#cast-operator).
|
||||
If an operation or language construct expects operand of one type and a value of another type is given,
|
||||
implict (automatic) conversion will be performed. Same will happen with most internal functions, though some
|
||||
functions may do different things depending on argument type and thus would not perform the conversion.
|
||||
|
||||
If an expression is converted to its own type, the type and value of the
|
||||
result are the same as the type and value of the expression.
|
||||
|
||||
Conversions to `resource` and `null` types can not be performed.
|
||||
|
||||
##Converting to Boolean Type
|
||||
|
||||
The [result type] (http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting) is [`bool`](05-types.md#the-boolean-type).
|
||||
|
||||
If the source type is `int` or `float`, then if the source value tests equal
|
||||
to 0, the result value is `FALSE`; otherwise, the result value is `TRUE`.
|
||||
|
||||
If the source value is `NULL`, the result value is `FALSE`.
|
||||
|
||||
If the source is an empty string or the string "0", the result value is
|
||||
`FALSE`; otherwise, the result value is `TRUE`.
|
||||
|
||||
If the source is an array with zero elements, the result value is `FALSE`;
|
||||
otherwise, the result value is `TRUE`.
|
||||
|
||||
If the source is an object, the result value is `TRUE`.
|
||||
|
||||
If the source is a resource, the result value is `TRUE`.
|
||||
|
||||
The library function [`boolval`](http://www.php.net/boolval) allows values to be converted to
|
||||
`bool`.
|
||||
|
||||
##Converting to Integer Type
|
||||
|
||||
The [result type](http://www.php.net/manual/en/language.types.integer.php#language.types.integer.casting) is [`int`](05-types.md#the-integer-type).
|
||||
|
||||
If the source type is `bool`, then if the source value is `FALSE`, the
|
||||
result value is 0; otherwise, the result value is 1.
|
||||
|
||||
If the source type is `float`, for the values `INF`, `-INF`, and `NAN`, the
|
||||
result value is zero. For all other values, if the
|
||||
precision can be preserved (that is, the float is within the range of an
|
||||
integer), the fractional part is rounded towards zero. If the precision cannot
|
||||
be preserved, the following conversion algorithm is used, where *X* is
|
||||
defined as two to the power of the number of bits in an integer (for example,
|
||||
2 to the power of 32, i.e. 4294967296):
|
||||
|
||||
1. We take the floating point remainder (wherein the remainder has the same
|
||||
sign as the dividend) of dividing the float by *X*, rounded towards zero.
|
||||
2. If the remainder is less than zero, it is rounded towards
|
||||
infinity and *X* is added.
|
||||
3. This result is converted to an unsigned integer.
|
||||
4. This result is converted to a signed integer by treating the unsigned
|
||||
integer as a two's complement representation of the signed integer.
|
||||
|
||||
Implementations may implement this conversion differently (for example, on some
|
||||
architectures there may be hardware support for this specific conversion mode)
|
||||
so long as the result is the same.
|
||||
|
||||
If the source value is `NULL`, the result value is 0.
|
||||
|
||||
If the source is a [numeric string or leading-numeric string](05-types.md#the-string-type)
|
||||
having integer format, if the precision can be preserved the result
|
||||
value is that string's integer value; otherwise, the result is
|
||||
undefined. If the source is a numeric string or leading-numeric string
|
||||
having floating-point format, the string's floating-point value is
|
||||
treated as described above for a conversion from `float`. The trailing
|
||||
non-numeric characters in leading-numeric strings are ignored. For any
|
||||
other string, the result value is 0.
|
||||
|
||||
If the source is an array with zero elements, the result value is 0;
|
||||
otherwise, the result value is 1.
|
||||
|
||||
If the source is an object, if the class defines a conversion function,
|
||||
the result is determined by that function (this is currently available only to internal classes).
|
||||
If not, the conversion is invalid, the result is assumed to be 1 and a non-fatal error is produced.
|
||||
|
||||
If the source is a resource, the result is the resource's unique ID.
|
||||
|
||||
The library function [`intval`](http://php.net/manual/function.intval.php) allows values
|
||||
to be converted to `int`.
|
||||
|
||||
##Converting to Floating-Point Type
|
||||
|
||||
The [result type](http://www.php.net/manual/en/language.types.float.php#language.types.float.casting) is [`float`](05-types.md#the-floating-point-type).
|
||||
|
||||
If the source type is `int`, if the precision can be preserved the result
|
||||
value is the closest approximation to the source value; otherwise, the
|
||||
result is undefined.
|
||||
|
||||
If the source is a [numeric string or leading-numeric string](05-types.md#the-string-type)
|
||||
having integer format, the string's integer value is treated as
|
||||
described above for a conversion from `int`. If the source is a numeric
|
||||
string or leading-numeric string having floating-point format, the
|
||||
result value is the closest approximation to the string's floating-point
|
||||
value. The trailing non-numeric characters in leading-numeric strings
|
||||
are ignored. For any other string, the result value is 0.
|
||||
|
||||
If the source is an object, if the class defines a conversion function,
|
||||
the result is determined by that function (this is currently available only to internal classes).
|
||||
If not, the conversion is invalid, the result is assumed to be 1.0 and a non-fatal error is produced.
|
||||
|
||||
For sources of all other types, the conversion result is obtained by first
|
||||
[converting the source value to `int`](#converting-to-integer-type) and then to `float`.
|
||||
|
||||
The library function [`floatval`](http://www.php.net/floatval) allows values to be converted to
|
||||
float.
|
||||
|
||||
##Converting to String Type
|
||||
|
||||
The [result type](http://www.php.net/manual/en/language.types.string.php#language.types.string.casting) is [`string`](05-types.md#the-string-type).
|
||||
|
||||
If the source type is `bool`, then if the source value is `FALSE`, the
|
||||
result value is the empty string; otherwise, the result value is "1".
|
||||
|
||||
If the source type is `int` or `float`, then the result value is a string
|
||||
containing the textual representation of the source value (as specified
|
||||
by the library function [`sprintf`](http://www.php.net/sprintf)).
|
||||
|
||||
If the source value is `NULL`, the result value is the empty string.
|
||||
|
||||
If the source is an array, the conversion is invalid. The result value is
|
||||
the string "Array" and a non-fatal error is produced.
|
||||
|
||||
If the source is an object, then if that object's class has a
|
||||
[`__toString` method](14-classes.md#method-__tostring), the result value is the string returned
|
||||
by that method; otherwise, the conversion is invalid and a fatal error is produced.
|
||||
|
||||
If the source is a resource, the result value is an
|
||||
implementation-defined string.
|
||||
|
||||
The library function [`strval`](http://www.php.net/strval) allows values to be converted to
|
||||
string.
|
||||
|
||||
##Converting to Array Type
|
||||
|
||||
The [result type](http://www.php.net/manual/en/language.types.array.php#language.types.array.casting) is [`array`](05-types.md#the-array-type).
|
||||
|
||||
If the source value is `NULL`, the result value is an array of zero
|
||||
elements.
|
||||
|
||||
If the source type is scalar or `resource` and it is non-`NULL`, the result value is
|
||||
an array of one element under the key 0 whose value is that of the source.
|
||||
|
||||
If the source is an object, the result is
|
||||
an [array](http://php.net/manual/language.types.array.php) of
|
||||
zero or more elements, where the elements are key/value pairs
|
||||
corresponding to the
|
||||
[object](http://php.net/manual/language.types.object.php)'s
|
||||
instance properties. The order of insertion of the elements into the
|
||||
array is the lexical order of the instance properties in the
|
||||
[*class-member-declarations*](14-classes.md#class-members) list.
|
||||
|
||||
For public instance properties, the keys of the array elements would
|
||||
be the same as the property name.
|
||||
|
||||
The key for a private instance property has the form "\\0*class*\\0*name*",
|
||||
where the *class* is the class name, and the *name* is the property name.
|
||||
|
||||
The key for a protected instance property has the form "\\0\*\\0*name*",
|
||||
where *name* is that of the property.
|
||||
|
||||
The value for each key is that from the corresponding property, or `NULL` if
|
||||
the property was not initialized.
|
||||
|
||||
##Converting to Object Type
|
||||
|
||||
The [result type](http://www.php.net/manual/en/language.types.object.php#language.types.object.casting) is [`object`](05-types.md#objects).
|
||||
|
||||
If the source has any type other than object, the result is an instance
|
||||
of the predefined class [`stdClass`](14-classes.md#class-stdclass). If the value of the source
|
||||
is `NULL`, the instance is empty. If the value of the source has a scalar
|
||||
type and is non-`NULL`, or is a `resource`, the instance contains a public property called
|
||||
`scalar` whose value is that of the source. If the value of the source is
|
||||
an array, the instance contains a set of public properties whose names
|
||||
and values are those of the corresponding key/value pairs in the source.
|
||||
The order of the properties is the order of insertion of the source's
|
||||
elements.
|
|
@ -0,0 +1,872 @@
|
|||
#Lexical Structure
|
||||
|
||||
##Scripts
|
||||
|
||||
A [script](04-basic-concepts.md#program-structure) is an ordered sequence of characters. Typically, a
|
||||
script has a one-to-one correspondence with a file in a file system, but
|
||||
this correspondence is not required.
|
||||
|
||||
Conceptually speaking, a script is translated using the following steps:
|
||||
|
||||
1. Transformation, which converts a script from a particular character
|
||||
repertoire and encoding scheme into a sequence of 8-bit characters.
|
||||
|
||||
2. Lexical analysis, which translates a stream of input characters into
|
||||
a stream of tokens.
|
||||
|
||||
3. Syntactic analysis, which translates the stream of tokens into
|
||||
executable code.
|
||||
|
||||
Conforming implementations must accept scripts encoded with the UTF-8
|
||||
encoding form (as defined by the Unicode standard), and transform them
|
||||
into a sequence of characters. Implementations can choose to accept and
|
||||
transform additional character encoding schemes.
|
||||
|
||||
##Grammars
|
||||
|
||||
This specification shows the syntax of the PHP programming language
|
||||
using two grammars. The *lexical grammar* defines how source
|
||||
characters are combined to form white space, comments, and tokens. The
|
||||
*syntactic grammar* defines how the resulting tokens are combined to
|
||||
form PHP programs.
|
||||
|
||||
The grammars are presented using *grammar productions*, with each one
|
||||
defining a non-terminal symbol and the possible expansions of that
|
||||
non-terminal symbol into sequences of non-terminal or terminal symbols.
|
||||
In productions, non-terminal symbols are shown in slanted type *like
|
||||
this*, and terminal symbols are shown in a fixed-width font `like this`.
|
||||
|
||||
The first line of a grammar production is the name of the non-terminal
|
||||
symbol being defined, followed by one colon for a syntactic grammar
|
||||
production, and two colons for a lexical grammar production. Each
|
||||
successive indented line contains a possible expansion of the
|
||||
non-terminal given as a sequence of non-terminal or terminal symbols.
|
||||
For example, the production:
|
||||
|
||||
<pre>
|
||||
<i>single-line-comment::</i>
|
||||
// input-characters<sub>opt</sub>
|
||||
# input-characters<sub>opt</sub>
|
||||
</pre>
|
||||
|
||||
defines the lexical grammar production *single-line-comment* as being
|
||||
the terminals `//` or `#`, followed by an optional *input-characters*. Each
|
||||
expansion is listed on a separate line.
|
||||
|
||||
Although alternatives are usually listed on separate lines, when there
|
||||
is a large number, the shorthand phrase “one of” may precede a list of
|
||||
expansions given on a single line. For example,
|
||||
|
||||
<pre>
|
||||
<i>hexadecimal-digit:: one of</i>
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
a b c d e f
|
||||
A B C D E F
|
||||
</pre>
|
||||
|
||||
##Lexical analysis
|
||||
|
||||
###General
|
||||
|
||||
The production *input-file* is the root of the lexical structure for a
|
||||
script. Each script must conform to this production.
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>input-file::</i>
|
||||
<i>input-element</i>
|
||||
<i>input-file input-element</i>
|
||||
<i>input-element::</i>
|
||||
<i>comment</i>
|
||||
<i>white-space</i>
|
||||
<i>token</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*comment*](#comments)
|
||||
* [*white-space*](#white-space)
|
||||
* [*token*](#tokens)
|
||||
|
||||
**Semantics**
|
||||
|
||||
The basic elements of a script are comments, white space, and tokens.
|
||||
|
||||
The lexical processing of a script involves the reduction of that script
|
||||
into a sequence of [tokens](#tokens) that becomes the input to the
|
||||
syntactic analysis. Tokens can be separated by [white space](#white-space) and
|
||||
delimited [comments](#comments).
|
||||
|
||||
Lexical processing always results in the creation of the longest
|
||||
possible lexical element. (For example, `$a+++++$b` must be parsed as
|
||||
`$a++ ++ +$b`, which syntactically is invalid).
|
||||
|
||||
###Comments
|
||||
|
||||
Two forms of comments are supported: *delimited comments* and
|
||||
*single-line comments*.
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>comment::</i>
|
||||
<i>single-line-comment</i>
|
||||
<i>delimited-comment</i>
|
||||
|
||||
<i>single-line-comment::</i>
|
||||
// <i>input-characters<sub>opt</sub></i>
|
||||
# <i>input-characters<sub>opt</sub></i>
|
||||
|
||||
<i>input-characters::</i>
|
||||
<i>input-character</i>
|
||||
<i>input-characters input-character</i>
|
||||
|
||||
<i>input-character::</i>
|
||||
Any source character except <i>new-line</i>
|
||||
|
||||
<i>new-line::</i>
|
||||
Carriage-return character (U+000D)
|
||||
Line-feed character (U+000A)
|
||||
Carriage-return character (U+000D) followed by line-feed character (U+000A)
|
||||
|
||||
<i>delimited-comment::</i>
|
||||
/* No characters or any source character sequence except */ */
|
||||
</pre>
|
||||
|
||||
**Semantics**
|
||||
|
||||
Except within a string literal or a comment, the characters `/*` start a
|
||||
delimited comment, which ends with the characters `*/`. Except within a
|
||||
string literal or a comment, the characters `//` or `#` start a single-line
|
||||
comment, which ends with a new line. That new line is not part of the
|
||||
comment. However, if the single-line comment is the last source element
|
||||
in an embedded script, the trailing new line can be omitted. (Note: this
|
||||
allows for uses like `<?php ... // ... ?>`).
|
||||
|
||||
A delimited comment can occur in any place in a script in which [white
|
||||
space](#white-space) can occur. (For example;
|
||||
`/*...*/$c/*...*/=/*...*/567/*...*/;/*...*/` is parsed as `$c=567;`, and
|
||||
`$k = $i+++/*...*/++$j;` is parsed as `$k = $i+++ ++$j;`).
|
||||
|
||||
**Implementation Notes**
|
||||
|
||||
During tokenizing, an implementation can treat a delimited comment as
|
||||
though it was white space.
|
||||
|
||||
###White Space
|
||||
|
||||
White space consists of an arbitrary combination of one or more
|
||||
new-line, space and horizontal tab characters.
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>white-space::</i>
|
||||
<i>white-space-character</i>
|
||||
<i>white-space white-space-character</i>
|
||||
|
||||
<i>white-space-character::</i>
|
||||
<i>new-line</i>
|
||||
Space character (U+0020)
|
||||
Horizontal-tab character (U+0009)
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*new-line*](#comments)
|
||||
|
||||
**Semantics**
|
||||
|
||||
The space and horizontal tab characters are considered *horizontal
|
||||
white-space characters*.
|
||||
|
||||
###Tokens
|
||||
|
||||
####General
|
||||
|
||||
There are several kinds of source *tokens*:
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>token::</i>
|
||||
<i>variable-name</i>
|
||||
<i>name</i>
|
||||
<i>keyword</i>
|
||||
<i>literal</i>
|
||||
<i>operator-or-punctuator</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*variable-name*](#names)
|
||||
* [*name*](#names)
|
||||
* [*keyword*](#keywords)
|
||||
* [*literal*](#general-2)
|
||||
* [*operator-or-punctuator*](#operators-and-punctuators)
|
||||
|
||||
####Names
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>variable-name::</i>
|
||||
$ <i>name</i>
|
||||
|
||||
<i>namespace-name::</i>
|
||||
<i>name</i>
|
||||
<i>namespace-name</i> \ <i>name</i>
|
||||
|
||||
<i>namespace-name-as-a-prefix::</i>
|
||||
\
|
||||
\<sub>opt</sub> <i>namespace-name</i> \
|
||||
namespace \
|
||||
namespace \ <i>namespace-name</i> \
|
||||
|
||||
<i>qualified-name::</i>
|
||||
<i>namespace-name-as-a-prefix<sub>opt</sub> name</i>
|
||||
|
||||
<i>name::</i>
|
||||
<i>name-nondigit</i>
|
||||
<i>name name-nondigit</i>
|
||||
<i>name digit</i>
|
||||
|
||||
<i>name-nondigit::</i>
|
||||
<i>nondigit</i>
|
||||
one of the characters U+0080–U+00ff
|
||||
|
||||
<i>nondigit:: one of</i>
|
||||
_
|
||||
a b c d e f g h i j k l m
|
||||
n o p q r s t u v w x y z
|
||||
A B C D E F G H I J K L M
|
||||
N O P Q R S T U V W X Y Z
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*digit*](#integer-literals)
|
||||
|
||||
**Semantics**
|
||||
|
||||
Names are used to identify the following: [constants](06-constants.md#general),
|
||||
[variables](07-variables.md#general), [labels](11-statements.md#labeled-statements),
|
||||
[functions](13-functions.md#function-definitions), [classes](14-classes.md#class-declarations),
|
||||
[class members](14-classes.md#class-members), [interfaces](15-interfaces.md#interface-declarations),
|
||||
[traits](16-traits.md#general), [namespaces](18-namespaces.md#general),
|
||||
and names in [heredoc](#heredoc-string-literals) and [nowdoc comments](#nowdoc-string-literals).
|
||||
|
||||
A *name* begins with an underscore (_), *name-nondigit*, or extended
|
||||
name character in the range U+0080–-U+00ff. Subsequent characters can
|
||||
also include *digits*. A *variable name* is a name with a leading
|
||||
dollar ($).
|
||||
|
||||
Unless stated otherwise ([functions](13-functions.md#function-definitions),
|
||||
[classes](14-classes.md#class-declarations), [methods](14-classes.md#methods),
|
||||
[interfaces](15-interfaces.md#interface-declarations), [traits](16-traits.md#trait-declarations),
|
||||
[namespaces](18-namespaces.md#defining-namespaces), names are case-sensitive, and every character in a name is significant.
|
||||
|
||||
Names beginning with two underscores (__) are reserved by the PHP language and should not be defined by the user code.
|
||||
|
||||
The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE`, and `void`.
|
||||
|
||||
The following names are reserved for future use and should not be used as the names of classes, interfaces, or traits: `mixed`, `numeric`, `object`, and `resource`.
|
||||
|
||||
With the exception of `class`, all [keywords](09-lexical-structures#keywords) can be used as names for the members of a class, interface, or trait. However, `class` can be used as the name of a property or method.
|
||||
|
||||
Variable names and function names (when used in a function-call context)
|
||||
need not be defined as source tokens; they can also be created at
|
||||
runtime using the [variable name-creation operator](10-expressions.md#variable-name-creation-operator). (For
|
||||
example, given `$a = "Total"; $b = 3; $c = $b + 5;`, `${$a.$b.$c} = TRUE;`
|
||||
is equivalent to `$Total38 = TRUE;`, and `${$a.$b.$c}()` is
|
||||
equivalent to `Total38()`).
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
const MAX_VALUE = 100;
|
||||
function getData() { /*...*/ }
|
||||
class Point { /*...*/ }
|
||||
interface ICollection { /*...*/ }
|
||||
```
|
||||
|
||||
**Implementation Notes**
|
||||
|
||||
An implementation is discouraged from placing arbitrary restrictions on
|
||||
name lengths.
|
||||
|
||||
####Keywords
|
||||
|
||||
A *keyword* is a name-like sequence of characters that is reserved, and
|
||||
cannot be used as a name.
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>keyword:: one of</i>
|
||||
abstract and array as break callable case catch class clone
|
||||
const continue declare default die do echo else elseif empty
|
||||
enddeclare endfor endforeach endif endswitch endwhile eval exit
|
||||
extends final finally for foreach function global
|
||||
goto if implements include include_once instanceof
|
||||
insteadof interface isset list namespace new or print private
|
||||
protected public require require_once return static switch
|
||||
throw trait try unset use var while xor yield yield from
|
||||
</pre>
|
||||
|
||||
**Semantics**
|
||||
|
||||
Keywords are not case-sensitive.
|
||||
|
||||
Note carefully that `yield from` is a single token that contains whitespace. However, [comments](#comments) are not permitted in that whitespace.
|
||||
|
||||
Also, all [*magic constants*](06-constants.md#context-dependent-constants) are also treated as keywords.
|
||||
|
||||
####Literals
|
||||
|
||||
The source code representation of a value is called a *literal*.
|
||||
|
||||
#####Integer Literals
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>integer-literal::</i>
|
||||
<i>decimal-literal</i>
|
||||
<i>octal-literal</i>
|
||||
<i>hexadecimal-literal</i>
|
||||
<i>binary-literal</i>
|
||||
|
||||
<i>decimal-literal::</i>
|
||||
<i>nonzero-digit</i>
|
||||
<i>decimal-literal digit</i>
|
||||
|
||||
<i>octal-literal::</i>
|
||||
0
|
||||
<i>octal-literal octal-digit</i>
|
||||
|
||||
<i>hexadecimal-literal::</i>
|
||||
<i>hexadecimal-prefix hexadecimal-digit</i>
|
||||
<i>hexadecimal-literal hexadecimal-digit</i>
|
||||
|
||||
<i>hexadecimal-prefix:: one of</i>
|
||||
0x 0X
|
||||
|
||||
<i>binary-literal::</i>
|
||||
<i>binary-prefix binary-digit</i>
|
||||
<i>binary-literal binary-digit</i>
|
||||
|
||||
<i>binary-prefix:: one of</i>
|
||||
0b 0B
|
||||
|
||||
<i>digit:: one of</i>
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
|
||||
<i>nonzero-digit:: one of</i>
|
||||
1 2 3 4 5 6 7 8 9
|
||||
|
||||
<i>octal-digit:: one of</i>
|
||||
0 1 2 3 4 5 6 7
|
||||
|
||||
<i>hexadecimal-digit:: one of</i>
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
a b c d e f
|
||||
A B C D E F
|
||||
|
||||
<i>binary-digit:: one of</i>
|
||||
0 1
|
||||
</pre>
|
||||
|
||||
**Semantics**
|
||||
|
||||
The value of a decimal integer literal is computed using base 10; that
|
||||
of an octal integer literal, base 8; that of a hexadecimal integer
|
||||
literal, base 16; and that of a binary integer literal, base 2.
|
||||
|
||||
If the value represented by *integer-literal* can fit in type int,
|
||||
that would be the type of the resulting value; otherwise, the type would be float,
|
||||
as described below.
|
||||
|
||||
Since negative numbers are represented in PHP as a negation of a positive
|
||||
number, the smallest negative value (-2147483648 for 32 bits and -9223372036854775808 for 64 bits)
|
||||
can not be represented as a decimal integer literal. If the non-negative
|
||||
value is too large to represent as an `int`, it becomes `float`, which is
|
||||
then negated.
|
||||
|
||||
Literals written using hexadecimal, octal, or binary notations are
|
||||
considered to have non-negative values.
|
||||
|
||||
An integer literal is always a constant expression.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
$count = 10; // decimal 10
|
||||
|
||||
0b101010 >> 4; // binary 101010 and decimal 4
|
||||
|
||||
0XAF << 023; // hexadecimal AF and octal 23
|
||||
```
|
||||
|
||||
On an implementation using 32-bit int representation
|
||||
|
||||
```
|
||||
2147483648 -> 2147483648 (too big for int, so is a float)
|
||||
|
||||
-2147483648 -> -2147483648 (too big for int, so is a float, negated)
|
||||
|
||||
-2147483647 - 1 -> -2147483648 fits in int
|
||||
|
||||
0x80000000 -> 2147483648 (too big for int, so is a float)
|
||||
```
|
||||
|
||||
#####Floating-Point Literals
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>floating-literal::</i>
|
||||
<i>fractional-literal exponent-part<sub>opt</sub></i>
|
||||
<i>digit-sequence exponent-part</i>
|
||||
|
||||
<i>fractional-literal::</i>
|
||||
<i>digit-sequence<sub>opt</sub></i> . <i>digit-sequence</i>
|
||||
<i>digit-sequence</i> .
|
||||
|
||||
<i>exponent-part::</i>
|
||||
e <i>sign<sub>opt</sub> digit-sequence</i>
|
||||
E <i>sign<sub>opt</sub> digit-sequence</i>
|
||||
|
||||
<i>sign:: one of</i>
|
||||
+ -
|
||||
|
||||
<i>digit-sequence::</i>
|
||||
<i>digit</i>
|
||||
<i>digit-sequence digit</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*digit*](#integer-literals)
|
||||
|
||||
**Constraints**
|
||||
|
||||
The value of a floating-point literal must be representable by its type.
|
||||
|
||||
**Semantics**
|
||||
|
||||
The type of a *floating-literal* is `float`.
|
||||
|
||||
The constants [`INF`](06-constants.md#core-predefined-constants) and
|
||||
[`NAN`](06-constants.md#core-predefined-constants) provide access to the
|
||||
floating-point values for infinity and Not-a-Number, respectively.
|
||||
|
||||
A floating point literal is always a constant expression.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
$values = array(1.23, 3e12, 543.678E-23);
|
||||
```
|
||||
|
||||
#####String Literals
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>string-literal::</i>
|
||||
<i>single-quoted-string-literal</i>
|
||||
<i>double-quoted-string-literal</i>
|
||||
<i>heredoc-string-literal</i>
|
||||
<i>nowdoc-string-literal</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*single-quoted-string-literal*](#single-quoted-string-literals)
|
||||
* [*double-quoted-string-literal*](#double-quoted-string-literals)
|
||||
* [*heredoc-string-literal*](#heredoc-string-literals)
|
||||
* [*nowdoc-string-literal*](#nowdoc-string-literals)
|
||||
|
||||
**Semantics**
|
||||
|
||||
A string literal is a sequence of zero or more characters delimited in
|
||||
some fashion. The delimiters are not part of the literal's content.
|
||||
|
||||
The type of a string literal is `string`.
|
||||
|
||||
######Single-Quoted String Literals
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>single-quoted-string-literal::</i>
|
||||
<i>b-prefix<sub>opt</sub></i> ' <i>sq-char-sequence<sub>opt</sub></i> '
|
||||
|
||||
<i>sq-char-sequence::</i>
|
||||
<i>sq-char</i>
|
||||
<i>sq-char-sequence sq-char</i>
|
||||
|
||||
<i>sq-char::</i>
|
||||
<i>sq-escape-sequence</i>
|
||||
\<i><sub>opt</sub></i> any member of the source character set except single-quote (') or backslash (\)
|
||||
|
||||
<i>sq-escape-sequence:: one of</i>
|
||||
\' \\
|
||||
|
||||
<i>b-prefix:: one of</i>
|
||||
b B
|
||||
</pre>
|
||||
|
||||
**Semantics**
|
||||
|
||||
A single-quoted string literal is a string literal delimited by
|
||||
single-quotes (`'`, U+0027). The literal can contain any source character except
|
||||
single-quote (`'`) and backslash (`\\`), which can only be represented by
|
||||
their corresponding escape sequence.
|
||||
|
||||
The optional *b-prefix* is reserved for future use in dealing with
|
||||
so-called *binary strings*. For now, a *single-quoted-string-literal*
|
||||
with a *b-prefix* is equivalent to one without.
|
||||
|
||||
A single-quoted string literal is always a constant expression.
|
||||
|
||||
**Examples**
|
||||
|
||||
```
|
||||
'This text is taken verbatim'
|
||||
|
||||
'Can embed a single quote (\') and a backslash (\\) like this'
|
||||
```
|
||||
|
||||
######Double-Quoted String Literals
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>double-quoted-string-literal::</i>
|
||||
<i>b-prefix<sub>opt</sub></i> " <i>dq-char-sequence<sub>opt</sub></i> "
|
||||
|
||||
<i>dq-char-sequence::</i>
|
||||
<i>dq-char</i>
|
||||
<i>dq-char-sequence dq-char</i>
|
||||
|
||||
<i>dq-char::</i>
|
||||
<i>dq-escape-sequence</i>
|
||||
any member of the source character set except double-quote (") or backslash (\)
|
||||
\ any member of the source character set except "\$efnrtvxX or <i>octal-digit</i>
|
||||
|
||||
<i>dq-escape-sequence::</i>
|
||||
<i>dq-simple-escape-sequence</i>
|
||||
<i>dq-octal-escape-sequence</i>
|
||||
<i>dq-hexadecimal-escape-sequence</i>
|
||||
<i>dq-unicode-escape-sequence</i>
|
||||
|
||||
<i>dq-simple-escape-sequence:: one of</i>
|
||||
\" \\ \$ \e \f \n \r \t \v
|
||||
|
||||
<i>dq-octal-escape-sequence::</i>
|
||||
\ <i>octal-digit</i>
|
||||
\ <i>octal-digit octal-digit</i>
|
||||
\ <i>octal-digit octal-digit octal-digit</i>
|
||||
|
||||
<i>dq-hexadecimal-escape-sequence::</i>
|
||||
\x <i>hexadecimal-digit hexadecimal-digit<sub>opt</sub></i>
|
||||
\X <i>hexadecimal-digit hexadecimal-digit<sub>opt</sub></i>
|
||||
|
||||
<i>dq-unicode-escape-sequence::</i>
|
||||
\u{ codepoint-digits }
|
||||
|
||||
<i>codepoint-digits::</i>
|
||||
<i>hexadecimal-digit</i>
|
||||
<i>hexadecimal-digit codepoint-digits</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*octal-digit*](#integer-literals)
|
||||
* [*hexadecimal-digit*](#integer-literals)
|
||||
* [*b-prefix*](#single-quoted-string-literals)
|
||||
|
||||
**Semantics**
|
||||
|
||||
A double-quoted string literal is a string literal delimited by
|
||||
double-quotes (`"`, U+0022). The literal can contain any source character except
|
||||
double-quote (`"`) and backslash (`\\`), which can only be represented by
|
||||
their corresponding escape sequence. Certain other (and sometimes
|
||||
non-printable) characters can also be expressed as escape sequences.
|
||||
|
||||
The optional *b-prefix* is reserved for future use in dealing with
|
||||
so-called *binary strings*. For now, a *double-quoted-string-literal*
|
||||
with a *b-prefix* is equivalent to one without.
|
||||
|
||||
An escape sequence represents a single-character encoding, as described
|
||||
in the table below:
|
||||
|
||||
Escape sequence | Character name | Unicode character
|
||||
--------------- | --------------| ------
|
||||
\$ | Dollar sign | U+0024
|
||||
\" | Double quote | U+0022
|
||||
\\ | Backslash | U+005C
|
||||
\e | Escape | U+001B
|
||||
\f | Form feed | U+000C
|
||||
\n | New line | U+000A
|
||||
\r | Carriage Return | U+000D
|
||||
\t | Horizontal Tab | U+0009
|
||||
\v | Vertical Tab | U+000B
|
||||
\ooo | 1–3-digit octal digit value ooo
|
||||
\xhh or \Xhh | 1–2-digit hexadecimal digit value hh
|
||||
\u{xxxxxx} | UTF-8 encoding of Unicode codepoint U+xxxxxx | U+xxxxxx
|
||||
|
||||
Within a double-quoted string literal, except when recognized as the
|
||||
start of an escape sequence, a backslash (\\) is retained verbatim.
|
||||
|
||||
Within a double-quoted string literal a dollar ($) character not
|
||||
escaped by a backslash (\\) is handled using a variable substitution rules
|
||||
described below.
|
||||
|
||||
The `\u{xxxxxx}` escape sequence produces the UTF-8 encoding of the Unicode
|
||||
codepoint with the hexadecimal number specified within the curly braces.
|
||||
Implementations MUST NOT allow Unicode codepoints beyond U+10FFFF as this is
|
||||
outside the range UTF-8 can encode (see
|
||||
[RFC 3629](http://tools.ietf.org/html/rfc3629#section-3)). If a codepoint
|
||||
larger than U+10FFFF is specified, implementations MUST error.
|
||||
Implementations MUST pass through `\u` verbatim and not interpret it as an
|
||||
escape sequence if it is not followed by an opening `{`, but if it is,
|
||||
implementations MUST produce an error if there is no terminating `}` or the
|
||||
contents are not a valid codepoint. Implementations MUST support leading zeroes,
|
||||
but MUST NOT support leading or trailing whitespace for the codepoint between
|
||||
the opening and terminating braces. Implementations MUST allow Unicode
|
||||
codepoints that are not Unicode scalar values, such as high and low surrogates.
|
||||
|
||||
A Unicode escape sequence cannot be created by variable substitution. For example, given `$v = "41"`,
|
||||
`"\u{$v}"` results in `"\u41"`, a string of length 4, while `"\u{0$v}"` and `"\u{{$v}}"` contain
|
||||
ill-formed Unicode escape sequences.
|
||||
|
||||
**Variable substitution**
|
||||
|
||||
The variable substitution accepts the following syntax:
|
||||
|
||||
<pre>
|
||||
<i>string-variable::</i>
|
||||
<i>variable-name</i> <i>offset-or-property<sub>opt</sub></i>
|
||||
${ <i>expression</i> }
|
||||
|
||||
<i>offset-or-property::</i>
|
||||
<i>offset-in-string</i>
|
||||
<i>property-in-string</i>
|
||||
|
||||
<i>offset-in-string::</i>
|
||||
[ <i>name</i> ]
|
||||
[ <i>variable-name</i> ]
|
||||
[ <i>integer-literal</i> ]
|
||||
|
||||
<i>property-in-string::</i>
|
||||
-> <i>name</i>
|
||||
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*variable-name*](#names)
|
||||
* [*name*](#names)
|
||||
* [*integer-literal*](#integer-literals)
|
||||
* [*expression*](10-expressions.md#general-6)
|
||||
|
||||
*expression* works the same way as in [variable name creation operator](10-expressions.md#variable-name-creation-operator).
|
||||
|
||||
After the variable defined by the syntax above is evaluated, its value is converted
|
||||
to string according to the rules of [string conversion](08-conversions.md#converting-to-string-type)
|
||||
and is substituted into the string in place of the variable substitution expression.
|
||||
|
||||
Subscript or property access defined by *offset-in-string* and *property-in-string*
|
||||
is resolved according to the rules of the [subscript operator](10-expressions.md#subscript-operator)
|
||||
and [member selection operator](10-expressions.md#member-selection-operator) respectively.
|
||||
The exception is that *name* inside *offset-in-string* is interpreted as a string literal even if it is not
|
||||
quoted.
|
||||
|
||||
If the character sequence following the `$` does not parse as *name* and does not start with `{`, the `$` character
|
||||
is instead interpreted verbatim and no variable substitution is performed.
|
||||
|
||||
Variable substitution also provides limited support for the evaluation
|
||||
of expressions. This is done by enclosing an expression in a pair of
|
||||
matching braces (`{ ... }`). The opening brace must be followed immediately by
|
||||
a dollar (`$`) without any intervening white space, and that dollar must
|
||||
begin a variable name. If this is not the case, braces are treated
|
||||
verbatim. If the opening brace (`{`) is escaped it is not interpreted as a start of
|
||||
the embedded expression and instead is interpreted verbatim.
|
||||
|
||||
The value of the expression is converted to string according to the rules of
|
||||
[string conversion](08-conversions.md#converting-to-string-type) and is substituted into the string
|
||||
in place of the substitution expression.
|
||||
|
||||
A double-quoted string literal is a constant expression if it does not
|
||||
contain any variable substitution.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
$x = 123;
|
||||
echo ">\$x.$x"."<"; // → >$x.123<
|
||||
// -----------------------------------------
|
||||
$colors = array("red", "white", "blue");
|
||||
$index = 2;
|
||||
echo "\$colors[$index] contains >$colors[$index]<\n";
|
||||
// → $colors[2] contains >blue<
|
||||
// -----------------------------------------
|
||||
class C {
|
||||
public $p1 = 2;
|
||||
}
|
||||
$myC = new C();
|
||||
echo "\$myC->p1 = >$myC->p1<\n"; // → $myC->p1 = >2<
|
||||
```
|
||||
|
||||
######Heredoc String Literals
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>heredoc-string-literal::</i>
|
||||
<i>b-prefix<sub>opt</sub></i> <<< <i>hd-start-identifier new-line hd-body<sub>opt</i> hd-end-identifier</i> ;<i><sub>opt</sub> new-line</i>
|
||||
|
||||
<i>hd-start-identifier::</i>
|
||||
<i>name</i>
|
||||
" <i>name</i> "
|
||||
|
||||
<i>hd-end-identifier::</i>
|
||||
<i>name</i>
|
||||
|
||||
<i>hd-body::</i>
|
||||
<i>hd-char-sequence<sub>opt</sub> new-line</i>
|
||||
|
||||
<i>hd-char-sequence::</i>
|
||||
<i>hd-char</i>
|
||||
<i>hd-char-sequence hd-char</i>
|
||||
|
||||
<i>hd-char::</i>
|
||||
<i>hd-escape-sequence</i>
|
||||
any member of the source character set except backslash (\)
|
||||
\ any member of the source character set except \$efnrtvxX or <i>octal-digit</i>
|
||||
|
||||
<i>hd-escape-sequence::</i>
|
||||
<i>hd-simple-escape-sequence</i>
|
||||
<i>dq-octal-escape-sequence</i>
|
||||
<i>dq-hexadecimal-escape-sequence</i>
|
||||
<i>dq-unicode-escape-sequence</i>
|
||||
|
||||
<i>hd-simple-escape-sequence:: one of</i>
|
||||
\\ \$ \e \f \n \r \t \v
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*name*](#names)
|
||||
* [*new-line*](#comments)
|
||||
* [*dq-octal-escape-sequence*](#double-quoted-string-literals)
|
||||
* [*dq-hexadecimal-escape-sequence*](#double-quoted-string-literals)
|
||||
* [*b-prefix*](#single-quoted-string-literals)
|
||||
|
||||
**Constraints**
|
||||
|
||||
The start and end identifier names must be the same. Only horizontal white
|
||||
space is permitted between `<<<` and the start identifier. No white
|
||||
space is permitted between the start identifier and the new-line that
|
||||
follows. No white space is permitted between the new-line and the end
|
||||
identifier that follows. Except for an optional semicolon (`;`), no
|
||||
characters—-not even comments or white space-—are permitted between the
|
||||
end identifier and the new-line that terminates that source line.
|
||||
|
||||
**Semantics**
|
||||
|
||||
A heredoc string literal is a string literal delimited by
|
||||
"`<<< name`" and "`name`". The literal can contain any source
|
||||
character. Certain other (and sometimes non-printable) characters can
|
||||
also be expressed as escape sequences.
|
||||
|
||||
A heredoc literal supports variable substitution as defined for
|
||||
[double-quoted string literals](#double-quoted-string-literals).
|
||||
|
||||
A heredoc string literal is a constant expression if it does not contain
|
||||
any variable substitution.
|
||||
|
||||
The optional *b-prefix* has no effect.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
$v = 123;
|
||||
$s = <<< ID
|
||||
S'o'me "\"t e\txt; \$v = $v"
|
||||
Some more text
|
||||
ID;
|
||||
echo ">$s<";
|
||||
// → >S'o'me "\"t e xt; $v = 123"
|
||||
// Some more text<
|
||||
```
|
||||
|
||||
######Nowdoc String Literals
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>nowdoc-string-literal::</i>
|
||||
<i>b-prefix<sub>opt</sub></i> <<< ' <i>name</i> ' <i>new-line hd-body<sub>opt</sub> name</i> ;<i><sub>opt</sub> new-line</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*hd-body*](#heredoc-string-literals)
|
||||
* [*new-line*](#comments)
|
||||
* [*b-prefix*](#single-quoted-string-literals)
|
||||
|
||||
**Constraints**
|
||||
|
||||
The start and end identifier names must be the same.
|
||||
No white space is permitted between the start identifier name and its
|
||||
enclosing single quotes (`'`). See also [heredoc string literal](#heredoc-string-literals).
|
||||
|
||||
**Semantics**
|
||||
|
||||
A nowdoc string literal looks like a [heredoc string literal](#heredoc-string-literals)
|
||||
except that in the former the start identifier name is
|
||||
enclosed in single quotes (`'`). The two forms of string literal have the
|
||||
same semantics and constraints except that a nowdoc string literal is
|
||||
not subject to variable substitution (like the single-quoted string).
|
||||
|
||||
A nowdoc string literal is a constant expression.
|
||||
|
||||
The optional *b-prefix* has no effect.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
$v = 123;
|
||||
$s = <<< 'ID'
|
||||
S'o'me "\"t e\txt; \$v = $v"
|
||||
Some more text
|
||||
ID;
|
||||
echo ">$s<\n\n";
|
||||
// → >S'o'me "\"t e\txt; \$v = $v"
|
||||
// Some more text<
|
||||
```
|
||||
|
||||
####Operators and Punctuators
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>operator-or-punctuator:: one of</i>
|
||||
[ ] ( ) { } . -> ++ -- ** * + - ~ !
|
||||
$ / % << >> < > <= >= == === != !== ^ |
|
||||
& && || ? : ; = **= *= /= %= += -= .= <<=
|
||||
>>= &= ^= |= , ?? <=> ... \
|
||||
</pre>
|
||||
|
||||
**Semantics**
|
||||
|
||||
Operators and punctuators are symbols that have independent syntactic
|
||||
and semantic significance. *Operators* are used in expressions to
|
||||
describe operations involving one or more *operands*, and that yield a
|
||||
resulting value, produce a side effect, or some combination thereof.
|
||||
*Punctuators* are used for grouping and separating.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,44 @@
|
|||
#Arrays
|
||||
|
||||
##General
|
||||
|
||||
An [*array*](http://php.net/manual/language.types.array.php) is a data structure that contains a collection of zero or
|
||||
more *elements*. An array element can have any type (which allows for arrays of arrays)
|
||||
and the elements of an array need not have the same type. The type of an array element can change over its lifetime.
|
||||
Multidimensional arrays can be implemented as arrays of arrays.
|
||||
|
||||
An array is represented as an ordered map in which each entry is a key/value pair
|
||||
that represents an element. An element key can be an expression of type
|
||||
`int` or `string`. Duplicate keys are not permitted. The order of the
|
||||
elements in the map is the order in which the elements were *inserted*
|
||||
into the array. An element is said to *exist* once it has been inserted
|
||||
into the array with a corresponding key. An array is *extended* by
|
||||
initializing a previously non-existent element using a new key. Elements
|
||||
can be *removed* from an array via the intrinsic [`unset`](10-expressions.md#unset).
|
||||
|
||||
The [`foreach` statement](11-statements.md#the-foreach-statement) can be used to iterate over the
|
||||
collection of elements in an array in order. This statement also provides a way to access the key and value
|
||||
for each element.
|
||||
|
||||
Each array has its own *current element pointer* that designates the
|
||||
*current array element*. When an array is created, the current element
|
||||
is the first element inserted into the array.
|
||||
|
||||
Numerous [library functions](http://php.net/manual/en/ref.array.php) are available to create and/or manipulate
|
||||
arrays.
|
||||
|
||||
Note: Arrays in PHP are different from arrays in several other languages.
|
||||
Specifically, in PHP, array elements need not have the same type, the subscript index need not be an integer,
|
||||
and there is no concept of consecutive elements of the array occupying physically adjacent memory locations).
|
||||
|
||||
##Array Creation and Initialization
|
||||
|
||||
An array is created and initialized by one of two equivalent ways: via
|
||||
the array-creation operator [`[]`](10-expressions.md#array-creation-operator) or the [intrinsic `array`](10-expressions.md#array).
|
||||
|
||||
##Element Access and Insertion
|
||||
|
||||
The value (and possibly the type) of an existing element is changed, and
|
||||
new elements are inserted, using the subscript operator [`[]`](10-expressions.md#subscript-operator).
|
||||
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
#Functions
|
||||
|
||||
##General
|
||||
|
||||
When a function is called, information may be passed to it by the caller
|
||||
via an *argument list*, which contains one or more *argument
|
||||
expressions*, or more simply, *arguments*. These correspond by position
|
||||
to the *parameters* in a *parameter list* in the called [function's
|
||||
definition](#function-definitions).
|
||||
|
||||
An *unconditionally defined function* is a function whose definition is
|
||||
at the top level of a script. A *conditionally defined function* is a
|
||||
function whose definition occurs inside a compound statement,
|
||||
such as the body of another function (a *nested function*), conditional statement, etc.
|
||||
There is no limit on the depth of levels of function nesting. Consider the
|
||||
case of an *outer function*, and an *inner function* defined within it.
|
||||
Until the outer function is called at least once, its inner function
|
||||
does not exist. Even if the outer function is called, if its runtime logic
|
||||
bypasses the definition of the inner function, that inner function still
|
||||
does not exist. The conditionally defined function comes into existance when
|
||||
the execution flow reaches the point where the function is defined.
|
||||
|
||||
Any function containing [`yield`](10-expressions.md#yield-operator) is a *generator function*.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
ucf1(); // can call ucf1 before its definition is seen
|
||||
function ucf1() { ... }
|
||||
ucf1(); // can call ucf1 after its definition is seen
|
||||
cf1(); // Error; call to non-existent function
|
||||
$flag = TRUE;
|
||||
if ($flag) { function cf1() { ... } } // cf1 now exists
|
||||
if ($flag) { cf1(); } // can call cf1 now
|
||||
// -----------------------------------------
|
||||
function ucf2() { function cf2() { ... } }
|
||||
cf2(); // Error; call to non-existent function
|
||||
ucf2(); // now cf2 exists
|
||||
cf2(); // so we can call it
|
||||
```
|
||||
|
||||
##Function Calls
|
||||
|
||||
A function is called via the function-call operator [`()`](10-expressions.md#function-call-operator).
|
||||
|
||||
##Function Definitions
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>function-definition:</i>
|
||||
<i>function-definition-header compound-statement</i>
|
||||
|
||||
<i>function-definition-header:</i>
|
||||
function &<i><sub>opt</sub></i> <i>name</i> ( <i>parameter-declaration-list<sub>opt</sub></i> ) <i>return-type<sub>opt</sub></i>
|
||||
|
||||
<i>parameter-declaration-list:</i>
|
||||
<i>simple-parameter-declaration-list</i>
|
||||
<i>variadic-declaration-list</i>
|
||||
|
||||
<i>simple-parameter-declaration-list:</i>
|
||||
<i>parameter-declaration</i>
|
||||
<i>parameter-declaration-list</i> , <i>parameter-declaration</i>
|
||||
|
||||
<i>variadic-declaration-list:</i>
|
||||
<i>simple-parameter-declaration-list</i> , <i>variadic-parameter</i>
|
||||
<i>variadic-parameter</i>
|
||||
|
||||
<i>parameter-declaration:</i>
|
||||
<i>type-declaration<sub>opt</sub></i> &<i><sub>opt</sub></i> <i>variable-name default-argument-specifier<sub>opt</sub></i>
|
||||
|
||||
<i>variadic-parameter:</i>
|
||||
<i>type-declaration<sub>opt</sub></i> &<i><sub>opt</sub></i> ... <i>variable-name</i>
|
||||
|
||||
<i>return-type:</i>
|
||||
: <i>type-declaration</i>
|
||||
: void
|
||||
|
||||
<i>type-declaration:</i>
|
||||
array
|
||||
callable
|
||||
<i>scalar-type</i>
|
||||
<i>qualified-name</i>
|
||||
|
||||
<i>scalar-type:</i>
|
||||
bool
|
||||
float
|
||||
int
|
||||
string
|
||||
|
||||
<i>default-argument-specifier:</i>
|
||||
= <i>constant-expression</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*constant-expression*](10-expressions.md#constant-expressions)
|
||||
* [*qualified-name*](09-lexical-structure.md#names)
|
||||
|
||||
**Constraints**
|
||||
|
||||
Each parameter name in a *function-definition* must be distinct.
|
||||
|
||||
A [conditionally defined function](#general) must exist before any calls are
|
||||
made to that function.
|
||||
|
||||
The *function-definition* for constructors, destructors, and clone methods must not contain *return-type*.
|
||||
|
||||
For generator functions, if the the return type is specified, it can only be one of:
|
||||
`Generator`, `Iterator` or `Traversable`.
|
||||
|
||||
**Semantics**
|
||||
|
||||
A *function-definition* defines a function called *name*. Function names
|
||||
are **not** case-sensitive. A function can be defined with zero or more
|
||||
parameters, each of which is specified in its own
|
||||
*parameter-declaration* in a *parameter-declaration-list*. Each
|
||||
parameter has a name, *variable-name*, and optionally, a
|
||||
*default-argument-specifier*. An `&` in *parameter-declaration* indicates
|
||||
that parameter is passed [byRef](04-basic-concepts.md#assignment) rather than by value. An `&`
|
||||
before *name* indicates that the value returned from this function is to
|
||||
be returned byRef. Returning values is described in [`return` statement description](11-statements.md#the-return-statement).
|
||||
|
||||
When the function is called, if there exists a parameter for which there
|
||||
is a corresponding argument, the argument is assigned to the parameter
|
||||
variable using value assignment, while for passing byRef, the argument is
|
||||
[assigned](04-basic-concepts.md#argument-passing) to the parameter variable using [byRef assignment](04-basic-concepts.md#assignment).
|
||||
If that parameter has no corresponding argument, but the parameter has a
|
||||
default argument value, for passing by value or byRef, the default
|
||||
value is assigned to the parameter variable using value assignment.
|
||||
Otherwise, if the parameter has no corresponding argument and the parameter
|
||||
does not have a default value, the parameter variable is non-existent and no corresponding
|
||||
[VSlot](04-basic-concepts.md#the-memory-model) exists. After all possible parameters have been
|
||||
assigned initial values or aliased to arguments, the body of the function,
|
||||
*compound-statement*, is executed. This execution may terminate [normally](04-basic-concepts.md#program-termination),
|
||||
with [`return` statement](11-statements.md#the-return-statement) or [abnormally](04-basic-concepts.md#program-termination).
|
||||
|
||||
Each parameter is a variable local to the parent function, and is a
|
||||
modifiable lvalue.
|
||||
|
||||
A *function-definition* may exist at the top level of a script, inside
|
||||
any *compound-statement*, in which case, the function is [conditionally
|
||||
defined](#general), or inside a [*method-declaration* section of a class](14-classes.md#methods).
|
||||
|
||||
If *variadic-parameter* is defined, every parameter that is supplied to function and is not matched
|
||||
by the preceding parameters is stored in this parameter, as an array element.
|
||||
The first such parameter gets index 0, the next one 1, etc. If no extra parameters is supplied,
|
||||
the value of the parameter is an empty array.
|
||||
Note that if type and/or byRef specifications are supplied to variadic parameter, they apply
|
||||
to every extra parameter captured by it.
|
||||
|
||||
By default, a parameter will accept an argument of any type. However, by
|
||||
specifying a *type-declaration*, the types of argument accepted can be
|
||||
restricted. By specifying `array`, only an argument of the `array`
|
||||
type is accepted. By specifying `callable`, only an argument designating a
|
||||
function (see below) is accepted. By specifying *qualified-name*, only an instance
|
||||
of a class having that type, or being derived from that type, are
|
||||
accepted, or only an instance of a class that implements that interface
|
||||
type directly or indirectly is accepted. The check is the same as for [`instanceof` operator](10-expressions.md#instanceof-operator).
|
||||
|
||||
`callable` pseudo-type accepts the following:
|
||||
* A string value containing the name of a function defined at the moment of the call.
|
||||
* An array value having two elements under indexes `0` and `1`. First element can be either string or object.
|
||||
If the first element is a string, the second element must be a string naming a method in a class designated by the first element.
|
||||
If the first element is an object, the second element must be a string naming a method
|
||||
that can be called on an object designated by the first element, from the context of the function being called.
|
||||
* An instance of the [`Closure`](14-classes.md#class-closure) class.
|
||||
* An instance of a class implementing [`__invoke`](14-classes.md#method-__invoke).
|
||||
|
||||
The library function [`is_callable`](http://php.net/is_callable) reports whether the contents of
|
||||
a variable can be called as a function.
|
||||
|
||||
Parameters typed with *scalar-type* are accepted if they pass the type check for this [scalar type](05-types.md#scalar-types),
|
||||
as [described below](#type-check-modes). Once the checks have been passed, the parameter types are always of the scalar type
|
||||
specified (or `NULL` if `NULL` is allowed).
|
||||
|
||||
If a parameter has a type declaration, `NULL` is not accepted unless it has a default value that evaluates to `NULL`.
|
||||
|
||||
The default value for a typed parameter must be of the type specified, or `NULL`,
|
||||
and conversion is not be performed for defaults, regardless of the mode.
|
||||
|
||||
## Return typing
|
||||
|
||||
If the function is defined with *return-type* declaration, the value returned by the function should
|
||||
be compatible with the defined type, using the same rules as for parameter type checks. `NULL` values
|
||||
are not allowed for typed returns. If the value of the [`return` statement](11-statements.md#the-return-statement)
|
||||
does not pass the type check, a fatal error is produced.
|
||||
|
||||
The `void` type is a special type that can only be used as a return type, and
|
||||
not in other contexts. It has no effect at runtime, see the [`return` statement](11-statements.md#the-return-statement).
|
||||
|
||||
## Type check modes
|
||||
|
||||
The type checking can be performed in two modes, strict and coercive (default).
|
||||
The difference between modes exists only for scalar typed parameters (`int`, `float`, `string` and `bool`).
|
||||
|
||||
For coercive mode, if the value passed is of the same type as the parameter, it is accepted.
|
||||
If not, the [conversion](08-conversions.md#general) is attempted. If the conversion succeeds,
|
||||
the converted value is the value assigned to the parameter. If the conversion fails, a fatal error
|
||||
is produced.
|
||||
|
||||
For strict mode, the parameter must be exactly of the type that is declared (e.g., string `"1"` is not
|
||||
accepted as a value for parameter typed as `int`). The only exception is that `int` values will be accepted
|
||||
for `float` typed parameter and [converted to `float`](08-conversions.md#converting-to-floating-point-type).
|
||||
Note that the strict mode applies not only to user-defined but also to internal functions,
|
||||
please consult [the manual](http://php.net/manual/) for appropriate parameter types. If the types do not match,
|
||||
an exception of type `TypeError` is thrown.
|
||||
|
||||
Note that if the parameter is passed byRef, and conversion happened,
|
||||
then the value will be re-assigned with the newly converted value.
|
||||
|
||||
The mode is set by the [`declare` statement](11-statements.md#the-declare-statement).
|
||||
|
||||
Note that the type check mode is for the function call controleed by the caller, not the callee.
|
||||
While the check is performed in the function being called, the caller defines whether the check is strict.
|
||||
Same function can be called with both strict and coercive mode checks from different contexts.
|
||||
|
||||
The check for the return type is always defined by the script that the function was defined in.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
// coercive mode by default
|
||||
function accept_int(int $a) { return $a+1; }
|
||||
accept_int(1); // ok
|
||||
accept_int("123"); // ok
|
||||
accept_int("123.34"); // ok
|
||||
accept_int("123.34 and some"); // ok + notice
|
||||
accept_int("not 123"); // fatal error!
|
||||
accept_int(null); // fatal error
|
||||
|
||||
function accept_int_or_not(int $a = null) { return $a+1; }
|
||||
accept_int_or_not(null); // ok
|
||||
|
||||
function convert_int(int &$a) { return $a+1; }
|
||||
$a = "12";
|
||||
convert_int($a);
|
||||
var_dump($a); // $a is now int
|
||||
|
||||
// Now in strict mode
|
||||
declare(strict_types=1);
|
||||
function accept_int(int $a) { return $a+1; }
|
||||
function accept_float(float $a) { return $a+1; }
|
||||
accept_int(1); // ok
|
||||
accept_float(1); // ok
|
||||
accept_int(1.5); // fatal error
|
||||
accept_int("123"); // fatal error
|
||||
echo substr("123", "1"); // fatal error
|
||||
|
||||
```
|
||||
|
||||
##Variable Functions
|
||||
|
||||
If a variable name is followed by the function-call operator [`()`](10-expressions.md#function-call-operator),
|
||||
and the value of that variable designates the function currently defined and visible (see description above),
|
||||
that function will be executed. If the variable does not designate a function or this function can not be called,
|
||||
a fatal error is produced.
|
||||
|
||||
##Anonymous Functions
|
||||
|
||||
An *anonymous function*, also known as a *closure*, is a function
|
||||
defined with no name. As such, it must be defined in the context of an
|
||||
expression whose value is used immediately to call that function, or
|
||||
that is saved in a variable for later execution. An anonymous function
|
||||
is defined via the [anonymous function creation operator](10-expressions.md#anonymous-function-creation).
|
||||
|
||||
For both [`__FUNCTION__` and `__METHOD__`](06-constants.md#context-dependent-constants), an anonymous
|
||||
function's name is reported as `{closure}`.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,293 @@
|
|||
#Interfaces
|
||||
|
||||
##General
|
||||
|
||||
A class can implement a set of capabilities — herein called a
|
||||
*contract* — through what is called an interface. An *interface* is a set
|
||||
of method declarations and constants. Note that the methods are only
|
||||
declared, not defined; that is, an interface defines a type consisting
|
||||
of abstract methods, where those methods are implemented by client
|
||||
classes as they see fit. An interface allows unrelated classes to
|
||||
implement the same facilities with the same names and types without
|
||||
requiring those classes to share a common base class.
|
||||
|
||||
An interface can extend one or more other interfaces, in which case, it
|
||||
inherits all members from its *base interface(s)*.
|
||||
|
||||
##Interface Declarations
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>interface-declaration:</i>
|
||||
interface <i>name interface-base-clause<sub>opt</sub></i> { <i>interface-member-declarations<sub>opt</sub></i> }
|
||||
|
||||
<i>interface-base-clause:</i>
|
||||
extends <i>qualified-name</i>
|
||||
<i>interface-base-clause</i> , <i>qualified-name</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*name*](09-lexical-structure.md#names)
|
||||
* [*interface-member-declarations*](#interface-members)
|
||||
|
||||
**Constraints**
|
||||
|
||||
An interface must not be derived directly or indirectly from itself.
|
||||
|
||||
Every *qualified-name* must name an interface type.
|
||||
|
||||
**Semantics**
|
||||
|
||||
An interface-declaration defines a contract that one or more classes can
|
||||
implement.
|
||||
|
||||
Interface names are case-insensitive.
|
||||
|
||||
The optional *interface-base-clause* specifies the base interfaces from
|
||||
which the interface being defined is derived. In such a case, the
|
||||
derived interface inherits all the members from the base interfaces.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
interface MyCollection
|
||||
{
|
||||
const MAX_NUMBER_ITEMS = 1000;
|
||||
function put($item);
|
||||
function get();
|
||||
}
|
||||
class MyList implements MyCollection
|
||||
{
|
||||
public function put($item) { /* implement method */ }
|
||||
public function get() { /* implement method */ }
|
||||
...
|
||||
}
|
||||
class MyQueue implements MyCollection
|
||||
{
|
||||
public function put($item) { /* implement method */ }
|
||||
public function get() { /* implement method */ }
|
||||
...
|
||||
}
|
||||
function processCollection(MyCollection $p1)
|
||||
{
|
||||
... /* can process any object whose class implements MyCollection */
|
||||
}
|
||||
processCollection(new MyList(...));
|
||||
processCollection(new MyQueue(...));
|
||||
```
|
||||
|
||||
##Interface Members
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>interface-member-declarations:</i>
|
||||
<i>interface-member-declaration</i>
|
||||
<i>interface-member-declarations interface-member-declaration</i>
|
||||
|
||||
<i>interface-member-declaration:</i>
|
||||
<i>class-const-declaration</i>
|
||||
<i>method-declaration</i>
|
||||
</pre>
|
||||
|
||||
* [*const-declaration*](14-classes.md#constants)
|
||||
* [*method-declaration*](14-classes.md#methods)
|
||||
|
||||
**Semantics**
|
||||
|
||||
The members of an interface are those specified by its
|
||||
*interface-member-declaration*, and the members inherited from its base
|
||||
interfaces.
|
||||
|
||||
An interface may contain the following members:
|
||||
|
||||
- [Constants](#constants) – the constant values associated with the interface.
|
||||
- [Methods](#methods) – placeholders for the computations and actions that can be
|
||||
performed by implementers of the interface.
|
||||
|
||||
##Constants
|
||||
|
||||
**Constraints**
|
||||
|
||||
All constants declared in an interface must be implicitly or explicitly public.
|
||||
|
||||
**Semantics**
|
||||
|
||||
An interface constant is just like a class [constant](14-classes.md#constants), except that
|
||||
an interface constant cannot be overridden by a class that implements it
|
||||
nor by an interface that extends it.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
interface MyCollection
|
||||
{
|
||||
const MAX_NUMBER_ITEMS = 1000;
|
||||
function put($item);
|
||||
function get();
|
||||
}
|
||||
```
|
||||
|
||||
##Methods
|
||||
|
||||
**Constraints**
|
||||
|
||||
All methods declared in an interface must be implicitly or explicitly
|
||||
public, and they must not be declared `abstract`.
|
||||
|
||||
**Semantics**
|
||||
|
||||
An interface method is just like an [abstract method](14-classes.md#methods).
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
interface MyCollection
|
||||
{
|
||||
const MAX_NUMBER_ITEMS = 1000;
|
||||
function put($item);
|
||||
function get();
|
||||
}
|
||||
```
|
||||
|
||||
##Predefined Interfaces
|
||||
|
||||
###Interface `ArrayAccess`
|
||||
|
||||
This interface allows an instance of an implementing class to be
|
||||
accessed using array-like notation. This interface is defined, as
|
||||
follows:
|
||||
|
||||
```PHP
|
||||
interface ArrayAccess
|
||||
{
|
||||
function offsetExists($offset);
|
||||
function offsetGet($offset);
|
||||
function offsetSet($offset, $value);
|
||||
function offsetUnset($offset);
|
||||
}
|
||||
```
|
||||
|
||||
The interface members are defined below:
|
||||
|
||||
Name | Purpose
|
||||
---- | -------
|
||||
`offsetExists` | This instance method returns `TRUE` if the instance contains an element with key `$offset`, otherwise, `FALSE`.
|
||||
`offsetGet` | This instance method gets the value having key `$offset`. It may return by value or byRef. (Ordinarily, this wouldn't be allowed because a class implementing an interface needs to match the interface's method signatures; however, the Engine gives special treatment to `ArrayAccess` and allows this). This method is called when an instance of a class that implements this interface is [subscripted](10-expressions.md#subscript-operator) in a non-lvalue context.
|
||||
`offsetSet` | This instance method sets the value having key `$offset` to $value. It returns no value. This method is called when an instance of a class that implements this interface is [subscripted](10-expressions.md#subscript-operator) in a modifiable-lvalue context.
|
||||
`offsetUnset` | This instance method unsets the value having key `$offset`. It returns no value.
|
||||
|
||||
###Interface `Iterator`
|
||||
|
||||
This interface allows instances of an implementing class to be treated
|
||||
as a collection. This interface is defined, as follows:
|
||||
|
||||
```PHP
|
||||
interface Iterator extends Traversable
|
||||
{
|
||||
function current();
|
||||
function key();
|
||||
function next();
|
||||
function rewind();
|
||||
function valid();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The interface members are defined below:
|
||||
|
||||
Name | Purpose
|
||||
---- | -------
|
||||
`current` | This instance method returns the element at the current position.
|
||||
`key` |This instance method returns the key of the current element. On failure, it returns `NULL`; otherwise, it returns the scalar value of the key.
|
||||
`next` | This instance method moves the current position forward to the next element. It returns no value. From within a `foreach` statement, this method is called after each loop.
|
||||
`rewind` | This instance method resets the current position to the first element. It returns no value. From within a `foreach` statement, this method is called once, at the beginning.
|
||||
`valid` | This instance method checks if the current position is valid. It takes no arguments. It returns a bool value of `TRUE` to indicate the current position is valid; `FALSE`, otherwise. This method is called after each call to [`Iterator::rewind()`](http://php.net/manual/iterator.rewind.php) and [`Iterator::next()`](http://php.net/manual/iterator.next.php).
|
||||
|
||||
###Interface `IteratorAggregate`
|
||||
|
||||
This interface allows the creation of an external iterator. This
|
||||
interface is defined, as follows:
|
||||
|
||||
```PHP
|
||||
interface IteratorAggregate extends Traversable
|
||||
{
|
||||
function getIterator();
|
||||
}
|
||||
```
|
||||
The interface members are defined below:
|
||||
|
||||
|
||||
Name | Purpose
|
||||
---- | -------
|
||||
`getIterator` | This instance method retrieves an iterator, which implements `Iterator` or `Traversable`. It throws an `Exception` on failure.
|
||||
|
||||
###Interface `Throwable`
|
||||
|
||||
This type is the base interface for the type of any object that can be thrown via a
|
||||
[throw statement](11-statements.md#the-throw-statement). A user-written class cannot
|
||||
implement `Throwable` directly. Instead, it must extend `Error` or `Exception`.
|
||||
|
||||
This type is defined, as follows:
|
||||
|
||||
```PHP
|
||||
interface Throwable {
|
||||
function __toString(): string;
|
||||
function getCode(): int;
|
||||
function getFile(): string;
|
||||
function getLine(): int;
|
||||
function getMessage(): string;
|
||||
function getPrevious(): Throwable;
|
||||
function getTrace(): array;
|
||||
function getTraceAsString(): string;
|
||||
}
|
||||
```
|
||||
The interface members are defined below:
|
||||
|
||||
|
||||
Name | Purpose
|
||||
---- | -------
|
||||
`__toString` | `string`; retrieves a string representation of the exception in some unspecified format
|
||||
`getCode` | `int`; retrieves the exception code
|
||||
`getFile` | `string`; retrieves the name of the script where the exception was generated
|
||||
`getLine` | `int`; retrieves the source line number in the script where the exception was generated
|
||||
`getMessage` | `string`; retrieves the exception message
|
||||
`getPrevious` | `Throwable`; retrieves the previous exception, if one exists; otherwise returns `NULL`
|
||||
`getTrace` | `array`; retrieves the function stack [trace information](17-exception-handling.md#tracing-exceptions) as an array
|
||||
`getTraceAsString` | `string`; retrieves the function stack trace information formatted as a single string in some unspecified format
|
||||
|
||||
###Interface `Traversable`
|
||||
|
||||
This interface is intended as the base interface for all traversable
|
||||
classes. This interface is defined, as follows:
|
||||
|
||||
```PHP
|
||||
interface Traversable
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
This interface has no members.
|
||||
|
||||
###Interface `Serializable`
|
||||
|
||||
This interface provides support for custom serialization. It is defined,
|
||||
as follows:
|
||||
|
||||
```PHP
|
||||
interface Serializable
|
||||
{
|
||||
function serialize();
|
||||
function unserialize ($serialized);
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
The interface members are defined below:
|
||||
|
||||
Name | Purpose
|
||||
-----| -------
|
||||
`serialize` | This instance method returns a string representation of the current instance. On failure, it returns `NULL`.
|
||||
`unserialize` | This instance method constructs an object from its string form designated by `$serialized`. It does not return a value.
|
|
@ -0,0 +1,204 @@
|
|||
#Traits
|
||||
|
||||
##General
|
||||
|
||||
PHP's class model allows [single inheritance](14-classes.md#general) only with contracts
|
||||
being enforced separately via [interfaces](15-interfaces.md#general). A *trait* can provide
|
||||
both implementation and contracts. Specifically, a class can inherit
|
||||
from a base class while also using code from one or more traits.
|
||||
At the same time, that class can implement contracts from one or more
|
||||
interfaces as well as from one or more traits. The use of a trait by a
|
||||
class does not involve any inheritance hierarchy, so unrelated classes
|
||||
can use the same trait. In summary, a trait is a set of methods and/or
|
||||
state information that can be reused.
|
||||
|
||||
Traits are designed to support classes; a trait cannot be instantiated
|
||||
directly.
|
||||
|
||||
The members of a trait each have [visibility](14-classes.md#general), which applies once
|
||||
they are used by a given class. The class that uses a trait can change
|
||||
the visibility of any of that trait's members, by either widening or
|
||||
narrowing that visibility. For example, a private trait member can be
|
||||
made public in the using class, and a public trait member can be made
|
||||
private in that class.
|
||||
|
||||
Once implementation comes from both a base class and one or more traits,
|
||||
name conflicts can occur. However, trait usage provides the means for
|
||||
disambiguating such conflicts. Names gotten from a trait can also be
|
||||
given aliases.
|
||||
|
||||
A class member with a given name overrides one with the same name in any
|
||||
traits that class uses, which, in turn, overrides any such name from
|
||||
base classes.
|
||||
|
||||
Traits can contain both instance and static members, including both
|
||||
methods and properties. In the case of a trait with a static property,
|
||||
each class using that trait has its own instance of that property.
|
||||
|
||||
Methods in a trait have full access to all members of any class in which
|
||||
that trait is used.
|
||||
|
||||
##Trait Declarations
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>trait-declaration:</i>
|
||||
trait <i>name</i> { trait-member-declarations<sub>opt</sub></i> }
|
||||
|
||||
<i>trait-member-declarations:</i>
|
||||
<i>trait-member-declaration</i>
|
||||
<i>trait-member-declarations trait-member-declaration</i>
|
||||
|
||||
<i>trait-member-declaration:</i>
|
||||
<i>property-declaration</i>
|
||||
<i>method-declaration</i>
|
||||
<i>constructor-declaration</i>
|
||||
<i>destructor-declaration</i>
|
||||
<i>trait-use-clauses</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*property-declaration*](14-classes.md#properties)
|
||||
* [*method-declaration*](14-classes.md#methods)
|
||||
* [*constructor-declaration*](14-classes.md#constructors)
|
||||
* [*destructor-declaration*](14-classes.md#destructors)
|
||||
* [*trait-use-clauses*](#trait-uses)
|
||||
|
||||
**Semantics**
|
||||
|
||||
A *trait-declaration* defines a named set of members, which are made
|
||||
available to any class that uses that trait.
|
||||
|
||||
Trait names are case-insensitive.
|
||||
|
||||
The members of a trait are those specified by its *trait-member-declaration*
|
||||
clauses, and members imported from any other traits using *trait-use-clauses*.
|
||||
|
||||
A trait may contain the following members:
|
||||
|
||||
- [Properties](14-classes.md#properties) – the variables made available to the class in which the
|
||||
trait is used.
|
||||
- [Methods](14-classes.md#methods) – the computations and actions that can be performed by the
|
||||
class in which the trait is used.
|
||||
- [Constructor](14-classes.md#constructors) – the actions required to initialize an instance of the
|
||||
class in which the trait is used.
|
||||
- [Destructor](14-classes.md#destructors) – the actions to be performed when an instance of the
|
||||
class in which the trait is used is no longer needed.
|
||||
|
||||
If a member has no explicit visibility, `public` is assumed.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
trait T
|
||||
{
|
||||
private $prop1 = 1000;
|
||||
protected static $prop2;
|
||||
var $prop3;
|
||||
public function compute( ... ) { ... }
|
||||
public static function getData( ... ) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
##Trait Uses
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>trait-use-clauses:</i>
|
||||
<i>trait-use-clause</i>
|
||||
<i>trait-use-clauses trait-use-clause</i>
|
||||
|
||||
<i>trait-use-clause:</i>
|
||||
use <i>trait-name-list trait-use-specification</i>
|
||||
|
||||
<i>trait-name-list:</i>
|
||||
<i>qualified-name</i>
|
||||
<i>trait-name-list</i> , <i>qualified-name</i>
|
||||
|
||||
<i>trait-use-specification:</i>
|
||||
;
|
||||
{ <i>trait-select-and-alias-clauses<sub>opt</sub></i> }
|
||||
|
||||
<i>trait-select-and-alias-clauses:</i>
|
||||
<i>trait-select-and-alias-clause</i>
|
||||
<i>trait-select-and-alias-clauses trait-select-and-alias-clause</i>
|
||||
|
||||
<i>trait-select-and-alias-clause:</i>
|
||||
<i>trait-select-insteadof-clause</i> ;
|
||||
<i>trait-alias-as-clause</i> ;
|
||||
|
||||
<i>trait-select-insteadof-clause:</i>
|
||||
<i>name</i> insteadof <i>name</i>
|
||||
|
||||
<i>trait-alias-as-clause:</i>
|
||||
<i>name</i> as <i>visibility-modifier<sub>opt</sub> name</i>
|
||||
<i>name</i> as <i>visibility-modifier name<sub>opt</sub></i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*name*](09-lexical-structure.md#names)
|
||||
* [*visibility-modifier*](14-classes.md#properties)
|
||||
|
||||
**Constraints**
|
||||
|
||||
The *name* items in *trait-name-list* must designate trait names, excluding
|
||||
the name of the trait being declared.
|
||||
|
||||
The left-hand *name* in *trait-select-insteadof-clause* must
|
||||
unambiguously designate a member of a trait made available by
|
||||
*trait-use-clauses*. The right-hand *name* in
|
||||
*trait-select-insteadof-clause* must unambiguously designate a trait
|
||||
made available by *trait-use-clauses*.
|
||||
|
||||
The left-hand *name* in *trait-alias-as-clause* must unambiguously
|
||||
designate a member of a trait made available by *trait-use-clauses*.
|
||||
The right-hand *name* in *trait-alias-as-clause* must be a new,
|
||||
unqualified name.
|
||||
|
||||
**Semantics**
|
||||
|
||||
*trait-use-clauses* can be used as part of *trait-member-declarations*
|
||||
or *class-member-declarations* to import members of a trait into a
|
||||
different trait or a class. This is done via one or more *trait-use-clause*
|
||||
items, each of which contains a comma-separated list of trait names.
|
||||
A *trait-use-clause* list ends in a semicolon or a brace-delimited set of
|
||||
*trait-select-insteadof-clause* and *trait-alias-as-clause* statements.
|
||||
|
||||
A *trait-select-insteadof-clause* allows to avoid name clashes.
|
||||
Specifically, the left-hand *name* designates which name to be used from
|
||||
of a pair of names. That is, `T1::compute insteadof T2`; indicates that
|
||||
calls to method compute, for example, should be satisfied by a method of
|
||||
that name in trait `T1` rather than `T2`.
|
||||
|
||||
A *trait-alias-as-clause* allows a (possibly qualified) name to be
|
||||
assigned a simple alias name. Specifically, the left-hand *name* in
|
||||
*trait-alias-as-clause* designates a name made available by
|
||||
*trait-use-clauses* - that is to be aliased, and the right-hand *name*
|
||||
is the alias.
|
||||
|
||||
If *trait-alias-as-clause* contains a visibility-modifier,
|
||||
if a right-hand name is provided, the modifier controls the visibility of the alias,
|
||||
otherwise, it controls the visibility of the left-hand name.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
trait T1 { public function compute( ... ) { ... } }
|
||||
trait T2 { public function compute( ... ) { ... } }
|
||||
trait T3 { public function sort( ... ) { ... } }
|
||||
trait T4
|
||||
{
|
||||
use T3;
|
||||
use T1, T2
|
||||
{
|
||||
T1::compute insteadof T2; // disambiguate between two computes
|
||||
T3::sort as private sorter; // make alias with adjusted visibility
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
#Exception Handling
|
||||
|
||||
##General
|
||||
|
||||
An *exception* is some unusual condition in that it is outside the
|
||||
ordinary expected behavior. Examples include dealing with situations in
|
||||
which a critical resource is needed, but is unavailable, and detecting
|
||||
an out-of-range value for some computation. As such, exceptions require
|
||||
special handling. This chapter describes how exceptions can be created
|
||||
and handled.
|
||||
|
||||
Whenever some exceptional condition is detected at runtime, an exception
|
||||
is *thrown*. A designated exception handler can *catch* the thrown
|
||||
exception and service it. Among other things, the handler might recover
|
||||
from the situation completely (allowing the script to continue
|
||||
execution), it might perform some recovery and then throw an exception
|
||||
to get further help, or it might perform some cleanup action and
|
||||
terminate the script. Exceptions may be thrown on behalf of the Engine
|
||||
or by explicit code source code in the script.
|
||||
|
||||
Exception handling involves the use of the following keywords:
|
||||
|
||||
- [`try`](11-statements.md#the-try-statement), which allows a *try-block* of code containing one or
|
||||
more possible exception generations, to be tried.
|
||||
- [`catch`](11-statements.md#the-try-statement), which defines a handler for a specific type of
|
||||
exception thrown from the corresponding try-block or from some
|
||||
function it calls.
|
||||
- [`finally`](11-statements.md#the-try-statement), which allows the *finally-block* of a try-block to
|
||||
be executed (to perform some cleanup, for example), whether or not
|
||||
an exception occurred within that try-block.
|
||||
- [`throw`](11-statements.md#the-throw-statement), which generates an exception of a given type, from
|
||||
a place called a *throw point*.
|
||||
|
||||
When an exception is thrown, an *exception object* of type [`Exception`](#class-exception),
|
||||
or of a subclass of that type, is created and made available to
|
||||
the first catch-handler that can catch it. Among other things, the
|
||||
exception object contains an *exception message* and an *exception
|
||||
code*, both of which can be used by a handler to determine how to handle
|
||||
the situation.
|
||||
|
||||
PHP errors also can be translated to exceptions via the class
|
||||
[`ErrorException`](http://php.net/manual/class.errorexception.php)
|
||||
(which is not part of this specification).
|
||||
|
||||
##Class `Exception`
|
||||
|
||||
Class `Exception` is the base class of all exception types. This class is
|
||||
defined, as follows:
|
||||
|
||||
```PHP
|
||||
class Exception implements Throwable
|
||||
{
|
||||
protected $message = 'Unknown exception';
|
||||
protected $code = 0;
|
||||
protected $file;
|
||||
protected $line;
|
||||
|
||||
public function __construct($message = "", $code = 0,
|
||||
Throwable $previous = NULL);
|
||||
|
||||
final private function __clone();
|
||||
}
|
||||
```
|
||||
|
||||
For information about exception trace-back and nested exceptions, see [tracing exceptions](#tracing-exceptions).
|
||||
|
||||
For information about the base interface, see [Throwable](15-interfaces.md#interface-throwable).
|
||||
Note that the methods from Throwable are implemented as `final` in the Exception class, which means
|
||||
the extending class can not override them.
|
||||
|
||||
The class members are defined below:
|
||||
|
||||
Name | Purpose
|
||||
---- | -------
|
||||
`$code` | `int`; the exception code (as provided by the constructor)
|
||||
`$file` | `string`; the name of the script where the exception was generated
|
||||
`$line` | `int`; the source line number in the script where the exception was generated
|
||||
`$message` | `string`; the exception message (as provided by the constructor)
|
||||
`__construct` | Takes three (optional) arguments – `string`: the exception message (defaults to ""), `int`: the exception code (defaults to 0), and `Exception`: the previous exception in the chain (defaults to `NULL`)
|
||||
`__clone` | Present to inhibit the cloning of exception objects
|
||||
|
||||
##Tracing Exceptions
|
||||
|
||||
When an exception is caught, the `get*` functions in class `Exception`
|
||||
provide useful information. If one or more nested function calls were
|
||||
involved to get to the place where the exception was generated, a record
|
||||
of those calls is also retained, and made available by `getTrace, through
|
||||
what is referred to as the *function stack trace*, or simply, `*trace*`.
|
||||
|
||||
Let's refer to the top level of a script as *function-level* 0.
|
||||
Function-level 1 is inside any function called from function-level 0.
|
||||
Function-level 2 is inside any function called from function-level 1,
|
||||
and so on. The method `getTrace` returns an array. Exceptions
|
||||
generated at function-level 0 involve no function call, in which case,
|
||||
the array returned by `getTrace` is empty.
|
||||
|
||||
Each element of the array returned by `getTrace` provides information
|
||||
about a given function level. Let us call this array *trace-array* and
|
||||
the number of elements in this array *call-level*. The key for each of
|
||||
trace-array's elements has type int, and ranges from 0 to
|
||||
call-level - 1. For example, when a top-level script calls function `f1`,
|
||||
which calls function `f2`, which calls function `f3`, which then generates
|
||||
an exception, there are four function levels, 0–3, and there are three
|
||||
lots of trace information, one per call level. That is, trace-array
|
||||
contains three elements, and they each correspond to the reverse order
|
||||
of the function calls. For example, `trace-array[0]` is for the call to
|
||||
function `f3`, `trace-array[1]` is for the call to function `f2`, and
|
||||
`trace-array[2]` is for the call to function `f1`.
|
||||
|
||||
Each element in trace-array is itself an array that contains elements
|
||||
with the following key/value pairs:
|
||||
|
||||
Key | Value Type | Value
|
||||
--- | ---------- | -----
|
||||
"args" | `array` | The set of arguments passed to the function
|
||||
"class" | `string` | The name of the function's parent class
|
||||
"file" | `string` | The name of the script where the function was called
|
||||
"function" | `string` | The name of the function or class method
|
||||
"line" | `int` | The line number in the source where the function was called
|
||||
"object" | `object` | The current object
|
||||
"type" | `string` | Type of call; `->` for an instance method call, `::` for a static method call, for ordinary function call, empty string(`""`) is returned.
|
||||
|
||||
The key `args` has a value that is yet another array, which we shall
|
||||
call *argument-array*. That array contains a set of values that
|
||||
corresponds directly to the set of values passed as arguments to the
|
||||
corresponding function. Regarding element order, `argument-array[0]`
|
||||
corresponds to the left-most argument, `argument-array[1]` corresponds to
|
||||
the next argument to the right, and so on.
|
||||
|
||||
Note that only the actual arguments passed to the function are reported.
|
||||
Consider the case in which a function has a default argument value
|
||||
defined for a parameter. If that function is called without an argument
|
||||
for the parameter having the default value, no corresponding argument
|
||||
exists in the argument array. Only arguments present at the function-call
|
||||
site have their values recorded in array-argument.
|
||||
|
||||
See also, library functions [`debug_backtrace`](http://www.php.net/debug_backtrace) and
|
||||
[`debug_print_backtrace`](http://www.php.net/debug_print_backtrace).
|
||||
|
||||
##User-Defined Exception Classes
|
||||
|
||||
An exception class is defined simply by having it extend class [`Exception`](#class-exception).
|
||||
However, as that class's `__clone` method is declared [`final`](14-classes.md#methods),
|
||||
exception objects cannot be cloned.
|
||||
|
||||
When an exception class is defined, typically, its constructors call the
|
||||
parent class' constructor as their first operation to ensure the
|
||||
base-class part of the new object is initialized appropriately. They
|
||||
often also provide an augmented implementation of
|
||||
[`__toString()`](14-classes.md#method-__tostring).
|
||||
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
#Namespaces
|
||||
|
||||
##General
|
||||
|
||||
A problem encountered when managing large projects is that of avoiding
|
||||
the use of the same name in the same scope for different purposes. This
|
||||
is especially problematic in a language that supports modular design and
|
||||
component libraries.
|
||||
|
||||
A *namespace* is a container for a set of (typically related)
|
||||
definitions of classes, interfaces, traits, functions, and constants.
|
||||
Namespaces serve two purposes:
|
||||
|
||||
- They help avoid name collisions.
|
||||
- They allow certain long names to be accessed via shorter, more
|
||||
convenient and readable, names.
|
||||
|
||||
A namespace may have *sub-namespaces*, where a sub-namespace name shares
|
||||
a common prefix with another namespace. For example, the namespace
|
||||
`Graphics` might have sub-namespaces `Graphics\D2` and `Graphics\D3`, for
|
||||
two- and three-dimensional facilities, respectively. Apart from their
|
||||
common prefix, a namespace and its sub-namespaces have no special
|
||||
relationship. The namespace whose prefix is part of a sub-namespace need
|
||||
not actually exist for the sub-namespace to exist. That is, `NS1\Sub` can
|
||||
exist without `NS1`.
|
||||
|
||||
In the absence of any namespace definition, the names of subsequent
|
||||
classes, interfaces, traits, functions, and constants are in the
|
||||
*default namespace*, which has no name, per se.
|
||||
|
||||
The namespaces `PHP`, `php`, and sub-namespaces beginning with those
|
||||
prefixes are reserved for use by PHP.
|
||||
|
||||
|
||||
##Defining Namespaces
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>namespace-definition:</i>
|
||||
namespace <i>name</i> ;
|
||||
namespace <i>name<sub>opt</sub> compound-statement</i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*name*](09-lexical-structure.md#names)
|
||||
* [*compound-statement*](11-statements.md#compound-statements)
|
||||
|
||||
**Constraints**
|
||||
|
||||
Except for white space and [*declare-statement*](11-statements.md#the-declare-statement), the
|
||||
first occurrence of a *namespace-definition* in a script must be the
|
||||
first thing in that script.
|
||||
|
||||
All occurrence of a *namespace-definition* in a script must have the
|
||||
*compound-statement* form or must not have that form; the two forms
|
||||
cannot be mixed within the same script file.
|
||||
|
||||
When a script contains source code that is not inside a namespace, and
|
||||
source code that is inside one or namespaces, the namespaced code must
|
||||
use the *compound-statement* form of *namespace-definition*.
|
||||
|
||||
*compound-statement* must not contain a *namespace-definition*.
|
||||
|
||||
**Semantics**
|
||||
|
||||
Although a namespace may contain any PHP source code, the fact that that
|
||||
code is contained in a namespace affects only the declaration and name
|
||||
resolution of classes, interfaces, traits, functions, and constants.
|
||||
For each of those, if they are defined using [unqualified or qualified name](#name-lookup),
|
||||
the current namespace name is prepended to the specified name.
|
||||
Note that while definition has a short name, the name known to the engine
|
||||
is always the full name, and can be either specified as fully qualified name,
|
||||
composed from current namespace name and specified name, or [imported](#namespace-use-declarations).
|
||||
|
||||
Namespace and sub-namespace names are case-insensitive.
|
||||
|
||||
The pre-defined constant [`__NAMESPACE__`](06-constants.md#context-dependent-constants) contains the name of
|
||||
the current namespace.
|
||||
|
||||
When the same namespace is defined in multiple scripts, and those
|
||||
scripts are combined into the same program, the namespace is considered
|
||||
the merger of its individual contributions.
|
||||
|
||||
The scope of the non-*compound-statement* form of *namespace-definition*
|
||||
runs until the end of the script, or until the lexically next
|
||||
*namespace-definition*, whichever comes first. The scope of the
|
||||
*compound-statement* form is the *compound-statement*.
|
||||
|
||||
**Examples**
|
||||
|
||||
Script1.php:
|
||||
```PHP
|
||||
namespace NS1;
|
||||
... // __NAMESPACE__ is "NS1"
|
||||
namespace NS3\Sub1;
|
||||
... // __NAMESPACE__ is "NS3\Sub1"
|
||||
```
|
||||
|
||||
Script2.php:
|
||||
```PHP
|
||||
namespace NS1
|
||||
{
|
||||
... // __NAMESPACE__ is "NS1"
|
||||
}
|
||||
namespace
|
||||
{
|
||||
... // __NAMESPACE__ is ""
|
||||
}
|
||||
namespace NS3\Sub1;
|
||||
{
|
||||
... // __NAMESPACE__ is "NS3\Sub1"
|
||||
}
|
||||
```
|
||||
|
||||
##Namespace Use Declarations
|
||||
|
||||
**Syntax**
|
||||
|
||||
<pre>
|
||||
<i>namespace-use-declaration:</i>
|
||||
use <i>namespace-function-or-const<sub>opt</sub></i> <i>namespace-use-clauses</i> ;
|
||||
use <i>namespace-function-or-const</i> \<i><sub>opt</sub> namespace-name</i> \
|
||||
{ <i>namespace-use-group-clauses-1</i> } ;
|
||||
use \<i><sub>opt</sub> namespace-name</i> \ { <i>namespace-use-group-clauses-2</i> } ;
|
||||
|
||||
<i>namespace-use-clauses:</i>
|
||||
<i>namespace-use-clause</i>
|
||||
<i>namespace-use-clauses</i> , <i>namespace-use-clause</i>
|
||||
|
||||
<i>namespace-use-clause:</i>
|
||||
<i>qualified-name namespace-aliasing-clause<sub>opt</sub></i>
|
||||
|
||||
<i>namespace-aliasing-clause:</i>
|
||||
as <i>name</i>
|
||||
|
||||
<i>namespace-function-or-const:</i>
|
||||
function
|
||||
const
|
||||
|
||||
<i>namespace-use-group-clauses-1:</i>
|
||||
<i>namespace-use-group-clause-1</i>
|
||||
<i>namespace-use-group-clauses-1</i> , <i>namespace-use-group-clause-1</i>
|
||||
|
||||
<i>namespace-use-group-clause-1:</i>
|
||||
<i>namespace-name</i> <i>namespace-aliasing-clause<sub>opt</sub></i>
|
||||
|
||||
<i>namespace-use-group-clauses-2:</i>
|
||||
<i>namespace-use-group-clause-2</i>
|
||||
<i>namespace-use-group-clauses-2</i> , <i>namespace-use-group-clause-2</i>
|
||||
|
||||
<i>namespace-use-group-clause-2:</i>
|
||||
<i>namespace-function-or-const<sub>opt</sub></i> <i>namespace-name</i> <i>namespace-aliasing-clause<sub>opt</sub></i>
|
||||
</pre>
|
||||
|
||||
**Defined elsewhere**
|
||||
|
||||
* [*name*](09-lexical-structure.md#names)
|
||||
* [*namespace-name*](09-lexical-structure.md#names)
|
||||
* [*qualified-name*](09-lexical-structure.md#names)
|
||||
|
||||
**Constraints**
|
||||
|
||||
A *namespace-use-declaration* must not occur except at the top level or directly in the context of a *namespace-definition*.
|
||||
|
||||
If the same *qualified-name*, *name*, or *namespace-name* is imported multiple times in the same
|
||||
scope, each occurrence must have a different alias.
|
||||
|
||||
**Semantics**
|
||||
|
||||
If *namespace-use-declaration* has a *namespace-function-or-const* with value `function`, the statement imports
|
||||
one or more functions. If *namespace-use-declaration* has a *namespace-function-or-const* with value `const`, the statement imports one or more constants. Otherwise, *namespace-use-declaration* has no *namespace-function-or-const*. In that case, if *namespace-use-clauses* is present, the names being imported are considered to be classes/interfaces/traits. Otherwise, *namespace-use-group-clauses-2* is present, in which case, the names being imported are considered to be functions, constants, or classes/interfaces/traits based on the respective presence of `function` or `const`, or the absence of *namespace-function-or-const* on each *namespace-name* in subordinate *namespace-use-group-clause-2*s.
|
||||
|
||||
Note that constant, function and class imports live in different spaces, so the same name
|
||||
can be used as function and class import and apply to the respective cases of class and function use,
|
||||
without interfering with each other.
|
||||
|
||||
A *namespace-use-declaration* *imports* — that is, makes available — one or
|
||||
more names into a scope, optionally giving them each an alias. Each of
|
||||
those names may designate a namespace, a sub-namespace, a class, an
|
||||
interface, or a trait. If a *namespace-aliasing-clause* is present, its
|
||||
*name* is the alias for *qualified-name*, *name*, or *namespace-name*. Otherwise, the right-most name component
|
||||
in *qualified-name* is the implied alias for *qualified-name*.
|
||||
|
||||
**Examples**
|
||||
|
||||
```PHP
|
||||
namespace NS1
|
||||
{
|
||||
const CON1 = 100;
|
||||
function f() { ... }
|
||||
class C { ... }
|
||||
interface I { ... }
|
||||
trait T { ... }
|
||||
}
|
||||
|
||||
namespace NS2
|
||||
{
|
||||
use \NS1\C, \NS1\I, \NS1\T;
|
||||
class D extends C implements I
|
||||
{
|
||||
use T; // trait (and not a namespace use declaration)
|
||||
}
|
||||
$v = \NS1\CON1; // explicit namespace still needed for constants
|
||||
\NS1\f(); // explicit namespace still needed for functions
|
||||
|
||||
use \NS1\C as C2; // C2 is an alias for the class name \NS1\C
|
||||
$c2 = new C2;
|
||||
|
||||
// importing a group of classes and interfaces
|
||||
use \NS\{C11, C12, I10};
|
||||
|
||||
// importing a function
|
||||
use function \My\Full\functionName;
|
||||
|
||||
// aliasing a function
|
||||
use function \NS1\f as func;
|
||||
use function \NS\{f1, g1 as myG};
|
||||
|
||||
// importing a constant
|
||||
use const \NS1\CON1;
|
||||
use \NS\{const CON11, const CON12};
|
||||
|
||||
$v = CON1; // imported constant
|
||||
func(); // imported function
|
||||
|
||||
// importing a class, a constant, and a function
|
||||
use \NS\ { C2 as CX, const CON2 as CZ, function f1 as FZ };
|
||||
}
|
||||
```
|
||||
|
||||
Note that the *qualified-name* is treated as absolute even if it does not start with `\`.
|
||||
For example:
|
||||
|
||||
```PHP
|
||||
namespace b
|
||||
{
|
||||
class B
|
||||
{
|
||||
function foo(){ echo "goodbye"; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace a\b
|
||||
{
|
||||
class B
|
||||
{
|
||||
function foo(){ echo "hello"; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace a
|
||||
{
|
||||
$b = new b\B();
|
||||
$b->foo(); // hello
|
||||
use b\B as C;
|
||||
$b = new C();
|
||||
$b->foo(); // goodbye
|
||||
}
|
||||
```
|
||||
|
||||
##Name Lookup
|
||||
|
||||
When an existing name is used in source code, the Engine must determine
|
||||
how that name is found with respect to namespace lookup. For this
|
||||
purpose, names can have one of the three following forms:
|
||||
|
||||
- Unqualified name: Such names are just simple names without any
|
||||
prefix, as in the class name `Point` in the following expression:
|
||||
`$p = new Point(3,5)`. If the current namespace is `NS1`, the name
|
||||
`Point` resolves to `NS1\Point`. If the current namespace is the
|
||||
default namespace, the name `Point` resolves to just `Point`. In the
|
||||
case of an unqualified function or constant name, if that name does
|
||||
not exist in the current namespace, a global function or constant by
|
||||
that name is used.
|
||||
- Qualified name: Such names have a prefix consisting of a namespace
|
||||
name and/or one or more levels of sub-namespace names,
|
||||
preceding a class, interface, trait, function, or constant name.
|
||||
Such names are relative. For example, `D2\Point` could be used to
|
||||
refer to the class `Point` in the sub-namespace `D2` of the current
|
||||
namespace. One special case of this is when the first component of
|
||||
the name is the keyword `namespace`. This means "the current
|
||||
namespace".
|
||||
- Fully qualified name: Such names begin with a backslash (`\`) and are
|
||||
followed optionally by a namespace name and one or more levels of
|
||||
sub-namespace names, and, finally, a class, interface, trait,
|
||||
function, or constant name. Such names are absolute. For example,
|
||||
`\Graphics\D2\Point` could be used to refer unambiguously to the
|
||||
class `Point` in namespace `Graphics`, sub-namespace `D2`.
|
||||
|
||||
However, if an unqualified name is used in a context where it represents the name
|
||||
of a constant or function, within a non-default namespace, if this namespace does not have
|
||||
such constant of function defined, the global unqualified name is used.
|
||||
|
||||
For example:
|
||||
```PHP
|
||||
<?php
|
||||
namespace A\B\C;
|
||||
function strlen($str)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
print strlen("Life, Universe and Everything"); // prints 42
|
||||
print mb_strlen("Life, Universe and Everything"); // calls global function and prints 29
|
||||
```
|
||||
|
||||
The names of the standard types (such as `Exception`), constants (such as
|
||||
`PHP_INT_MAX`), and library functions (such as `is_null`) are defined outside
|
||||
any namespace. To refer unambiguously to such names, one can prefix them
|
||||
with a backslash (`\`), as in `\Exception`, `\PHP_INT_MAX`, and `\is_null`.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,13 @@
|
|||
#Bibliography
|
||||
|
||||
The following documents are useful references for implementers and users
|
||||
of this specification:
|
||||
|
||||
IEC 60559:1989, *Binary floating-point arithmetic for microprocessor
|
||||
systems* (previously designated IEC 559:1989). (This standard is widely
|
||||
known by its U.S. national designation, ANSI/IEEE Standard 754-1985,
|
||||
IEEE Standard for Binary Floating-Point Arithmetic).
|
||||
|
||||
The Unicode Consortium. *The Unicode Standard, Version 5.0*,
|
||||
[www.Unicode.org](http://www.Unicode.org)).
|
||||
|
|
@ -0,0 +1 @@
|
|||
00-specification-for-php.md
|
|
@ -0,0 +1,7 @@
|
|||
*.out
|
||||
*.diff
|
||||
*.exp
|
||||
*.log
|
||||
*.sh
|
||||
*.repo
|
||||
.DS_Store
|
|
@ -0,0 +1,14 @@
|
|||
# The PHP Specification Test Suite
|
||||
|
||||
If you pass this suite, you aren't necessarily spec compliant, but it is a helpful bellwether.
|
||||
|
||||
## Usage
|
||||
|
||||
To run using the PHP5 test runner, you'll need to convert to PHP5's .phpt format first. The following demonstrates writing the tests out to /tmp/phpt:
|
||||
|
||||
./make_phpt . /tmp/phpt
|
||||
TEST_PHP_EXECUTABLE=~/php-src/sapi/cli/php ~/php-src/run-tests.php /tmp/phpt
|
||||
|
||||
To use the HHVM test runner:
|
||||
|
||||
~/hhvm/hphp/test/run .
|
|
@ -0,0 +1,584 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./arrays/arrays.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
echo "================= array of zero elements is possible =================\n";
|
||||
|
||||
$v = array();
|
||||
var_dump($v);
|
||||
$v = [];
|
||||
var_dump($v);
|
||||
|
||||
echo "================= array of 1 element is possible =================\n";
|
||||
|
||||
$v = array(TRUE);
|
||||
var_dump($v);
|
||||
$v = [TRUE];
|
||||
var_dump($v);
|
||||
$v = array(0 => TRUE); // specify explicit key
|
||||
var_dump($v);
|
||||
$v = [0 => TRUE];
|
||||
var_dump($v);
|
||||
|
||||
echo "================= array of 2 elements each having the same type =================\n";
|
||||
|
||||
$v = array(123, -56);
|
||||
var_dump($v);
|
||||
$v = [123, -56];
|
||||
var_dump($v);
|
||||
$v = array(0 => 123, 1 => -56); // specify explicit keys
|
||||
var_dump($v);
|
||||
$v = [0 => 123, 1 => -56];
|
||||
var_dump($v);
|
||||
|
||||
$pos = 1;
|
||||
$v = array(0 => 123, $pos => -56); // specify explicit keys
|
||||
var_dump($v);
|
||||
$v = [0 => 123, $pos => -56]; // key can be a variable
|
||||
var_dump($v);
|
||||
|
||||
$i = 10;
|
||||
$v = array(0 => 123, $pos => -56); // specify explicit keys
|
||||
var_dump($v);
|
||||
$v = [$i - 10 => 123, $i - 9 => -56]; // key can be a runtime expression
|
||||
var_dump($v);
|
||||
|
||||
echo "================= array of 5 elements each having different type =================\n";
|
||||
|
||||
$v = array(NULL, FALSE, 123, 34e12, "Hello");
|
||||
var_dump($v);
|
||||
$v = [NULL, FALSE, 123, 34e12, "Hello"];
|
||||
var_dump($v);
|
||||
$v = array(0 => NULL, 1 => FALSE, 2 => 123, 3 => 34e12, 4 => "Hello");
|
||||
var_dump($v);
|
||||
$v = [0 => NULL, 1 => FALSE, 2 => 123, 3 => 34e12, 4 => "Hello"];
|
||||
var_dump($v);
|
||||
$v = array(NULL, 1 => FALSE, 123, 3 => 34e12, "Hello"); // some keys default, others not
|
||||
var_dump($v);
|
||||
$v = [NULL, 1 => FALSE, 123, 3 => 34e12, "Hello"];
|
||||
var_dump($v);
|
||||
|
||||
echo "================= trailing comma permitted if list has at least one entry =================\n";
|
||||
|
||||
// $v = array(,); // error
|
||||
// $v = [,]; // error
|
||||
|
||||
$v = array(TRUE,);
|
||||
var_dump($v);
|
||||
$v = [TRUE,];
|
||||
var_dump($v);
|
||||
$v = array(0 => TRUE,);
|
||||
var_dump($v);
|
||||
$v = [0 => TRUE,];
|
||||
var_dump($v);
|
||||
|
||||
$v = array(123, -56,);
|
||||
var_dump($v);
|
||||
$v = [123, -56,];
|
||||
var_dump($v);
|
||||
$v = array(0 => 123, 1 => -56,);
|
||||
var_dump($v);
|
||||
$v = [0 => 123, 1 => -56,];
|
||||
var_dump($v);
|
||||
|
||||
echo "================= specify keys in arbitrary order, initial values of runtime expressions, leave gaps =================\n";
|
||||
|
||||
$i = 6;
|
||||
$j = 12;
|
||||
$v = array(7 => 123, 3 => $i, 6 => ++$j);
|
||||
var_dump($v);
|
||||
|
||||
$i = 6;
|
||||
$j = 12;
|
||||
$v = [7 => 123, 3 => $i, 6 => ++$j];
|
||||
var_dump($v);
|
||||
|
||||
foreach($v as $e) // only has 3 elements ([3], [6], and [7]), not 8 ([0]-[7])
|
||||
{
|
||||
echo $e.' ';
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
echo "\$v[1] is >".$v[1]."<\n"; var_dump($v1[1]); // access non-existant element
|
||||
echo "\$v[4] is >".$v[4]."<\n"; var_dump($v1[4]); // access non-existant element
|
||||
|
||||
$v[1] = TRUE; // increases array to 4 elements
|
||||
$v[4] = 99; // increases array to 5 elements
|
||||
var_dump($v);
|
||||
foreach($v as $e) // now has 5 elements
|
||||
{
|
||||
echo $e.' ';
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
echo "================= duplicate keys allowed, but lexically final one used =================\n";
|
||||
|
||||
$v = array(2 => 23, 1 => 10, 2 => 46, 1.9 => 6); // key 1.9 is truncated to key 1
|
||||
var_dump($v);
|
||||
|
||||
echo "================= string keys can be expressions too =================\n";
|
||||
|
||||
$s1 = "color";
|
||||
$s2 = "shape";
|
||||
$v = array($s1 => "red", $s2 => "square");
|
||||
var_dump($v);
|
||||
|
||||
echo "================= can mix int and string keys =================\n";
|
||||
|
||||
// "4" as key is taken as key 4
|
||||
// 9.2 as key is truncated to key 9
|
||||
// "12.8" as key is treated as key with that string, NOT truncated and made int 12
|
||||
// NULL as key becomes key ""
|
||||
|
||||
$v = array("red" => 10, "4" => 3, 9.2 => 5, "12.8" => 111, NULL => 1);
|
||||
var_dump($v);
|
||||
|
||||
$v = array(FALSE => -4); // FALSE as key becomes key 0
|
||||
var_dump($v);
|
||||
$v = array("" => -3);
|
||||
var_dump($v);
|
||||
$v = array(INF => 21); // INF as key becomes key 0
|
||||
var_dump($v);
|
||||
$v = array(-INF => -1); // -INF as key becomes key 0
|
||||
var_dump($v);
|
||||
$v = array(NAN => 123); // NAN as key becomes key of 0
|
||||
var_dump($v);
|
||||
|
||||
echo "================= arrays some of whose elements are arrays, and so on =================\n";
|
||||
|
||||
$c = array("red", "white", "blue");
|
||||
$v = array(10, $c, NULL, array(FALSE, NULL, $c));
|
||||
var_dump($v);
|
||||
|
||||
$v = [[2,4,6,8], [5,10], [100,200,300]];
|
||||
var_dump($v);
|
||||
|
||||
echo "================= see if int keys can be specified in any base. =================\n";
|
||||
|
||||
$v = [12 => 10, 0x10 => 16, 010 => 8, 0b11 => 2];
|
||||
var_dump($v);
|
||||
|
||||
echo "================= what about int-looking strings? It appears not. =================\n";
|
||||
|
||||
$v = ["12" => 10, "0x10" => 16, "010" => 8, "0b11" => 2];
|
||||
var_dump($v);
|
||||
|
||||
echo "================= iterate using foreach and compare with for loop =================\n";
|
||||
|
||||
$v = array(2 => TRUE, 0 => 123, 1 => 34.5, -1 => "red");
|
||||
var_dump($v);
|
||||
foreach($v as $e)
|
||||
{
|
||||
echo $e.' ';
|
||||
}
|
||||
echo "\n";
|
||||
for ($i = -1; $i <= 2; ++$i)
|
||||
{
|
||||
echo $v[$i].' ';
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
echo "================= remove some elements from an array =================\n";
|
||||
|
||||
$v = array("red" => TRUE, 123, 9 => 34e12, "Hello");
|
||||
var_dump($v);
|
||||
unset($v[0], $v["red"]);
|
||||
var_dump($v);
|
||||
--EXPECTF--
|
||||
================= array of zero elements is possible =================
|
||||
array(0) {
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
================= array of 1 element is possible =================
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
================= array of 2 elements each having the same type =================
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
================= array of 5 elements each having different type =================
|
||||
array(5) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
bool(false)
|
||||
[2]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
float(34000000000000)
|
||||
[4]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
array(5) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
bool(false)
|
||||
[2]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
float(34000000000000)
|
||||
[4]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
array(5) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
bool(false)
|
||||
[2]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
float(34000000000000)
|
||||
[4]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
array(5) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
bool(false)
|
||||
[2]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
float(34000000000000)
|
||||
[4]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
array(5) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
bool(false)
|
||||
[2]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
float(34000000000000)
|
||||
[4]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
array(5) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
bool(false)
|
||||
[2]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
float(34000000000000)
|
||||
[4]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
================= trailing comma permitted if list has at least one entry =================
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
bool(true)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
int(-56)
|
||||
}
|
||||
================= specify keys in arbitrary order, initial values of runtime expressions, leave gaps =================
|
||||
array(3) {
|
||||
[7]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
int(6)
|
||||
[6]=>
|
||||
int(13)
|
||||
}
|
||||
array(3) {
|
||||
[7]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
int(6)
|
||||
[6]=>
|
||||
int(13)
|
||||
}
|
||||
123 6 13
|
||||
|
||||
Notice: Undefined %s: 1 in %s/arrays/arrays.php on line 108
|
||||
$v[1] is ><
|
||||
|
||||
Notice: Undefined variable: v1 in %s/arrays/arrays.php on line 108
|
||||
NULL
|
||||
|
||||
Notice: Undefined %s: 4 in %s/arrays/arrays.php on line 109
|
||||
$v[4] is ><
|
||||
|
||||
Notice: Undefined variable: v1 in %s/arrays/arrays.php on line 109
|
||||
NULL
|
||||
array(5) {
|
||||
[7]=>
|
||||
int(123)
|
||||
[3]=>
|
||||
int(6)
|
||||
[6]=>
|
||||
int(13)
|
||||
[1]=>
|
||||
bool(true)
|
||||
[4]=>
|
||||
int(99)
|
||||
}
|
||||
123 6 13 1 99
|
||||
================= duplicate keys allowed, but lexically final one used =================
|
||||
array(2) {
|
||||
[2]=>
|
||||
int(46)
|
||||
[1]=>
|
||||
int(6)
|
||||
}
|
||||
================= string keys can be expressions too =================
|
||||
array(2) {
|
||||
["color"]=>
|
||||
string(3) "red"
|
||||
["shape"]=>
|
||||
string(6) "square"
|
||||
}
|
||||
================= can mix int and string keys =================
|
||||
array(5) {
|
||||
["red"]=>
|
||||
int(10)
|
||||
[4]=>
|
||||
int(3)
|
||||
[9]=>
|
||||
int(5)
|
||||
["12.8"]=>
|
||||
int(111)
|
||||
[""]=>
|
||||
int(1)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(-4)
|
||||
}
|
||||
array(1) {
|
||||
[""]=>
|
||||
int(-3)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(21)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(-1)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(123)
|
||||
}
|
||||
================= arrays some of whose elements are arrays, and so on =================
|
||||
array(4) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(3) "red"
|
||||
[1]=>
|
||||
string(5) "white"
|
||||
[2]=>
|
||||
string(4) "blue"
|
||||
}
|
||||
[2]=>
|
||||
NULL
|
||||
[3]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
bool(false)
|
||||
[1]=>
|
||||
NULL
|
||||
[2]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(3) "red"
|
||||
[1]=>
|
||||
string(5) "white"
|
||||
[2]=>
|
||||
string(4) "blue"
|
||||
}
|
||||
}
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
int(4)
|
||||
[2]=>
|
||||
int(6)
|
||||
[3]=>
|
||||
int(8)
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(5)
|
||||
[1]=>
|
||||
int(10)
|
||||
}
|
||||
[2]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(100)
|
||||
[1]=>
|
||||
int(200)
|
||||
[2]=>
|
||||
int(300)
|
||||
}
|
||||
}
|
||||
================= see if int keys can be specified in any base. =================
|
||||
array(4) {
|
||||
[12]=>
|
||||
int(10)
|
||||
[16]=>
|
||||
int(16)
|
||||
[8]=>
|
||||
int(8)
|
||||
[3]=>
|
||||
int(2)
|
||||
}
|
||||
================= what about int-looking strings? It appears not. =================
|
||||
array(4) {
|
||||
[12]=>
|
||||
int(10)
|
||||
["0x10"]=>
|
||||
int(16)
|
||||
["010"]=>
|
||||
int(8)
|
||||
["0b11"]=>
|
||||
int(2)
|
||||
}
|
||||
================= iterate using foreach and compare with for loop =================
|
||||
array(4) {
|
||||
[2]=>
|
||||
bool(true)
|
||||
[0]=>
|
||||
int(123)
|
||||
[1]=>
|
||||
float(34.5)
|
||||
[-1]=>
|
||||
string(3) "red"
|
||||
}
|
||||
1 123 34.5 red
|
||||
red 123 34.5 1
|
||||
================= remove some elements from an array =================
|
||||
array(4) {
|
||||
["red"]=>
|
||||
bool(true)
|
||||
[0]=>
|
||||
int(123)
|
||||
[9]=>
|
||||
float(34000000000000)
|
||||
[10]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
array(2) {
|
||||
[9]=>
|
||||
float(34000000000000)
|
||||
[10]=>
|
||||
string(5) "Hello"
|
||||
}
|
|
@ -0,0 +1,492 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./basic_concepts/memory_model_and_array_types.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private static $pointCount = 0;
|
||||
|
||||
private $x;
|
||||
private $y;
|
||||
|
||||
public static function getPointCount()
|
||||
{
|
||||
return self::$pointCount;
|
||||
}
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
|
||||
public function move($x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function translate($x, $y)
|
||||
{
|
||||
$this->x += $x;
|
||||
$this->y += $y;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
--self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
///*
|
||||
public function __clone()
|
||||
{
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
//*/
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
}
|
||||
|
||||
///*
|
||||
echo "----------------- simple assignment of array types ----------------------\n";
|
||||
|
||||
$x = 123;
|
||||
$a = array(10, &$x, 'B' => new Point(1, 3));
|
||||
|
||||
echo "After '\$a = array(...)', \$a is "; var_dump($a);
|
||||
|
||||
$b = $a;
|
||||
|
||||
echo "After '\$b = \$a', \$a is "; var_dump($a);
|
||||
echo "\$b is "; var_dump($b);
|
||||
|
||||
++$b[0];
|
||||
|
||||
echo "After '++\$b[0]', \$a is "; var_dump($a);
|
||||
echo "\$b is "; var_dump($b);
|
||||
|
||||
$a[0] = 99;
|
||||
|
||||
echo "After '\$a[0] = 99', \$a is "; var_dump($a);
|
||||
echo "\$b is "; var_dump($b);
|
||||
|
||||
--$x;
|
||||
|
||||
echo "After '--\$x', \$a is "; var_dump($a);
|
||||
echo "\$b is "; var_dump($b);
|
||||
|
||||
unset($a);
|
||||
echo "After 'unset(\$a)', \$a is undefined, \$b is "; var_dump($b);
|
||||
unset($b);
|
||||
echo "After 'unset(\$b)', \$b is undefined\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- byRef assignment of array types ----------------------\n";
|
||||
|
||||
$x = 123;
|
||||
$a = array(10, &$x, 'B' => new Point(1, 3));
|
||||
|
||||
echo "After '\$a = array(...)', \$a is "; var_dump($a);
|
||||
|
||||
$c =& $a;
|
||||
|
||||
echo "After '\$c =& \$a', \$a is "; var_dump($a);
|
||||
echo "\$c is "; var_dump($c);
|
||||
|
||||
++$c[0];
|
||||
|
||||
echo "After '++\$c[0]', \$a is "; var_dump($a);
|
||||
echo "\$c is "; var_dump($c);
|
||||
|
||||
$a[0] = 99;
|
||||
|
||||
echo "After '\$a[0] = 99', \$a is "; var_dump($a);
|
||||
echo "\$c is "; var_dump($c);
|
||||
|
||||
--$x;
|
||||
|
||||
echo "After '--\$x', \$a is "; var_dump($a);
|
||||
echo "\$c is "; var_dump($c);
|
||||
|
||||
unset($a);
|
||||
echo "After 'unset(\$a)', \$a is undefined, \$c is "; var_dump($c);
|
||||
|
||||
unset($c);
|
||||
echo "End\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- unsetting array elements ----------------------\n";
|
||||
|
||||
$x = 123;
|
||||
$a = array(10, 'M' => TRUE, &$x, 'B' => new Point(1, 3));
|
||||
|
||||
echo "at start, \$x is $x, \$a is "; var_dump($a);
|
||||
|
||||
unset($a[0]);
|
||||
echo "after unset(\$a[0]), \$x is $x, \$a is "; var_dump($a);
|
||||
|
||||
unset($a['M']);
|
||||
echo "after unset(\$a['M']), \$x is $x, \$a is "; var_dump($a);
|
||||
|
||||
unset($a[1]);
|
||||
echo "after unset(\$a[1]), \$x is $x, \$a is "; var_dump($a);
|
||||
|
||||
//unset($a['B']);
|
||||
//echo "after unset(\$a['B']), \$x is $x, \$a is "; var_dump($a);
|
||||
|
||||
unset($a);
|
||||
echo "after unset(\$a), \$x is $x, \$a is undefined\n";
|
||||
//*/
|
||||
--EXPECT--
|
||||
----------------- simple assignment of array types ----------------------
|
||||
|
||||
Inside Point::__construct, (1,3), point count = 1
|
||||
|
||||
After '$a = array(...)', $a is array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '$b = $a', $a is array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$b is array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '++$b[0]', $a is array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$b is array(3) {
|
||||
[0]=>
|
||||
int(11)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '$a[0] = 99', $a is array(3) {
|
||||
[0]=>
|
||||
int(99)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$b is array(3) {
|
||||
[0]=>
|
||||
int(11)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '--$x', $a is array(3) {
|
||||
[0]=>
|
||||
int(99)
|
||||
[1]=>
|
||||
&int(122)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$b is array(3) {
|
||||
[0]=>
|
||||
int(11)
|
||||
[1]=>
|
||||
&int(122)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After 'unset($a)', $a is undefined, $b is array(3) {
|
||||
[0]=>
|
||||
int(11)
|
||||
[1]=>
|
||||
&int(122)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
|
||||
Inside Point::__destruct, (1,3), point count = 0
|
||||
|
||||
After 'unset($b)', $b is undefined
|
||||
----------------- byRef assignment of array types ----------------------
|
||||
|
||||
Inside Point::__construct, (1,3), point count = 1
|
||||
|
||||
After '$a = array(...)', $a is array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '$c =& $a', $a is array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$c is array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '++$c[0]', $a is array(3) {
|
||||
[0]=>
|
||||
int(11)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$c is array(3) {
|
||||
[0]=>
|
||||
int(11)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '$a[0] = 99', $a is array(3) {
|
||||
[0]=>
|
||||
int(99)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$c is array(3) {
|
||||
[0]=>
|
||||
int(99)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After '--$x', $a is array(3) {
|
||||
[0]=>
|
||||
int(99)
|
||||
[1]=>
|
||||
&int(122)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
$c is array(3) {
|
||||
[0]=>
|
||||
int(99)
|
||||
[1]=>
|
||||
&int(122)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
After 'unset($a)', $a is undefined, $c is array(3) {
|
||||
[0]=>
|
||||
int(99)
|
||||
[1]=>
|
||||
&int(122)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
|
||||
Inside Point::__destruct, (1,3), point count = 0
|
||||
|
||||
End
|
||||
----------------- unsetting array elements ----------------------
|
||||
|
||||
Inside Point::__construct, (1,3), point count = 1
|
||||
|
||||
at start, $x is 123, $a is array(4) {
|
||||
[0]=>
|
||||
int(10)
|
||||
["M"]=>
|
||||
bool(true)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
after unset($a[0]), $x is 123, $a is array(3) {
|
||||
["M"]=>
|
||||
bool(true)
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
after unset($a['M']), $x is 123, $a is array(2) {
|
||||
[1]=>
|
||||
&int(123)
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
after unset($a[1]), $x is 123, $a is array(1) {
|
||||
["B"]=>
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(1)
|
||||
["y":"Point":private]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
|
||||
Inside Point::__destruct, (1,3), point count = 0
|
||||
|
||||
after unset($a), $x is 123, $a is undefined
|
|
@ -0,0 +1,371 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./basic_concepts/memory_model_and_handle_types.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private static $pointCount = 0;
|
||||
|
||||
private $x;
|
||||
private $y;
|
||||
|
||||
public static function getPointCount()
|
||||
{
|
||||
return self::$pointCount;
|
||||
}
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
|
||||
public function move($x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function translate($x, $y)
|
||||
{
|
||||
$this->x += $x;
|
||||
$this->y += $y;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
--self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
///*
|
||||
public function __clone()
|
||||
{
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
//*/
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
}
|
||||
|
||||
///*
|
||||
echo "----------------- simple assignment of handle types ----------------------\n";
|
||||
|
||||
$a = new Point(1, 3); // create first new point, and make $a an alias to it
|
||||
|
||||
echo "After '\$a = new Point(1, 3)', \$a is $a\n";
|
||||
|
||||
$b = $a; // $b is a snapshot copy of $a, so create second alias to first point
|
||||
|
||||
echo "After '\$b = \$a', \$b is $b\n";
|
||||
|
||||
$d = clone $b; // create second point, and make $d the first alias to that
|
||||
|
||||
echo "After '\$d = clone \$b', \$d is $d\n";
|
||||
|
||||
$b->move(4, 6); // moving $b also moves $a, but $d is unchanged
|
||||
|
||||
echo "After '\$b->move(4, 6)', \$d is $d, \$b is $b, and \$a is $a\n";
|
||||
|
||||
$a = new Point(2, 1); // remove $a's alias from first point
|
||||
// create third new point, and make $a an alias to it
|
||||
// As $b still aliases the first point, $b is unchanged
|
||||
|
||||
echo "After '\$a = new Point(2, 1)', \$d is $d, \$b is $b, and \$a is $a\n";
|
||||
|
||||
unset($a); // remove only alias from third point, so destructor runs
|
||||
unset($b); // remove only alias from first point, so destructor runs
|
||||
unset($d); // remove only alias from second point, so destructor runs
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- byRef assignment of handle types ----------------------\n";
|
||||
|
||||
$a = new Point(1, 3); // create first new point, and make $a an alias to it
|
||||
|
||||
echo "After '\$a = new Point(1, 3)', \$a is $a\n";
|
||||
|
||||
$c =& $a; // make $c forever alias whatever $a aliases
|
||||
|
||||
echo "After '\$c =& \$a', \$c is $c, and \$a is $a\n";
|
||||
|
||||
$a->move(4, 6); // moving $a also moves $c
|
||||
|
||||
echo "After '\$a->move(4, 6)', \$c is $c, and \$a is $a\n";
|
||||
|
||||
$a = new Point(2, 1); // remove $a's alias from first point
|
||||
// create second new point, and make $a an alias to it
|
||||
// As $c aliases whatever $a aliases, $c's old alias to the first
|
||||
// point is also removed, allowing the destructor to run.
|
||||
// $c's new alias is to the new point
|
||||
|
||||
echo "After '\$a = new Point(2, 1)', \$c is $c, and \$a is $a\n";
|
||||
|
||||
unset($a); // remove one alias from second point
|
||||
echo "After 'unset(\$a)', \$c is $c\n";
|
||||
unset($c); // remove second (and final) alias from second point, so destructor runs
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- value argument passing of handle types ----------------------\n";
|
||||
|
||||
function f1($b) // pass-by-value creates second alias to first point
|
||||
{
|
||||
echo "\tInside function " . __FUNCTION__ . ", \$b is $b\n";
|
||||
|
||||
$b->move(4, 6); // moving $b also moves $a
|
||||
echo "After '\$b->move(4, 6)', \$b is $b\n";
|
||||
|
||||
$b = new Point(5, 7); // removes second alias from first point;
|
||||
// then create first alias to second new point
|
||||
|
||||
echo "After 'new Point(5, 7)', \$b is $b\n";
|
||||
} // $b goes away, remove the only alias from second point, so destructor runs
|
||||
|
||||
$a = new Point(1, 3); // create first new point, and make $a an alias to it
|
||||
|
||||
echo "After '\$a = new Point(1, 3)', \$a is $a\n";
|
||||
|
||||
f1($a); // $a's point value is changed, but $a still aliases first point
|
||||
|
||||
echo "After 'f1(\$a)', \$a is $a\n";
|
||||
|
||||
unset($a); // remove only alias from first point, so destructor runs
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- byRef argument passing of handle types ----------------------\n";
|
||||
|
||||
function g1(&$b) // make $b alias whatever $a aliases
|
||||
{
|
||||
echo "\tInside function " . __FUNCTION__ . ", \$b is $b\n";
|
||||
|
||||
$b->move(4, 6); // moving $b also moves $a
|
||||
echo "After '\$b->move(4, 6)', \$b is $b\n";
|
||||
|
||||
$b = new Point(5, 7); // removes second alias from first point;
|
||||
// then create first alias to second new point
|
||||
// changing $b also changes $a as well, so $a's alias
|
||||
// is also removed, alowing the destructor run
|
||||
|
||||
echo "After 'new Point(5, 7)', \$b is $b\n";
|
||||
} // $b goes away, remove its alias from new point
|
||||
|
||||
$a = new Point(1, 3); // create first new point, and make $a an alias to it
|
||||
|
||||
echo "After '\$a = new Point(1, 3)', \$a is $a\n";
|
||||
|
||||
g1($a); // $a is changed via change to $b
|
||||
|
||||
echo "After 'g1(\$a)', \$a is $a\n";
|
||||
unset($a); // remove only alias from point, so destructor runs
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- value returning of handle types ----------------------\n";
|
||||
|
||||
function f2()
|
||||
{
|
||||
$b = new Point(5, 7); // create first new point, and make $b an alias to it
|
||||
|
||||
echo "After 'new Point(5, 7)', \$b is $b\n";
|
||||
|
||||
return $b; // return a temporary copy, which is a new alias
|
||||
// However, as $b goes away, remove its alias
|
||||
}
|
||||
|
||||
$a = f2(); // make a new alias in $a and remove the temporary alias
|
||||
|
||||
echo "After '\$a = f2()', \$a is $a\n";
|
||||
unset($a); // remove only alias from point, so destructor runs
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- byRef returning of handle types ----------------------\n";
|
||||
|
||||
function & g2()
|
||||
{
|
||||
$b = new Point(5, 7); // create first new point, and make $b an alias to it
|
||||
|
||||
echo "After 'new Point(5, 7)', \$b is $b\n";
|
||||
|
||||
return $b; // return as though using $a =& $b
|
||||
// as $b goes away, remove its alias
|
||||
}
|
||||
|
||||
$a = g2();
|
||||
|
||||
echo "After '\$a = f2()', \$a is $a\n";
|
||||
unset($a); // remove only alias from point, so destructor runs
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
echo "----------------- unsetting properties ----------------------\n";
|
||||
|
||||
class C
|
||||
{
|
||||
public $prop1;
|
||||
public $prop2;
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
echo "\nInside " . __METHOD__ . "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
$c = new C;
|
||||
|
||||
echo "at start, \$c is "; var_dump($c);
|
||||
|
||||
unset($c->prop1);
|
||||
echo "after unset(\$c->prop1), \$c is "; var_dump($c);
|
||||
|
||||
unset($c->prop2);
|
||||
echo "after unset(\$c->prop2), \$c is "; var_dump($c);
|
||||
|
||||
unset($c);
|
||||
echo "after unset(\$c), \$c is undefined\n";
|
||||
echo "Done\n";
|
||||
--EXPECTF--
|
||||
----------------- simple assignment of handle types ----------------------
|
||||
|
||||
Inside Point::__construct, (1,3), point count = 1
|
||||
|
||||
After '$a = new Point(1, 3)', $a is (1,3)
|
||||
After '$b = $a', $b is (1,3)
|
||||
|
||||
Inside Point::__clone, (1,3), point count = 2
|
||||
|
||||
After '$d = clone $b', $d is (1,3)
|
||||
After '$b->move(4, 6)', $d is (1,3), $b is (4,6), and $a is (4,6)
|
||||
|
||||
Inside Point::__construct, (2,1), point count = 3
|
||||
|
||||
After '$a = new Point(2, 1)', $d is (1,3), $b is (4,6), and $a is (2,1)
|
||||
|
||||
Inside Point::__destruct, (2,1), point count = 2
|
||||
|
||||
|
||||
Inside Point::__destruct, (4,6), point count = 1
|
||||
|
||||
|
||||
Inside Point::__destruct, (1,3), point count = 0
|
||||
|
||||
Done
|
||||
----------------- byRef assignment of handle types ----------------------
|
||||
|
||||
Inside Point::__construct, (1,3), point count = 1
|
||||
|
||||
After '$a = new Point(1, 3)', $a is (1,3)
|
||||
After '$c =& $a', $c is (1,3), and $a is (1,3)
|
||||
After '$a->move(4, 6)', $c is (4,6), and $a is (4,6)
|
||||
|
||||
Inside Point::__construct, (2,1), point count = 2
|
||||
|
||||
|
||||
Inside Point::__destruct, (4,6), point count = 1
|
||||
|
||||
After '$a = new Point(2, 1)', $c is (2,1), and $a is (2,1)
|
||||
After 'unset($a)', $c is (2,1)
|
||||
|
||||
Inside Point::__destruct, (2,1), point count = 0
|
||||
|
||||
Done
|
||||
----------------- value argument passing of handle types ----------------------
|
||||
|
||||
Inside Point::__construct, (1,3), point count = 1
|
||||
|
||||
After '$a = new Point(1, 3)', $a is (1,3)
|
||||
Inside function f1, $b is (1,3)
|
||||
After '$b->move(4, 6)', $b is (4,6)
|
||||
|
||||
Inside Point::__construct, (5,7), point count = 2
|
||||
|
||||
After 'new Point(5, 7)', $b is (5,7)
|
||||
|
||||
Inside Point::__destruct, (5,7), point count = 1
|
||||
|
||||
After 'f1($a)', $a is (4,6)
|
||||
|
||||
Inside Point::__destruct, (4,6), point count = 0
|
||||
|
||||
Done
|
||||
----------------- byRef argument passing of handle types ----------------------
|
||||
|
||||
Inside Point::__construct, (1,3), point count = 1
|
||||
|
||||
After '$a = new Point(1, 3)', $a is (1,3)
|
||||
Inside function g1, $b is (1,3)
|
||||
After '$b->move(4, 6)', $b is (4,6)
|
||||
|
||||
Inside Point::__construct, (5,7), point count = 2
|
||||
|
||||
|
||||
Inside Point::__destruct, (4,6), point count = 1
|
||||
|
||||
After 'new Point(5, 7)', $b is (5,7)
|
||||
After 'g1($a)', $a is (5,7)
|
||||
|
||||
Inside Point::__destruct, (5,7), point count = 0
|
||||
|
||||
Done
|
||||
----------------- value returning of handle types ----------------------
|
||||
|
||||
Inside Point::__construct, (5,7), point count = 1
|
||||
|
||||
After 'new Point(5, 7)', $b is (5,7)
|
||||
After '$a = f2()', $a is (5,7)
|
||||
|
||||
Inside Point::__destruct, (5,7), point count = 0
|
||||
|
||||
Done
|
||||
----------------- byRef returning of handle types ----------------------
|
||||
|
||||
Inside Point::__construct, (5,7), point count = 1
|
||||
|
||||
After 'new Point(5, 7)', $b is (5,7)
|
||||
After '$a = f2()', $a is (5,7)
|
||||
|
||||
Inside Point::__destruct, (5,7), point count = 0
|
||||
|
||||
Done
|
||||
----------------- unsetting properties ----------------------
|
||||
at start, $c is object(C)#%d (2) {
|
||||
["prop1"]=>
|
||||
NULL
|
||||
["prop2"]=>
|
||||
NULL
|
||||
}
|
||||
after unset($c->prop1), $c is object(C)#%d (1) {
|
||||
["prop2"]=>
|
||||
NULL
|
||||
}
|
||||
after unset($c->prop2), $c is object(C)#%d (0) {
|
||||
}
|
||||
|
||||
Inside C::__destruct
|
||||
|
||||
after unset($c), $c is undefined
|
||||
Done
|
|
@ -0,0 +1,162 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./basic_concepts/memory_model_and_resources.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
///*
|
||||
echo "----------------- resource value assignment ----------------------\n";
|
||||
|
||||
$a = STDIN;
|
||||
|
||||
echo "After '\$a = STDIN', \$a is $a\n";
|
||||
|
||||
$b = $a;
|
||||
|
||||
echo "After '\$b = \$a', \$b is $b\n";
|
||||
|
||||
$a = STDOUT;
|
||||
|
||||
echo "After '\$a = STDOUT', \$b is $b, and \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- resource byRef assignment ----------------------\n";
|
||||
|
||||
$a = STDIN;
|
||||
|
||||
echo "After '\$a = STDIN', \$a is $a\n";
|
||||
|
||||
$c =& $a;
|
||||
|
||||
echo "After '\$c =& \$a', \$c is $c, and \$a is $a\n";
|
||||
|
||||
$a = STDOUT; // this causes $c to also alias 99
|
||||
|
||||
echo "After '\$a = STDOUT', \$c is $c, and \$a is $a\n";
|
||||
|
||||
unset($a);
|
||||
|
||||
echo "After 'unset(\$a)', \$c is $c, and \$a is undefined\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- resource value argument passing ----------------------\n";
|
||||
|
||||
function f1($b)
|
||||
{
|
||||
echo "\tInside function " . __FUNCTION__ . ", \$b is $b\n";
|
||||
|
||||
$b = STDOUT;
|
||||
|
||||
echo "After '\$b = STDOUT', \$b is $b\n";
|
||||
}
|
||||
|
||||
$a = STDIN;
|
||||
|
||||
echo "After '\$a = STDIN', \$a is $a\n";
|
||||
|
||||
f1($a);
|
||||
|
||||
echo "After 'f1(\$a)', \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- resource byRef argument passing ----------------------\n";
|
||||
|
||||
function g1(&$b)
|
||||
{
|
||||
echo "\tInside function " . __FUNCTION__ . ", \$b is $b\n";
|
||||
|
||||
$b = STDOUT;
|
||||
|
||||
echo "After '\$b = STDOUT', \$b is $b\n";
|
||||
}
|
||||
|
||||
$a = STDIN;
|
||||
|
||||
echo "After '\$a = STDIN', \$a is $a\n";
|
||||
|
||||
g1($a);
|
||||
|
||||
echo "After 'g1(\$a)', \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- resource value returning ----------------------\n";
|
||||
|
||||
function f2()
|
||||
{
|
||||
$b = STDOUT;
|
||||
|
||||
echo "After '\$b = STDOUT', \$b is $b\n";
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
$a = f2();
|
||||
|
||||
echo "After '\$a = f2()', \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- resource byRef returning ----------------------\n";
|
||||
|
||||
function & g2()
|
||||
{
|
||||
$b = STDOUT;
|
||||
|
||||
echo "After '\$b = STDOUT', \$b is $b\n";
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
$a = g2();
|
||||
|
||||
echo "After '\$a = f2()', \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
--EXPECT--
|
||||
----------------- resource value assignment ----------------------
|
||||
After '$a = STDIN', $a is Resource id #1
|
||||
After '$b = $a', $b is Resource id #1
|
||||
After '$a = STDOUT', $b is Resource id #1, and $a is Resource id #2
|
||||
Done
|
||||
----------------- resource byRef assignment ----------------------
|
||||
After '$a = STDIN', $a is Resource id #1
|
||||
After '$c =& $a', $c is Resource id #1, and $a is Resource id #1
|
||||
After '$a = STDOUT', $c is Resource id #2, and $a is Resource id #2
|
||||
After 'unset($a)', $c is Resource id #2, and $a is undefined
|
||||
Done
|
||||
----------------- resource value argument passing ----------------------
|
||||
After '$a = STDIN', $a is Resource id #1
|
||||
Inside function f1, $b is Resource id #1
|
||||
After '$b = STDOUT', $b is Resource id #2
|
||||
After 'f1($a)', $a is Resource id #1
|
||||
Done
|
||||
----------------- resource byRef argument passing ----------------------
|
||||
After '$a = STDIN', $a is Resource id #1
|
||||
Inside function g1, $b is Resource id #1
|
||||
After '$b = STDOUT', $b is Resource id #2
|
||||
After 'g1($a)', $a is Resource id #2
|
||||
Done
|
||||
----------------- resource value returning ----------------------
|
||||
After '$b = STDOUT', $b is Resource id #2
|
||||
After '$a = f2()', $a is Resource id #2
|
||||
Done
|
||||
----------------- resource byRef returning ----------------------
|
||||
After '$b = STDOUT', $b is Resource id #2
|
||||
After '$a = f2()', $a is Resource id #2
|
||||
Done
|
|
@ -0,0 +1,229 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./basic_concepts/memory_model_and_value_types.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
const CON = TRUE;
|
||||
|
||||
///*
|
||||
echo "----------------- simple assignment of value types ----------------------\n";
|
||||
|
||||
$a = 123;
|
||||
|
||||
echo "After '\$a = 123', \$a is $a\n";
|
||||
|
||||
$b = $a;
|
||||
|
||||
echo "After '\$b = \$a', \$b is $b\n";
|
||||
|
||||
++$b;
|
||||
|
||||
echo "After '++\$b', \$b is $b, and \$a is $a\n";
|
||||
|
||||
$a = 99;
|
||||
|
||||
echo "After '\$a = 99', \$b is $b, and \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- byRef assignment of value types ----------------------\n";
|
||||
|
||||
$a = 123;
|
||||
|
||||
echo "After '\$a = 123', \$a is $a\n";
|
||||
|
||||
$c =& $a;
|
||||
|
||||
echo "After '\$c =& \$a', \$c is $c, and \$a is $a\n";
|
||||
|
||||
++$c;
|
||||
|
||||
echo "After '++\$c', \$c is $c, and \$a is $a\n";
|
||||
|
||||
$a = 99;
|
||||
|
||||
echo "After '\$a = 99', \$c is $c, and \$a is $a\n";
|
||||
|
||||
unset($a);
|
||||
|
||||
echo "After 'unset(\$a)', \$c is $c, and \$a is undefined\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- value argument passing of value types ----------------------\n";
|
||||
|
||||
function f1($b)
|
||||
{
|
||||
echo "\tInside function " . __FUNCTION__ . ", \$b is $b\n";
|
||||
|
||||
$b = "abc";
|
||||
|
||||
echo "After '\$b = \"abc\"', \$b is $b\n";
|
||||
}
|
||||
|
||||
$a = 123;
|
||||
|
||||
echo "After '\$a = 123', \$a is $a\n";
|
||||
|
||||
f1($a);
|
||||
|
||||
echo "After 'f1(\$a)', \$a is $a\n";
|
||||
|
||||
f1($a + 2); // non-lvalue
|
||||
f1(999); // non-lvalue
|
||||
f1(CON); // non-lvalue
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- byRef argument passing of value types ----------------------\n";
|
||||
|
||||
function g1(&$b)
|
||||
{
|
||||
echo "\tInside function " . __FUNCTION__ . ", \$b is $b\n";
|
||||
|
||||
$b = "abc";
|
||||
|
||||
echo "After '\$b = \"abc\"', \$b is $b\n";
|
||||
}
|
||||
|
||||
$a = 123;
|
||||
|
||||
echo "After '\$a = 123', \$a is $a\n";
|
||||
|
||||
g1($a);
|
||||
|
||||
echo "After 'g1(\$a)', \$a is $a\n";
|
||||
|
||||
//g1($a + 2); // non-lvalue; can't be passed by reference
|
||||
//g1(999) // non-lvalue; can't be passed by reference
|
||||
//g1(CON); // non-lvalue; can't be passed by reference
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- value returning of value types ----------------------\n";
|
||||
|
||||
function f2()
|
||||
{
|
||||
$b = "abc";
|
||||
|
||||
echo "After '\$b = \"abc\"', \$b is $b\n";
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
$a = f2();
|
||||
|
||||
echo "After '\$a = f2()', \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----------------- byRef returning of value types ----------------------\n";
|
||||
|
||||
function & g2()
|
||||
{
|
||||
$b = "abc";
|
||||
|
||||
echo "After '\$b = \"abc\"', \$b is $b\n";
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
$a = g2();
|
||||
|
||||
echo "After '\$a = f2()', \$a is $a\n";
|
||||
echo "Done\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
echo "----- test using literals, constants, and arbitrary-complex expressions ----\n";
|
||||
|
||||
//$a =& 12; // literals are disallowed
|
||||
//$a =& CON; // constants are disallowed
|
||||
|
||||
$b = 10;
|
||||
$a =& $b;
|
||||
echo "After '=&', \$a is $a, \$b is $b\n";
|
||||
//$a =& 5 + $b; // arbitrary-complex expressions are disallowed
|
||||
echo "After '=&', \$a is $a, \$b is $b\n";
|
||||
|
||||
function h1()
|
||||
{
|
||||
$b = 10;
|
||||
return $b + 5;
|
||||
// return 12;
|
||||
// return CON;
|
||||
}
|
||||
|
||||
echo "h1() is " . h1() . "\n";
|
||||
//*/
|
||||
|
||||
///*
|
||||
function & h2()
|
||||
{
|
||||
$b = 10;
|
||||
// return $b + 5; // Only variable references should be returned by reference
|
||||
// return 12;
|
||||
// return CON;
|
||||
}
|
||||
|
||||
h2();
|
||||
echo "Done\n";
|
||||
//*/
|
||||
--EXPECTF--
|
||||
----------------- simple assignment of value types ----------------------
|
||||
After '$a = 123', $a is 123
|
||||
After '$b = $a', $b is 123
|
||||
After '++$b', $b is 124, and $a is 123
|
||||
After '$a = 99', $b is 124, and $a is 99
|
||||
Done
|
||||
----------------- byRef assignment of value types ----------------------
|
||||
After '$a = 123', $a is 123
|
||||
After '$c =& $a', $c is 123, and $a is 123
|
||||
After '++$c', $c is 124, and $a is 124
|
||||
After '$a = 99', $c is 99, and $a is 99
|
||||
After 'unset($a)', $c is 99, and $a is undefined
|
||||
Done
|
||||
----------------- value argument passing of value types ----------------------
|
||||
After '$a = 123', $a is 123
|
||||
Inside function f1, $b is 123
|
||||
After '$b = "abc"', $b is abc
|
||||
After 'f1($a)', $a is 123
|
||||
Inside function f1, $b is 125
|
||||
After '$b = "abc"', $b is abc
|
||||
Inside function f1, $b is 999
|
||||
After '$b = "abc"', $b is abc
|
||||
Inside function f1, $b is 1
|
||||
After '$b = "abc"', $b is abc
|
||||
Done
|
||||
----------------- byRef argument passing of value types ----------------------
|
||||
After '$a = 123', $a is 123
|
||||
Inside function g1, $b is 123
|
||||
After '$b = "abc"', $b is abc
|
||||
After 'g1($a)', $a is abc
|
||||
Done
|
||||
----------------- value returning of value types ----------------------
|
||||
After '$b = "abc"', $b is abc
|
||||
After '$a = f2()', $a is abc
|
||||
Done
|
||||
----------------- byRef returning of value types ----------------------
|
||||
After '$b = "abc"', $b is abc
|
||||
After '$a = f2()', $a is abc
|
||||
Done
|
||||
----- test using literals, constants, and arbitrary-complex expressions ----
|
||||
After '=&', $a is 10, $b is 10
|
||||
After '=&', $a is 10, $b is 10
|
||||
h1() is 15%A
|
||||
Done
|
|
@ -0,0 +1,196 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./basic_concepts/storage_duration.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private static $pointCount = 0;
|
||||
|
||||
private $x;
|
||||
private $y;
|
||||
|
||||
public static function getPointCount()
|
||||
{
|
||||
return self::$pointCount;
|
||||
}
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
|
||||
public function move($x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function translate($x, $y)
|
||||
{
|
||||
$this->x += $x;
|
||||
$this->y += $y;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
--self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
///*
|
||||
public function __clone()
|
||||
{
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
//*/
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
}
|
||||
|
||||
echo "---------------- start -------------------\n";
|
||||
|
||||
$av1 = new Point(0, 1);
|
||||
|
||||
echo "---------------- after \$av1 init -------------------\n";
|
||||
|
||||
static $sv1 = TRUE;
|
||||
|
||||
echo "---------------- after \$sv1 decl -------------------\n";
|
||||
|
||||
$sv1 = new Point(0, 2);
|
||||
|
||||
echo "---------------- after \$sv1 init -------------------\n";
|
||||
|
||||
function doit($p1)
|
||||
{
|
||||
echo "---------------- Inside function_A -------------------\n";
|
||||
|
||||
$av2 = new Point(1, 1);
|
||||
|
||||
echo "---------------- after \$av2 init -------------------\n";
|
||||
|
||||
static $sv2 = 0;
|
||||
|
||||
echo "---------------- after \$sv2 decl -------------------\n";
|
||||
|
||||
$sv2 = new Point(1, 2);
|
||||
|
||||
echo "---------------- after \$sv2 init -------------------\n";
|
||||
|
||||
if ($p1)
|
||||
{
|
||||
echo "---------------- Inside if TRUE -------------------\n";
|
||||
|
||||
$av3 = new Point(2, 1);
|
||||
|
||||
echo "---------------- after \$av3 init -------------------\n";
|
||||
|
||||
static $sv3 = NULL;
|
||||
|
||||
echo "---------------- after \$sv3 decl -------------------\n";
|
||||
|
||||
$sv3 = new Point(2, 2);
|
||||
|
||||
echo "---------------- after \$sv3 init -------------------\n";
|
||||
// ...
|
||||
}
|
||||
|
||||
$av1 = new Point(2, 3);
|
||||
|
||||
// Order of destruction is implementation-defined
|
||||
echo "---------------- after \$av1 reinit -------------------\n";
|
||||
}
|
||||
|
||||
doit(TRUE);
|
||||
|
||||
echo "---------------- after call to func -------------------\n";
|
||||
|
||||
function factorial($i)
|
||||
{
|
||||
if ($i > 1) return $i * factorial($i - 1);
|
||||
else if ($i == 1) return $i;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
$count = 10;
|
||||
$result = factorial($count);
|
||||
echo "\$result = $result\n";
|
||||
|
||||
echo "---------------- end -------------------\n";
|
||||
--EXPECTF--
|
||||
---------------- start -------------------
|
||||
|
||||
Inside Point::__construct, (0,1), point count = 1
|
||||
|
||||
---------------- after $av1 init -------------------
|
||||
---------------- after $sv1 decl -------------------
|
||||
|
||||
Inside Point::__construct, (0,2), point count = 2
|
||||
|
||||
---------------- after $sv1 init -------------------
|
||||
---------------- Inside function_A -------------------
|
||||
|
||||
Inside Point::__construct, (1,1), point count = 3
|
||||
|
||||
---------------- after $av2 init -------------------
|
||||
---------------- after $sv2 decl -------------------
|
||||
|
||||
Inside Point::__construct, (1,2), point count = 4
|
||||
|
||||
---------------- after $sv2 init -------------------
|
||||
---------------- Inside if TRUE -------------------
|
||||
|
||||
Inside Point::__construct, (2,1), point count = 5
|
||||
|
||||
---------------- after $av3 init -------------------
|
||||
---------------- after $sv3 decl -------------------
|
||||
|
||||
Inside Point::__construct, (2,2), point count = 6
|
||||
|
||||
---------------- after $sv3 init -------------------
|
||||
|
||||
Inside Point::__construct, (2,3), point count = 7
|
||||
|
||||
---------------- after $av1 reinit -------------------
|
||||
|
||||
Inside Point::__destruct, (%d,%d), point count = 6
|
||||
|
||||
|
||||
Inside Point::__destruct, (%d,%d), point count = 5
|
||||
|
||||
|
||||
Inside Point::__destruct, (%d,%d), point count = 4
|
||||
|
||||
---------------- after call to func -------------------
|
||||
$result = 3628800
|
||||
---------------- end -------------------
|
||||
|
||||
Inside Point::__destruct, (%d,%d), point count = 3
|
||||
|
||||
|
||||
Inside Point::__destruct, (%d,%d), point count = 2
|
||||
|
||||
|
||||
Inside Point::__destruct, (%d,%d), point count = 1
|
||||
|
||||
|
||||
Inside Point::__destruct, (%d,%d), point count = 0
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'Vehicle.inc';
|
||||
|
||||
abstract class Aircraft extends Vehicle
|
||||
{
|
||||
public abstract function getMaxAltitude();
|
||||
// ...
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
final class MathLibrary
|
||||
{
|
||||
private function __construct() {} // disallows instantiation
|
||||
|
||||
public static function sin() { /* ... */ }
|
||||
public static function cos() { /* ... */ }
|
||||
public static function tan() { /* ... */ }
|
||||
// ...
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
interface MyCollection
|
||||
{
|
||||
function put($item);
|
||||
function get();
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'Aircraft.inc';
|
||||
|
||||
class PassengerJet extends Aircraft
|
||||
{
|
||||
public function getMaxSpeed()
|
||||
{
|
||||
// implement method
|
||||
return 550;
|
||||
}
|
||||
|
||||
public function getMaxAltitude()
|
||||
{
|
||||
// implement method
|
||||
return 30000;
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private $x; // Cartesian x-coordinate
|
||||
private $y; // Cartesian y-coordinate
|
||||
|
||||
public function getX() { return $this->x; }
|
||||
public function setX($x) { $this->x = $x; }
|
||||
public function getY() { return $this->y; }
|
||||
public function setY($y) { $this->y = $y; }
|
||||
|
||||
// public function __construct($x, $y) // see what happens if no default values
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function move($x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function translate($x, $y)
|
||||
{
|
||||
$this->x += $x;
|
||||
$this->y += $y;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// throw new Exception; // throw statement is not permitted
|
||||
|
||||
return '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point2
|
||||
{
|
||||
private static $pointCount = 0;
|
||||
|
||||
public $x; // Cartesian x-coordinate
|
||||
public $y; // Cartesian y-coordinate
|
||||
|
||||
public static function getPointCount()
|
||||
{
|
||||
return self::$pointCount;
|
||||
}
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
++self::$pointCount;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
--self::$pointCount;
|
||||
}
|
||||
///*
|
||||
public function __clone()
|
||||
{
|
||||
++self::$pointCount;
|
||||
|
||||
echo "Inside " . __METHOD__ . ", point count = " . self::$pointCount . "\n";
|
||||
|
||||
// return 999; // ignored; not passed along as the result of 'clone'
|
||||
|
||||
}
|
||||
//*/
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
|
||||
return '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
abstract class Vehicle
|
||||
{
|
||||
public abstract function getMaxSpeed();
|
||||
|
||||
// ...
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/__gets_return_type.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class C {
|
||||
public $a = array();
|
||||
|
||||
|
||||
// Try removing the '&' and see how this example behaves differently
|
||||
// public function __get($k) {
|
||||
public function & __get($k) {
|
||||
echo "__get $k\n";
|
||||
return $this->a;
|
||||
}
|
||||
}
|
||||
|
||||
$c = new C;
|
||||
//var_dump($c);
|
||||
$c->foo[0] = 1;
|
||||
var_dump($c);
|
||||
|
||||
echo "========\n";
|
||||
|
||||
$c = new C;
|
||||
//var_dump($c);
|
||||
$a =& $c->foo;
|
||||
$a[0] = 1;
|
||||
unset($a);
|
||||
var_dump($c);
|
||||
--EXPECT--
|
||||
__get foo
|
||||
object(C)#1 (1) {
|
||||
["a"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
}
|
||||
========
|
||||
__get foo
|
||||
object(C)#2 (1) {
|
||||
["a"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/classes.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
interface i1 {}
|
||||
interface i2 {}
|
||||
class C1 {}
|
||||
class C2 extends c1 implements i1, i2 {}
|
||||
|
||||
$c = new C2;
|
||||
var_dump($c);
|
||||
--EXPECT--
|
||||
object(C2)#1 (0) {
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/cloning.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
echo "================= play around a bit =================\n";
|
||||
|
||||
class C
|
||||
{
|
||||
private $m;
|
||||
public function __construct($p1)
|
||||
{
|
||||
$this->m = $p1;
|
||||
}
|
||||
|
||||
///*
|
||||
public function __clone()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
|
||||
// return NULL; // ignored; not passed along as the result of 'clone'
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
$obj1 = new C(10);
|
||||
var_dump($obj1);
|
||||
|
||||
$obj2 = clone $obj1; // default action is to make a shallow copy
|
||||
var_dump($obj2);
|
||||
|
||||
//$obj3 = $obj1->__clone(); // can't call directly!! Why is that?
|
||||
//var_dump($obj3);
|
||||
|
||||
echo "================= Use cloning in Point class =================\n";
|
||||
|
||||
include_once 'Point2.inc';
|
||||
|
||||
echo "Point count = " . Point2::getPointCount() . "\n";
|
||||
$p1 = new Point2;
|
||||
var_dump($p1);
|
||||
echo "Point count = " . Point2::getPointCount() . "\n";
|
||||
$p2 = clone $p1;
|
||||
var_dump($p2);
|
||||
echo "Point count = " . Point2::getPointCount() . "\n";
|
||||
|
||||
var_dump($p3 = clone $p1);
|
||||
echo "Point count = " . Point2::getPointCount() . "\n";
|
||||
|
||||
var_dump($p4 = clone $p1);
|
||||
echo "Point count = " . Point2::getPointCount() . "\n";
|
||||
|
||||
echo "================= use chained cloning in a class heirarchy =================\n";
|
||||
|
||||
class Employee
|
||||
{
|
||||
private $name;
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
// $v = parent::__clone(); // as class has no parent, this is diagnosed
|
||||
|
||||
// make a copy of Employee object
|
||||
|
||||
return 999; // ignored; not passed along as the result of 'clone'
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Manager extends Employee
|
||||
{
|
||||
private $level;
|
||||
|
||||
public function __construct($name, $level)
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
|
||||
$v = parent::__clone();
|
||||
echo "\n====>>>>"; var_dump($v);
|
||||
|
||||
// make a copy of Manager object
|
||||
|
||||
// return 999; // ignored; not passed along as the result of 'clone'
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$obj3 = new Manager("Smith", 23);
|
||||
var_dump($obj3);
|
||||
|
||||
$obj4 = clone $obj3;
|
||||
var_dump($obj4);
|
||||
--EXPECTF--
|
||||
================= play around a bit =================
|
||||
object(C)#1 (1) {
|
||||
["m":"C":private]=>
|
||||
int(10)
|
||||
}
|
||||
Inside C::__clone
|
||||
object(C)#2 (1) {
|
||||
["m":"C":private]=>
|
||||
int(10)
|
||||
}
|
||||
================= Use cloning in Point class =================
|
||||
Point count = 0
|
||||
object(Point2)#3 (2) {
|
||||
["x"]=>
|
||||
int(0)
|
||||
["y"]=>
|
||||
int(0)
|
||||
}
|
||||
Point count = 1
|
||||
Inside Point2::__clone, point count = 2
|
||||
object(Point2)#4 (2) {
|
||||
["x"]=>
|
||||
int(0)
|
||||
["y"]=>
|
||||
int(0)
|
||||
}
|
||||
Point count = 2
|
||||
Inside Point2::__clone, point count = 3
|
||||
object(Point2)#5 (2) {
|
||||
["x"]=>
|
||||
int(0)
|
||||
["y"]=>
|
||||
int(0)
|
||||
}
|
||||
Point count = 3
|
||||
Inside Point2::__clone, point count = 4
|
||||
object(Point2)#6 (2) {
|
||||
["x"]=>
|
||||
int(0)
|
||||
["y"]=>
|
||||
int(0)
|
||||
}
|
||||
Point count = 4
|
||||
================= use chained cloning in a class heirarchy =================
|
||||
object(Manager)#7 (2) {
|
||||
["level":"Manager":private]=>
|
||||
int(23)
|
||||
["name":"Employee":private]=>
|
||||
string(5) "Smith"
|
||||
}
|
||||
Inside Manager::__clone
|
||||
Inside Employee::__clone
|
||||
|
||||
====>>>>int(999)
|
||||
object(Manager)#8 (2) {
|
||||
["level":"Manager":private]=>
|
||||
int(23)
|
||||
["name":"Employee":private]=>
|
||||
string(5) "Smith"
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/constructors.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class D1
|
||||
{
|
||||
// private function __construct($p1)
|
||||
// public function __construct($p1)
|
||||
protected function & __construct($p1)
|
||||
{
|
||||
echo "In D1 constructor, $p1\n";
|
||||
|
||||
// return;
|
||||
$v = 123;
|
||||
return $v; // Surprise; this is allowed and it works!!
|
||||
}
|
||||
}
|
||||
|
||||
class D2 extends D1
|
||||
{
|
||||
///*
|
||||
// protected function __construct($p1, $p2) // Access level to D2::__construct() must be public
|
||||
public function __construct($p1, $p2)
|
||||
{
|
||||
$v = parent::__construct($p1);
|
||||
var_dump($v); // I see the 123 returned!!
|
||||
echo "In D2 constructor, $p1, $p2\n";
|
||||
|
||||
// return;
|
||||
// return 123; // PHP5 does not diagnose this
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
class D3 extends D2
|
||||
{
|
||||
///*
|
||||
public function __construct($p1, $p2, $p3)
|
||||
{
|
||||
parent::__construct($p1, $p2);
|
||||
echo "In D3 constructor, $p1, $p2, $p3\n";
|
||||
// parent::__construct($p1, $p2); // not first statement in body, but OK
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
class D4 extends D3
|
||||
{
|
||||
///*
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(1,2,3);
|
||||
echo "In D4 constructor\n";
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
//$d1 = new D1(10);
|
||||
//$d2 = new D2(10, 20);
|
||||
//$d3 = new D3(10, 20, 30);
|
||||
$d4 = new D4;
|
||||
--EXPECT--
|
||||
In D1 constructor, 1
|
||||
int(123)
|
||||
In D2 constructor, 1, 2
|
||||
In D3 constructor, 1, 2, 3
|
||||
In D4 constructor
|
|
@ -0,0 +1,77 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/destructors.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class D1
|
||||
{
|
||||
// private function __destruct()
|
||||
public function & __destruct() // return by reference
|
||||
// protected function __destruct()
|
||||
{
|
||||
echo "In D1 destructor\n";
|
||||
|
||||
// return;
|
||||
$v = 123;
|
||||
return $v; // PHP5 does not diagnose this, and it works!!
|
||||
}
|
||||
}
|
||||
|
||||
class D2 extends D1
|
||||
{
|
||||
///*
|
||||
// protected function __destruct() // Access level to D2::__destruct() must be public
|
||||
public function __destruct()
|
||||
{
|
||||
echo "In D2 destructor\n";
|
||||
// exit();
|
||||
$v = parent::__destruct();
|
||||
var_dump($v); // I see the 123 returned!!
|
||||
|
||||
// return;
|
||||
// return 123; // PHP5 does not diagnose this
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
class D3 extends D2
|
||||
{
|
||||
///*
|
||||
public function __destruct()
|
||||
{
|
||||
// parent::__destruct();
|
||||
echo "In D3 destructor\n";
|
||||
parent::__destruct();
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
class D4 extends D3
|
||||
{
|
||||
///*
|
||||
public function __destruct()
|
||||
{
|
||||
echo "In D4 destructor\n";
|
||||
parent::__destruct();
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
//$d1 = new D1;
|
||||
//$d2 = new D2;
|
||||
//$d3 = new D3;
|
||||
$d4 = new D4;
|
||||
--EXPECTF--
|
||||
%AIn D4 destructor
|
||||
In D3 destructor
|
||||
In D2 destructor
|
||||
In D1 destructor
|
||||
int(123)
|
|
@ -0,0 +1,113 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/dynamic_methods.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Widget
|
||||
{
|
||||
public function iDoit()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
return 99;
|
||||
}
|
||||
|
||||
public static function sDoit()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
return 88;
|
||||
}
|
||||
///*
|
||||
public function __call($name, $arguments)
|
||||
// public function __call(&$name, &$arguments)
|
||||
{
|
||||
echo "Calling instance method >$name<\n";
|
||||
var_dump($arguments);
|
||||
|
||||
return 987;
|
||||
}
|
||||
//*/
|
||||
///*
|
||||
public static function __callStatic($name, $arguments)
|
||||
// public static function __callStatic(&$name, &$arguments)
|
||||
{
|
||||
echo "Calling static method >$name<\n";
|
||||
var_dump($arguments);
|
||||
|
||||
return "hello";
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
$obj = new Widget;
|
||||
$v = $obj->iDoit();
|
||||
$obj->__call('iDoit', []);
|
||||
|
||||
$v = $obj->iMethod(10, TRUE, "abc");
|
||||
var_dump($v);
|
||||
$obj->__call('iMethod', array(10, TRUE, "abc"));
|
||||
$obj->__call('123#$%', []);
|
||||
|
||||
$v = Widget::sDoit();
|
||||
Widget::__callStatic('sDoit', []);
|
||||
|
||||
$v = Widget::sMethod(NULL, 1.234);
|
||||
var_dump($v);
|
||||
Widget::__callStatic('sMethod', array(NULL, 1.234));
|
||||
Widget::__callStatic('[]{}', []);
|
||||
--EXPECTF--
|
||||
Inside Widget::iDoit
|
||||
Calling instance method >iDoit<
|
||||
array(0) {
|
||||
}
|
||||
Calling instance method >iMethod<
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
bool(true)
|
||||
[2]=>
|
||||
string(3) "abc"
|
||||
}
|
||||
int(987)
|
||||
Calling instance method >iMethod<
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
bool(true)
|
||||
[2]=>
|
||||
string(3) "abc"
|
||||
}
|
||||
Calling instance method >123#$%<
|
||||
array(0) {
|
||||
}
|
||||
Inside Widget::sDoit
|
||||
Calling static method >sDoit<
|
||||
array(0) {
|
||||
}
|
||||
Calling static method >sMethod<
|
||||
array(2) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
float(1.234)
|
||||
}
|
||||
string(5) "hello"
|
||||
Calling static method >sMethod<
|
||||
array(2) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
float(1.234)
|
||||
}
|
||||
Calling static method >[]{}<
|
||||
array(0) {
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/dynamic_properties.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private $x;
|
||||
private $y;
|
||||
private $dynamicProperties = array();
|
||||
|
||||
public $dummy = -100; // for test purposes only
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
// echo __METHOD__ . "($name, $value)\n";
|
||||
echo __METHOD__ . "($name, xx)\n"; // used if $value can't be converted to string
|
||||
|
||||
$this->dynamicProperties[$name] = $value;
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
if (array_key_exists($name, $this->dynamicProperties))
|
||||
{
|
||||
return $this->dynamicProperties[$name];
|
||||
}
|
||||
|
||||
// no-such-property error handling goes here
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
return isset($this->dynamicProperties[$name]);
|
||||
}
|
||||
|
||||
public function __unset($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
unset($this->dynamicProperties[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$p = new Point(5, 9);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->dummy; // get visible property
|
||||
var_dump($v);
|
||||
$v = $p->DUMmy; // this is not the same as "dummy"
|
||||
var_dump($v);
|
||||
echo "dummy: $v\n";
|
||||
$v = $p->__get('dummy'); // get dynamic property, if one exists; else, fails
|
||||
echo "dynamic dummy: $v\n";
|
||||
|
||||
$p->dummy = 987; // set visible property
|
||||
$p->__set('dummy', 456); // set dynamic property
|
||||
//$p->__set('DUMmy', 456); // case is sensitive
|
||||
|
||||
$v = $p->dummy; // get visible property
|
||||
echo "dummy: $v\n";
|
||||
$v = $p->__get('dummy'); // get dynamic property
|
||||
echo "dynamic dummy: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->dummy)); // test if dummy exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('dummy')); // test if dynamic dummy exists
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->x; // try to get at an invisible property; can't. The runtime sees that x
|
||||
// exists, but is invisible, so it calls __get to search for a dynamic
|
||||
// property of that name, which fails. NULL is returned.
|
||||
var_dump($v);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->x)); // test if x exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('x')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
$p->x = 200;
|
||||
var_dump($p->x);
|
||||
|
||||
var_dump(isset($p->x)); // test if x exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('x')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$p->color = "red"; // set dynamic property
|
||||
$v = $p->color; // get dynamic property
|
||||
echo "color: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->color)); // test if color exists and is accessible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->dummy = 555;
|
||||
echo "\$v: $v, dummy: " . $p->dummy . "\n";
|
||||
|
||||
$v = $p->color = "White"; // this calls __set but not __get
|
||||
echo "\$v: $v, color: " . $p->color . "\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->dummy));
|
||||
var_dump($p->__isset('dummy')); // test if x exists and is accessible, or is dynamic
|
||||
$p->__unset('dummy');
|
||||
var_dump(isset($p->dummy));
|
||||
var_dump($p->__isset('dummy')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
unset($p->abc); // request to unset a non-existent is ignored
|
||||
unset($p->x); // request to unset an inaccessible is ignored
|
||||
var_dump(isset($p->dummy));
|
||||
unset($p->dummy); // request to unset a declared accessible is OK
|
||||
var_dump(isset($p->dummy));
|
||||
|
||||
var_dump(isset($p->color));
|
||||
unset($p->color); //
|
||||
var_dump(isset($p->color));
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
class X
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
///*
|
||||
$p->thing = new X; // set dynamic property to an instance having a destructor
|
||||
$v = $p->thing;
|
||||
var_dump($v);
|
||||
|
||||
//unset($p->thing); // was sort-of expecting this to trigger the destructor, but ...
|
||||
//$p->__unset('thing');
|
||||
//echo "unset(\$p->thing) called\n";
|
||||
//*/
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
// show that attempts to use a non-existent property cause one to be created
|
||||
// even in the absence of the __set/__get machinery.
|
||||
|
||||
class Test {}
|
||||
|
||||
$x1 = new Test;
|
||||
$x1->p1 = 23;
|
||||
$x1->p2 = "Hello";
|
||||
var_dump($x1);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
foreach ($x1 as $key => $value)
|
||||
{
|
||||
echo "key $key has a value of $value\n";
|
||||
}
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$x2 = new Test;
|
||||
$x2->p3 = FALSE;
|
||||
var_dump($x2);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
foreach ($x2 as $key => $value)
|
||||
{
|
||||
echo "key $key has a value of $value\n";
|
||||
}
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$x3 = new Test;
|
||||
for ($i = 4; $i <= 10; ++$i)
|
||||
{
|
||||
$q = "p$i";
|
||||
$x3->$q = 999;
|
||||
}
|
||||
var_dump($x3);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
foreach ($x3 as $key => $value)
|
||||
{
|
||||
echo "key $key has a value of $value\n";
|
||||
}
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
// However, this doesn't work for non-existent methods
|
||||
|
||||
// $x1->m1(); // Call to undefined method Test::m1()
|
||||
|
||||
|
||||
// at program termination, the destructor for the dynamic property is called
|
||||
--EXPECT--
|
||||
----------------------
|
||||
int(-100)
|
||||
Point::__get(DUMmy)
|
||||
NULL
|
||||
dummy:
|
||||
Point::__get(dummy)
|
||||
dynamic dummy:
|
||||
Point::__set(dummy, xx)
|
||||
dummy: 987
|
||||
Point::__get(dummy)
|
||||
dynamic dummy: 456
|
||||
----------------------
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(true)
|
||||
----------------------
|
||||
Point::__get(x)
|
||||
NULL
|
||||
----------------------
|
||||
Point::__isset(x)
|
||||
bool(false)
|
||||
Point::__isset(x)
|
||||
bool(false)
|
||||
Point::__set(x, xx)
|
||||
Point::__get(x)
|
||||
int(200)
|
||||
Point::__isset(x)
|
||||
bool(true)
|
||||
Point::__isset(x)
|
||||
bool(true)
|
||||
----------------------
|
||||
Point::__set(color, xx)
|
||||
Point::__get(color)
|
||||
color: red
|
||||
----------------------
|
||||
Point::__isset(color)
|
||||
bool(true)
|
||||
----------------------
|
||||
$v: 555, dummy: 555
|
||||
Point::__set(color, xx)
|
||||
Point::__get(color)
|
||||
$v: White, color: White
|
||||
----------------------
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(true)
|
||||
Point::__unset(dummy)
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(false)
|
||||
Point::__unset(abc)
|
||||
Point::__unset(x)
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(false)
|
||||
Point::__isset(color)
|
||||
bool(true)
|
||||
Point::__unset(color)
|
||||
Point::__isset(color)
|
||||
bool(false)
|
||||
----------------------
|
||||
Point::__set(thing, xx)
|
||||
Point::__get(thing)
|
||||
object(X)#2 (0) {
|
||||
}
|
||||
----------------------
|
||||
object(Test)#3 (2) {
|
||||
["p1"]=>
|
||||
int(23)
|
||||
["p2"]=>
|
||||
string(5) "Hello"
|
||||
}
|
||||
----------------------
|
||||
key p1 has a value of 23
|
||||
key p2 has a value of Hello
|
||||
----------------------
|
||||
object(Test)#4 (1) {
|
||||
["p3"]=>
|
||||
bool(false)
|
||||
}
|
||||
----------------------
|
||||
key p3 has a value of
|
||||
----------------------
|
||||
object(Test)#5 (7) {
|
||||
["p4"]=>
|
||||
int(999)
|
||||
["p5"]=>
|
||||
int(999)
|
||||
["p6"]=>
|
||||
int(999)
|
||||
["p7"]=>
|
||||
int(999)
|
||||
["p8"]=>
|
||||
int(999)
|
||||
["p9"]=>
|
||||
int(999)
|
||||
["p10"]=>
|
||||
int(999)
|
||||
}
|
||||
----------------------
|
||||
key p4 has a value of 999
|
||||
key p5 has a value of 999
|
||||
key p6 has a value of 999
|
||||
key p7 has a value of 999
|
||||
key p8 has a value of 999
|
||||
key p9 has a value of 999
|
||||
key p10 has a value of 999
|
||||
----------------------
|
||||
X::__destruct
|
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/dynamic_properties2.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// stripped-down version of overloading.php for inclusion in the spec
|
||||
|
||||
class Point { /*…*/ } // has no public property "color"
|
||||
$p = new Point(10, 15);
|
||||
|
||||
var_dump(isset($p->color));
|
||||
$v = $p->color; // get the dynamic property "color"
|
||||
var_dump($v);
|
||||
|
||||
$p->color = "red"; // create/set the dynamic property "color"
|
||||
$v = $p->color; // get the dynamic property "color"
|
||||
isset($p->color); // test if (dynamic or not) "color" property exists
|
||||
unset($p->color); // remove the property "color"
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
|
||||
Notice: Undefined property: Point::$color in %s/classes/dynamic_properties2.php on line 9
|
||||
NULL
|
|
@ -0,0 +1,52 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/dynamic_properties3.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class C
|
||||
{
|
||||
public function __get($name) {
|
||||
echo "get\n";
|
||||
return $this->$name; // must not recurse
|
||||
}
|
||||
|
||||
public function __set($name, $val) {
|
||||
echo "set\n";
|
||||
$this->$name = $val; // must not recurse
|
||||
}
|
||||
|
||||
public function __isset($name) {
|
||||
echo "isset\n";
|
||||
return isset($this->$name); // must not recurse
|
||||
}
|
||||
|
||||
public function __unset($name) {
|
||||
echo "unset\n";
|
||||
unset($this->$name); // must not recurse
|
||||
}
|
||||
}
|
||||
|
||||
$c = new C;
|
||||
$x = $c->prop; // Undefined property: C::$prop
|
||||
$c->prop = 123; // Defined now
|
||||
$x = $c->prop;
|
||||
var_dump($x);
|
||||
var_dump($c);
|
||||
--EXPECTF--
|
||||
get
|
||||
|
||||
Notice: Undefined property: C::$prop in %s/classes/dynamic_properties3.php on line 15
|
||||
set
|
||||
int(123)
|
||||
object(C)#1 (1) {
|
||||
["prop"]=>
|
||||
int(123)
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/invoke.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class C
|
||||
{
|
||||
///*
|
||||
public function __invoke($p)
|
||||
{
|
||||
echo "Inside " . __METHOD__ . " with arg $p\n";
|
||||
|
||||
return "xxx";
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
$c = new C;
|
||||
var_dump(is_callable($c)); // returns TRUE is __invoke exists; otherwise, FALSE
|
||||
$r = $c(123);
|
||||
var_dump($r);
|
||||
$r = $c("Hello");
|
||||
var_dump($r);
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
Inside C::__invoke with arg 123
|
||||
string(3) "xxx"
|
||||
Inside C::__invoke with arg Hello
|
||||
string(3) "xxx"
|
|
@ -0,0 +1,32 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/invoking.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class C
|
||||
{
|
||||
///*
|
||||
public function __invoke($p)
|
||||
{
|
||||
echo "Inside " . __METHOD__ . " with arg $p\n";
|
||||
|
||||
return "xxx";
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
$c = new C;
|
||||
var_dump(is_callable($c)); // returns TRUE is __invoke exists; otherwise, FALSE
|
||||
$r = $c(123);
|
||||
var_dump($r);
|
||||
$r = $c("Hello");
|
||||
var_dump($r);
|
||||
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
Inside C::__invoke with arg 123
|
||||
string(3) "xxx"
|
||||
Inside C::__invoke with arg Hello
|
||||
string(3) "xxx"
|
|
@ -0,0 +1,21 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/mathlibrary_test1.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'MathLibrary.inc';
|
||||
|
||||
// $m = new MathLibrary; // can't instantiate a final class
|
||||
|
||||
MathLibrary::sin(2.34);
|
||||
MathLibrary::cos(2.34);
|
||||
MathLibrary::tan(2.34);
|
||||
--EXPECTF--
|
|
@ -0,0 +1,30 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/mylist.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'MyCollection.inc';
|
||||
|
||||
class MyList implements MyCollection
|
||||
{
|
||||
public function put($item)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
--EXPECT--
|
|
@ -0,0 +1,218 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/overloading.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private $x;
|
||||
private $y;
|
||||
private $dynamicProperties = array();
|
||||
|
||||
public $dummy = -100; // for test purposes only
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
// echo __METHOD__ . "($name, $value)\n";
|
||||
echo __METHOD__ . "($name, xx)\n"; // used if $value can't be converted to string
|
||||
|
||||
$this->dynamicProperties[$name] = $value;
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
if (array_key_exists($name, $this->dynamicProperties))
|
||||
{
|
||||
return $this->dynamicProperties[$name];
|
||||
}
|
||||
|
||||
// no-such-property error handling goes here
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
return isset($this->dynamicProperties[$name]);
|
||||
}
|
||||
|
||||
public function __unset($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
unset($this->dynamicProperties[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$p = new Point(5, 9);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->dummy; // get visible property
|
||||
echo "dummy: $v\n";
|
||||
$v = $p->__get('dummy'); // get dynamic property, if one exists; else, fails
|
||||
echo "dynamic dummy: $v\n";
|
||||
|
||||
$p->dummy = 987; // set visible property
|
||||
$p->__set('dummy', 456); // set dynamic property
|
||||
|
||||
$v = $p->dummy; // get visible property
|
||||
echo "dummy: $v\n";
|
||||
$v = $p->__get('dummy'); // get dynamic property
|
||||
echo "dynamic dummy: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->dummy)); // test if dummy exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('dummy')); // test if dynamic dummy exists
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->x; // try to get at an invisible property; can't. The runtime sees that x
|
||||
// exists, but is invisible, so it calls __get to search for a dynamic
|
||||
// property of that name, which fails. NULL is returned.
|
||||
var_dump($v);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->x)); // test if x exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('x')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
$p->x = 200;
|
||||
var_dump($p->x);
|
||||
|
||||
var_dump(isset($p->x)); // test if x exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('x')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$p->color = "red"; // set dynamic property
|
||||
$v = $p->color; // get dynamic property
|
||||
echo "color: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->color)); // test if color exists and is accessible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->dummy = 555;
|
||||
echo "\$v: $v, dummy: " . $p->dummy . "\n";
|
||||
|
||||
$v = $p->color = "White"; // this calls __set but not __get
|
||||
echo "\$v: $v, color: " . $p->color . "\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->dummy));
|
||||
var_dump($p->__isset('dummy')); // test if x exists and is accessible, or is dynamic
|
||||
$p->__unset('dummy');
|
||||
var_dump(isset($p->dummy));
|
||||
var_dump($p->__isset('dummy')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
unset($p->abc); // request to unset a non-existent is ignored
|
||||
unset($p->x); // request to unset an inaccessible is ignored
|
||||
var_dump(isset($p->dummy));
|
||||
unset($p->dummy); // request to unset a declared accessible is OK
|
||||
var_dump(isset($p->dummy));
|
||||
|
||||
var_dump(isset($p->color));
|
||||
unset($p->color); //
|
||||
var_dump(isset($p->color));
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
class X
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
///*
|
||||
$p->thing = new X; // set dynamic property to an instance having a destructor
|
||||
$v = $p->thing;
|
||||
var_dump($v);
|
||||
|
||||
//unset($p->thing); // was sort-of expecting this to trigger the destructor, but ...
|
||||
//$p->__unset('thing');
|
||||
//echo "unset(\$p->thing) called\n";
|
||||
//*/
|
||||
|
||||
// at program termination, the destructor for the dynamic property is called
|
||||
--EXPECT--
|
||||
----------------------
|
||||
dummy: -100
|
||||
Point::__get(dummy)
|
||||
dynamic dummy:
|
||||
Point::__set(dummy, xx)
|
||||
dummy: 987
|
||||
Point::__get(dummy)
|
||||
dynamic dummy: 456
|
||||
----------------------
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(true)
|
||||
----------------------
|
||||
Point::__get(x)
|
||||
NULL
|
||||
----------------------
|
||||
Point::__isset(x)
|
||||
bool(false)
|
||||
Point::__isset(x)
|
||||
bool(false)
|
||||
Point::__set(x, xx)
|
||||
Point::__get(x)
|
||||
int(200)
|
||||
Point::__isset(x)
|
||||
bool(true)
|
||||
Point::__isset(x)
|
||||
bool(true)
|
||||
----------------------
|
||||
Point::__set(color, xx)
|
||||
Point::__get(color)
|
||||
color: red
|
||||
----------------------
|
||||
Point::__isset(color)
|
||||
bool(true)
|
||||
----------------------
|
||||
$v: 555, dummy: 555
|
||||
Point::__set(color, xx)
|
||||
Point::__get(color)
|
||||
$v: White, color: White
|
||||
----------------------
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(true)
|
||||
Point::__unset(dummy)
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(false)
|
||||
Point::__unset(abc)
|
||||
Point::__unset(x)
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(false)
|
||||
Point::__isset(color)
|
||||
bool(true)
|
||||
Point::__unset(color)
|
||||
Point::__isset(color)
|
||||
bool(false)
|
||||
----------------------
|
||||
Point::__set(thing, xx)
|
||||
Point::__get(thing)
|
||||
object(X)#2 (0) {
|
||||
}
|
||||
X::__destruct
|
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/overloading_2.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// stripped-down version of overloading.php for inclusion in the spec
|
||||
|
||||
class Point { /*…*/ } // has no public property "color"
|
||||
$p = new Point(10, 15);
|
||||
|
||||
var_dump(isset($p->color));
|
||||
$v = $p->color; // get the dynamic property "color"
|
||||
var_dump($v);
|
||||
|
||||
$p->color = "red"; // create/set the dynamic property "color"
|
||||
$v = $p->color; // get the dynamic property "color"
|
||||
isset($p->color); // test if (dynamic or not) "color" property exists
|
||||
unset($p->color); // remove the property "color"
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
|
||||
Notice: Undefined property: Point::$color in %s/classes/overloading_2.php on line 9
|
||||
NULL
|
|
@ -0,0 +1,108 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/overloading_methods.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Widget
|
||||
{
|
||||
public function iDoit()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
return 99;
|
||||
}
|
||||
|
||||
public static function sDoit()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
return 88;
|
||||
}
|
||||
//*
|
||||
public function __call($name, $arguments)
|
||||
// public function __call(&$name, &$arguments)
|
||||
{
|
||||
echo "Calling instance method >$name<\n";
|
||||
var_dump($arguments);
|
||||
|
||||
return 987;
|
||||
}
|
||||
//*/
|
||||
///*
|
||||
public static function __callStatic($name, $arguments)
|
||||
// public static function __callStatic(&$name, &$arguments)
|
||||
{
|
||||
echo "Calling static method >$name<\n";
|
||||
var_dump($arguments);
|
||||
|
||||
return "hello";
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
$obj = new Widget;
|
||||
$v = $obj->iDoit();
|
||||
$obj->__call('iDoit', []);
|
||||
|
||||
$v = $obj->iMethod(10, TRUE, "abc");
|
||||
var_dump($v);
|
||||
$obj->__call('iMethod', array(10, TRUE, "abc"));
|
||||
$obj->__call('123#$%', []);
|
||||
|
||||
$v = Widget::sDoit();
|
||||
Widget::__callStatic('sDoit', []);
|
||||
|
||||
$v = Widget::sMethod(NULL, 1.234);
|
||||
var_dump($v);
|
||||
Widget::__callStatic('sMethod', array(NULL, 1.234));
|
||||
Widget::__callStatic('[]{}', []);
|
||||
|
||||
--EXPECTF--
|
||||
Inside Widget::iDoit
|
||||
Calling instance method >iDoit<
|
||||
array(0) {
|
||||
}
|
||||
Calling instance method >iMethod<
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
bool(true)
|
||||
[2]=>
|
||||
string(3) "abc"
|
||||
}
|
||||
int(987)
|
||||
Calling instance method >iMethod<
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
bool(true)
|
||||
[2]=>
|
||||
string(3) "abc"
|
||||
}
|
||||
Calling instance method >123#$%<
|
||||
array(0) {
|
||||
}
|
||||
Inside Widget::sDoit
|
||||
Calling static method >sDoit<
|
||||
array(0) {
|
||||
}
|
||||
Calling static method >sMethod<
|
||||
array(2) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
float(1.234)
|
||||
}
|
||||
string(5) "hello"
|
||||
Calling static method >sMethod<
|
||||
array(2) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
float(1.234)
|
||||
}
|
||||
Calling static method >[]{}<
|
||||
array(0) {
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/overloading_play.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class PropertyTest
|
||||
{
|
||||
/** Location for overloaded data. */
|
||||
private $data = array();
|
||||
|
||||
/** Overloading not used on declared properties. */
|
||||
public $declared = 1;
|
||||
|
||||
/** Overloading only used on this when accessed outside the class. */
|
||||
private $hidden = 2;
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
echo "Setting '$name' to '$value'\n";
|
||||
$this->data[$name] = $value;
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
echo "Getting '$name'\n";
|
||||
if (array_key_exists($name, $this->data)) {
|
||||
return $this->data[$name];
|
||||
}
|
||||
|
||||
$trace = debug_backtrace();
|
||||
trigger_error(
|
||||
'Undefined property via __get(): ' . $name .
|
||||
' in ' . $trace[0]['file'] .
|
||||
' on line ' . $trace[0]['line'],
|
||||
E_USER_NOTICE);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** As of PHP 5.1.0 */
|
||||
public function __isset($name)
|
||||
{
|
||||
echo "Is '$name' set?\n";
|
||||
return isset($this->data[$name]);
|
||||
}
|
||||
|
||||
/** As of PHP 5.1.0 */
|
||||
public function __unset($name)
|
||||
{
|
||||
echo "Unsetting '$name'\n";
|
||||
unset($this->data[$name]);
|
||||
}
|
||||
|
||||
/** Not a magic method, just here for example. */
|
||||
public function getHidden()
|
||||
{
|
||||
return $this->hidden;
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new PropertyTest;
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $obj->declared; // get visible property
|
||||
echo "declared: $v\n";
|
||||
$obj->declared = 987; // set visible property
|
||||
$v = $obj->declared; // get visible property
|
||||
echo "declared: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $obj->hidden; // try to get invisible property; can't
|
||||
// Runtime sees that hidden exists, but is invisible,
|
||||
// so calls __get to search for dynamic property, which fails.
|
||||
var_dump($v);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($obj->hidden)); // test if hidden exists and is accesible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$obj->hidden = "Hello"; // set dynamic invisible property
|
||||
$v = $obj->hidden; // get dynamic invisible property
|
||||
echo "hidden: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($obj->hidden)); // test if hidden exists and is accesible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
unset($obj->hidden);
|
||||
var_dump(isset($obj->hidden));
|
||||
--EXPECTF--
|
||||
----------------------
|
||||
declared: 1
|
||||
declared: 987
|
||||
----------------------
|
||||
Getting 'hidden'
|
||||
|
||||
Notice: Undefined property via __get(): hidden in %s/classes/overloading_play.php on line 71 in %s/classes/overloading_play.php on line 34
|
||||
NULL
|
||||
----------------------
|
||||
Is 'hidden' set?
|
||||
bool(false)
|
||||
----------------------
|
||||
Setting 'hidden' to 'Hello'
|
||||
Getting 'hidden'
|
||||
hidden: Hello
|
||||
----------------------
|
||||
Is 'hidden' set?
|
||||
bool(true)
|
||||
----------------------
|
||||
Unsetting 'hidden'
|
||||
Is 'hidden' set?
|
||||
bool(false)
|
|
@ -0,0 +1,225 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/overloading_properties.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private $x;
|
||||
private $y;
|
||||
private $dynamicProperties = array();
|
||||
|
||||
public $dummy = -100; // for test purposes only
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
// echo __METHOD__ . "($name, $value)\n";
|
||||
echo __METHOD__ . "($name, xx)\n"; // used if $value can't be converted to string
|
||||
|
||||
$this->dynamicProperties[$name] = $value;
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
if (array_key_exists($name, $this->dynamicProperties))
|
||||
{
|
||||
return $this->dynamicProperties[$name];
|
||||
}
|
||||
|
||||
// no-such-property error handling goes here
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
return isset($this->dynamicProperties[$name]);
|
||||
}
|
||||
|
||||
public function __unset($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
|
||||
unset($this->dynamicProperties[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$p = new Point(5, 9);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->dummy; // get visible property
|
||||
var_dump($v);
|
||||
$v = $p->DUMmy; // this is not the same as "dummy"
|
||||
var_dump($v);
|
||||
echo "dummy: $v\n";
|
||||
$v = $p->__get('dummy'); // get dynamic property, if one exists; else, fails
|
||||
echo "dynamic dummy: $v\n";
|
||||
|
||||
$p->dummy = 987; // set visible property
|
||||
$p->__set('dummy', 456); // set dynamic property
|
||||
//$p->__set('DUMmy', 456); // case is sensitive
|
||||
|
||||
$v = $p->dummy; // get visible property
|
||||
echo "dummy: $v\n";
|
||||
$v = $p->__get('dummy'); // get dynamic property
|
||||
echo "dynamic dummy: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->dummy)); // test if dummy exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('dummy')); // test if dynamic dummy exists
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->x; // try to get at an invisible property; can't. The runtime sees that x
|
||||
// exists, but is invisible, so it calls __get to search for a dynamic
|
||||
// property of that name, which fails. NULL is returned.
|
||||
var_dump($v);
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->x)); // test if x exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('x')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
$p->x = 200;
|
||||
var_dump($p->x);
|
||||
|
||||
var_dump(isset($p->x)); // test if x exists and is accessible, or is dynamic
|
||||
var_dump($p->__isset('x')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$p->color = "red"; // set dynamic property
|
||||
$v = $p->color; // get dynamic property
|
||||
echo "color: $v\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->color)); // test if color exists and is accessible, or is dynamic
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
$v = $p->dummy = 555;
|
||||
echo "\$v: $v, dummy: " . $p->dummy . "\n";
|
||||
|
||||
$v = $p->color = "White"; // this calls __set but not __get
|
||||
echo "\$v: $v, color: " . $p->color . "\n";
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
var_dump(isset($p->dummy));
|
||||
var_dump($p->__isset('dummy')); // test if x exists and is accessible, or is dynamic
|
||||
$p->__unset('dummy');
|
||||
var_dump(isset($p->dummy));
|
||||
var_dump($p->__isset('dummy')); // test if x exists and is accessible, or is dynamic
|
||||
|
||||
unset($p->abc); // request to unset a non-existent is ignored
|
||||
unset($p->x); // request to unset an inaccessible is ignored
|
||||
var_dump(isset($p->dummy));
|
||||
unset($p->dummy); // request to unset a declared accessible is OK
|
||||
var_dump(isset($p->dummy));
|
||||
|
||||
var_dump(isset($p->color));
|
||||
unset($p->color); //
|
||||
var_dump(isset($p->color));
|
||||
|
||||
echo "----------------------\n";
|
||||
|
||||
class X
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
///*
|
||||
$p->thing = new X; // set dynamic property to an instance having a destructor
|
||||
$v = $p->thing;
|
||||
var_dump($v);
|
||||
|
||||
//unset($p->thing); // was sort-of expecting this to trigger the destructor, but ...
|
||||
//$p->__unset('thing');
|
||||
//echo "unset(\$p->thing) called\n";
|
||||
//*/
|
||||
|
||||
// at program termination, the destructor for the dynamic property is called
|
||||
--EXPECT--
|
||||
----------------------
|
||||
int(-100)
|
||||
Point::__get(DUMmy)
|
||||
NULL
|
||||
dummy:
|
||||
Point::__get(dummy)
|
||||
dynamic dummy:
|
||||
Point::__set(dummy, xx)
|
||||
dummy: 987
|
||||
Point::__get(dummy)
|
||||
dynamic dummy: 456
|
||||
----------------------
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(true)
|
||||
----------------------
|
||||
Point::__get(x)
|
||||
NULL
|
||||
----------------------
|
||||
Point::__isset(x)
|
||||
bool(false)
|
||||
Point::__isset(x)
|
||||
bool(false)
|
||||
Point::__set(x, xx)
|
||||
Point::__get(x)
|
||||
int(200)
|
||||
Point::__isset(x)
|
||||
bool(true)
|
||||
Point::__isset(x)
|
||||
bool(true)
|
||||
----------------------
|
||||
Point::__set(color, xx)
|
||||
Point::__get(color)
|
||||
color: red
|
||||
----------------------
|
||||
Point::__isset(color)
|
||||
bool(true)
|
||||
----------------------
|
||||
$v: 555, dummy: 555
|
||||
Point::__set(color, xx)
|
||||
Point::__get(color)
|
||||
$v: White, color: White
|
||||
----------------------
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(true)
|
||||
Point::__unset(dummy)
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(false)
|
||||
Point::__unset(abc)
|
||||
Point::__unset(x)
|
||||
bool(true)
|
||||
Point::__isset(dummy)
|
||||
bool(false)
|
||||
Point::__isset(color)
|
||||
bool(true)
|
||||
Point::__unset(color)
|
||||
Point::__isset(color)
|
||||
bool(false)
|
||||
----------------------
|
||||
Point::__set(thing, xx)
|
||||
Point::__get(thing)
|
||||
object(X)#2 (0) {
|
||||
}
|
||||
X::__destruct
|
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/overloading_properties2.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// stripped-down version of overloading.php for inclusion in the spec
|
||||
|
||||
class Point { /*…*/ } // has no public property "color"
|
||||
$p = new Point(10, 15);
|
||||
|
||||
var_dump(isset($p->color));
|
||||
$v = $p->color; // get the dynamic property "color"
|
||||
var_dump($v);
|
||||
|
||||
$p->color = "red"; // create/set the dynamic property "color"
|
||||
$v = $p->color; // get the dynamic property "color"
|
||||
isset($p->color); // test if (dynamic or not) "color" property exists
|
||||
unset($p->color); // remove the property "color"
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
|
||||
Notice: Undefined property: Point::$color in %s/classes/overloading_properties2.php on line 9
|
||||
NULL
|
|
@ -0,0 +1,25 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/point2_test1.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'Point2.inc';
|
||||
|
||||
$p1 = new Point2;
|
||||
$p2 = new Point2(-4,3);
|
||||
$p3 = new Point2(20,30);
|
||||
|
||||
echo "Point count = " . Point2::getPointCount() . "\n";
|
||||
$cName = 'Point2';
|
||||
echo "Point count = " . $cName::getPointCount() . "\n";
|
||||
--EXPECT--
|
||||
Point count = 3
|
||||
Point count = 3
|
|
@ -0,0 +1,85 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/point_test1.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'Point.inc';
|
||||
|
||||
$p1 = new Point; // without () uses the "default" constructor
|
||||
// note that without the default values in the constructor,
|
||||
// PHP5 warns "Missing argument n for Point::__construct()"
|
||||
// then constructor has undefined parameters, so uses NULL
|
||||
var_dump($p1);
|
||||
|
||||
$p1 = new Point(); // parens are optional
|
||||
var_dump($p1);
|
||||
|
||||
$p1 = new Point(100); // let y default
|
||||
var_dump($p1);
|
||||
|
||||
$cName = 'Point';
|
||||
$p1 = new $cName(-1, 1); // use string form
|
||||
//$p1 = new 'Point'(-1, 1); // but can't be a string literal!!!
|
||||
var_dump($p1);
|
||||
|
||||
$p1 = new Point(20,30);
|
||||
var_dump($p1);
|
||||
|
||||
var_dump($p1->getX());
|
||||
var_dump($p1->getY());
|
||||
|
||||
$p1->setX(-3);
|
||||
$p1->setY(10);
|
||||
echo $p1 . "\n"; // implicit call to __toString()
|
||||
echo $p1->__toString() . "\n"; // explicit call to __toString()
|
||||
|
||||
$p1->move(-5, 7);
|
||||
echo $p1 . "\n";
|
||||
|
||||
$p1->translate(1, 1);
|
||||
echo $p1 . "\n";
|
||||
--EXPECTF--
|
||||
object(Point)#1 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(0)
|
||||
["y":"Point":private]=>
|
||||
int(0)
|
||||
}
|
||||
object(Point)#2 (2) {
|
||||
["x":"Point":private]=>
|
||||
int(0)
|
||||
["y":"Point":private]=>
|
||||
int(0)
|
||||
}
|
||||
object(Point)#%d (2) {
|
||||
["x":"Point":private]=>
|
||||
int(100)
|
||||
["y":"Point":private]=>
|
||||
int(0)
|
||||
}
|
||||
object(Point)#%d (2) {
|
||||
["x":"Point":private]=>
|
||||
int(-1)
|
||||
["y":"Point":private]=>
|
||||
int(1)
|
||||
}
|
||||
object(Point)#%d (2) {
|
||||
["x":"Point":private]=>
|
||||
int(20)
|
||||
["y":"Point":private]=>
|
||||
int(30)
|
||||
}
|
||||
int(20)
|
||||
int(30)
|
||||
(-3,10)
|
||||
(-3,10)
|
||||
(-5,7)
|
||||
(-4,8)
|
|
@ -0,0 +1,80 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/property_initializer.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
///*
|
||||
class Point
|
||||
{
|
||||
public $x = -10; // gets applied before constructor runs
|
||||
public $y = 10; // gets applied before constructor runs
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
}
|
||||
|
||||
$p = new Point;
|
||||
echo $p . "\n";
|
||||
|
||||
$p = new Point();
|
||||
echo $p . "\n";
|
||||
|
||||
$p = new Point(100);
|
||||
echo $p . "\n";
|
||||
|
||||
$p = new Point(1000, 2000);
|
||||
echo $p . "\n";
|
||||
//*/
|
||||
|
||||
echo "--------------------\n";
|
||||
|
||||
function f() { return 10; }
|
||||
|
||||
class X
|
||||
{
|
||||
// const Cprop1 = 10 + 12 - 5.6; // invalid
|
||||
// const Cprop2 = f(); // invalid
|
||||
// const Cprop10 = array(); // Arrays are not allowed in class constants
|
||||
// const Cprop11 = array(10, "red", TRUE);
|
||||
// const Cprop12 = array(10, "red", TRUE, f());
|
||||
// const Cprop13 = array(10, "red", array(2.3, NULL, array(12, FALSE, "zzz")));
|
||||
|
||||
// private $prop1 = 10 + 12 - 5.6; // invalid
|
||||
// private $prop2 = f(); // invalid
|
||||
private $prop10 = array();
|
||||
private $prop11 = array(10, "red", TRUE);
|
||||
// private $prop12 = array(10, "red", TRUE, f()); // invalid
|
||||
private $prop13 = array(10, "red", array(2.3, NULL, array(12, FALSE, "zzz")));
|
||||
|
||||
|
||||
public $q1; // take on NULL by default
|
||||
public static $q2; // take on NULL by default
|
||||
}
|
||||
|
||||
$x = new X;
|
||||
var_dump($x->q1);
|
||||
var_dump(X::$q2);
|
||||
--EXPECT--
|
||||
(0,0)
|
||||
(0,0)
|
||||
(100,0)
|
||||
(1000,2000)
|
||||
--------------------
|
||||
NULL
|
||||
NULL
|
|
@ -0,0 +1,175 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/serializable.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point implements Serializable
|
||||
{
|
||||
private static $nextId = 1;
|
||||
|
||||
private $x;
|
||||
private $y;
|
||||
private $id;
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
$this->id = self::$nextId++;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this\n\n";
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return 'ID:' . $this->id . '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
echo "\nInside " . __METHOD__ . ", $this\n\n";
|
||||
|
||||
return serialize(array('y' => $this->y, 'x' => $this->x));
|
||||
}
|
||||
|
||||
public function unserialize($data)
|
||||
{
|
||||
$data = unserialize($data);
|
||||
$this->x = $data['x'];
|
||||
$this->y = $data['y'];
|
||||
$this->id = self::$nextId++;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "---------------- create, serialize, and unserialize a Point -------------------\n";
|
||||
|
||||
$p = new Point(2, 5);
|
||||
echo "Point \$p = $p\n";
|
||||
|
||||
$s = serialize($p);
|
||||
var_dump($s);
|
||||
|
||||
echo "------\n";
|
||||
|
||||
$v = unserialize($s);
|
||||
var_dump($v);
|
||||
|
||||
echo "------\n";
|
||||
|
||||
class ColoredPoint extends Point implements Serializable
|
||||
{
|
||||
const RED = 1;
|
||||
const BLUE = 2;
|
||||
|
||||
private $color;
|
||||
|
||||
public function __construct($x = 0, $y = 0, $color = RED)
|
||||
{
|
||||
parent::__construct($x, $y);
|
||||
$this->color = $color;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this\n\n";
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return parent::__toString() . $this->color;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
echo "\nInside " . __METHOD__ . ", $this\n\n";
|
||||
|
||||
return serialize(array(
|
||||
'color' => $this->color,
|
||||
'baseData' => parent::serialize()
|
||||
));
|
||||
}
|
||||
|
||||
public function unserialize($data)
|
||||
{
|
||||
$data = unserialize($data);
|
||||
$this->color = $data['color'];
|
||||
parent::unserialize($data['baseData']);
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "---------------- Serialize ColoredPoint -------------------\n";
|
||||
|
||||
$cp = new ColoredPoint(9, 8, ColoredPoint::BLUE);
|
||||
echo "ColoredPoint \$cp = $cp\n";
|
||||
|
||||
$s = serialize($cp);
|
||||
var_dump($s);
|
||||
|
||||
$v = unserialize($s);
|
||||
var_dump($v);
|
||||
|
||||
echo "---------------- end -------------------\n";
|
||||
--EXPECT--
|
||||
---------------- create, serialize, and unserialize a Point -------------------
|
||||
|
||||
Inside Point::__construct, ID:1(2,5)
|
||||
|
||||
Point $p = ID:1(2,5)
|
||||
|
||||
Inside Point::serialize, ID:1(2,5)
|
||||
|
||||
string(47) "C:5:"Point":30:{a:2:{s:1:"y";i:5;s:1:"x";i:2;}}"
|
||||
------
|
||||
|
||||
Inside Point::unserialize, ID:2(2,5)
|
||||
|
||||
object(Point)#2 (3) {
|
||||
["x":"Point":private]=>
|
||||
int(2)
|
||||
["y":"Point":private]=>
|
||||
int(5)
|
||||
["id":"Point":private]=>
|
||||
int(2)
|
||||
}
|
||||
------
|
||||
---------------- Serialize ColoredPoint -------------------
|
||||
|
||||
Inside Point::__construct, ID:3(9,8)
|
||||
|
||||
|
||||
Inside ColoredPoint::__construct, ID:3(9,8)2
|
||||
|
||||
ColoredPoint $cp = ID:3(9,8)2
|
||||
|
||||
Inside ColoredPoint::serialize, ID:3(9,8)2
|
||||
|
||||
|
||||
Inside Point::serialize, ID:3(9,8)2
|
||||
|
||||
string(100) "C:12:"ColoredPoint":75:{a:2:{s:5:"color";i:2;s:8:"baseData";s:30:"a:2:{s:1:"y";i:8;s:1:"x";i:9;}";}}"
|
||||
|
||||
Inside Point::unserialize, ID:4(9,8)2
|
||||
|
||||
|
||||
Inside ColoredPoint::unserialize, ID:4(9,8)2
|
||||
|
||||
object(ColoredPoint)#4 (4) {
|
||||
["color":"ColoredPoint":private]=>
|
||||
int(2)
|
||||
["x":"Point":private]=>
|
||||
int(9)
|
||||
["y":"Point":private]=>
|
||||
int(8)
|
||||
["id":"Point":private]=>
|
||||
int(4)
|
||||
}
|
||||
---------------- end -------------------
|
|
@ -0,0 +1,277 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/setting_state.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class Point
|
||||
{
|
||||
private static $pointCount = 0;
|
||||
|
||||
private $x;
|
||||
private $y;
|
||||
const CON = 10;
|
||||
protected static $prots;
|
||||
protected $proti;
|
||||
public $pubi;
|
||||
|
||||
public static function getPointCount()
|
||||
{
|
||||
return self::$pointCount;
|
||||
}
|
||||
|
||||
public function __construct($x = 0, $y = 0)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
|
||||
public function move($x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function translate($x, $y)
|
||||
{
|
||||
$this->x += $x;
|
||||
$this->y += $y;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
--self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
///*
|
||||
public function __clone()
|
||||
{
|
||||
++self::$pointCount;
|
||||
|
||||
echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n";
|
||||
}
|
||||
//*/
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '(' . $this->x . ',' . $this->y . ')';
|
||||
}
|
||||
///*
|
||||
static public function __set_state(array $properties)
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
var_dump($properties);
|
||||
|
||||
$p = new Point;
|
||||
$p->x = $properties['x'];
|
||||
$p->y = $properties['y'];
|
||||
var_dump($p);
|
||||
return $p;
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
echo "---------------- start -------------------\n";
|
||||
|
||||
$p = new Point(3, 5);
|
||||
|
||||
echo "---------------- calling var_export -------------------\n";
|
||||
|
||||
$v = var_export($p, TRUE);
|
||||
var_dump($v);
|
||||
|
||||
echo "---------------- calling eval -------------------\n";
|
||||
|
||||
eval('$z = ' . $v . ";");
|
||||
echo "Point \$z is $z\n";
|
||||
|
||||
unset($p, $v, $z);
|
||||
|
||||
echo "---------------- test with inheritance -------------------\n";
|
||||
|
||||
class B
|
||||
{
|
||||
private $bprop;
|
||||
|
||||
public function __construct($p)
|
||||
{
|
||||
$this->bprop = $p;
|
||||
}
|
||||
|
||||
static public function __set_state(array $properties)
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
var_dump($properties);
|
||||
|
||||
$b = new static($properties['bprop']);
|
||||
// $b->bprop = $properties['bprop'];
|
||||
var_dump($b);
|
||||
echo "about to return from " . __METHOD__ . "\n";
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
|
||||
class D extends B
|
||||
{
|
||||
private $dprop = 123;
|
||||
|
||||
public function __construct($bp, $dp = NULL)
|
||||
{
|
||||
$this->dprop = $dp;
|
||||
parent::__construct($bp);
|
||||
}
|
||||
///*
|
||||
static public function __set_state(array $properties)
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
var_dump($properties);
|
||||
|
||||
$d = parent::__set_state($properties);
|
||||
var_dump($d);
|
||||
$d->dprop = $properties['dprop'];
|
||||
var_dump($d);
|
||||
echo "about to return from " . __METHOD__ . "\n";
|
||||
return $d;
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
echo "---------------- test with type B -------------------\n";
|
||||
|
||||
$b = new B(10);
|
||||
$v = var_export($b, TRUE);
|
||||
var_dump($v);
|
||||
|
||||
$r = eval('$z = ' . $v . ";");
|
||||
var_dump($z);
|
||||
|
||||
echo "---------------- test with type D -------------------\n";
|
||||
|
||||
$d = new D(20, 30);
|
||||
$v = var_export($d, TRUE);
|
||||
var_dump($v);
|
||||
|
||||
$r = eval('$z = ' . $v . ";");
|
||||
var_dump($z);
|
||||
|
||||
echo "---------------- end -------------------\n";
|
||||
--EXPECTF--
|
||||
---------------- start -------------------
|
||||
|
||||
Inside Point::__construct, (3,5), point count = 1
|
||||
|
||||
---------------- calling var_export -------------------
|
||||
string(%d) "Point::__set_state(array(
|
||||
%w 'x' => 3,
|
||||
%w 'y' => 5,
|
||||
%w 'proti' => NULL,
|
||||
%w 'pubi' => NULL,
|
||||
))"
|
||||
---------------- calling eval -------------------
|
||||
Inside Point::__set_state
|
||||
array(4) {
|
||||
["x"]=>
|
||||
int(3)
|
||||
["y"]=>
|
||||
int(5)
|
||||
["proti"]=>
|
||||
NULL
|
||||
["pubi"]=>
|
||||
NULL
|
||||
}
|
||||
|
||||
Inside Point::__construct, (0,0), point count = 2
|
||||
|
||||
object(Point)#2 (4) {
|
||||
["x":"Point":private]=>
|
||||
int(3)
|
||||
["y":"Point":private]=>
|
||||
int(5)
|
||||
["proti":protected]=>
|
||||
NULL
|
||||
["pubi"]=>
|
||||
NULL
|
||||
}
|
||||
Point $z is (3,5)
|
||||
|
||||
Inside Point::__destruct, (3,5), point count = 1
|
||||
|
||||
|
||||
Inside Point::__destruct, (3,5), point count = 0
|
||||
|
||||
---------------- test with inheritance -------------------
|
||||
---------------- test with type B -------------------
|
||||
string(%d) "B::__set_state(array(
|
||||
%w 'bprop' => 10,
|
||||
))"
|
||||
Inside B::__set_state
|
||||
array(1) {
|
||||
["bprop"]=>
|
||||
int(10)
|
||||
}
|
||||
object(B)#%d (1) {
|
||||
["bprop":"B":private]=>
|
||||
int(10)
|
||||
}
|
||||
about to return from B::__set_state
|
||||
object(B)#%d (1) {
|
||||
["bprop":"B":private]=>
|
||||
int(10)
|
||||
}
|
||||
---------------- test with type D -------------------
|
||||
string(%d) "D::__set_state(array(
|
||||
%w 'dprop' => 30,
|
||||
%w 'bprop' => 20,
|
||||
))"
|
||||
Inside D::__set_state
|
||||
array(2) {
|
||||
["dprop"]=>
|
||||
int(30)
|
||||
["bprop"]=>
|
||||
int(20)
|
||||
}
|
||||
Inside B::__set_state
|
||||
array(2) {
|
||||
["dprop"]=>
|
||||
int(30)
|
||||
["bprop"]=>
|
||||
int(20)
|
||||
}
|
||||
object(D)#%d (2) {
|
||||
["dprop":"D":private]=>
|
||||
NULL
|
||||
["bprop":"B":private]=>
|
||||
int(20)
|
||||
}
|
||||
about to return from B::__set_state
|
||||
object(D)#%d (2) {
|
||||
["dprop":"D":private]=>
|
||||
NULL
|
||||
["bprop":"B":private]=>
|
||||
int(20)
|
||||
}
|
||||
object(D)#%d (2) {
|
||||
["dprop":"D":private]=>
|
||||
int(30)
|
||||
["bprop":"B":private]=>
|
||||
int(20)
|
||||
}
|
||||
about to return from D::__set_state
|
||||
object(D)#%d (2) {
|
||||
["dprop":"D":private]=>
|
||||
int(30)
|
||||
["bprop":"B":private]=>
|
||||
int(20)
|
||||
}
|
||||
---------------- end -------------------
|
Двоичный файл не отображается.
|
@ -0,0 +1,75 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/stdClass.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL^ E_WARNING);
|
||||
|
||||
function displayClass($o)
|
||||
{
|
||||
// var_dump($o);
|
||||
echo "\nType is >" . get_class($o) . "<\n";
|
||||
$a = (array)$o;
|
||||
// var_dump($a);
|
||||
if (count($a) == 0)
|
||||
{
|
||||
echo " Instance has no properties\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($a as $name => $value)
|
||||
{
|
||||
echo " Property >$name< with value $value\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "====== explicit conversions of certain values to type object ======\n";
|
||||
|
||||
displayClass((object)NULL);
|
||||
displayClass((object)10);
|
||||
displayClass((object)array(11, 21, 31));
|
||||
|
||||
echo "\n====== Use of certain values as the left-hand operand of -> ======\n";
|
||||
|
||||
$p = FALSE;
|
||||
$p->x = 33;
|
||||
displayClass($p);
|
||||
|
||||
$p = NULL;
|
||||
$p->x = 44;
|
||||
displayClass($p);
|
||||
|
||||
$p = "";
|
||||
$p->x = 55;
|
||||
displayClass($p);
|
||||
--EXPECT--
|
||||
====== explicit conversions of certain values to type object ======
|
||||
|
||||
Type is >stdClass<
|
||||
Instance has no properties
|
||||
|
||||
Type is >stdClass<
|
||||
Property >scalar< with value 10
|
||||
|
||||
Type is >stdClass<
|
||||
Property >0< with value 11
|
||||
Property >1< with value 21
|
||||
Property >2< with value 31
|
||||
|
||||
====== Use of certain values as the left-hand operand of -> ======
|
||||
|
||||
Type is >stdClass<
|
||||
Property >x< with value 33
|
||||
|
||||
Type is >stdClass<
|
||||
Property >x< with value 44
|
||||
|
||||
Type is >stdClass<
|
||||
Property >x< with value 55
|
|
@ -0,0 +1,29 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/using_class_declarations.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
new C1; // OK; finds a forward declaration
|
||||
//new D1; // Fatal error: Class 'D' not found
|
||||
|
||||
class D1 extends C1 {}
|
||||
class C1 {}
|
||||
|
||||
//class C2 implements I2 {} // Fatal error: Interface 'I2' not found
|
||||
interface I2 extends I1 {} // OK; finds a forward declaration
|
||||
interface I1 {}
|
||||
--EXPECT--
|
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/vehicle_test1.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'PassengerJet.inc';
|
||||
|
||||
// $v = new Vehicle; // can't instantiate an abstract class
|
||||
// $a = new Aircraft; // can't instantiate an abstract class
|
||||
|
||||
$pj = new PassengerJet("Horizon", 1993, 33000, 235);
|
||||
echo "\$pj's maximum speed: " . $pj->getMaxSpeed() . "\n";
|
||||
echo "\$pj's maximum altitude: " . $pj->getMaxAltitude() . "\n";
|
||||
--EXPECT--
|
||||
$pj's maximum speed: 550
|
||||
$pj's maximum altitude: 30000
|
|
@ -0,0 +1,127 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./classes/visibility.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class C
|
||||
{
|
||||
// constants
|
||||
|
||||
const CON1 = 123; // implicitly static and can't say so explicitly
|
||||
// implicitly public
|
||||
|
||||
public const CON2 = 123; // explicitly public
|
||||
protected const CON3 = 123; // protected constant
|
||||
private const CON4 = 123; // private constant
|
||||
|
||||
// properties
|
||||
|
||||
// $prop1a; // rejected; must have a modifier of some sort
|
||||
// $prop1b = 123; // rejected; must have a modifier of some sort
|
||||
public $prop2;
|
||||
protected $prop3;
|
||||
private $prop4;
|
||||
|
||||
var $vprop1a; // OK; implies public
|
||||
var $vprop1b = 123; // OK; implies public
|
||||
// public var $vprop2; // can't combine var with visibility modifiers
|
||||
// var public $vprop2;
|
||||
// protected var $vprop3;
|
||||
// var protected $vprop3;
|
||||
// var private $vprop4;
|
||||
|
||||
static $sprop1;
|
||||
public static $sprop2;
|
||||
static protected $sprop3; // visibility and static ordering unimportant
|
||||
private static $sprop4;
|
||||
|
||||
// static var $vsprop1; // can't combine var with static modifier
|
||||
// var static $vsprop1;
|
||||
// var public static $vsprop2;
|
||||
// protected var static $vsprop3;
|
||||
// private static var $vsprop4;
|
||||
|
||||
// methods
|
||||
|
||||
function f1() {}
|
||||
public function f2() {}
|
||||
protected function f3() {}
|
||||
private function f4() {}
|
||||
|
||||
static function sf1() {}
|
||||
public static function sf2() {}
|
||||
static protected function sf3() {} // visibility and static ordering unimportant
|
||||
private static function sf4() {}
|
||||
|
||||
// constructors
|
||||
|
||||
function __construct() {} // OK on its own; implicitly public
|
||||
// public function __construct() {} // OK on its own
|
||||
// protected function __construct() {} // OK on its own
|
||||
// private function __construct() {} // OK on its own
|
||||
|
||||
// static function __construct() {} // constructors can't be static
|
||||
// public static function __construct() {}
|
||||
// protected static function __construct() {}
|
||||
// private static function __construct() {}
|
||||
|
||||
// destructors
|
||||
|
||||
function __destruct() {} // OK on its own; implicitly public
|
||||
// public function __destruct() {} // OK on its own
|
||||
// protected function __destruct() {} // OK on its own
|
||||
// private function __destruct() {} // OK on its own
|
||||
|
||||
// static function __destruct() {} // destructors can't be static
|
||||
// public static function __destruct() {}
|
||||
// protected static function __destruct() {}
|
||||
// private static function __destruct() {}
|
||||
}
|
||||
|
||||
echo "CON1: " . C::CON1 . "\n"; // use :: notation, as a const is implicitly static
|
||||
|
||||
$c = new C; // calls public constructor
|
||||
$c->vprop1a; // accesses public instance method
|
||||
$c->vprop1b; // accesses public instance method
|
||||
|
||||
abstract class D1
|
||||
{
|
||||
public abstract function paf1($p1);
|
||||
abstract protected function paf2();
|
||||
// private abstract function paf3(); // can't ever provide an implementation
|
||||
public static abstract function pasf1();
|
||||
protected abstract static function pasf2($p1);
|
||||
}
|
||||
|
||||
class D2 extends D1
|
||||
{
|
||||
// public function paf1() {} // Declaration of D2::paf1() must be compatible with D1::paf1($p1)
|
||||
public function paf1($q1) {} // OK; has same visibility as abstract decl, and same signature
|
||||
// public function paf1($q1, $q2) {} // Declaration of D2::paf1() must be compatible with D1::paf1($p1)
|
||||
// protected function paf1($q1) {} // Access level to D2::paf1() must be public
|
||||
// private function paf1($q1) {} // Access level to D2::paf1() must be public
|
||||
|
||||
// public function paf2() {} // OK; has wider visibility than abstract decl
|
||||
protected function paf2() {} // OK; has same visibility as abstract decl
|
||||
// private function paf2() {} // Access level to D2::paf2() must be protected
|
||||
|
||||
public static function pasf1() {} // OK; has same visibility as abstract decl
|
||||
// protected static function pasf1() {}// Access level to D2::pasf1() must be public
|
||||
// private static function pasf1() {} // Access level to D2::pasf1() must be public
|
||||
|
||||
// static public function pasf2($q1) {} // OK; has wider visibility than abstract decl
|
||||
// static protected function pasf2() {} // Declaration of D2::pasf2() must be compatible with D1::pasf2($p1)
|
||||
static protected function pasf2($q1) {} // OK; has same visibility as abstract decl, and same signature
|
||||
// static protected function pasf2($q1, $q2) {} // Declaration of D2::pasf2() must be compatible with D1::pasf2($p1)
|
||||
// static private function pasf2() {$q1} // Access level to D2::pasf2() must be protected
|
||||
}
|
||||
--EXPECTF--
|
||||
%ACON1: 123
|
|
@ -0,0 +1,5 @@
|
|||
hhvm.enable_obj_destruct_call = true
|
||||
hhvm.enable_zend_compat = true
|
||||
hhvm.http.slow_query_threshold = 0
|
||||
hhvm.mysql.slow_query_threshold = 0
|
||||
hhvm.mysql.typed_results = false
|
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./constants/classes.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
/*
|
||||
abstract class AC {}
|
||||
|
||||
new AC; // Cannot instantiate abstract class AC
|
||||
*/
|
||||
|
||||
interface i1 {}
|
||||
interface i2 {}
|
||||
class C1 {}
|
||||
class C2 extends c1 implements i1, i2 {}
|
||||
|
||||
$c = new C2;
|
||||
var_dump($c);
|
||||
--EXPECT--
|
||||
object(C2)#1 (0) {
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./constants/constants.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
function trace($name, $value, $b = FALSE)
|
||||
{
|
||||
$r = define($name, $value, $b);
|
||||
echo "define $name " . ($r ? "succeeded" : "failed");
|
||||
if (defined($name))
|
||||
echo "; value is >" . constant($name) . "<\n";
|
||||
else
|
||||
echo "; not defined\n";
|
||||
}
|
||||
|
||||
///*
|
||||
// define some constants with simple (single-token) scalar initial values
|
||||
|
||||
trace("STATUS1", TRUE);
|
||||
trace("MIN", 10);
|
||||
trace("MAX", 20, TRUE); // HHVM Warning: Case insensitive constant names are not supported in HipHop
|
||||
trace("MY_PI", 3.1415926);
|
||||
trace("MY_COLOR", "red");
|
||||
trace("C1", NULL);
|
||||
//*/
|
||||
|
||||
///*
|
||||
// try to define some constants with multiple-token scalar initial values
|
||||
|
||||
// involving literals only
|
||||
|
||||
trace("CON1", 5 + 10.1 * 3);// succeeded;
|
||||
|
||||
// involving variables and other non-basic operators
|
||||
|
||||
function getValue() { return 250; }
|
||||
|
||||
$v1 = 10;
|
||||
trace("CON2", 5 + $v1); // succeeded
|
||||
$v2 = array(10, 20);
|
||||
trace("CON3", 5 + $v2[0]); // succeeded
|
||||
trace("CON4", 5 + array(10, 20)[0]); // succeeded
|
||||
trace("CON5", 5 + ++$v2[0]); // succeeded
|
||||
trace("CON6", 5 + $v2[0]--); // succeeded
|
||||
trace("CON7", 5 + (float)$v1); // succeeded
|
||||
trace("CON8", 1 << $v1); // succeeded
|
||||
trace("CON9", $v2[0] == $v2[1]); // succeeded
|
||||
trace("CON10", $v2[0] = 123); // succeeded
|
||||
trace("CON11", getValue() - 100); // succeeded
|
||||
|
||||
// involving constants
|
||||
|
||||
trace("CON21", 1 + CON1); // succeeded;
|
||||
trace("CON22", 2 * CON2 + CON1); // succeeded;
|
||||
//*/
|
||||
|
||||
///*
|
||||
// try to define some constants with names not permitted as tokens
|
||||
|
||||
trace("36ABC", 100) . "\n"; // ill-formed name, but no error. Seems to work
|
||||
trace("#%&", 200) . "\n"; // ill-formed name, but no error. Seems to work
|
||||
//*/
|
||||
|
||||
///*
|
||||
// try to redefine a user-defined constant
|
||||
|
||||
trace("MY_COLOR", "green"); // Warning, and doesn't change the value
|
||||
|
||||
// try to redefine a pre-defined constant
|
||||
|
||||
trace("TRUE", 999) . "\n"; // PHP5: No warning, and doesn't change the value, but
|
||||
// constant("TRUE") and get_defined_constants show 999!
|
||||
// HHVM: Constant TRUE already defined ...
|
||||
echo " TRUE's value:" . TRUE . "\n"; // however, this shows the old value, 1
|
||||
//*/
|
||||
|
||||
///*
|
||||
// try to define some constants with non-scalar initial values
|
||||
|
||||
trace("COLORS", [10, 20]); // Works from PHP 7 onwards
|
||||
|
||||
class C {}
|
||||
trace("MY_OBJECT", new C); // Constants may only evaluate to scalar values or arrays
|
||||
|
||||
$infile = fopen("Testfile.txt", 'r');
|
||||
if ($infile == FALSE)
|
||||
{
|
||||
echo "Can't open file\n";
|
||||
}
|
||||
trace("MY_RESOURCE", $infile); // PHP5: Succeeded
|
||||
// HHVM: Constants may only evaluate to scalar values
|
||||
trace("MY_RESOURCE", $infile); // PHP5: Duplicate rejected
|
||||
//*/
|
||||
|
||||
///*
|
||||
class MyClass
|
||||
{
|
||||
// define("DEFINE_INSIDE_CLASS", 10); // not permitted inside a class; OK
|
||||
|
||||
// const CON30; // not permitted; OK
|
||||
// const CON31 = 5 + 10.1 * 3;// failed; unexpected '+', expecting ',' or ';'
|
||||
// const CON32 = $v1; // failed; unexpected '$v1'
|
||||
// const CON33 = $v2[0]; // failed
|
||||
// const CON34 = array(10, 20)[0]; // failed; Arrays are not allowed in class constants
|
||||
// const CON35 = ++$v2[0]; // failed; unexpected '++'
|
||||
// const CON37 = (float)10;// failed; unexpected '(float)' const CON38 = 1 << $v1); // surprise? succeeded
|
||||
// const CON40 = new C; // failed; unexpected 'new'
|
||||
const CON38 = 99; // succeeded
|
||||
const CON39 = CON38; // succeeded
|
||||
}
|
||||
//*/
|
||||
|
||||
///*
|
||||
// Note: As opposed to defining constants using define(), constants defined using the
|
||||
// const keyword must be declared at the top-level scope because they are defined at
|
||||
// compile-time. This means that they cannot be declared inside functions, loops or
|
||||
// if statements.
|
||||
|
||||
// const CON50; // not permitted; OK
|
||||
// const CON51 = 5 + 10.1 * 3;// failed; unexpected '+', expecting ',' or ';'
|
||||
// const CON52 = $v1; // failed; unexpected '$v1'
|
||||
// const CON53 = $v2[0]; // failed
|
||||
// const CON54 = array(10, 20)[0]; // failed; Arrays are not allowed in class constants
|
||||
// const CON55 = ++$v2[0]; // failed; unexpected '++'
|
||||
// const CON57 = (float)10; // failed; unexpected '(float)' const CON38 = 1 << $v1); // surprise? succeeded
|
||||
// const CON58 = new C; // failed; unexpected 'new'
|
||||
const CON59 = 99; // succeeded
|
||||
const CON60 = CON59; // succeeded
|
||||
|
||||
trace("CON61", 321);
|
||||
const CON62 = CON61; // succeeded
|
||||
trace("CON63", CON62);
|
||||
|
||||
function f($p)
|
||||
{
|
||||
// const CON70A = 10; // unexpected 'const'
|
||||
trace("CON70B", 10); // succeeded
|
||||
|
||||
if ($p)
|
||||
{
|
||||
// const CON71A = 101; // unexpected 'const'
|
||||
trace("CON71B", 101); // succeeded
|
||||
}
|
||||
}
|
||||
|
||||
f(10);
|
||||
//*/
|
||||
|
||||
///*
|
||||
// try defining a constant whose name is a keyword
|
||||
|
||||
trace("FOR", 100); // succeeded
|
||||
// echo FOR; // unexpected 'FOR' (T_FOR)
|
||||
|
||||
// const FOR = 100; // unexpected 'FOR' (T_FOR)
|
||||
//*/
|
||||
|
||||
class C3
|
||||
{
|
||||
|
||||
const CON1 = 123; // implicitly static and can't say so explicitly
|
||||
// implicitly public
|
||||
|
||||
public const CON2 = 123; // explicitly public
|
||||
protected const CON3 = 123; // protected constant
|
||||
private const CON4 = 123; // private constant
|
||||
}
|
||||
|
||||
echo "CON1: " . C3::CON1 . "\n"; // use :: notation, as a const is implicitly static
|
||||
|
||||
// public const CON80 = 80; // top level const can not have visibility modifier
|
||||
// protected const CON81 = 81; // top level const can not have visibility modifier
|
||||
// private const CON82 = 82; // top level const can not have visibility modifier
|
||||
|
||||
//print_r(get_defined_constants());
|
||||
--EXPECTF--
|
||||
define STATUS1 succeeded; value is >1<
|
||||
define MIN succeeded; value is >10<
|
||||
define MAX succeeded; value is >20<
|
||||
define MY_PI succeeded; value is >3.1415926<
|
||||
define MY_COLOR succeeded; value is >red<
|
||||
define C1 succeeded; value is ><
|
||||
define CON1 succeeded; value is >35.3<
|
||||
define CON2 succeeded; value is >15<
|
||||
define CON3 succeeded; value is >15<
|
||||
define CON4 succeeded; value is >15<
|
||||
define CON5 succeeded; value is >16<
|
||||
define CON6 succeeded; value is >16<
|
||||
define CON7 succeeded; value is >15<
|
||||
define CON8 succeeded; value is >1024<
|
||||
define CON9 succeeded; value is ><
|
||||
define CON10 succeeded; value is >123<
|
||||
define CON11 succeeded; value is >150<
|
||||
define CON21 succeeded; value is >36.3<
|
||||
define CON22 succeeded; value is >65.3<
|
||||
define 36ABC succeeded; value is >100<
|
||||
define #%& succeeded; value is >200<
|
||||
|
||||
Notice: Constant MY_COLOR already defined in %s/constants/constants.php on line 13
|
||||
define MY_COLOR failed; value is >red<
|
||||
define TRUE succeeded; value is >999<
|
||||
TRUE's value:1
|
||||
define COLORS succeeded
|
||||
Notice: Array to string conversion in %s/constants/constants.php on line 16
|
||||
; value is >Array<
|
||||
|
||||
Warning: Constants may only evaluate to scalar values or arrays in %s/constants/constants.php on line 13
|
||||
define MY_OBJECT failed; not defined
|
||||
|
||||
Warning: fopen(Testfile.txt): failed to open stream: No such file or directory in %s/constants/constants.php on line 90
|
||||
Can't open file
|
||||
define MY_RESOURCE succeeded; value is ><
|
||||
|
||||
Notice: Constant MY_RESOURCE already defined in %s/constants/constants.php on line 13
|
||||
define MY_RESOURCE failed; value is ><
|
||||
define CON61 succeeded; value is >321<
|
||||
define CON63 succeeded; value is >321<
|
||||
define CON70B succeeded; value is >10<
|
||||
define CON71B succeeded; value is >101<
|
||||
define FOR succeeded; value is >100<
|
||||
CON1: 123
|
|
@ -0,0 +1,199 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./constants/core_predefined_constants.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
function trace($text, $pdc)
|
||||
{
|
||||
echo "$text: ";
|
||||
var_dump($pdc);
|
||||
}
|
||||
|
||||
trace("__LINE__", __LINE__);
|
||||
|
||||
trace("__FILE__", __FILE__);
|
||||
|
||||
trace("__DIR__", __DIR__);
|
||||
var_dump(dirname(__FILE__));
|
||||
|
||||
trace("__LINE__", __LINE__);
|
||||
|
||||
trace("__NAMESPACE__", __NAMESPACE__);
|
||||
|
||||
echo "-----------------------------------------\n";
|
||||
|
||||
echo "At the top level of a script\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
|
||||
echo "-----------------------------------------\n";
|
||||
|
||||
echo "At the top level of a script and outside all classes\n";
|
||||
trace("__METHOD__", __METHOD__);
|
||||
|
||||
echo "-----------------------------------------\n";
|
||||
|
||||
echo "Outside all classes\n";
|
||||
trace("__CLASS__", __CLASS__);
|
||||
|
||||
echo "-----------------------------------------\n";
|
||||
|
||||
echo "Outside all classes\n";
|
||||
trace("__TRAIT__", __TRAIT__);
|
||||
|
||||
echo "-----------------------------------------\n";
|
||||
|
||||
function ComputeResult()
|
||||
{
|
||||
echo "Inside ComputeResult\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
trace("__METHOD__", __METHOD__);
|
||||
trace("__CLASS__", __CLASS__);
|
||||
trace("__TRAIT__", __TRAIT__);
|
||||
trace("__NAMESPACE__", __NAMESPACE__);
|
||||
|
||||
function Inner()
|
||||
{
|
||||
echo "Inside ComputeResult\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
trace("__METHOD__", __METHOD__);
|
||||
}
|
||||
|
||||
Inner();
|
||||
}
|
||||
|
||||
ComputeResult();
|
||||
|
||||
echo "-----------------------------------------\n";
|
||||
|
||||
class Date
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
trace("__CLASS__", __CLASS__);
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
trace("__TRAIT__", __TRAIT__);
|
||||
trace("__NAMESPACE__", __NAMESPACE__);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
public function setDay($day)
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
trace("__LINE__", __LINE__);
|
||||
|
||||
$this->priv1();
|
||||
$this->spf1();
|
||||
}
|
||||
|
||||
// public vs. private doesn't matter
|
||||
|
||||
private function priv1()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
}
|
||||
|
||||
static public function spf1()
|
||||
{
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$date1 = new Date;
|
||||
$date1->setDay(22);
|
||||
|
||||
echo "-----------------------------------------\n";
|
||||
|
||||
class DatePlus extends Date
|
||||
{
|
||||
public function xx()
|
||||
{
|
||||
trace("__CLASS__", __CLASS__);
|
||||
echo "Inside " . __METHOD__ . "\n";
|
||||
trace("__FUNCTION__", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
$datePlus1 = new DatePlus;
|
||||
$datePlus1->xx();
|
||||
|
||||
include_once('includefile.inc');
|
||||
--EXPECTF--
|
||||
__LINE__: int(17)
|
||||
__FILE__: string(%d) "%s/constants/core_predefined_constants.php"
|
||||
__DIR__: string(%d) "%s/constants"
|
||||
string(%d) "%s/constants"
|
||||
__LINE__: int(24)
|
||||
__NAMESPACE__: string(0) ""
|
||||
-----------------------------------------
|
||||
At the top level of a script
|
||||
__FUNCTION__: string(0) ""
|
||||
-----------------------------------------
|
||||
At the top level of a script and outside all classes
|
||||
__METHOD__: string(0) ""
|
||||
-----------------------------------------
|
||||
Outside all classes
|
||||
__CLASS__: string(0) ""
|
||||
-----------------------------------------
|
||||
Outside all classes
|
||||
__TRAIT__: string(0) ""
|
||||
-----------------------------------------
|
||||
Inside ComputeResult
|
||||
__FUNCTION__: string(13) "ComputeResult"
|
||||
__METHOD__: string(13) "ComputeResult"
|
||||
__CLASS__: string(0) ""
|
||||
__TRAIT__: string(0) ""
|
||||
__NAMESPACE__: string(0) ""
|
||||
Inside ComputeResult
|
||||
__FUNCTION__: string(5) "Inner"
|
||||
__METHOD__: string(5) "Inner"
|
||||
-----------------------------------------
|
||||
Inside Date::__construct
|
||||
__CLASS__: string(4) "Date"
|
||||
__FUNCTION__: string(11) "__construct"
|
||||
__TRAIT__: string(0) ""
|
||||
__NAMESPACE__: string(0) ""
|
||||
Inside Date::setDay
|
||||
__FUNCTION__: string(6) "setDay"
|
||||
__LINE__: int(98)
|
||||
Inside Date::priv1
|
||||
__FUNCTION__: string(5) "priv1"
|
||||
Inside Date::spf1
|
||||
__FUNCTION__: string(4) "spf1"
|
||||
-----------------------------------------
|
||||
Inside Date::__construct
|
||||
__CLASS__: string(4) "Date"
|
||||
__FUNCTION__: string(11) "__construct"
|
||||
__TRAIT__: string(0) ""
|
||||
__NAMESPACE__: string(0) ""
|
||||
__CLASS__: string(8) "DatePlus"
|
||||
Inside DatePlus::xx
|
||||
__FUNCTION__: string(2) "xx"
|
||||
Inside includefile.php
|
||||
string(%d) "%s/constants/includefile.inc"
|
||||
string(%d) "%s/constants"
|
||||
Inside Date::__destruct
|
||||
__FUNCTION__: string(10) "__destruct"
|
||||
Inside Date::__destruct
|
||||
__FUNCTION__: string(10) "__destruct"
|
|
@ -0,0 +1,110 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./constants/core_predefined_constants2.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
function trace($text, $pdc)
|
||||
{
|
||||
echo "$text: ";
|
||||
var_dump($pdc);
|
||||
}
|
||||
|
||||
trace("PHP_VERSION", PHP_VERSION);
|
||||
trace("PHP_MAJOR_VERSION", PHP_MAJOR_VERSION);
|
||||
trace("PHP_MINOR_VERSION", PHP_MINOR_VERSION);
|
||||
trace("PHP_RELEASE_VERSION", PHP_RELEASE_VERSION);
|
||||
trace("PHP_VERSION_ID", PHP_VERSION_ID);
|
||||
trace("PHP_EXTRA_VERSION", PHP_EXTRA_VERSION);
|
||||
// HHVM doesn't have this
|
||||
// trace("PHP_ZTS", PHP_ZTS);
|
||||
trace("PHP_DEBUG", PHP_DEBUG);
|
||||
trace("PHP_MAXPATHLEN", PHP_MAXPATHLEN);
|
||||
trace("PHP_OS", PHP_OS);
|
||||
trace("PHP_SAPI", PHP_SAPI);
|
||||
trace("PHP_EOL", PHP_EOL);
|
||||
trace("DEFAULT_INCLUDE_PATH", DEFAULT_INCLUDE_PATH);
|
||||
trace("PEAR_INSTALL_DIR", PEAR_INSTALL_DIR);
|
||||
trace("PEAR_EXTENSION_DIR", PEAR_EXTENSION_DIR);
|
||||
trace("PHP_EXTENSION_DIR", PHP_EXTENSION_DIR);
|
||||
trace("PHP_PREFIX", PHP_PREFIX);
|
||||
trace("PHP_BINDIR", PHP_BINDIR);
|
||||
// HHVM doesn't have this
|
||||
// trace("PHP_MANDIR", PHP_MANDIR);
|
||||
trace("PHP_LIBDIR", PHP_LIBDIR);
|
||||
trace("PHP_DATADIR", PHP_DATADIR);
|
||||
trace("PHP_SYSCONFDIR", PHP_SYSCONFDIR);
|
||||
trace("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH);
|
||||
trace("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR);
|
||||
trace("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX);
|
||||
trace("E_ERROR", E_ERROR);
|
||||
trace("E_WARNING", E_WARNING);
|
||||
trace("E_PARSE", E_PARSE);
|
||||
trace("E_NOTICE", E_NOTICE);
|
||||
trace("E_CORE_ERROR", E_CORE_ERROR);
|
||||
trace("E_CORE_WARNING", E_CORE_WARNING);
|
||||
trace("E_COMPILE_ERROR", E_COMPILE_ERROR);
|
||||
trace("E_COMPILE_WARNING", E_COMPILE_WARNING);
|
||||
trace("E_USER_ERROR", E_USER_ERROR);
|
||||
trace("E_USER_WARNING", E_USER_WARNING);
|
||||
trace("E_USER_NOTICE", E_USER_NOTICE);
|
||||
trace("E_DEPRECATED", E_DEPRECATED);
|
||||
trace("E_USER_DEPRECATED", E_USER_DEPRECATED);
|
||||
trace("E_ALL", E_ALL);
|
||||
trace("E_STRICT", E_STRICT);
|
||||
trace("__COMPILER_HALT_OFFSET__", __COMPILER_HALT_OFFSET__);
|
||||
trace("TRUE", TRUE);
|
||||
trace("FALSE", FALSE);
|
||||
trace("NULL", NULL);
|
||||
__HALT_COMPILER();
|
||||
--EXPECTF--
|
||||
PHP_VERSION: string(%d) "%s"
|
||||
PHP_MAJOR_VERSION: int(%d)
|
||||
PHP_MINOR_VERSION: int(%d)
|
||||
PHP_RELEASE_VERSION: int(%d)
|
||||
PHP_VERSION_ID: int(%d)
|
||||
PHP_EXTRA_VERSION: string(%d) "%S"
|
||||
PHP_DEBUG: %s
|
||||
PHP_MAXPATHLEN: int(%d)
|
||||
PHP_OS: string(%d) "%s"
|
||||
PHP_SAPI: string(3) "cli"
|
||||
PHP_EOL: string(1) "
|
||||
"
|
||||
DEFAULT_INCLUDE_PATH: string(%d) "%S"
|
||||
PEAR_INSTALL_DIR: string(%d) "%S"
|
||||
PEAR_EXTENSION_DIR: string(%d) "%S"
|
||||
PHP_EXTENSION_DIR: string(%d) "%S"
|
||||
PHP_PREFIX: string(%d) "%S"
|
||||
PHP_BINDIR: string(%d) "%S"
|
||||
PHP_LIBDIR: string(%d) "%S"
|
||||
PHP_DATADIR: string(%d) "%S"
|
||||
PHP_SYSCONFDIR: string(%d) "%S"
|
||||
PHP_CONFIG_FILE_PATH: string(%d) "%S"
|
||||
PHP_CONFIG_FILE_SCAN_DIR: string(%d) "%S"
|
||||
PHP_SHLIB_SUFFIX: string(2) "so"
|
||||
E_ERROR: int(1)
|
||||
E_WARNING: int(2)
|
||||
E_PARSE: int(4)
|
||||
E_NOTICE: int(8)
|
||||
E_CORE_ERROR: int(16)
|
||||
E_CORE_WARNING: int(32)
|
||||
E_COMPILE_ERROR: int(64)
|
||||
E_COMPILE_WARNING: int(128)
|
||||
E_USER_ERROR: int(256)
|
||||
E_USER_WARNING: int(512)
|
||||
E_USER_NOTICE: int(1024)
|
||||
E_DEPRECATED: int(8192)
|
||||
E_USER_DEPRECATED: int(16384)
|
||||
E_ALL: int(32767)
|
||||
E_STRICT: int(2048)
|
||||
%a
|
||||
TRUE: bool(true)
|
||||
FALSE: bool(false)
|
||||
NULL: NULL
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
echo "Inside includefile.php\n";
|
||||
|
||||
var_dump(__FILE__);
|
||||
var_dump(__DIR__);
|
|
@ -0,0 +1,5 @@
|
|||
Once upon a time,
|
||||
in a land
|
||||
far,
|
||||
far away,
|
||||
there lived an ogre called Big Bad Bruce.
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class MyRangeException extends Exception
|
||||
{
|
||||
private $badValue;
|
||||
private $lowerValue;
|
||||
private $upperValue;
|
||||
|
||||
public function __construct($message, $badValue, $lowerValue, $upperValue)
|
||||
{
|
||||
parent::__construct($message);
|
||||
|
||||
$this->badValue = $badValue;
|
||||
$this->lowerValue = $lowerValue;
|
||||
$this->upperValue = $upperValue;
|
||||
}
|
||||
|
||||
public function getBadValue() { return $this->badValue; }
|
||||
public function getLowerValue() { return $this->lowerValue; }
|
||||
public function getUpperValue() { return $this->upperValue; }
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return parent::__toString()
|
||||
. ", badValue: " . $this->badValue
|
||||
. ", lowerValue: " . $this->lowerValue
|
||||
. ", upperValue: " . $this->upperValue;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,360 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/exception_class.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function displayExceptionObject(Exception $e)
|
||||
{
|
||||
echo "\$e = >$e<\n"; // calls __toString
|
||||
echo "getMessage: >".$e->getMessage()."<\n";
|
||||
echo "getCode: >".$e->getCode()."<\n";
|
||||
echo "getPrevious: >".$e->getPrevious()."<\n";
|
||||
echo "getFile: >".$e->getFile()."<\n";
|
||||
echo "getLine: >".$e->getLine()."<\n";
|
||||
echo "getTraceAsString: >".$e->getTraceAsString()."<\n";
|
||||
|
||||
$traceInfo = $e->getTrace();
|
||||
var_dump($traceInfo);
|
||||
echo "Trace Info:".((count($traceInfo) == 0) ? " none\n" : "\n");
|
||||
foreach ($traceInfo as $traceInfoKey => $traceLevel) // process all traceback levels
|
||||
{
|
||||
echo "Key[$traceInfoKey]:\n";
|
||||
foreach ($traceLevel as $levelKey => $levelVal) // process one traceback level
|
||||
{
|
||||
if ($levelKey != "args")
|
||||
{
|
||||
echo " Key[$levelKey] => >$levelVal<\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " Key[$levelKey]:\n";
|
||||
foreach ($levelVal as $argKey => $argVal) // process all args for that level
|
||||
{
|
||||
echo " Key[$argKey] => >$argVal<\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function fL1($p1 = -10)
|
||||
{
|
||||
try {
|
||||
echo "fL1: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL1 Message", 123);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL1: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL1: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL1: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL1: Calling fL2\n";
|
||||
$a = -4.5;
|
||||
fL2(2.3, $a); // pass 2nd arg as a non-literal to see how traceback handles it
|
||||
//fL2(2.3); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function fL2($p1, $p2 = -100)
|
||||
{
|
||||
try {
|
||||
echo "fL2: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL2 Message", 234);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL2: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL2: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL2: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL2: Calling fL3\n";
|
||||
$a = "xyz"; $b = NULL; $c = TRUE;
|
||||
fL3($a, $b, $c); // pass args as a non-literal to see how traceback handles them
|
||||
//fL3($a, $b); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function fL3($p1, $p2, $p3 = -1000)
|
||||
{
|
||||
try {
|
||||
echo "fL3: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL3 Message", 345);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL3: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL3: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL3: Beyond try/catch/finally blocks\n==========\n";
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
try {
|
||||
echo "L0: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("L0 Message", -1);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "L0: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "L0: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "L0: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "L0: Calling fL1\n";
|
||||
fL1(10);
|
||||
//fL1(); // see what happens when a default argument value is used
|
||||
--EXPECTF--
|
||||
L0: In try-block
|
||||
L0: In catch-block
|
||||
$e = >Exception: L0 Message in %s/exception_handling/exception_class.php:127
|
||||
Stack trace:
|
||||
#0 {main}<
|
||||
getMessage: >L0 Message<
|
||||
getCode: >-1<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class.php<
|
||||
getLine: >127<
|
||||
getTraceAsString: >#0 {main}<
|
||||
array(0) {
|
||||
}
|
||||
Trace Info: none
|
||||
L0: In finally-block
|
||||
L0: Beyond try/catch/finally blocks
|
||||
==========
|
||||
L0: Calling fL1
|
||||
fL1: In try-block
|
||||
fL1: In catch-block
|
||||
$e = >Exception: fL1 Message in %s/exception_handling/exception_class.php:55
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class.php(140): fL1(10)
|
||||
#1 {main}<
|
||||
getMessage: >fL1 Message<
|
||||
getCode: >123<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class.php<
|
||||
getLine: >55<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class.php(140): fL1(10)
|
||||
#1 {main}<
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class.php"
|
||||
["line"]=>
|
||||
int(140)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
%Sint(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class.php<
|
||||
Key[line] => >140<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL1: In finally-block
|
||||
fL1: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL1: Calling fL2
|
||||
fL2: In try-block
|
||||
fL2: In catch-block
|
||||
$e = >Exception: fL2 Message in %s/exception_handling/exception_class.php:81
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class.php(69): fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class.php(140): fL1(10)
|
||||
#2 {main}<
|
||||
getMessage: >fL2 Message<
|
||||
getCode: >234<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class.php<
|
||||
getLine: >81<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class.php(69): fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class.php(140): fL1(10)
|
||||
#2 {main}<
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class.php"
|
||||
["line"]=>
|
||||
int(69)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
%Sfloat(2.3)
|
||||
[1]=>
|
||||
%Sfloat(-4.5)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class.php"
|
||||
["line"]=>
|
||||
int(140)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
%Sint(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class.php<
|
||||
Key[line] => >69<
|
||||
Key[function] => >fL2<
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class.php<
|
||||
Key[line] => >140<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL2: In finally-block
|
||||
fL2: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL2: Calling fL3
|
||||
fL3: In try-block
|
||||
fL3: In catch-block
|
||||
$e = >Exception: fL3 Message in %s/exception_handling/exception_class.php:107
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class.php(95): fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class.php(69): fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class.php(140): fL1(10)
|
||||
#3 {main}<
|
||||
getMessage: >fL3 Message<
|
||||
getCode: >345<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class.php<
|
||||
getLine: >107<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class.php(95): fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class.php(69): fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class.php(140): fL1(10)
|
||||
#3 {main}<
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class.php"
|
||||
["line"]=>
|
||||
int(95)
|
||||
["function"]=>
|
||||
string(3) "fL3"
|
||||
["args"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
%Sstring(3) "xyz"
|
||||
[1]=>
|
||||
%SNULL
|
||||
[2]=>
|
||||
%Sbool(true)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class.php"
|
||||
["line"]=>
|
||||
int(69)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
%Sfloat(2.3)
|
||||
[1]=>
|
||||
%Sfloat(-4.5)
|
||||
}
|
||||
}
|
||||
[2]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class.php"
|
||||
["line"]=>
|
||||
int(140)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
%Sint(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class.php<
|
||||
Key[line] => >95<
|
||||
Key[function] => >fL3<
|
||||
Key[args]:
|
||||
Key[0] => >xyz<
|
||||
Key[1] => ><
|
||||
Key[2] => >1<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class.php<
|
||||
Key[line] => >69<
|
||||
Key[function] => >fL2<
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[2]:
|
||||
Key[file] => >%s/exception_handling/exception_class.php<
|
||||
Key[line] => >140<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL3: In finally-block
|
||||
fL3: Beyond try/catch/finally blocks
|
||||
==========
|
|
@ -0,0 +1,372 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/exception_class_experiment_1.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
// trying to see if the supposed initial value for $message in Exception
|
||||
// ('Unknown exception') is ever used. I can;t get it to appear.
|
||||
// If I construct a Exception, the passed-in or default "" gets used. If I subclass
|
||||
// Exception, whether I define a constructor for that class or not, the base
|
||||
// class constructor appears to be called anyway, and overwrites the supposed unknown.
|
||||
|
||||
class MyEx extends Exception {
|
||||
|
||||
public function __construct() {} // does nothing; possibly the superclass's
|
||||
// constructor isn't called implicitly either
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function displayExceptionObject(Exception $e)
|
||||
{
|
||||
echo "\$e = >$e<\n"; // calls __toString
|
||||
echo "getMessage: >".$e->getMessage()."<\n";
|
||||
echo "getCode: >".$e->getCode()."<\n";
|
||||
echo "getPrevious: >".$e->getPrevious()."<\n";
|
||||
echo "getFile: >".$e->getFile()."<\n";
|
||||
echo "getLine: >".$e->getLine()."<\n";
|
||||
echo "getTraceAsString: >".$e->getTraceAsString()."<\n";
|
||||
|
||||
$traceInfo = $e->getTrace();
|
||||
var_dump($traceInfo);
|
||||
echo "Trace Info:".((count($traceInfo) == 0) ? " none\n" : "\n");
|
||||
foreach ($traceInfo as $traceInfoKey => $traceLevel) // process all traceback levels
|
||||
{
|
||||
echo "Key[$traceInfoKey]:\n";
|
||||
foreach ($traceLevel as $levelKey => $levelVal) // process one traceback level
|
||||
{
|
||||
if ($levelKey != "args")
|
||||
{
|
||||
echo " Key[$levelKey] => >$levelVal<\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " Key[$levelKey]:\n";
|
||||
foreach ($levelVal as $argKey => $argVal) // process all args for that level
|
||||
{
|
||||
echo " Key[$argKey] => >$argVal<\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function fL1($p1 = -10)
|
||||
{
|
||||
try {
|
||||
echo "fL1: In try-block\n";
|
||||
|
||||
throw new MyEx(); // no message string
|
||||
// throw new Exception("fL1 Message", 123);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL1: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL1: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL1: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL1: Calling fL2\n";
|
||||
$a = -4.5;
|
||||
fL2(2.3, $a); // pass 2nd arg as a non-literal to see how traceback handles it
|
||||
//fL2(2.3); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function fL2($p1, $p2 = -100)
|
||||
{
|
||||
try {
|
||||
echo "fL2: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL2 Message", 234);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL2: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL2: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL2: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL2: Calling fL3\n";
|
||||
$a = "xyz"; $b = NULL; $c = TRUE;
|
||||
fL3($a, $b, $c); // pass args as a non-literal to see how traceback handles them
|
||||
//fL3($a, $b); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function fL3($p1, $p2, $p3 = -1000)
|
||||
{
|
||||
try {
|
||||
echo "fL3: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL3 Message", 345);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL3: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL3: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL3: Beyond try/catch/finally blocks\n==========\n";
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
try {
|
||||
echo "L0: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("L0 Message", -1);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "L0: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "L0: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "L0: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "L0: Calling fL1\n";
|
||||
fL1(10);
|
||||
//fL1(); // see what happens when a default argument value is used
|
||||
--EXPECTF--
|
||||
L0: In try-block
|
||||
L0: In catch-block
|
||||
$e = >Exception: L0 Message in %s/exception_handling/exception_class_experiment_1.php:139
|
||||
Stack trace:
|
||||
#0 {main}<
|
||||
getMessage: >L0 Message<
|
||||
getCode: >-1<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_experiment_1.php<
|
||||
getLine: >139<
|
||||
getTraceAsString: >#0 {main}<
|
||||
array(0) {
|
||||
}
|
||||
Trace Info: none
|
||||
L0: In finally-block
|
||||
L0: Beyond try/catch/finally blocks
|
||||
==========
|
||||
L0: Calling fL1
|
||||
fL1: In try-block
|
||||
fL1: In catch-block
|
||||
$e = >MyEx in %s/exception_handling/exception_class_experiment_1.php:66
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10)
|
||||
#1 {main}<
|
||||
getMessage: ><
|
||||
getCode: >0<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_experiment_1.php<
|
||||
getLine: >66<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10)
|
||||
#1 {main}<
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_experiment_1.php"
|
||||
["line"]=>
|
||||
int(152)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_experiment_1.php<
|
||||
Key[line] => >152<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL1: In finally-block
|
||||
fL1: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL1: Calling fL2
|
||||
fL2: In try-block
|
||||
fL2: In catch-block
|
||||
$e = >Exception: fL2 Message in %s/exception_handling/exception_class_experiment_1.php:93
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_experiment_1.php(81): fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10)
|
||||
#2 {main}<
|
||||
getMessage: >fL2 Message<
|
||||
getCode: >234<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_experiment_1.php<
|
||||
getLine: >93<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_experiment_1.php(81): fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10)
|
||||
#2 {main}<
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_experiment_1.php"
|
||||
["line"]=>
|
||||
int(81)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
float(2.3)
|
||||
[1]=>
|
||||
float(-4.5)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_experiment_1.php"
|
||||
["line"]=>
|
||||
int(152)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_experiment_1.php<
|
||||
Key[line] => >81<
|
||||
Key[function] => >fL2<
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class_experiment_1.php<
|
||||
Key[line] => >152<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL2: In finally-block
|
||||
fL2: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL2: Calling fL3
|
||||
fL3: In try-block
|
||||
fL3: In catch-block
|
||||
$e = >Exception: fL3 Message in %s/exception_handling/exception_class_experiment_1.php:119
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_experiment_1.php(107): fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class_experiment_1.php(81): fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10)
|
||||
#3 {main}<
|
||||
getMessage: >fL3 Message<
|
||||
getCode: >345<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_experiment_1.php<
|
||||
getLine: >119<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_experiment_1.php(107): fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class_experiment_1.php(81): fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10)
|
||||
#3 {main}<
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_experiment_1.php"
|
||||
["line"]=>
|
||||
int(107)
|
||||
["function"]=>
|
||||
string(3) "fL3"
|
||||
["args"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(3) "xyz"
|
||||
[1]=>
|
||||
NULL
|
||||
[2]=>
|
||||
bool(true)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_experiment_1.php"
|
||||
["line"]=>
|
||||
int(81)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
float(2.3)
|
||||
[1]=>
|
||||
float(-4.5)
|
||||
}
|
||||
}
|
||||
[2]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_experiment_1.php"
|
||||
["line"]=>
|
||||
int(152)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_experiment_1.php<
|
||||
Key[line] => >107<
|
||||
Key[function] => >fL3<
|
||||
Key[args]:
|
||||
Key[0] => >xyz<
|
||||
Key[1] => ><
|
||||
Key[2] => >1<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class_experiment_1.php<
|
||||
Key[line] => >81<
|
||||
Key[function] => >fL2<
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[2]:
|
||||
Key[file] => >%s/exception_handling/exception_class_experiment_1.php<
|
||||
Key[line] => >152<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL3: In finally-block
|
||||
fL3: Beyond try/catch/finally blocks
|
||||
==========
|
|
@ -0,0 +1,402 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/exception_class_from_within_a_class.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function displayExceptionObject(Exception $e)
|
||||
{
|
||||
echo "\$e = >$e<\n"; // calls __toString
|
||||
echo "getMessage: >".$e->getMessage()."<\n";
|
||||
echo "getCode: >".$e->getCode()."<\n";
|
||||
echo "getPrevious: >".$e->getPrevious()."<\n";
|
||||
echo "getFile: >".$e->getFile()."<\n";
|
||||
echo "getLine: >".$e->getLine()."<\n";
|
||||
echo "getTraceAsString: >".$e->getTraceAsString()."<\n";
|
||||
|
||||
$traceInfo = $e->getTrace();
|
||||
var_dump($traceInfo);
|
||||
echo "Trace Info:".((count($traceInfo) == 0) ? " none\n" : "\n");
|
||||
foreach ($traceInfo as $traceInfoKey => $traceLevel) // process all traceback levels
|
||||
{
|
||||
echo "Key[$traceInfoKey]:\n";
|
||||
foreach ($traceLevel as $levelKey => $levelVal) // process one traceback level
|
||||
{
|
||||
if ($levelKey != "args")
|
||||
{
|
||||
echo " Key[$levelKey] => >$levelVal<\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " Key[$levelKey]:\n";
|
||||
foreach ($levelVal as $argKey => $argVal) // process all args for that level
|
||||
{
|
||||
echo " Key[$argKey] => >$argVal<\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
class MyClass {
|
||||
|
||||
public function fL1($p1 = -10)
|
||||
{
|
||||
try {
|
||||
echo "fL1: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL1 Message", 123);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL1: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL1: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL1: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL1: Calling fL2\n";
|
||||
$a = -4.5;
|
||||
$this->fL2(2.3, $a); // pass 2nd arg as a non-literal to see how traceback handles it
|
||||
//$this->fL2(2.3); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
public function fL2($p1, $p2 = -100)
|
||||
{
|
||||
try {
|
||||
echo "fL2: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL2 Message", 234);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL2: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL2: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL2: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL2: Calling fL3\n";
|
||||
$a = "xyz"; $b = NULL; $c = TRUE;
|
||||
$this->fL3($a, $b, $c); // pass args as a non-literal to see how traceback handles them
|
||||
//$this->fL3($a, $b); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
public function fL3($p1, $p2, $p3 = -1000)
|
||||
{
|
||||
try {
|
||||
echo "fL3: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL3 Message", 345);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL3: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL3: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL3: Beyond try/catch/finally blocks\n==========\n";
|
||||
}
|
||||
|
||||
} // end of class MyClass
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
try {
|
||||
echo "L0: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("L0 Message", -1);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "L0: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "L0: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "L0: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "L0: Calling fL1\n";
|
||||
|
||||
$o = new MyClass;
|
||||
$o->fL1(10);
|
||||
//$o->fL1(); // see what happens when a default argument value is used
|
||||
--EXPECTF--
|
||||
L0: In try-block
|
||||
L0: In catch-block
|
||||
$e = >Exception: L0 Message in %s/exception_handling/exception_class_from_within_a_class.php:131
|
||||
Stack trace:
|
||||
#0 {main}<
|
||||
getMessage: >L0 Message<
|
||||
getCode: >-1<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
getLine: >131<
|
||||
getTraceAsString: >#0 {main}<
|
||||
array(0) {
|
||||
}
|
||||
Trace Info: none
|
||||
L0: In finally-block
|
||||
L0: Beyond try/catch/finally blocks
|
||||
==========
|
||||
L0: Calling fL1
|
||||
fL1: In try-block
|
||||
fL1: In catch-block
|
||||
$e = >Exception: fL1 Message in %s/exception_handling/exception_class_from_within_a_class.php:57
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10)
|
||||
#1 {main}<
|
||||
getMessage: >fL1 Message<
|
||||
getCode: >123<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
getLine: >57<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10)
|
||||
#1 {main}<
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_from_within_a_class.php"
|
||||
["line"]=>
|
||||
int(146)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["class"]=>
|
||||
string(7) "MyClass"
|
||||
["type"]=>
|
||||
string(2) "->"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
Key[line] => >146<
|
||||
Key[function] => >fL1<
|
||||
Key[class] => >MyClass<
|
||||
Key[type] => >-><
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL1: In finally-block
|
||||
fL1: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL1: Calling fL2
|
||||
fL2: In try-block
|
||||
fL2: In catch-block
|
||||
$e = >Exception: fL2 Message in %s/exception_handling/exception_class_from_within_a_class.php:83
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_from_within_a_class.php(71): MyClass->fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10)
|
||||
#2 {main}<
|
||||
getMessage: >fL2 Message<
|
||||
getCode: >234<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
getLine: >83<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_from_within_a_class.php(71): MyClass->fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10)
|
||||
#2 {main}<
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_from_within_a_class.php"
|
||||
["line"]=>
|
||||
int(71)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["class"]=>
|
||||
string(7) "MyClass"
|
||||
["type"]=>
|
||||
string(2) "->"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
float(2.3)
|
||||
[1]=>
|
||||
float(-4.5)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(6) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_from_within_a_class.php"
|
||||
["line"]=>
|
||||
int(146)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["class"]=>
|
||||
string(7) "MyClass"
|
||||
["type"]=>
|
||||
string(2) "->"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
Key[line] => >71<
|
||||
Key[function] => >fL2<
|
||||
Key[class] => >MyClass<
|
||||
Key[type] => >-><
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
Key[line] => >146<
|
||||
Key[function] => >fL1<
|
||||
Key[class] => >MyClass<
|
||||
Key[type] => >-><
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL2: In finally-block
|
||||
fL2: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL2: Calling fL3
|
||||
fL3: In try-block
|
||||
fL3: In catch-block
|
||||
$e = >Exception: fL3 Message in %s/exception_handling/exception_class_from_within_a_class.php:109
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_from_within_a_class.php(97): MyClass->fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class_from_within_a_class.php(71): MyClass->fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10)
|
||||
#3 {main}<
|
||||
getMessage: >fL3 Message<
|
||||
getCode: >345<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
getLine: >109<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_from_within_a_class.php(97): MyClass->fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class_from_within_a_class.php(71): MyClass->fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10)
|
||||
#3 {main}<
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_from_within_a_class.php"
|
||||
["line"]=>
|
||||
int(97)
|
||||
["function"]=>
|
||||
string(3) "fL3"
|
||||
["class"]=>
|
||||
string(7) "MyClass"
|
||||
["type"]=>
|
||||
string(2) "->"
|
||||
["args"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(3) "xyz"
|
||||
[1]=>
|
||||
NULL
|
||||
[2]=>
|
||||
bool(true)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(6) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_from_within_a_class.php"
|
||||
["line"]=>
|
||||
int(71)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["class"]=>
|
||||
string(7) "MyClass"
|
||||
["type"]=>
|
||||
string(2) "->"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
float(2.3)
|
||||
[1]=>
|
||||
float(-4.5)
|
||||
}
|
||||
}
|
||||
[2]=>
|
||||
array(6) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_from_within_a_class.php"
|
||||
["line"]=>
|
||||
int(146)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["class"]=>
|
||||
string(7) "MyClass"
|
||||
["type"]=>
|
||||
string(2) "->"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
Key[line] => >97<
|
||||
Key[function] => >fL3<
|
||||
Key[class] => >MyClass<
|
||||
Key[type] => >-><
|
||||
Key[args]:
|
||||
Key[0] => >xyz<
|
||||
Key[1] => ><
|
||||
Key[2] => >1<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
Key[line] => >71<
|
||||
Key[function] => >fL2<
|
||||
Key[class] => >MyClass<
|
||||
Key[type] => >-><
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[2]:
|
||||
Key[file] => >%s/exception_handling/exception_class_from_within_a_class.php<
|
||||
Key[line] => >146<
|
||||
Key[function] => >fL1<
|
||||
Key[class] => >MyClass<
|
||||
Key[type] => >-><
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL3: In finally-block
|
||||
fL3: Beyond try/catch/finally blocks
|
||||
==========
|
|
@ -0,0 +1,366 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/exception_class_using_conditional_functions.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function displayExceptionObject(Exception $e)
|
||||
{
|
||||
echo "\$e = >$e<\n"; // calls __toString
|
||||
echo "getMessage: >".$e->getMessage()."<\n";
|
||||
echo "getCode: >".$e->getCode()."<\n";
|
||||
echo "getPrevious: >".$e->getPrevious()."<\n";
|
||||
echo "getFile: >".$e->getFile()."<\n";
|
||||
echo "getLine: >".$e->getLine()."<\n";
|
||||
echo "getTraceAsString: >".$e->getTraceAsString()."<\n";
|
||||
|
||||
$traceInfo = $e->getTrace();
|
||||
var_dump($traceInfo);
|
||||
echo "Trace Info:".((count($traceInfo) == 0) ? " none\n" : "\n");
|
||||
foreach ($traceInfo as $traceInfoKey => $traceLevel) // process all traceback levels
|
||||
{
|
||||
echo "Key[$traceInfoKey]:\n";
|
||||
foreach ($traceLevel as $levelKey => $levelVal) // process one traceback level
|
||||
{
|
||||
if ($levelKey != "args")
|
||||
{
|
||||
echo " Key[$levelKey] => >$levelVal<\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " Key[$levelKey]:\n";
|
||||
foreach ($levelVal as $argKey => $argVal) // process all args for that level
|
||||
{
|
||||
echo " Key[$argKey] => >$argVal<\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function fL1($p1 = -10)
|
||||
{
|
||||
|
||||
// define fL2 inside fL1
|
||||
|
||||
function fL2($p1, $p2 = -100)
|
||||
{
|
||||
|
||||
// define fL3 inside fL2
|
||||
|
||||
function fL3($p1, $p2, $p3 = -1000)
|
||||
{
|
||||
try {
|
||||
echo "fL3: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL3 Message", 345);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL3: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL3: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "fL3: Beyond try/catch/finally blocks\n==========\n";
|
||||
}
|
||||
|
||||
try {
|
||||
echo "fL2: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL2 Message", 234);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL2: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL2: In finally-block\n";
|
||||
}
|
||||
|
||||
// fL2 definition continues here
|
||||
|
||||
echo "fL2: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL2: Calling fL3\n";
|
||||
$a = "xyz"; $b = NULL; $c = TRUE;
|
||||
fL3($a, $b, $c); // pass args as a non-literal to see how traceback handles them
|
||||
//fL3($a, $b); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
try {
|
||||
echo "fL1: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("fL1 Message", 123);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "fL1: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "fL1: In finally-block\n";
|
||||
}
|
||||
|
||||
// fL1 definition continues here
|
||||
|
||||
echo "fL1: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "fL1: Calling fL2\n";
|
||||
$a = -4.5;
|
||||
fL2(2.3, $a); // pass 2nd arg as a non-literal to see how traceback handles it
|
||||
// fL2(2.3); // see what happens when a default argument value is used
|
||||
}
|
||||
|
||||
// main script definition continues here
|
||||
|
||||
try {
|
||||
echo "L0: In try-block\n";
|
||||
|
||||
// throw new Exception();
|
||||
throw new Exception("L0 Message", -1);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "L0: In catch-block\n";
|
||||
|
||||
displayExceptionObject($e);
|
||||
}
|
||||
finally {
|
||||
echo "L0: In finally-block\n";
|
||||
}
|
||||
|
||||
echo "L0: Beyond try/catch/finally blocks\n==========\n";
|
||||
echo "L0: Calling fL1\n";
|
||||
fL1(10);
|
||||
//fL1(); // see what happens when a default argument value is used
|
||||
--EXPECTF--
|
||||
L0: In try-block
|
||||
L0: In catch-block
|
||||
$e = >Exception: L0 Message in %s/exception_handling/exception_class_using_conditional_functions.php:133
|
||||
Stack trace:
|
||||
#0 {main}<
|
||||
getMessage: >L0 Message<
|
||||
getCode: >-1<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
getLine: >133<
|
||||
getTraceAsString: >#0 {main}<
|
||||
array(0) {
|
||||
}
|
||||
Trace Info: none
|
||||
L0: In finally-block
|
||||
L0: Beyond try/catch/finally blocks
|
||||
==========
|
||||
L0: Calling fL1
|
||||
fL1: In try-block
|
||||
fL1: In catch-block
|
||||
$e = >Exception: fL1 Message in %s/exception_handling/exception_class_using_conditional_functions.php:107
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10)
|
||||
#1 {main}<
|
||||
getMessage: >fL1 Message<
|
||||
getCode: >123<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
getLine: >107<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10)
|
||||
#1 {main}<
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_using_conditional_functions.php"
|
||||
["line"]=>
|
||||
int(146)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
Key[line] => >146<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL1: In finally-block
|
||||
fL1: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL1: Calling fL2
|
||||
fL2: In try-block
|
||||
fL2: In catch-block
|
||||
$e = >Exception: fL2 Message in %s/exception_handling/exception_class_using_conditional_functions.php:83
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_using_conditional_functions.php(123): fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10)
|
||||
#2 {main}<
|
||||
getMessage: >fL2 Message<
|
||||
getCode: >234<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
getLine: >83<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_using_conditional_functions.php(123): fL2(2.3, -4.5)
|
||||
#1 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10)
|
||||
#2 {main}<
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_using_conditional_functions.php"
|
||||
["line"]=>
|
||||
int(123)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
float(2.3)
|
||||
[1]=>
|
||||
float(-4.5)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_using_conditional_functions.php"
|
||||
["line"]=>
|
||||
int(146)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
Key[line] => >123<
|
||||
Key[function] => >fL2<
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
Key[line] => >146<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL2: In finally-block
|
||||
fL2: Beyond try/catch/finally blocks
|
||||
==========
|
||||
fL2: Calling fL3
|
||||
fL3: In try-block
|
||||
fL3: In catch-block
|
||||
$e = >Exception: fL3 Message in %s/exception_handling/exception_class_using_conditional_functions.php:65
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/exception_class_using_conditional_functions.php(99): fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class_using_conditional_functions.php(123): fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10)
|
||||
#3 {main}<
|
||||
getMessage: >fL3 Message<
|
||||
getCode: >345<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
getLine: >65<
|
||||
getTraceAsString: >#0 %s/exception_handling/exception_class_using_conditional_functions.php(99): fL3('xyz', NULL, true)
|
||||
#1 %s/exception_handling/exception_class_using_conditional_functions.php(123): fL2(2.3, -4.5)
|
||||
#2 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10)
|
||||
#3 {main}<
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_using_conditional_functions.php"
|
||||
["line"]=>
|
||||
int(99)
|
||||
["function"]=>
|
||||
string(3) "fL3"
|
||||
["args"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(3) "xyz"
|
||||
[1]=>
|
||||
NULL
|
||||
[2]=>
|
||||
bool(true)
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_using_conditional_functions.php"
|
||||
["line"]=>
|
||||
int(123)
|
||||
["function"]=>
|
||||
string(3) "fL2"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
float(2.3)
|
||||
[1]=>
|
||||
float(-4.5)
|
||||
}
|
||||
}
|
||||
[2]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/exception_class_using_conditional_functions.php"
|
||||
["line"]=>
|
||||
int(146)
|
||||
["function"]=>
|
||||
string(3) "fL1"
|
||||
["args"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
Key[line] => >99<
|
||||
Key[function] => >fL3<
|
||||
Key[args]:
|
||||
Key[0] => >xyz<
|
||||
Key[1] => ><
|
||||
Key[2] => >1<
|
||||
Key[1]:
|
||||
Key[file] => >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
Key[line] => >123<
|
||||
Key[function] => >fL2<
|
||||
Key[args]:
|
||||
Key[0] => >2.3<
|
||||
Key[1] => >-4.5<
|
||||
Key[2]:
|
||||
Key[file] => >%s/exception_handling/exception_class_using_conditional_functions.php<
|
||||
Key[line] => >146<
|
||||
Key[function] => >fL1<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
fL3: In finally-block
|
||||
fL3: Beyond try/catch/finally blocks
|
||||
==========
|
|
@ -0,0 +1,71 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/hierarchy_of_exception_classes.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class DeviceException extends Exception { /*...*/ }
|
||||
class DiskException extends DeviceException { /*...*/ }
|
||||
class RemovableDiskException extends DiskException { /*...*/ }
|
||||
class FloppyDiskException extends RemovableDiskException { /*...*/ }
|
||||
|
||||
function process()
|
||||
{
|
||||
throw new DeviceException;
|
||||
// throw new Exception;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
process(); // call a function that might generate disk-related exception
|
||||
}
|
||||
/*
|
||||
|
||||
// see if compiler complains (ala C#) if there are unreachable catch clauses by putting
|
||||
// the ultimate base exception class first. It does not.
|
||||
|
||||
catch (Exception $e) {
|
||||
echo "In handler for Exception\n";
|
||||
// ...
|
||||
}
|
||||
*/
|
||||
catch (FloppyDiskException $fde)
|
||||
{
|
||||
echo "In handler for FloppyDiskException\n";
|
||||
// ...
|
||||
}
|
||||
catch (RemovableDiskException $rde)
|
||||
{
|
||||
echo "In handler for RemovableDiskException\n";
|
||||
// ...
|
||||
}
|
||||
catch (DiskException $de)
|
||||
{
|
||||
echo "In handler for DiskException\n";
|
||||
// ...
|
||||
}
|
||||
catch (DeviceException $dve) {
|
||||
echo "In handler for DeviceException\n";
|
||||
// ...
|
||||
}
|
||||
///*
|
||||
catch (Exception $e) {
|
||||
echo "In handler for Exception\n";
|
||||
// ...
|
||||
}
|
||||
//*/
|
||||
finally
|
||||
{
|
||||
echo "In finally block\n";
|
||||
// perform some cleanup
|
||||
}
|
||||
--EXPECT--
|
||||
In handler for DeviceException
|
||||
In finally block
|
|
@ -0,0 +1,59 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/jump_from_catch_or_finally_clause.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
function msg()
|
||||
{
|
||||
echo "In msg\n";
|
||||
return 999;
|
||||
}
|
||||
|
||||
function f()
|
||||
{
|
||||
for ($i = 1; $i < 3; ++$i)
|
||||
{
|
||||
try
|
||||
{
|
||||
throw new Exception;
|
||||
}
|
||||
///*
|
||||
catch (Exception $e) {
|
||||
echo "In handler for Exception\n";
|
||||
// break; // allowed
|
||||
// continue; // allowed
|
||||
// goto end; // allowed
|
||||
// return msg(); // expression is evaluated, but value actually returned
|
||||
// when both returns exist is 20, from finally block,
|
||||
}
|
||||
//*/
|
||||
finally
|
||||
{
|
||||
echo "In finally block\n";
|
||||
// break; // not allowed
|
||||
// continue; // not allowed
|
||||
// goto end; // not allowed
|
||||
// return 20; // if the catch-block is omitted, this returns control to the
|
||||
// caller, and the exception currently uncaught is discarded.
|
||||
}
|
||||
}
|
||||
end:
|
||||
return 1;
|
||||
}
|
||||
|
||||
$r = f();
|
||||
var_dump($r);
|
||||
--EXPECT--
|
||||
In handler for Exception
|
||||
In finally block
|
||||
In handler for Exception
|
||||
In finally block
|
||||
int(1)
|
|
@ -0,0 +1,49 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/myrangeexception_test1.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
include_once 'MyRangeException.inc';
|
||||
|
||||
$re = new MyRangeException("xxx", 5, 20, 30);
|
||||
var_dump($re);
|
||||
|
||||
echo "=======\n";
|
||||
|
||||
echo "\$re = >$re<\n";
|
||||
--EXPECTF--
|
||||
object(MyRangeException)#1 (10) {
|
||||
["badValue":"MyRangeException":private]=>
|
||||
int(5)
|
||||
["lowerValue":"MyRangeException":private]=>
|
||||
int(20)
|
||||
["upperValue":"MyRangeException":private]=>
|
||||
int(30)
|
||||
["message":protected]=>
|
||||
string(3) "xxx"
|
||||
["string":"Exception":private]=>
|
||||
string(0) ""
|
||||
["code":protected]=>
|
||||
int(0)
|
||||
["file":protected]=>
|
||||
string(%d) "%s/exception_handling/myrangeexception_test1.php"
|
||||
["line":protected]=>
|
||||
int(13)
|
||||
["trace":"Exception":private]=>
|
||||
array(0) {
|
||||
}
|
||||
["previous":"Exception":private]=>
|
||||
NULL
|
||||
}
|
||||
=======
|
||||
$re = >MyRangeException: xxx in %s/exception_handling/myrangeexception_test1.php:13
|
||||
Stack trace:
|
||||
#0 {main}, badValue: 5, lowerValue: 20, upperValue: 30<
|
|
@ -0,0 +1,85 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/odds_and_ends.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
class X {} // not derived from Exception
|
||||
|
||||
try {
|
||||
echo "L0: In try-block\n";
|
||||
|
||||
// throw 10; // Diagnosed; good
|
||||
// throw new X; // Diagnosed; good
|
||||
throw new Exception();
|
||||
}
|
||||
//*/
|
||||
///*
|
||||
catch (int $e) { // Not diagnosed; bad
|
||||
echo "L0: In catch-block int\n";
|
||||
}
|
||||
//*/
|
||||
///*
|
||||
catch (X $e) { // Not diagnosed; bad
|
||||
echo "L0: In catch-block int\n";
|
||||
}
|
||||
//*/
|
||||
///*
|
||||
catch (Exception $e) {
|
||||
echo "L0: In catch-block Exception\n";
|
||||
|
||||
// throw $e;
|
||||
// throw new Exception;
|
||||
// throw; // can't re-throw current exception ala C#, C++
|
||||
}
|
||||
//*/
|
||||
/*
|
||||
finally {
|
||||
echo "L0: In finally-block\n";
|
||||
}
|
||||
*/
|
||||
|
||||
echo "Try catch byRef\n";
|
||||
|
||||
class Except extends Exception
|
||||
{
|
||||
public $prop = 0;
|
||||
}
|
||||
|
||||
$o = new Except();
|
||||
echo "\$o->prop = " . $o->prop . "\n";
|
||||
|
||||
try
|
||||
{
|
||||
echo "In try-block\n";
|
||||
|
||||
throw new Except();
|
||||
|
||||
echo "End of try-block\n";
|
||||
}
|
||||
catch (Except /*&*/ $e)
|
||||
{
|
||||
echo "In catch-block Except\n";
|
||||
echo "\$e->prop = " . $e->prop . "\n";
|
||||
$e->prop = 999;
|
||||
echo "\$e->prop = " . $e->prop . "\n";
|
||||
}
|
||||
|
||||
echo "\$o->prop = " . $o->prop . "\n";
|
||||
--EXPECT--
|
||||
L0: In try-block
|
||||
L0: In catch-block Exception
|
||||
Try catch byRef
|
||||
$o->prop = 0
|
||||
In try-block
|
||||
In catch-block Except
|
||||
$e->prop = 0
|
||||
$e->prop = 999
|
||||
$o->prop = 0
|
|
@ -0,0 +1,139 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./exception_handling/set_exception_handler.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
function displayExceptionObject(Exception $e)
|
||||
{
|
||||
echo "\$e = >$e<\n"; // calls __toString
|
||||
echo "getMessage: >".$e->getMessage()."<\n";
|
||||
echo "getCode: >".$e->getCode()."<\n";
|
||||
echo "getPrevious: >".$e->getPrevious()."<\n";
|
||||
echo "getFile: >".$e->getFile()."<\n";
|
||||
echo "getLine: >".$e->getLine()."<\n";
|
||||
echo "getTraceAsString: >".$e->getTraceAsString()."<\n";
|
||||
|
||||
$traceInfo = $e->getTrace();
|
||||
var_dump($traceInfo);
|
||||
echo "Trace Info:".((count($traceInfo) == 0) ? " none\n" : "\n");
|
||||
foreach ($traceInfo as $traceInfoKey => $traceLevel) // process all traceback levels
|
||||
{
|
||||
echo "Key[$traceInfoKey]:\n";
|
||||
foreach ($traceLevel as $levelKey => $levelVal) // process one traceback level
|
||||
{
|
||||
if ($levelKey != "args")
|
||||
{
|
||||
echo " Key[$levelKey] => >$levelVal<\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " Key[$levelKey]:\n";
|
||||
foreach ($levelVal as $argKey => $argVal) // process all args for that level
|
||||
{
|
||||
echo " Key[$argKey] => >$argVal<\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
$prev = set_exception_handler(NULL); // set to default handler
|
||||
var_dump($prev);
|
||||
|
||||
// define a default un-caught exception handler
|
||||
|
||||
function MyDefExHandler(Exception $e)
|
||||
{
|
||||
echo "In MyDefExHandler\n";
|
||||
displayExceptionObject($e);
|
||||
echo "Leaving MyDefExHandler\n";
|
||||
}
|
||||
|
||||
// establish a new un-caught exception handler
|
||||
|
||||
$prev = set_exception_handler("MyDefExHandler"); // use my handler
|
||||
var_dump($prev);
|
||||
|
||||
// try it out
|
||||
|
||||
function f($p1, $p2)
|
||||
{
|
||||
try {
|
||||
echo "In try-block\n";
|
||||
|
||||
throw new Exception("Watson, come here!", 1234);
|
||||
}
|
||||
|
||||
// no catch block(s)
|
||||
|
||||
finally {
|
||||
echo "In finally-block\n";
|
||||
}
|
||||
|
||||
echo "Beyond try/catch/finally blocks\n==========\n";
|
||||
}
|
||||
|
||||
/*
|
||||
restore_exception_handler();
|
||||
*/
|
||||
|
||||
echo "About to call f\n";
|
||||
f(10, TRUE);
|
||||
echo "Beyond the call to f()\n"; // never gets here; script terminates after my handler ends
|
||||
--EXPECTF--
|
||||
NULL
|
||||
NULL
|
||||
About to call f
|
||||
In try-block
|
||||
In finally-block
|
||||
In MyDefExHandler
|
||||
$e = >Exception: Watson, come here! in %s/exception_handling/set_exception_handler.php:73
|
||||
Stack trace:
|
||||
#0 %s/exception_handling/set_exception_handler.php(90): f(10, true)
|
||||
#1 {main}<
|
||||
getMessage: >Watson, come here!<
|
||||
getCode: >1234<
|
||||
getPrevious: ><
|
||||
getFile: >%s/exception_handling/set_exception_handler.php<
|
||||
getLine: >73<
|
||||
getTraceAsString: >#0 %s/exception_handling/set_exception_handler.php(90): f(10, true)
|
||||
#1 {main}<
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["file"]=>
|
||||
string(%d) "%s/exception_handling/set_exception_handler.php"
|
||||
["line"]=>
|
||||
int(90)
|
||||
["function"]=>
|
||||
string(1) "f"
|
||||
["args"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(10)
|
||||
[1]=>
|
||||
bool(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
Trace Info:
|
||||
Key[0]:
|
||||
Key[file] => >%s/exception_handling/set_exception_handler.php<
|
||||
Key[line] => >90<
|
||||
Key[function] => >f<
|
||||
Key[args]:
|
||||
Key[0] => >10<
|
||||
Key[1] => >1<
|
||||
Leaving MyDefExHandler
|
|
@ -0,0 +1,291 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./expressions/additive_operators/addition_subtraction_concatenation.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
$oper = array(0, -10, 100, -3.4e10, INF, -INF, NAN, TRUE, FALSE, NULL,
|
||||
"123", "2e+5", "", "abc", PHP_INT_MAX );
|
||||
/*
|
||||
foreach ($oper as $e1)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
echo ">$e1< + >$e2<, result: "; var_dump($e1 + $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
*/
|
||||
/*
|
||||
foreach ($oper as $e1)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
echo ">$e1< - >$e2<, result: "; var_dump($e1 - $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
*/
|
||||
///*
|
||||
foreach ($oper as $e1)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
echo ">$e1< . >$e2<, result: "; var_dump($e1 . $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
//*/
|
||||
|
||||
var_dump(10 + 5 . 12 . 100 - 50);
|
||||
var_dump((((10 + 5) . 12) . 100) - 50);
|
||||
--EXPECT--
|
||||
>0< . >0<, result: string(2) "00"
|
||||
>0< . >-10<, result: string(4) "0-10"
|
||||
>0< . >100<, result: string(4) "0100"
|
||||
>0< . >-34000000000<, result: string(13) "0-34000000000"
|
||||
>0< . >INF<, result: string(4) "0INF"
|
||||
>0< . >-INF<, result: string(5) "0-INF"
|
||||
>0< . >NAN<, result: string(4) "0NAN"
|
||||
>0< . >1<, result: string(2) "01"
|
||||
>0< . ><, result: string(1) "0"
|
||||
>0< . ><, result: string(1) "0"
|
||||
>0< . >123<, result: string(4) "0123"
|
||||
>0< . >2e+5<, result: string(5) "02e+5"
|
||||
>0< . ><, result: string(1) "0"
|
||||
>0< . >abc<, result: string(4) "0abc"
|
||||
>0< . >9223372036854775807<, result: string(20) "09223372036854775807"
|
||||
-------------------------------------
|
||||
>-10< . >0<, result: string(4) "-100"
|
||||
>-10< . >-10<, result: string(6) "-10-10"
|
||||
>-10< . >100<, result: string(6) "-10100"
|
||||
>-10< . >-34000000000<, result: string(15) "-10-34000000000"
|
||||
>-10< . >INF<, result: string(6) "-10INF"
|
||||
>-10< . >-INF<, result: string(7) "-10-INF"
|
||||
>-10< . >NAN<, result: string(6) "-10NAN"
|
||||
>-10< . >1<, result: string(4) "-101"
|
||||
>-10< . ><, result: string(3) "-10"
|
||||
>-10< . ><, result: string(3) "-10"
|
||||
>-10< . >123<, result: string(6) "-10123"
|
||||
>-10< . >2e+5<, result: string(7) "-102e+5"
|
||||
>-10< . ><, result: string(3) "-10"
|
||||
>-10< . >abc<, result: string(6) "-10abc"
|
||||
>-10< . >9223372036854775807<, result: string(22) "-109223372036854775807"
|
||||
-------------------------------------
|
||||
>100< . >0<, result: string(4) "1000"
|
||||
>100< . >-10<, result: string(6) "100-10"
|
||||
>100< . >100<, result: string(6) "100100"
|
||||
>100< . >-34000000000<, result: string(15) "100-34000000000"
|
||||
>100< . >INF<, result: string(6) "100INF"
|
||||
>100< . >-INF<, result: string(7) "100-INF"
|
||||
>100< . >NAN<, result: string(6) "100NAN"
|
||||
>100< . >1<, result: string(4) "1001"
|
||||
>100< . ><, result: string(3) "100"
|
||||
>100< . ><, result: string(3) "100"
|
||||
>100< . >123<, result: string(6) "100123"
|
||||
>100< . >2e+5<, result: string(7) "1002e+5"
|
||||
>100< . ><, result: string(3) "100"
|
||||
>100< . >abc<, result: string(6) "100abc"
|
||||
>100< . >9223372036854775807<, result: string(22) "1009223372036854775807"
|
||||
-------------------------------------
|
||||
>-34000000000< . >0<, result: string(13) "-340000000000"
|
||||
>-34000000000< . >-10<, result: string(15) "-34000000000-10"
|
||||
>-34000000000< . >100<, result: string(15) "-34000000000100"
|
||||
>-34000000000< . >-34000000000<, result: string(24) "-34000000000-34000000000"
|
||||
>-34000000000< . >INF<, result: string(15) "-34000000000INF"
|
||||
>-34000000000< . >-INF<, result: string(16) "-34000000000-INF"
|
||||
>-34000000000< . >NAN<, result: string(15) "-34000000000NAN"
|
||||
>-34000000000< . >1<, result: string(13) "-340000000001"
|
||||
>-34000000000< . ><, result: string(12) "-34000000000"
|
||||
>-34000000000< . ><, result: string(12) "-34000000000"
|
||||
>-34000000000< . >123<, result: string(15) "-34000000000123"
|
||||
>-34000000000< . >2e+5<, result: string(16) "-340000000002e+5"
|
||||
>-34000000000< . ><, result: string(12) "-34000000000"
|
||||
>-34000000000< . >abc<, result: string(15) "-34000000000abc"
|
||||
>-34000000000< . >9223372036854775807<, result: string(31) "-340000000009223372036854775807"
|
||||
-------------------------------------
|
||||
>INF< . >0<, result: string(4) "INF0"
|
||||
>INF< . >-10<, result: string(6) "INF-10"
|
||||
>INF< . >100<, result: string(6) "INF100"
|
||||
>INF< . >-34000000000<, result: string(15) "INF-34000000000"
|
||||
>INF< . >INF<, result: string(6) "INFINF"
|
||||
>INF< . >-INF<, result: string(7) "INF-INF"
|
||||
>INF< . >NAN<, result: string(6) "INFNAN"
|
||||
>INF< . >1<, result: string(4) "INF1"
|
||||
>INF< . ><, result: string(3) "INF"
|
||||
>INF< . ><, result: string(3) "INF"
|
||||
>INF< . >123<, result: string(6) "INF123"
|
||||
>INF< . >2e+5<, result: string(7) "INF2e+5"
|
||||
>INF< . ><, result: string(3) "INF"
|
||||
>INF< . >abc<, result: string(6) "INFabc"
|
||||
>INF< . >9223372036854775807<, result: string(22) "INF9223372036854775807"
|
||||
-------------------------------------
|
||||
>-INF< . >0<, result: string(5) "-INF0"
|
||||
>-INF< . >-10<, result: string(7) "-INF-10"
|
||||
>-INF< . >100<, result: string(7) "-INF100"
|
||||
>-INF< . >-34000000000<, result: string(16) "-INF-34000000000"
|
||||
>-INF< . >INF<, result: string(7) "-INFINF"
|
||||
>-INF< . >-INF<, result: string(8) "-INF-INF"
|
||||
>-INF< . >NAN<, result: string(7) "-INFNAN"
|
||||
>-INF< . >1<, result: string(5) "-INF1"
|
||||
>-INF< . ><, result: string(4) "-INF"
|
||||
>-INF< . ><, result: string(4) "-INF"
|
||||
>-INF< . >123<, result: string(7) "-INF123"
|
||||
>-INF< . >2e+5<, result: string(8) "-INF2e+5"
|
||||
>-INF< . ><, result: string(4) "-INF"
|
||||
>-INF< . >abc<, result: string(7) "-INFabc"
|
||||
>-INF< . >9223372036854775807<, result: string(23) "-INF9223372036854775807"
|
||||
-------------------------------------
|
||||
>NAN< . >0<, result: string(4) "NAN0"
|
||||
>NAN< . >-10<, result: string(6) "NAN-10"
|
||||
>NAN< . >100<, result: string(6) "NAN100"
|
||||
>NAN< . >-34000000000<, result: string(15) "NAN-34000000000"
|
||||
>NAN< . >INF<, result: string(6) "NANINF"
|
||||
>NAN< . >-INF<, result: string(7) "NAN-INF"
|
||||
>NAN< . >NAN<, result: string(6) "NANNAN"
|
||||
>NAN< . >1<, result: string(4) "NAN1"
|
||||
>NAN< . ><, result: string(3) "NAN"
|
||||
>NAN< . ><, result: string(3) "NAN"
|
||||
>NAN< . >123<, result: string(6) "NAN123"
|
||||
>NAN< . >2e+5<, result: string(7) "NAN2e+5"
|
||||
>NAN< . ><, result: string(3) "NAN"
|
||||
>NAN< . >abc<, result: string(6) "NANabc"
|
||||
>NAN< . >9223372036854775807<, result: string(22) "NAN9223372036854775807"
|
||||
-------------------------------------
|
||||
>1< . >0<, result: string(2) "10"
|
||||
>1< . >-10<, result: string(4) "1-10"
|
||||
>1< . >100<, result: string(4) "1100"
|
||||
>1< . >-34000000000<, result: string(13) "1-34000000000"
|
||||
>1< . >INF<, result: string(4) "1INF"
|
||||
>1< . >-INF<, result: string(5) "1-INF"
|
||||
>1< . >NAN<, result: string(4) "1NAN"
|
||||
>1< . >1<, result: string(2) "11"
|
||||
>1< . ><, result: string(1) "1"
|
||||
>1< . ><, result: string(1) "1"
|
||||
>1< . >123<, result: string(4) "1123"
|
||||
>1< . >2e+5<, result: string(5) "12e+5"
|
||||
>1< . ><, result: string(1) "1"
|
||||
>1< . >abc<, result: string(4) "1abc"
|
||||
>1< . >9223372036854775807<, result: string(20) "19223372036854775807"
|
||||
-------------------------------------
|
||||
>< . >0<, result: string(1) "0"
|
||||
>< . >-10<, result: string(3) "-10"
|
||||
>< . >100<, result: string(3) "100"
|
||||
>< . >-34000000000<, result: string(12) "-34000000000"
|
||||
>< . >INF<, result: string(3) "INF"
|
||||
>< . >-INF<, result: string(4) "-INF"
|
||||
>< . >NAN<, result: string(3) "NAN"
|
||||
>< . >1<, result: string(1) "1"
|
||||
>< . ><, result: string(0) ""
|
||||
>< . ><, result: string(0) ""
|
||||
>< . >123<, result: string(3) "123"
|
||||
>< . >2e+5<, result: string(4) "2e+5"
|
||||
>< . ><, result: string(0) ""
|
||||
>< . >abc<, result: string(3) "abc"
|
||||
>< . >9223372036854775807<, result: string(19) "9223372036854775807"
|
||||
-------------------------------------
|
||||
>< . >0<, result: string(1) "0"
|
||||
>< . >-10<, result: string(3) "-10"
|
||||
>< . >100<, result: string(3) "100"
|
||||
>< . >-34000000000<, result: string(12) "-34000000000"
|
||||
>< . >INF<, result: string(3) "INF"
|
||||
>< . >-INF<, result: string(4) "-INF"
|
||||
>< . >NAN<, result: string(3) "NAN"
|
||||
>< . >1<, result: string(1) "1"
|
||||
>< . ><, result: string(0) ""
|
||||
>< . ><, result: string(0) ""
|
||||
>< . >123<, result: string(3) "123"
|
||||
>< . >2e+5<, result: string(4) "2e+5"
|
||||
>< . ><, result: string(0) ""
|
||||
>< . >abc<, result: string(3) "abc"
|
||||
>< . >9223372036854775807<, result: string(19) "9223372036854775807"
|
||||
-------------------------------------
|
||||
>123< . >0<, result: string(4) "1230"
|
||||
>123< . >-10<, result: string(6) "123-10"
|
||||
>123< . >100<, result: string(6) "123100"
|
||||
>123< . >-34000000000<, result: string(15) "123-34000000000"
|
||||
>123< . >INF<, result: string(6) "123INF"
|
||||
>123< . >-INF<, result: string(7) "123-INF"
|
||||
>123< . >NAN<, result: string(6) "123NAN"
|
||||
>123< . >1<, result: string(4) "1231"
|
||||
>123< . ><, result: string(3) "123"
|
||||
>123< . ><, result: string(3) "123"
|
||||
>123< . >123<, result: string(6) "123123"
|
||||
>123< . >2e+5<, result: string(7) "1232e+5"
|
||||
>123< . ><, result: string(3) "123"
|
||||
>123< . >abc<, result: string(6) "123abc"
|
||||
>123< . >9223372036854775807<, result: string(22) "1239223372036854775807"
|
||||
-------------------------------------
|
||||
>2e+5< . >0<, result: string(5) "2e+50"
|
||||
>2e+5< . >-10<, result: string(7) "2e+5-10"
|
||||
>2e+5< . >100<, result: string(7) "2e+5100"
|
||||
>2e+5< . >-34000000000<, result: string(16) "2e+5-34000000000"
|
||||
>2e+5< . >INF<, result: string(7) "2e+5INF"
|
||||
>2e+5< . >-INF<, result: string(8) "2e+5-INF"
|
||||
>2e+5< . >NAN<, result: string(7) "2e+5NAN"
|
||||
>2e+5< . >1<, result: string(5) "2e+51"
|
||||
>2e+5< . ><, result: string(4) "2e+5"
|
||||
>2e+5< . ><, result: string(4) "2e+5"
|
||||
>2e+5< . >123<, result: string(7) "2e+5123"
|
||||
>2e+5< . >2e+5<, result: string(8) "2e+52e+5"
|
||||
>2e+5< . ><, result: string(4) "2e+5"
|
||||
>2e+5< . >abc<, result: string(7) "2e+5abc"
|
||||
>2e+5< . >9223372036854775807<, result: string(23) "2e+59223372036854775807"
|
||||
-------------------------------------
|
||||
>< . >0<, result: string(1) "0"
|
||||
>< . >-10<, result: string(3) "-10"
|
||||
>< . >100<, result: string(3) "100"
|
||||
>< . >-34000000000<, result: string(12) "-34000000000"
|
||||
>< . >INF<, result: string(3) "INF"
|
||||
>< . >-INF<, result: string(4) "-INF"
|
||||
>< . >NAN<, result: string(3) "NAN"
|
||||
>< . >1<, result: string(1) "1"
|
||||
>< . ><, result: string(0) ""
|
||||
>< . ><, result: string(0) ""
|
||||
>< . >123<, result: string(3) "123"
|
||||
>< . >2e+5<, result: string(4) "2e+5"
|
||||
>< . ><, result: string(0) ""
|
||||
>< . >abc<, result: string(3) "abc"
|
||||
>< . >9223372036854775807<, result: string(19) "9223372036854775807"
|
||||
-------------------------------------
|
||||
>abc< . >0<, result: string(4) "abc0"
|
||||
>abc< . >-10<, result: string(6) "abc-10"
|
||||
>abc< . >100<, result: string(6) "abc100"
|
||||
>abc< . >-34000000000<, result: string(15) "abc-34000000000"
|
||||
>abc< . >INF<, result: string(6) "abcINF"
|
||||
>abc< . >-INF<, result: string(7) "abc-INF"
|
||||
>abc< . >NAN<, result: string(6) "abcNAN"
|
||||
>abc< . >1<, result: string(4) "abc1"
|
||||
>abc< . ><, result: string(3) "abc"
|
||||
>abc< . ><, result: string(3) "abc"
|
||||
>abc< . >123<, result: string(6) "abc123"
|
||||
>abc< . >2e+5<, result: string(7) "abc2e+5"
|
||||
>abc< . ><, result: string(3) "abc"
|
||||
>abc< . >abc<, result: string(6) "abcabc"
|
||||
>abc< . >9223372036854775807<, result: string(22) "abc9223372036854775807"
|
||||
-------------------------------------
|
||||
>9223372036854775807< . >0<, result: string(20) "92233720368547758070"
|
||||
>9223372036854775807< . >-10<, result: string(22) "9223372036854775807-10"
|
||||
>9223372036854775807< . >100<, result: string(22) "9223372036854775807100"
|
||||
>9223372036854775807< . >-34000000000<, result: string(31) "9223372036854775807-34000000000"
|
||||
>9223372036854775807< . >INF<, result: string(22) "9223372036854775807INF"
|
||||
>9223372036854775807< . >-INF<, result: string(23) "9223372036854775807-INF"
|
||||
>9223372036854775807< . >NAN<, result: string(22) "9223372036854775807NAN"
|
||||
>9223372036854775807< . >1<, result: string(20) "92233720368547758071"
|
||||
>9223372036854775807< . ><, result: string(19) "9223372036854775807"
|
||||
>9223372036854775807< . ><, result: string(19) "9223372036854775807"
|
||||
>9223372036854775807< . >123<, result: string(22) "9223372036854775807123"
|
||||
>9223372036854775807< . >2e+5<, result: string(23) "92233720368547758072e+5"
|
||||
>9223372036854775807< . ><, result: string(19) "9223372036854775807"
|
||||
>9223372036854775807< . >abc<, result: string(22) "9223372036854775807abc"
|
||||
>9223372036854775807< . >9223372036854775807<, result: string(38) "92233720368547758079223372036854775807"
|
||||
-------------------------------------
|
||||
int(1512050)
|
||||
int(1512050)
|
|
@ -0,0 +1,207 @@
|
|||
--TEST--
|
||||
PHP Spec test generated from ./expressions/additive_operators/array_concatenation.php
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-------------------------------------------------------------+
|
||||
| Copyright (c) 2014 Facebook, Inc. (http://www.facebook.com) |
|
||||
+-------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
///*
|
||||
$oper = array([1, 5 => FALSE, "red"], [NULL], [4 => -5, 1.23]);
|
||||
|
||||
foreach ($oper as $e1)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
echo ">$e1< + >$e2<, result: "; var_dump($e1 + $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
//*/
|
||||
|
||||
/*
|
||||
// the following LHS-operands all have "Unsupported operand types"
|
||||
|
||||
-10 + [1, 5 => FALSE, "red"];
|
||||
3.4e10 + [1, 5 => FALSE, "red"];
|
||||
TRUE + [1, 5 => FALSE, "red"];
|
||||
NULL + [1, 5 => FALSE, "red"];
|
||||
"" + [1, 5 => FALSE, "red"];
|
||||
"123" + [1, 5 => FALSE, "red"];
|
||||
|
||||
// likewise for the following RHS-operands
|
||||
|
||||
[1, 5 => FALSE, "red"] + -10;
|
||||
[1, 5 => FALSE, "red"] + 3.4e10;
|
||||
[1, 5 => FALSE, "red"] + TRUE;
|
||||
[1, 5 => FALSE, "red"] + NULL;
|
||||
[1, 5 => FALSE, "red"] + "";
|
||||
[1, 5 => FALSE, "red"] + "123";
|
||||
|
||||
// So we conclude that if one operand is an array and the other not, the array
|
||||
// is not converted to a string and concatenated, and neither is the non-array
|
||||
// converted to an array and merged with the other array.
|
||||
*/
|
||||
|
||||
///*
|
||||
// show that a new array is created and that the operand-arrays are unchanged
|
||||
|
||||
$a1 = [1, 5 => FALSE, "red"]; // [0], [5], [6]
|
||||
$a2 = [4 => -5, 1.23]; // [4], [5]
|
||||
|
||||
$a3 = $a1 + $a2; // [0], [5], [6], [4]
|
||||
var_dump($a3);
|
||||
$a3[0] = 11;
|
||||
$a3[6] = 99;
|
||||
var_dump($a3);
|
||||
var_dump($a1);
|
||||
var_dump($a2);
|
||||
//*/
|
||||
--EXPECTF--
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(3) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[5]=>
|
||||
bool(false)
|
||||
[6]=>
|
||||
string(3) "red"
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(3) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[5]=>
|
||||
bool(false)
|
||||
[6]=>
|
||||
string(3) "red"
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(4) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[5]=>
|
||||
bool(false)
|
||||
[6]=>
|
||||
string(3) "red"
|
||||
[4]=>
|
||||
int(-5)
|
||||
}
|
||||
-------------------------------------
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(3) {
|
||||
[0]=>
|
||||
NULL
|
||||
[5]=>
|
||||
bool(false)
|
||||
[6]=>
|
||||
string(3) "red"
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(1) {
|
||||
[0]=>
|
||||
NULL
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(3) {
|
||||
[0]=>
|
||||
NULL
|
||||
[4]=>
|
||||
int(-5)
|
||||
[5]=>
|
||||
float(1.23)
|
||||
}
|
||||
-------------------------------------
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(4) {
|
||||
[4]=>
|
||||
int(-5)
|
||||
[5]=>
|
||||
float(1.23)
|
||||
[0]=>
|
||||
int(1)
|
||||
[6]=>
|
||||
string(3) "red"
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(3) {
|
||||
[4]=>
|
||||
int(-5)
|
||||
[5]=>
|
||||
float(1.23)
|
||||
[0]=>
|
||||
NULL
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
|
||||
Notice: Array to string conversion in %s/expressions/additive_operators/array_concatenation.php on line 18
|
||||
>Array< + >Array<, result: array(2) {
|
||||
[4]=>
|
||||
int(-5)
|
||||
[5]=>
|
||||
float(1.23)
|
||||
}
|
||||
-------------------------------------
|
||||
array(4) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[5]=>
|
||||
bool(false)
|
||||
[6]=>
|
||||
string(3) "red"
|
||||
[4]=>
|
||||
int(-5)
|
||||
}
|
||||
array(4) {
|
||||
[0]=>
|
||||
int(11)
|
||||
[5]=>
|
||||
bool(false)
|
||||
[6]=>
|
||||
int(99)
|
||||
[4]=>
|
||||
int(-5)
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[5]=>
|
||||
bool(false)
|
||||
[6]=>
|
||||
string(3) "red"
|
||||
}
|
||||
array(2) {
|
||||
[4]=>
|
||||
int(-5)
|
||||
[5]=>
|
||||
float(1.23)
|
||||
}
|
|
@ -0,0 +1,379 @@
|
|||
--TEST--
|
||||
+= operator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
foreach ($oper as $t)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
$e1 = $t;
|
||||
echo ">$e1< += >$e2<, result: "; var_dump($e1 += $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
>0< += >0<, result: int(0)
|
||||
>0< += >-10<, result: int(-10)
|
||||
>0< += >100<, result: int(100)
|
||||
>0< += >-34000000000<, result: float(-34000000000)
|
||||
>0< += >INF<, result: float(INF)
|
||||
>0< += >-INF<, result: float(-INF)
|
||||
>0< += >NAN<, result: float(NAN)
|
||||
>0< += >1<, result: int(1)
|
||||
>0< += ><, result: int(0)
|
||||
>0< += ><, result: int(0)
|
||||
>0< += >123<, result: int(123)
|
||||
>0< += >2e+5<, result: float(200000)
|
||||
>0< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< += >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>-10< += >0<, result: int(-10)
|
||||
>-10< += >-10<, result: int(-20)
|
||||
>-10< += >100<, result: int(90)
|
||||
>-10< += >-34000000000<, result: float(-34000000010)
|
||||
>-10< += >INF<, result: float(INF)
|
||||
>-10< += >-INF<, result: float(-INF)
|
||||
>-10< += >NAN<, result: float(NAN)
|
||||
>-10< += >1<, result: int(-9)
|
||||
>-10< += ><, result: int(-10)
|
||||
>-10< += ><, result: int(-10)
|
||||
>-10< += >123<, result: int(113)
|
||||
>-10< += >2e+5<, result: float(199990)
|
||||
>-10< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>-10< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>-10< += >9223372036854775807<, result: int(9223372036854775797)
|
||||
-------------------------------------
|
||||
>100< += >0<, result: int(100)
|
||||
>100< += >-10<, result: int(90)
|
||||
>100< += >100<, result: int(200)
|
||||
>100< += >-34000000000<, result: float(-33999999900)
|
||||
>100< += >INF<, result: float(INF)
|
||||
>100< += >-INF<, result: float(-INF)
|
||||
>100< += >NAN<, result: float(NAN)
|
||||
>100< += >1<, result: int(101)
|
||||
>100< += ><, result: int(100)
|
||||
>100< += ><, result: int(100)
|
||||
>100< += >123<, result: int(223)
|
||||
>100< += >2e+5<, result: float(200100)
|
||||
>100< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>100< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>100< += >9223372036854775807<, result: float(9.2233720368548E+18)
|
||||
-------------------------------------
|
||||
>-34000000000< += >0<, result: float(-34000000000)
|
||||
>-34000000000< += >-10<, result: float(-34000000010)
|
||||
>-34000000000< += >100<, result: float(-33999999900)
|
||||
>-34000000000< += >-34000000000<, result: float(-68000000000)
|
||||
>-34000000000< += >INF<, result: float(INF)
|
||||
>-34000000000< += >-INF<, result: float(-INF)
|
||||
>-34000000000< += >NAN<, result: float(NAN)
|
||||
>-34000000000< += >1<, result: float(-33999999999)
|
||||
>-34000000000< += ><, result: float(-34000000000)
|
||||
>-34000000000< += ><, result: float(-34000000000)
|
||||
>-34000000000< += >123<, result: float(-33999999877)
|
||||
>-34000000000< += >2e+5<, result: float(-33999800000)
|
||||
>-34000000000< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-34000000000)
|
||||
>-34000000000< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-34000000000)
|
||||
>-34000000000< += >9223372036854775807<, result: float(9.2233720028548E+18)
|
||||
-------------------------------------
|
||||
>INF< += >0<, result: float(INF)
|
||||
>INF< += >-10<, result: float(INF)
|
||||
>INF< += >100<, result: float(INF)
|
||||
>INF< += >-34000000000<, result: float(INF)
|
||||
>INF< += >INF<, result: float(INF)
|
||||
>INF< += >-INF<, result: float(NAN)
|
||||
>INF< += >NAN<, result: float(NAN)
|
||||
>INF< += >1<, result: float(INF)
|
||||
>INF< += ><, result: float(INF)
|
||||
>INF< += ><, result: float(INF)
|
||||
>INF< += >123<, result: float(INF)
|
||||
>INF< += >2e+5<, result: float(INF)
|
||||
>INF< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(INF)
|
||||
>INF< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(INF)
|
||||
>INF< += >9223372036854775807<, result: float(INF)
|
||||
-------------------------------------
|
||||
>-INF< += >0<, result: float(-INF)
|
||||
>-INF< += >-10<, result: float(-INF)
|
||||
>-INF< += >100<, result: float(-INF)
|
||||
>-INF< += >-34000000000<, result: float(-INF)
|
||||
>-INF< += >INF<, result: float(NAN)
|
||||
>-INF< += >-INF<, result: float(-INF)
|
||||
>-INF< += >NAN<, result: float(NAN)
|
||||
>-INF< += >1<, result: float(-INF)
|
||||
>-INF< += ><, result: float(-INF)
|
||||
>-INF< += ><, result: float(-INF)
|
||||
>-INF< += >123<, result: float(-INF)
|
||||
>-INF< += >2e+5<, result: float(-INF)
|
||||
>-INF< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-INF)
|
||||
>-INF< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-INF)
|
||||
>-INF< += >9223372036854775807<, result: float(-INF)
|
||||
-------------------------------------
|
||||
>NAN< += >0<, result: float(NAN)
|
||||
>NAN< += >-10<, result: float(NAN)
|
||||
>NAN< += >100<, result: float(NAN)
|
||||
>NAN< += >-34000000000<, result: float(NAN)
|
||||
>NAN< += >INF<, result: float(NAN)
|
||||
>NAN< += >-INF<, result: float(NAN)
|
||||
>NAN< += >NAN<, result: float(NAN)
|
||||
>NAN< += >1<, result: float(NAN)
|
||||
>NAN< += ><, result: float(NAN)
|
||||
>NAN< += ><, result: float(NAN)
|
||||
>NAN< += >123<, result: float(NAN)
|
||||
>NAN< += >2e+5<, result: float(NAN)
|
||||
>NAN< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>NAN< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>NAN< += >9223372036854775807<, result: float(NAN)
|
||||
-------------------------------------
|
||||
>1< += >0<, result: int(1)
|
||||
>1< += >-10<, result: int(-9)
|
||||
>1< += >100<, result: int(101)
|
||||
>1< += >-34000000000<, result: float(-33999999999)
|
||||
>1< += >INF<, result: float(INF)
|
||||
>1< += >-INF<, result: float(-INF)
|
||||
>1< += >NAN<, result: float(NAN)
|
||||
>1< += >1<, result: int(2)
|
||||
>1< += ><, result: int(1)
|
||||
>1< += ><, result: int(1)
|
||||
>1< += >123<, result: int(124)
|
||||
>1< += >2e+5<, result: float(200001)
|
||||
>1< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>1< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>1< += >9223372036854775807<, result: float(9.2233720368548E+18)
|
||||
-------------------------------------
|
||||
>< += >0<, result: int(0)
|
||||
>< += >-10<, result: int(-10)
|
||||
>< += >100<, result: int(100)
|
||||
>< += >-34000000000<, result: float(-34000000000)
|
||||
>< += >INF<, result: float(INF)
|
||||
>< += >-INF<, result: float(-INF)
|
||||
>< += >NAN<, result: float(NAN)
|
||||
>< += >1<, result: int(1)
|
||||
>< += ><, result: int(0)
|
||||
>< += ><, result: int(0)
|
||||
>< += >123<, result: int(123)
|
||||
>< += >2e+5<, result: float(200000)
|
||||
>< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>< += >0<, result: int(0)
|
||||
>< += >-10<, result: int(-10)
|
||||
>< += >100<, result: int(100)
|
||||
>< += >-34000000000<, result: float(-34000000000)
|
||||
>< += >INF<, result: float(INF)
|
||||
>< += >-INF<, result: float(-INF)
|
||||
>< += >NAN<, result: float(NAN)
|
||||
>< += >1<, result: int(1)
|
||||
>< += ><, result: int(0)
|
||||
>< += ><, result: int(0)
|
||||
>< += >123<, result: int(123)
|
||||
>< += >2e+5<, result: float(200000)
|
||||
>< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>123< += >0<, result: int(123)
|
||||
>123< += >-10<, result: int(113)
|
||||
>123< += >100<, result: int(223)
|
||||
>123< += >-34000000000<, result: float(-33999999877)
|
||||
>123< += >INF<, result: float(INF)
|
||||
>123< += >-INF<, result: float(-INF)
|
||||
>123< += >NAN<, result: float(NAN)
|
||||
>123< += >1<, result: int(124)
|
||||
>123< += ><, result: int(123)
|
||||
>123< += ><, result: int(123)
|
||||
>123< += >123<, result: int(246)
|
||||
>123< += >2e+5<, result: float(200123)
|
||||
>123< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(123)
|
||||
>123< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(123)
|
||||
>123< += >9223372036854775807<, result: float(9.2233720368548E+18)
|
||||
-------------------------------------
|
||||
>2e+5< += >0<, result: float(200000)
|
||||
>2e+5< += >-10<, result: float(199990)
|
||||
>2e+5< += >100<, result: float(200100)
|
||||
>2e+5< += >-34000000000<, result: float(-33999800000)
|
||||
>2e+5< += >INF<, result: float(INF)
|
||||
>2e+5< += >-INF<, result: float(-INF)
|
||||
>2e+5< += >NAN<, result: float(NAN)
|
||||
>2e+5< += >1<, result: float(200001)
|
||||
>2e+5< += ><, result: float(200000)
|
||||
>2e+5< += ><, result: float(200000)
|
||||
>2e+5< += >123<, result: float(200123)
|
||||
>2e+5< += >2e+5<, result: float(400000)
|
||||
>2e+5< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(200000)
|
||||
>2e+5< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(200000)
|
||||
>2e+5< += >9223372036854775807<, result: float(9.223372036855E+18)
|
||||
-------------------------------------
|
||||
>< += >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>< += >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>< += >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-34000000000)
|
||||
>< += >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(INF)
|
||||
>< += >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-INF)
|
||||
>< += >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>< += >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(123)
|
||||
>< += >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(200000)
|
||||
>< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< += >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>abc< += >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< += >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>abc< += >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>abc< += >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-34000000000)
|
||||
>abc< += >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(INF)
|
||||
>abc< += >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-INF)
|
||||
>abc< += >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>abc< += >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>abc< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< += >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(123)
|
||||
>abc< += >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(200000)
|
||||
>abc< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< += >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>9223372036854775807< += >0<, result: int(9223372036854775807)
|
||||
>9223372036854775807< += >-10<, result: int(9223372036854775797)
|
||||
>9223372036854775807< += >100<, result: float(9.2233720368548E+18)
|
||||
>9223372036854775807< += >-34000000000<, result: float(9.2233720028548E+18)
|
||||
>9223372036854775807< += >INF<, result: float(INF)
|
||||
>9223372036854775807< += >-INF<, result: float(-INF)
|
||||
>9223372036854775807< += >NAN<, result: float(NAN)
|
||||
>9223372036854775807< += >1<, result: float(9.2233720368548E+18)
|
||||
>9223372036854775807< += ><, result: int(9223372036854775807)
|
||||
>9223372036854775807< += ><, result: int(9223372036854775807)
|
||||
>9223372036854775807< += >123<, result: float(9.2233720368548E+18)
|
||||
>9223372036854775807< += >2e+5<, result: float(9.223372036855E+18)
|
||||
>9223372036854775807< += ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
>9223372036854775807< += >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
>9223372036854775807< += >9223372036854775807<, result: float(1.844674407371E+19)
|
||||
-------------------------------------
|
|
@ -0,0 +1,347 @@
|
|||
--TEST--
|
||||
&= operator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
foreach ($oper as $t)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
$e1 = $t;
|
||||
echo ">$e1< &= >$e2<, result: "; var_dump($e1 &= $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
>0< &= >0<, result: int(0)
|
||||
>0< &= >-10<, result: int(0)
|
||||
>0< &= >100<, result: int(0)
|
||||
>0< &= >-34000000000<, result: int(0)
|
||||
>0< &= >INF<, result: int(0)
|
||||
>0< &= >-INF<, result: int(0)
|
||||
>0< &= >NAN<, result: int(0)
|
||||
>0< &= >1<, result: int(0)
|
||||
>0< &= ><, result: int(0)
|
||||
>0< &= ><, result: int(0)
|
||||
>0< &= >123<, result: int(0)
|
||||
>0< &= >2e+5<, result: int(0)
|
||||
>0< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< &= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>-10< &= >0<, result: int(0)
|
||||
>-10< &= >-10<, result: int(-10)
|
||||
>-10< &= >100<, result: int(100)
|
||||
>-10< &= >-34000000000<, result: int(-34000000000)
|
||||
>-10< &= >INF<, result: int(0)
|
||||
>-10< &= >-INF<, result: int(0)
|
||||
>-10< &= >NAN<, result: int(0)
|
||||
>-10< &= >1<, result: int(0)
|
||||
>-10< &= ><, result: int(0)
|
||||
>-10< &= ><, result: int(0)
|
||||
>-10< &= >123<, result: int(114)
|
||||
>-10< &= >2e+5<, result: int(200000)
|
||||
>-10< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-10< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-10< &= >9223372036854775807<, result: int(9223372036854775798)
|
||||
-------------------------------------
|
||||
>100< &= >0<, result: int(0)
|
||||
>100< &= >-10<, result: int(100)
|
||||
>100< &= >100<, result: int(100)
|
||||
>100< &= >-34000000000<, result: int(0)
|
||||
>100< &= >INF<, result: int(0)
|
||||
>100< &= >-INF<, result: int(0)
|
||||
>100< &= >NAN<, result: int(0)
|
||||
>100< &= >1<, result: int(0)
|
||||
>100< &= ><, result: int(0)
|
||||
>100< &= ><, result: int(0)
|
||||
>100< &= >123<, result: int(96)
|
||||
>100< &= >2e+5<, result: int(64)
|
||||
>100< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>100< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>100< &= >9223372036854775807<, result: int(100)
|
||||
-------------------------------------
|
||||
>-34000000000< &= >0<, result: int(0)
|
||||
>-34000000000< &= >-10<, result: int(-34000000000)
|
||||
>-34000000000< &= >100<, result: int(0)
|
||||
>-34000000000< &= >-34000000000<, result: int(-34000000000)
|
||||
>-34000000000< &= >INF<, result: int(0)
|
||||
>-34000000000< &= >-INF<, result: int(0)
|
||||
>-34000000000< &= >NAN<, result: int(0)
|
||||
>-34000000000< &= >1<, result: int(0)
|
||||
>-34000000000< &= ><, result: int(0)
|
||||
>-34000000000< &= ><, result: int(0)
|
||||
>-34000000000< &= >123<, result: int(0)
|
||||
>-34000000000< &= >2e+5<, result: int(68608)
|
||||
>-34000000000< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-34000000000< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-34000000000< &= >9223372036854775807<, result: int(9223372002854775808)
|
||||
-------------------------------------
|
||||
>INF< &= >0<, result: int(0)
|
||||
>INF< &= >-10<, result: int(0)
|
||||
>INF< &= >100<, result: int(0)
|
||||
>INF< &= >-34000000000<, result: int(0)
|
||||
>INF< &= >INF<, result: int(0)
|
||||
>INF< &= >-INF<, result: int(0)
|
||||
>INF< &= >NAN<, result: int(0)
|
||||
>INF< &= >1<, result: int(0)
|
||||
>INF< &= ><, result: int(0)
|
||||
>INF< &= ><, result: int(0)
|
||||
>INF< &= >123<, result: int(0)
|
||||
>INF< &= >2e+5<, result: int(0)
|
||||
>INF< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>INF< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>INF< &= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>-INF< &= >0<, result: int(0)
|
||||
>-INF< &= >-10<, result: int(0)
|
||||
>-INF< &= >100<, result: int(0)
|
||||
>-INF< &= >-34000000000<, result: int(0)
|
||||
>-INF< &= >INF<, result: int(0)
|
||||
>-INF< &= >-INF<, result: int(0)
|
||||
>-INF< &= >NAN<, result: int(0)
|
||||
>-INF< &= >1<, result: int(0)
|
||||
>-INF< &= ><, result: int(0)
|
||||
>-INF< &= ><, result: int(0)
|
||||
>-INF< &= >123<, result: int(0)
|
||||
>-INF< &= >2e+5<, result: int(0)
|
||||
>-INF< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-INF< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-INF< &= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>NAN< &= >0<, result: int(0)
|
||||
>NAN< &= >-10<, result: int(0)
|
||||
>NAN< &= >100<, result: int(0)
|
||||
>NAN< &= >-34000000000<, result: int(0)
|
||||
>NAN< &= >INF<, result: int(0)
|
||||
>NAN< &= >-INF<, result: int(0)
|
||||
>NAN< &= >NAN<, result: int(0)
|
||||
>NAN< &= >1<, result: int(0)
|
||||
>NAN< &= ><, result: int(0)
|
||||
>NAN< &= ><, result: int(0)
|
||||
>NAN< &= >123<, result: int(0)
|
||||
>NAN< &= >2e+5<, result: int(0)
|
||||
>NAN< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>NAN< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>NAN< &= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>1< &= >0<, result: int(0)
|
||||
>1< &= >-10<, result: int(0)
|
||||
>1< &= >100<, result: int(0)
|
||||
>1< &= >-34000000000<, result: int(0)
|
||||
>1< &= >INF<, result: int(0)
|
||||
>1< &= >-INF<, result: int(0)
|
||||
>1< &= >NAN<, result: int(0)
|
||||
>1< &= >1<, result: int(1)
|
||||
>1< &= ><, result: int(0)
|
||||
>1< &= ><, result: int(0)
|
||||
>1< &= >123<, result: int(1)
|
||||
>1< &= >2e+5<, result: int(0)
|
||||
>1< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>1< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>1< &= >9223372036854775807<, result: int(1)
|
||||
-------------------------------------
|
||||
>< &= >0<, result: int(0)
|
||||
>< &= >-10<, result: int(0)
|
||||
>< &= >100<, result: int(0)
|
||||
>< &= >-34000000000<, result: int(0)
|
||||
>< &= >INF<, result: int(0)
|
||||
>< &= >-INF<, result: int(0)
|
||||
>< &= >NAN<, result: int(0)
|
||||
>< &= >1<, result: int(0)
|
||||
>< &= ><, result: int(0)
|
||||
>< &= ><, result: int(0)
|
||||
>< &= >123<, result: int(0)
|
||||
>< &= >2e+5<, result: int(0)
|
||||
>< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>< &= >0<, result: int(0)
|
||||
>< &= >-10<, result: int(0)
|
||||
>< &= >100<, result: int(0)
|
||||
>< &= >-34000000000<, result: int(0)
|
||||
>< &= >INF<, result: int(0)
|
||||
>< &= >-INF<, result: int(0)
|
||||
>< &= >NAN<, result: int(0)
|
||||
>< &= >1<, result: int(0)
|
||||
>< &= ><, result: int(0)
|
||||
>< &= ><, result: int(0)
|
||||
>< &= >123<, result: int(0)
|
||||
>< &= >2e+5<, result: int(0)
|
||||
>< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>123< &= >0<, result: int(0)
|
||||
>123< &= >-10<, result: int(114)
|
||||
>123< &= >100<, result: int(96)
|
||||
>123< &= >-34000000000<, result: int(0)
|
||||
>123< &= >INF<, result: int(0)
|
||||
>123< &= >-INF<, result: int(0)
|
||||
>123< &= >NAN<, result: int(0)
|
||||
>123< &= >1<, result: int(1)
|
||||
>123< &= ><, result: int(0)
|
||||
>123< &= ><, result: int(0)
|
||||
>123< &= >123<, result: string(3) "123"
|
||||
>123< &= >2e+5<, result: string(3) "0 #"
|
||||
>123< &= ><, result: string(0) ""
|
||||
>123< &= >abc<, result: string(3) "!"#"
|
||||
>123< &= >9223372036854775807<, result: int(123)
|
||||
-------------------------------------
|
||||
>2e+5< &= >0<, result: int(0)
|
||||
>2e+5< &= >-10<, result: int(200000)
|
||||
>2e+5< &= >100<, result: int(64)
|
||||
>2e+5< &= >-34000000000<, result: int(68608)
|
||||
>2e+5< &= >INF<, result: int(0)
|
||||
>2e+5< &= >-INF<, result: int(0)
|
||||
>2e+5< &= >NAN<, result: int(0)
|
||||
>2e+5< &= >1<, result: int(0)
|
||||
>2e+5< &= ><, result: int(0)
|
||||
>2e+5< &= ><, result: int(0)
|
||||
>2e+5< &= >123<, result: string(3) "0 #"
|
||||
>2e+5< &= >2e+5<, result: string(4) "2e+5"
|
||||
>2e+5< &= ><, result: string(0) ""
|
||||
>2e+5< &= >abc<, result: string(3) " `#"
|
||||
>2e+5< &= >9223372036854775807<, result: int(200000)
|
||||
-------------------------------------
|
||||
>< &= >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< &= >123<, result: string(0) ""
|
||||
>< &= >2e+5<, result: string(0) ""
|
||||
>< &= ><, result: string(0) ""
|
||||
>< &= >abc<, result: string(0) ""
|
||||
>< &= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>abc< &= >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< &= >123<, result: string(3) "!"#"
|
||||
>abc< &= >2e+5<, result: string(3) " `#"
|
||||
>abc< &= ><, result: string(0) ""
|
||||
>abc< &= >abc<, result: string(3) "abc"
|
||||
>abc< &= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>9223372036854775807< &= >0<, result: int(0)
|
||||
>9223372036854775807< &= >-10<, result: int(9223372036854775798)
|
||||
>9223372036854775807< &= >100<, result: int(100)
|
||||
>9223372036854775807< &= >-34000000000<, result: int(9223372002854775808)
|
||||
>9223372036854775807< &= >INF<, result: int(0)
|
||||
>9223372036854775807< &= >-INF<, result: int(0)
|
||||
>9223372036854775807< &= >NAN<, result: int(0)
|
||||
>9223372036854775807< &= >1<, result: int(1)
|
||||
>9223372036854775807< &= ><, result: int(0)
|
||||
>9223372036854775807< &= ><, result: int(0)
|
||||
>9223372036854775807< &= >123<, result: int(123)
|
||||
>9223372036854775807< &= >2e+5<, result: int(200000)
|
||||
>9223372036854775807< &= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>9223372036854775807< &= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>9223372036854775807< &= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
$oper = array(0, -10, 100, -3.4e10, INF, -INF, NAN, TRUE, FALSE, NULL, "123", "2e+5", "", "abc", PHP_INT_MAX);
|
|
@ -0,0 +1,259 @@
|
|||
--TEST--
|
||||
.= operator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
foreach ($oper as $t)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
$e1 = $t;
|
||||
echo ">$e1< .= >$e2<, result: "; var_dump($e1 .= $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
>0< .= >0<, result: string(2) "00"
|
||||
>0< .= >-10<, result: string(4) "0-10"
|
||||
>0< .= >100<, result: string(4) "0100"
|
||||
>0< .= >-34000000000<, result: string(13) "0-34000000000"
|
||||
>0< .= >INF<, result: string(4) "0INF"
|
||||
>0< .= >-INF<, result: string(5) "0-INF"
|
||||
>0< .= >NAN<, result: string(4) "0NAN"
|
||||
>0< .= >1<, result: string(2) "01"
|
||||
>0< .= ><, result: string(1) "0"
|
||||
>0< .= ><, result: string(1) "0"
|
||||
>0< .= >123<, result: string(4) "0123"
|
||||
>0< .= >2e+5<, result: string(5) "02e+5"
|
||||
>0< .= ><, result: string(1) "0"
|
||||
>0< .= >abc<, result: string(4) "0abc"
|
||||
>0< .= >9223372036854775807<, result: string(20) "09223372036854775807"
|
||||
-------------------------------------
|
||||
>-10< .= >0<, result: string(4) "-100"
|
||||
>-10< .= >-10<, result: string(6) "-10-10"
|
||||
>-10< .= >100<, result: string(6) "-10100"
|
||||
>-10< .= >-34000000000<, result: string(15) "-10-34000000000"
|
||||
>-10< .= >INF<, result: string(6) "-10INF"
|
||||
>-10< .= >-INF<, result: string(7) "-10-INF"
|
||||
>-10< .= >NAN<, result: string(6) "-10NAN"
|
||||
>-10< .= >1<, result: string(4) "-101"
|
||||
>-10< .= ><, result: string(3) "-10"
|
||||
>-10< .= ><, result: string(3) "-10"
|
||||
>-10< .= >123<, result: string(6) "-10123"
|
||||
>-10< .= >2e+5<, result: string(7) "-102e+5"
|
||||
>-10< .= ><, result: string(3) "-10"
|
||||
>-10< .= >abc<, result: string(6) "-10abc"
|
||||
>-10< .= >9223372036854775807<, result: string(22) "-109223372036854775807"
|
||||
-------------------------------------
|
||||
>100< .= >0<, result: string(4) "1000"
|
||||
>100< .= >-10<, result: string(6) "100-10"
|
||||
>100< .= >100<, result: string(6) "100100"
|
||||
>100< .= >-34000000000<, result: string(15) "100-34000000000"
|
||||
>100< .= >INF<, result: string(6) "100INF"
|
||||
>100< .= >-INF<, result: string(7) "100-INF"
|
||||
>100< .= >NAN<, result: string(6) "100NAN"
|
||||
>100< .= >1<, result: string(4) "1001"
|
||||
>100< .= ><, result: string(3) "100"
|
||||
>100< .= ><, result: string(3) "100"
|
||||
>100< .= >123<, result: string(6) "100123"
|
||||
>100< .= >2e+5<, result: string(7) "1002e+5"
|
||||
>100< .= ><, result: string(3) "100"
|
||||
>100< .= >abc<, result: string(6) "100abc"
|
||||
>100< .= >9223372036854775807<, result: string(22) "1009223372036854775807"
|
||||
-------------------------------------
|
||||
>-34000000000< .= >0<, result: string(13) "-340000000000"
|
||||
>-34000000000< .= >-10<, result: string(15) "-34000000000-10"
|
||||
>-34000000000< .= >100<, result: string(15) "-34000000000100"
|
||||
>-34000000000< .= >-34000000000<, result: string(24) "-34000000000-34000000000"
|
||||
>-34000000000< .= >INF<, result: string(15) "-34000000000INF"
|
||||
>-34000000000< .= >-INF<, result: string(16) "-34000000000-INF"
|
||||
>-34000000000< .= >NAN<, result: string(15) "-34000000000NAN"
|
||||
>-34000000000< .= >1<, result: string(13) "-340000000001"
|
||||
>-34000000000< .= ><, result: string(12) "-34000000000"
|
||||
>-34000000000< .= ><, result: string(12) "-34000000000"
|
||||
>-34000000000< .= >123<, result: string(15) "-34000000000123"
|
||||
>-34000000000< .= >2e+5<, result: string(16) "-340000000002e+5"
|
||||
>-34000000000< .= ><, result: string(12) "-34000000000"
|
||||
>-34000000000< .= >abc<, result: string(15) "-34000000000abc"
|
||||
>-34000000000< .= >9223372036854775807<, result: string(31) "-340000000009223372036854775807"
|
||||
-------------------------------------
|
||||
>INF< .= >0<, result: string(4) "INF0"
|
||||
>INF< .= >-10<, result: string(6) "INF-10"
|
||||
>INF< .= >100<, result: string(6) "INF100"
|
||||
>INF< .= >-34000000000<, result: string(15) "INF-34000000000"
|
||||
>INF< .= >INF<, result: string(6) "INFINF"
|
||||
>INF< .= >-INF<, result: string(7) "INF-INF"
|
||||
>INF< .= >NAN<, result: string(6) "INFNAN"
|
||||
>INF< .= >1<, result: string(4) "INF1"
|
||||
>INF< .= ><, result: string(3) "INF"
|
||||
>INF< .= ><, result: string(3) "INF"
|
||||
>INF< .= >123<, result: string(6) "INF123"
|
||||
>INF< .= >2e+5<, result: string(7) "INF2e+5"
|
||||
>INF< .= ><, result: string(3) "INF"
|
||||
>INF< .= >abc<, result: string(6) "INFabc"
|
||||
>INF< .= >9223372036854775807<, result: string(22) "INF9223372036854775807"
|
||||
-------------------------------------
|
||||
>-INF< .= >0<, result: string(5) "-INF0"
|
||||
>-INF< .= >-10<, result: string(7) "-INF-10"
|
||||
>-INF< .= >100<, result: string(7) "-INF100"
|
||||
>-INF< .= >-34000000000<, result: string(16) "-INF-34000000000"
|
||||
>-INF< .= >INF<, result: string(7) "-INFINF"
|
||||
>-INF< .= >-INF<, result: string(8) "-INF-INF"
|
||||
>-INF< .= >NAN<, result: string(7) "-INFNAN"
|
||||
>-INF< .= >1<, result: string(5) "-INF1"
|
||||
>-INF< .= ><, result: string(4) "-INF"
|
||||
>-INF< .= ><, result: string(4) "-INF"
|
||||
>-INF< .= >123<, result: string(7) "-INF123"
|
||||
>-INF< .= >2e+5<, result: string(8) "-INF2e+5"
|
||||
>-INF< .= ><, result: string(4) "-INF"
|
||||
>-INF< .= >abc<, result: string(7) "-INFabc"
|
||||
>-INF< .= >9223372036854775807<, result: string(23) "-INF9223372036854775807"
|
||||
-------------------------------------
|
||||
>NAN< .= >0<, result: string(4) "NAN0"
|
||||
>NAN< .= >-10<, result: string(6) "NAN-10"
|
||||
>NAN< .= >100<, result: string(6) "NAN100"
|
||||
>NAN< .= >-34000000000<, result: string(15) "NAN-34000000000"
|
||||
>NAN< .= >INF<, result: string(6) "NANINF"
|
||||
>NAN< .= >-INF<, result: string(7) "NAN-INF"
|
||||
>NAN< .= >NAN<, result: string(6) "NANNAN"
|
||||
>NAN< .= >1<, result: string(4) "NAN1"
|
||||
>NAN< .= ><, result: string(3) "NAN"
|
||||
>NAN< .= ><, result: string(3) "NAN"
|
||||
>NAN< .= >123<, result: string(6) "NAN123"
|
||||
>NAN< .= >2e+5<, result: string(7) "NAN2e+5"
|
||||
>NAN< .= ><, result: string(3) "NAN"
|
||||
>NAN< .= >abc<, result: string(6) "NANabc"
|
||||
>NAN< .= >9223372036854775807<, result: string(22) "NAN9223372036854775807"
|
||||
-------------------------------------
|
||||
>1< .= >0<, result: string(2) "10"
|
||||
>1< .= >-10<, result: string(4) "1-10"
|
||||
>1< .= >100<, result: string(4) "1100"
|
||||
>1< .= >-34000000000<, result: string(13) "1-34000000000"
|
||||
>1< .= >INF<, result: string(4) "1INF"
|
||||
>1< .= >-INF<, result: string(5) "1-INF"
|
||||
>1< .= >NAN<, result: string(4) "1NAN"
|
||||
>1< .= >1<, result: string(2) "11"
|
||||
>1< .= ><, result: string(1) "1"
|
||||
>1< .= ><, result: string(1) "1"
|
||||
>1< .= >123<, result: string(4) "1123"
|
||||
>1< .= >2e+5<, result: string(5) "12e+5"
|
||||
>1< .= ><, result: string(1) "1"
|
||||
>1< .= >abc<, result: string(4) "1abc"
|
||||
>1< .= >9223372036854775807<, result: string(20) "19223372036854775807"
|
||||
-------------------------------------
|
||||
>< .= >0<, result: string(1) "0"
|
||||
>< .= >-10<, result: string(3) "-10"
|
||||
>< .= >100<, result: string(3) "100"
|
||||
>< .= >-34000000000<, result: string(12) "-34000000000"
|
||||
>< .= >INF<, result: string(3) "INF"
|
||||
>< .= >-INF<, result: string(4) "-INF"
|
||||
>< .= >NAN<, result: string(3) "NAN"
|
||||
>< .= >1<, result: string(1) "1"
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= >123<, result: string(3) "123"
|
||||
>< .= >2e+5<, result: string(4) "2e+5"
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= >abc<, result: string(3) "abc"
|
||||
>< .= >9223372036854775807<, result: string(19) "9223372036854775807"
|
||||
-------------------------------------
|
||||
>< .= >0<, result: string(1) "0"
|
||||
>< .= >-10<, result: string(3) "-10"
|
||||
>< .= >100<, result: string(3) "100"
|
||||
>< .= >-34000000000<, result: string(12) "-34000000000"
|
||||
>< .= >INF<, result: string(3) "INF"
|
||||
>< .= >-INF<, result: string(4) "-INF"
|
||||
>< .= >NAN<, result: string(3) "NAN"
|
||||
>< .= >1<, result: string(1) "1"
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= >123<, result: string(3) "123"
|
||||
>< .= >2e+5<, result: string(4) "2e+5"
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= >abc<, result: string(3) "abc"
|
||||
>< .= >9223372036854775807<, result: string(19) "9223372036854775807"
|
||||
-------------------------------------
|
||||
>123< .= >0<, result: string(4) "1230"
|
||||
>123< .= >-10<, result: string(6) "123-10"
|
||||
>123< .= >100<, result: string(6) "123100"
|
||||
>123< .= >-34000000000<, result: string(15) "123-34000000000"
|
||||
>123< .= >INF<, result: string(6) "123INF"
|
||||
>123< .= >-INF<, result: string(7) "123-INF"
|
||||
>123< .= >NAN<, result: string(6) "123NAN"
|
||||
>123< .= >1<, result: string(4) "1231"
|
||||
>123< .= ><, result: string(3) "123"
|
||||
>123< .= ><, result: string(3) "123"
|
||||
>123< .= >123<, result: string(6) "123123"
|
||||
>123< .= >2e+5<, result: string(7) "1232e+5"
|
||||
>123< .= ><, result: string(3) "123"
|
||||
>123< .= >abc<, result: string(6) "123abc"
|
||||
>123< .= >9223372036854775807<, result: string(22) "1239223372036854775807"
|
||||
-------------------------------------
|
||||
>2e+5< .= >0<, result: string(5) "2e+50"
|
||||
>2e+5< .= >-10<, result: string(7) "2e+5-10"
|
||||
>2e+5< .= >100<, result: string(7) "2e+5100"
|
||||
>2e+5< .= >-34000000000<, result: string(16) "2e+5-34000000000"
|
||||
>2e+5< .= >INF<, result: string(7) "2e+5INF"
|
||||
>2e+5< .= >-INF<, result: string(8) "2e+5-INF"
|
||||
>2e+5< .= >NAN<, result: string(7) "2e+5NAN"
|
||||
>2e+5< .= >1<, result: string(5) "2e+51"
|
||||
>2e+5< .= ><, result: string(4) "2e+5"
|
||||
>2e+5< .= ><, result: string(4) "2e+5"
|
||||
>2e+5< .= >123<, result: string(7) "2e+5123"
|
||||
>2e+5< .= >2e+5<, result: string(8) "2e+52e+5"
|
||||
>2e+5< .= ><, result: string(4) "2e+5"
|
||||
>2e+5< .= >abc<, result: string(7) "2e+5abc"
|
||||
>2e+5< .= >9223372036854775807<, result: string(23) "2e+59223372036854775807"
|
||||
-------------------------------------
|
||||
>< .= >0<, result: string(1) "0"
|
||||
>< .= >-10<, result: string(3) "-10"
|
||||
>< .= >100<, result: string(3) "100"
|
||||
>< .= >-34000000000<, result: string(12) "-34000000000"
|
||||
>< .= >INF<, result: string(3) "INF"
|
||||
>< .= >-INF<, result: string(4) "-INF"
|
||||
>< .= >NAN<, result: string(3) "NAN"
|
||||
>< .= >1<, result: string(1) "1"
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= >123<, result: string(3) "123"
|
||||
>< .= >2e+5<, result: string(4) "2e+5"
|
||||
>< .= ><, result: string(0) ""
|
||||
>< .= >abc<, result: string(3) "abc"
|
||||
>< .= >9223372036854775807<, result: string(19) "9223372036854775807"
|
||||
-------------------------------------
|
||||
>abc< .= >0<, result: string(4) "abc0"
|
||||
>abc< .= >-10<, result: string(6) "abc-10"
|
||||
>abc< .= >100<, result: string(6) "abc100"
|
||||
>abc< .= >-34000000000<, result: string(15) "abc-34000000000"
|
||||
>abc< .= >INF<, result: string(6) "abcINF"
|
||||
>abc< .= >-INF<, result: string(7) "abc-INF"
|
||||
>abc< .= >NAN<, result: string(6) "abcNAN"
|
||||
>abc< .= >1<, result: string(4) "abc1"
|
||||
>abc< .= ><, result: string(3) "abc"
|
||||
>abc< .= ><, result: string(3) "abc"
|
||||
>abc< .= >123<, result: string(6) "abc123"
|
||||
>abc< .= >2e+5<, result: string(7) "abc2e+5"
|
||||
>abc< .= ><, result: string(3) "abc"
|
||||
>abc< .= >abc<, result: string(6) "abcabc"
|
||||
>abc< .= >9223372036854775807<, result: string(22) "abc9223372036854775807"
|
||||
-------------------------------------
|
||||
>9223372036854775807< .= >0<, result: string(20) "92233720368547758070"
|
||||
>9223372036854775807< .= >-10<, result: string(22) "9223372036854775807-10"
|
||||
>9223372036854775807< .= >100<, result: string(22) "9223372036854775807100"
|
||||
>9223372036854775807< .= >-34000000000<, result: string(31) "9223372036854775807-34000000000"
|
||||
>9223372036854775807< .= >INF<, result: string(22) "9223372036854775807INF"
|
||||
>9223372036854775807< .= >-INF<, result: string(23) "9223372036854775807-INF"
|
||||
>9223372036854775807< .= >NAN<, result: string(22) "9223372036854775807NAN"
|
||||
>9223372036854775807< .= >1<, result: string(20) "92233720368547758071"
|
||||
>9223372036854775807< .= ><, result: string(19) "9223372036854775807"
|
||||
>9223372036854775807< .= ><, result: string(19) "9223372036854775807"
|
||||
>9223372036854775807< .= >123<, result: string(22) "9223372036854775807123"
|
||||
>9223372036854775807< .= >2e+5<, result: string(23) "92233720368547758072e+5"
|
||||
>9223372036854775807< .= ><, result: string(19) "9223372036854775807"
|
||||
>9223372036854775807< .= >abc<, result: string(22) "9223372036854775807abc"
|
||||
>9223372036854775807< .= >9223372036854775807<, result: string(38) "92233720368547758079223372036854775807"
|
||||
-------------------------------------
|
|
@ -0,0 +1,226 @@
|
|||
--TEST--
|
||||
/= operator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
foreach ($oper as $t)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
if (($e2) == 0) continue; // skip divide-by-zeros
|
||||
|
||||
$e1 = $t;
|
||||
echo ">$e1< /= >$e2<, result: "; var_dump($e1 /= $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
>0< /= >-10<, result: int(0)
|
||||
>0< /= >100<, result: int(0)
|
||||
>0< /= >-34000000000<, result: float(-0)
|
||||
>0< /= >INF<, result: float(0)
|
||||
>0< /= >-INF<, result: float(-0)
|
||||
>0< /= >NAN<, result: float(NAN)
|
||||
>0< /= >1<, result: int(0)
|
||||
>0< /= >123<, result: int(0)
|
||||
>0< /= >2e+5<, result: float(0)
|
||||
>0< /= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>-10< /= >-10<, result: int(1)
|
||||
>-10< /= >100<, result: float(-0.1)
|
||||
>-10< /= >-34000000000<, result: float(2.9411764705882E-10)
|
||||
>-10< /= >INF<, result: float(-0)
|
||||
>-10< /= >-INF<, result: float(0)
|
||||
>-10< /= >NAN<, result: float(NAN)
|
||||
>-10< /= >1<, result: int(-10)
|
||||
>-10< /= >123<, result: float(-0.08130081300813)
|
||||
>-10< /= >2e+5<, result: float(-5.0E-5)
|
||||
>-10< /= >9223372036854775807<, result: float(-1.0842021724855E-18)
|
||||
-------------------------------------
|
||||
>100< /= >-10<, result: int(-10)
|
||||
>100< /= >100<, result: int(1)
|
||||
>100< /= >-34000000000<, result: float(-2.9411764705882E-9)
|
||||
>100< /= >INF<, result: float(0)
|
||||
>100< /= >-INF<, result: float(-0)
|
||||
>100< /= >NAN<, result: float(NAN)
|
||||
>100< /= >1<, result: int(100)
|
||||
>100< /= >123<, result: float(0.8130081300813)
|
||||
>100< /= >2e+5<, result: float(0.0005)
|
||||
>100< /= >9223372036854775807<, result: float(1.0842021724855E-17)
|
||||
-------------------------------------
|
||||
>-34000000000< /= >-10<, result: float(3400000000)
|
||||
>-34000000000< /= >100<, result: float(-340000000)
|
||||
>-34000000000< /= >-34000000000<, result: float(1)
|
||||
>-34000000000< /= >INF<, result: float(-0)
|
||||
>-34000000000< /= >-INF<, result: float(0)
|
||||
>-34000000000< /= >NAN<, result: float(NAN)
|
||||
>-34000000000< /= >1<, result: float(-34000000000)
|
||||
>-34000000000< /= >123<, result: float(-276422764.22764)
|
||||
>-34000000000< /= >2e+5<, result: float(-170000)
|
||||
>-34000000000< /= >9223372036854775807<, result: float(-3.6862873864507E-9)
|
||||
-------------------------------------
|
||||
>INF< /= >-10<, result: float(-INF)
|
||||
>INF< /= >100<, result: float(INF)
|
||||
>INF< /= >-34000000000<, result: float(-INF)
|
||||
>INF< /= >INF<, result: float(NAN)
|
||||
>INF< /= >-INF<, result: float(NAN)
|
||||
>INF< /= >NAN<, result: float(NAN)
|
||||
>INF< /= >1<, result: float(INF)
|
||||
>INF< /= >123<, result: float(INF)
|
||||
>INF< /= >2e+5<, result: float(INF)
|
||||
>INF< /= >9223372036854775807<, result: float(INF)
|
||||
-------------------------------------
|
||||
>-INF< /= >-10<, result: float(INF)
|
||||
>-INF< /= >100<, result: float(-INF)
|
||||
>-INF< /= >-34000000000<, result: float(INF)
|
||||
>-INF< /= >INF<, result: float(NAN)
|
||||
>-INF< /= >-INF<, result: float(NAN)
|
||||
>-INF< /= >NAN<, result: float(NAN)
|
||||
>-INF< /= >1<, result: float(-INF)
|
||||
>-INF< /= >123<, result: float(-INF)
|
||||
>-INF< /= >2e+5<, result: float(-INF)
|
||||
>-INF< /= >9223372036854775807<, result: float(-INF)
|
||||
-------------------------------------
|
||||
>NAN< /= >-10<, result: float(NAN)
|
||||
>NAN< /= >100<, result: float(NAN)
|
||||
>NAN< /= >-34000000000<, result: float(NAN)
|
||||
>NAN< /= >INF<, result: float(NAN)
|
||||
>NAN< /= >-INF<, result: float(NAN)
|
||||
>NAN< /= >NAN<, result: float(NAN)
|
||||
>NAN< /= >1<, result: float(NAN)
|
||||
>NAN< /= >123<, result: float(NAN)
|
||||
>NAN< /= >2e+5<, result: float(NAN)
|
||||
>NAN< /= >9223372036854775807<, result: float(NAN)
|
||||
-------------------------------------
|
||||
>1< /= >-10<, result: float(-0.1)
|
||||
>1< /= >100<, result: float(0.01)
|
||||
>1< /= >-34000000000<, result: float(-2.9411764705882E-11)
|
||||
>1< /= >INF<, result: float(0)
|
||||
>1< /= >-INF<, result: float(-0)
|
||||
>1< /= >NAN<, result: float(NAN)
|
||||
>1< /= >1<, result: int(1)
|
||||
>1< /= >123<, result: float(0.008130081300813)
|
||||
>1< /= >2e+5<, result: float(5.0E-6)
|
||||
>1< /= >9223372036854775807<, result: float(1.0842021724855E-19)
|
||||
-------------------------------------
|
||||
>< /= >-10<, result: int(0)
|
||||
>< /= >100<, result: int(0)
|
||||
>< /= >-34000000000<, result: float(-0)
|
||||
>< /= >INF<, result: float(0)
|
||||
>< /= >-INF<, result: float(-0)
|
||||
>< /= >NAN<, result: float(NAN)
|
||||
>< /= >1<, result: int(0)
|
||||
>< /= >123<, result: int(0)
|
||||
>< /= >2e+5<, result: float(0)
|
||||
>< /= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>< /= >-10<, result: int(0)
|
||||
>< /= >100<, result: int(0)
|
||||
>< /= >-34000000000<, result: float(-0)
|
||||
>< /= >INF<, result: float(0)
|
||||
>< /= >-INF<, result: float(-0)
|
||||
>< /= >NAN<, result: float(NAN)
|
||||
>< /= >1<, result: int(0)
|
||||
>< /= >123<, result: int(0)
|
||||
>< /= >2e+5<, result: float(0)
|
||||
>< /= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>123< /= >-10<, result: float(-12.3)
|
||||
>123< /= >100<, result: float(1.23)
|
||||
>123< /= >-34000000000<, result: float(-3.6176470588235E-9)
|
||||
>123< /= >INF<, result: float(0)
|
||||
>123< /= >-INF<, result: float(-0)
|
||||
>123< /= >NAN<, result: float(NAN)
|
||||
>123< /= >1<, result: int(123)
|
||||
>123< /= >123<, result: int(1)
|
||||
>123< /= >2e+5<, result: float(0.000615)
|
||||
>123< /= >9223372036854775807<, result: float(1.3335686721572E-17)
|
||||
-------------------------------------
|
||||
>2e+5< /= >-10<, result: float(-20000)
|
||||
>2e+5< /= >100<, result: float(2000)
|
||||
>2e+5< /= >-34000000000<, result: float(-5.8823529411765E-6)
|
||||
>2e+5< /= >INF<, result: float(0)
|
||||
>2e+5< /= >-INF<, result: float(-0)
|
||||
>2e+5< /= >NAN<, result: float(NAN)
|
||||
>2e+5< /= >1<, result: float(200000)
|
||||
>2e+5< /= >123<, result: float(1626.0162601626)
|
||||
>2e+5< /= >2e+5<, result: float(1)
|
||||
>2e+5< /= >9223372036854775807<, result: float(2.168404344971E-14)
|
||||
-------------------------------------
|
||||
>< /= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< /= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< /= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>< /= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>< /= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>< /= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>< /= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< /= >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< /= >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>< /= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>abc< /= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< /= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< /= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>abc< /= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>abc< /= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>abc< /= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>abc< /= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< /= >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< /= >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>abc< /= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>9223372036854775807< /= >-10<, result: float(-9.2233720368548E+17)
|
||||
>9223372036854775807< /= >100<, result: float(9.2233720368548E+16)
|
||||
>9223372036854775807< /= >-34000000000<, result: float(-271275648.14279)
|
||||
>9223372036854775807< /= >INF<, result: float(0)
|
||||
>9223372036854775807< /= >-INF<, result: float(-0)
|
||||
>9223372036854775807< /= >NAN<, result: float(NAN)
|
||||
>9223372036854775807< /= >1<, result: int(9223372036854775807)
|
||||
>9223372036854775807< /= >123<, result: float(7.4986764527275E+16)
|
||||
>9223372036854775807< /= >2e+5<, result: float(46116860184274)
|
||||
>9223372036854775807< /= >9223372036854775807<, result: int(1)
|
||||
-------------------------------------
|
|
@ -0,0 +1,22 @@
|
|||
--TEST--
|
||||
Misc. assignment operator testing
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
var_dump($v = 10);
|
||||
var_dump($v += 20);
|
||||
var_dump($v -= 5);
|
||||
var_dump($v .= 123.45);
|
||||
$a = [100, 200, 300];
|
||||
$i = 1;
|
||||
var_dump($a[$i++] += 50);
|
||||
var_dump($i);
|
||||
--EXPECT--
|
||||
int(10)
|
||||
int(30)
|
||||
int(25)
|
||||
string(8) "25123.45"
|
||||
int(250)
|
||||
int(2)
|
|
@ -0,0 +1,169 @@
|
|||
--TEST--
|
||||
%= operator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
foreach ($oper as $t)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
if (((int)$e2) == 0) continue; // skip divide-by-zeros
|
||||
|
||||
$e1 = $t;
|
||||
echo ">$e1< %= >$e2<, result: "; var_dump($e1 %= $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
>0< %= >-10<, result: int(0)
|
||||
>0< %= >100<, result: int(0)
|
||||
>0< %= >-34000000000<, result: int(0)
|
||||
>0< %= >1<, result: int(0)
|
||||
>0< %= >123<, result: int(0)
|
||||
>0< %= >2e+5<, result: int(0)
|
||||
>0< %= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>-10< %= >-10<, result: int(0)
|
||||
>-10< %= >100<, result: int(-10)
|
||||
>-10< %= >-34000000000<, result: int(-10)
|
||||
>-10< %= >1<, result: int(0)
|
||||
>-10< %= >123<, result: int(-10)
|
||||
>-10< %= >2e+5<, result: int(-10)
|
||||
>-10< %= >9223372036854775807<, result: int(-10)
|
||||
-------------------------------------
|
||||
>100< %= >-10<, result: int(0)
|
||||
>100< %= >100<, result: int(0)
|
||||
>100< %= >-34000000000<, result: int(100)
|
||||
>100< %= >1<, result: int(0)
|
||||
>100< %= >123<, result: int(100)
|
||||
>100< %= >2e+5<, result: int(100)
|
||||
>100< %= >9223372036854775807<, result: int(100)
|
||||
-------------------------------------
|
||||
>-34000000000< %= >-10<, result: int(0)
|
||||
>-34000000000< %= >100<, result: int(0)
|
||||
>-34000000000< %= >-34000000000<, result: int(0)
|
||||
>-34000000000< %= >1<, result: int(0)
|
||||
>-34000000000< %= >123<, result: int(-28)
|
||||
>-34000000000< %= >2e+5<, result: int(0)
|
||||
>-34000000000< %= >9223372036854775807<, result: int(-34000000000)
|
||||
-------------------------------------
|
||||
>INF< %= >-10<, result: int(0)
|
||||
>INF< %= >100<, result: int(0)
|
||||
>INF< %= >-34000000000<, result: int(0)
|
||||
>INF< %= >1<, result: int(0)
|
||||
>INF< %= >123<, result: int(0)
|
||||
>INF< %= >2e+5<, result: int(0)
|
||||
>INF< %= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>-INF< %= >-10<, result: int(0)
|
||||
>-INF< %= >100<, result: int(0)
|
||||
>-INF< %= >-34000000000<, result: int(0)
|
||||
>-INF< %= >1<, result: int(0)
|
||||
>-INF< %= >123<, result: int(0)
|
||||
>-INF< %= >2e+5<, result: int(0)
|
||||
>-INF< %= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>NAN< %= >-10<, result: int(0)
|
||||
>NAN< %= >100<, result: int(0)
|
||||
>NAN< %= >-34000000000<, result: int(0)
|
||||
>NAN< %= >1<, result: int(0)
|
||||
>NAN< %= >123<, result: int(0)
|
||||
>NAN< %= >2e+5<, result: int(0)
|
||||
>NAN< %= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>1< %= >-10<, result: int(1)
|
||||
>1< %= >100<, result: int(1)
|
||||
>1< %= >-34000000000<, result: int(1)
|
||||
>1< %= >1<, result: int(0)
|
||||
>1< %= >123<, result: int(1)
|
||||
>1< %= >2e+5<, result: int(1)
|
||||
>1< %= >9223372036854775807<, result: int(1)
|
||||
-------------------------------------
|
||||
>< %= >-10<, result: int(0)
|
||||
>< %= >100<, result: int(0)
|
||||
>< %= >-34000000000<, result: int(0)
|
||||
>< %= >1<, result: int(0)
|
||||
>< %= >123<, result: int(0)
|
||||
>< %= >2e+5<, result: int(0)
|
||||
>< %= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>< %= >-10<, result: int(0)
|
||||
>< %= >100<, result: int(0)
|
||||
>< %= >-34000000000<, result: int(0)
|
||||
>< %= >1<, result: int(0)
|
||||
>< %= >123<, result: int(0)
|
||||
>< %= >2e+5<, result: int(0)
|
||||
>< %= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>123< %= >-10<, result: int(3)
|
||||
>123< %= >100<, result: int(23)
|
||||
>123< %= >-34000000000<, result: int(123)
|
||||
>123< %= >1<, result: int(0)
|
||||
>123< %= >123<, result: int(0)
|
||||
>123< %= >2e+5<, result: int(123)
|
||||
>123< %= >9223372036854775807<, result: int(123)
|
||||
-------------------------------------
|
||||
>2e+5< %= >-10<, result: int(0)
|
||||
>2e+5< %= >100<, result: int(0)
|
||||
>2e+5< %= >-34000000000<, result: int(200000)
|
||||
>2e+5< %= >1<, result: int(0)
|
||||
>2e+5< %= >123<, result: int(2)
|
||||
>2e+5< %= >2e+5<, result: int(0)
|
||||
>2e+5< %= >9223372036854775807<, result: int(200000)
|
||||
-------------------------------------
|
||||
>< %= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< %= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< %= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< %= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< %= >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< %= >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< %= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>abc< %= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< %= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< %= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< %= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< %= >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< %= >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< %= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>9223372036854775807< %= >-10<, result: int(7)
|
||||
>9223372036854775807< %= >100<, result: int(7)
|
||||
>9223372036854775807< %= >-34000000000<, result: int(4854775807)
|
||||
>9223372036854775807< %= >1<, result: int(0)
|
||||
>9223372036854775807< %= >123<, result: int(7)
|
||||
>9223372036854775807< %= >2e+5<, result: int(175807)
|
||||
>9223372036854775807< %= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
|
@ -0,0 +1,379 @@
|
|||
--TEST--
|
||||
*= operator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
foreach ($oper as $t)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
$e1 = $t;
|
||||
echo ">$e1< *= >$e2<, result: "; var_dump($e1 *= $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
>0< *= >0<, result: int(0)
|
||||
>0< *= >-10<, result: int(0)
|
||||
>0< *= >100<, result: int(0)
|
||||
>0< *= >-34000000000<, result: float(-0)
|
||||
>0< *= >INF<, result: float(NAN)
|
||||
>0< *= >-INF<, result: float(NAN)
|
||||
>0< *= >NAN<, result: float(NAN)
|
||||
>0< *= >1<, result: int(0)
|
||||
>0< *= ><, result: int(0)
|
||||
>0< *= ><, result: int(0)
|
||||
>0< *= >123<, result: int(0)
|
||||
>0< *= >2e+5<, result: float(0)
|
||||
>0< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< *= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>-10< *= >0<, result: int(0)
|
||||
>-10< *= >-10<, result: int(100)
|
||||
>-10< *= >100<, result: int(-1000)
|
||||
>-10< *= >-34000000000<, result: float(340000000000)
|
||||
>-10< *= >INF<, result: float(-INF)
|
||||
>-10< *= >-INF<, result: float(INF)
|
||||
>-10< *= >NAN<, result: float(NAN)
|
||||
>-10< *= >1<, result: int(-10)
|
||||
>-10< *= ><, result: int(0)
|
||||
>-10< *= ><, result: int(0)
|
||||
>-10< *= >123<, result: int(-1230)
|
||||
>-10< *= >2e+5<, result: float(-2000000)
|
||||
>-10< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-10< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-10< *= >9223372036854775807<, result: float(-9.2233720368548E+19)
|
||||
-------------------------------------
|
||||
>100< *= >0<, result: int(0)
|
||||
>100< *= >-10<, result: int(-1000)
|
||||
>100< *= >100<, result: int(10000)
|
||||
>100< *= >-34000000000<, result: float(-3400000000000)
|
||||
>100< *= >INF<, result: float(INF)
|
||||
>100< *= >-INF<, result: float(-INF)
|
||||
>100< *= >NAN<, result: float(NAN)
|
||||
>100< *= >1<, result: int(100)
|
||||
>100< *= ><, result: int(0)
|
||||
>100< *= ><, result: int(0)
|
||||
>100< *= >123<, result: int(12300)
|
||||
>100< *= >2e+5<, result: float(20000000)
|
||||
>100< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>100< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>100< *= >9223372036854775807<, result: float(9.2233720368548E+20)
|
||||
-------------------------------------
|
||||
>-34000000000< *= >0<, result: float(-0)
|
||||
>-34000000000< *= >-10<, result: float(340000000000)
|
||||
>-34000000000< *= >100<, result: float(-3400000000000)
|
||||
>-34000000000< *= >-34000000000<, result: float(1.156E+21)
|
||||
>-34000000000< *= >INF<, result: float(-INF)
|
||||
>-34000000000< *= >-INF<, result: float(INF)
|
||||
>-34000000000< *= >NAN<, result: float(NAN)
|
||||
>-34000000000< *= >1<, result: float(-34000000000)
|
||||
>-34000000000< *= ><, result: float(-0)
|
||||
>-34000000000< *= ><, result: float(-0)
|
||||
>-34000000000< *= >123<, result: float(-4182000000000)
|
||||
>-34000000000< *= >2e+5<, result: float(-6.8E+15)
|
||||
>-34000000000< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>-34000000000< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>-34000000000< *= >9223372036854775807<, result: float(-3.1359464925306E+29)
|
||||
-------------------------------------
|
||||
>INF< *= >0<, result: float(NAN)
|
||||
>INF< *= >-10<, result: float(-INF)
|
||||
>INF< *= >100<, result: float(INF)
|
||||
>INF< *= >-34000000000<, result: float(-INF)
|
||||
>INF< *= >INF<, result: float(INF)
|
||||
>INF< *= >-INF<, result: float(-INF)
|
||||
>INF< *= >NAN<, result: float(NAN)
|
||||
>INF< *= >1<, result: float(INF)
|
||||
>INF< *= ><, result: float(NAN)
|
||||
>INF< *= ><, result: float(NAN)
|
||||
>INF< *= >123<, result: float(INF)
|
||||
>INF< *= >2e+5<, result: float(INF)
|
||||
>INF< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>INF< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>INF< *= >9223372036854775807<, result: float(INF)
|
||||
-------------------------------------
|
||||
>-INF< *= >0<, result: float(NAN)
|
||||
>-INF< *= >-10<, result: float(INF)
|
||||
>-INF< *= >100<, result: float(-INF)
|
||||
>-INF< *= >-34000000000<, result: float(INF)
|
||||
>-INF< *= >INF<, result: float(-INF)
|
||||
>-INF< *= >-INF<, result: float(INF)
|
||||
>-INF< *= >NAN<, result: float(NAN)
|
||||
>-INF< *= >1<, result: float(-INF)
|
||||
>-INF< *= ><, result: float(NAN)
|
||||
>-INF< *= ><, result: float(NAN)
|
||||
>-INF< *= >123<, result: float(-INF)
|
||||
>-INF< *= >2e+5<, result: float(-INF)
|
||||
>-INF< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>-INF< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>-INF< *= >9223372036854775807<, result: float(-INF)
|
||||
-------------------------------------
|
||||
>NAN< *= >0<, result: float(NAN)
|
||||
>NAN< *= >-10<, result: float(NAN)
|
||||
>NAN< *= >100<, result: float(NAN)
|
||||
>NAN< *= >-34000000000<, result: float(NAN)
|
||||
>NAN< *= >INF<, result: float(NAN)
|
||||
>NAN< *= >-INF<, result: float(NAN)
|
||||
>NAN< *= >NAN<, result: float(NAN)
|
||||
>NAN< *= >1<, result: float(NAN)
|
||||
>NAN< *= ><, result: float(NAN)
|
||||
>NAN< *= ><, result: float(NAN)
|
||||
>NAN< *= >123<, result: float(NAN)
|
||||
>NAN< *= >2e+5<, result: float(NAN)
|
||||
>NAN< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>NAN< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>NAN< *= >9223372036854775807<, result: float(NAN)
|
||||
-------------------------------------
|
||||
>1< *= >0<, result: int(0)
|
||||
>1< *= >-10<, result: int(-10)
|
||||
>1< *= >100<, result: int(100)
|
||||
>1< *= >-34000000000<, result: float(-34000000000)
|
||||
>1< *= >INF<, result: float(INF)
|
||||
>1< *= >-INF<, result: float(-INF)
|
||||
>1< *= >NAN<, result: float(NAN)
|
||||
>1< *= >1<, result: int(1)
|
||||
>1< *= ><, result: int(0)
|
||||
>1< *= ><, result: int(0)
|
||||
>1< *= >123<, result: int(123)
|
||||
>1< *= >2e+5<, result: float(200000)
|
||||
>1< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>1< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>1< *= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>< *= >0<, result: int(0)
|
||||
>< *= >-10<, result: int(0)
|
||||
>< *= >100<, result: int(0)
|
||||
>< *= >-34000000000<, result: float(-0)
|
||||
>< *= >INF<, result: float(NAN)
|
||||
>< *= >-INF<, result: float(NAN)
|
||||
>< *= >NAN<, result: float(NAN)
|
||||
>< *= >1<, result: int(0)
|
||||
>< *= ><, result: int(0)
|
||||
>< *= ><, result: int(0)
|
||||
>< *= >123<, result: int(0)
|
||||
>< *= >2e+5<, result: float(0)
|
||||
>< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>< *= >0<, result: int(0)
|
||||
>< *= >-10<, result: int(0)
|
||||
>< *= >100<, result: int(0)
|
||||
>< *= >-34000000000<, result: float(-0)
|
||||
>< *= >INF<, result: float(NAN)
|
||||
>< *= >-INF<, result: float(NAN)
|
||||
>< *= >NAN<, result: float(NAN)
|
||||
>< *= >1<, result: int(0)
|
||||
>< *= ><, result: int(0)
|
||||
>< *= ><, result: int(0)
|
||||
>< *= >123<, result: int(0)
|
||||
>< *= >2e+5<, result: float(0)
|
||||
>< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >9223372036854775807<, result: int(0)
|
||||
-------------------------------------
|
||||
>123< *= >0<, result: int(0)
|
||||
>123< *= >-10<, result: int(-1230)
|
||||
>123< *= >100<, result: int(12300)
|
||||
>123< *= >-34000000000<, result: float(-4182000000000)
|
||||
>123< *= >INF<, result: float(INF)
|
||||
>123< *= >-INF<, result: float(-INF)
|
||||
>123< *= >NAN<, result: float(NAN)
|
||||
>123< *= >1<, result: int(123)
|
||||
>123< *= ><, result: int(0)
|
||||
>123< *= ><, result: int(0)
|
||||
>123< *= >123<, result: int(15129)
|
||||
>123< *= >2e+5<, result: float(24600000)
|
||||
>123< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>123< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>123< *= >9223372036854775807<, result: float(1.1344747605331E+21)
|
||||
-------------------------------------
|
||||
>2e+5< *= >0<, result: float(0)
|
||||
>2e+5< *= >-10<, result: float(-2000000)
|
||||
>2e+5< *= >100<, result: float(20000000)
|
||||
>2e+5< *= >-34000000000<, result: float(-6.8E+15)
|
||||
>2e+5< *= >INF<, result: float(INF)
|
||||
>2e+5< *= >-INF<, result: float(-INF)
|
||||
>2e+5< *= >NAN<, result: float(NAN)
|
||||
>2e+5< *= >1<, result: float(200000)
|
||||
>2e+5< *= ><, result: float(0)
|
||||
>2e+5< *= ><, result: float(0)
|
||||
>2e+5< *= >123<, result: float(24600000)
|
||||
>2e+5< *= >2e+5<, result: float(40000000000)
|
||||
>2e+5< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>2e+5< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>2e+5< *= >9223372036854775807<, result: float(1.844674407371E+24)
|
||||
-------------------------------------
|
||||
>< *= >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>< *= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>< *= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>< *= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>< *= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< *= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>abc< *= >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(-0)
|
||||
>abc< *= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>abc< *= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>abc< *= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(NAN)
|
||||
>abc< *= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= >123<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= >2e+5<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
float(0)
|
||||
>abc< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< *= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
-------------------------------------
|
||||
>9223372036854775807< *= >0<, result: int(0)
|
||||
>9223372036854775807< *= >-10<, result: float(-9.2233720368548E+19)
|
||||
>9223372036854775807< *= >100<, result: float(9.2233720368548E+20)
|
||||
>9223372036854775807< *= >-34000000000<, result: float(-3.1359464925306E+29)
|
||||
>9223372036854775807< *= >INF<, result: float(INF)
|
||||
>9223372036854775807< *= >-INF<, result: float(-INF)
|
||||
>9223372036854775807< *= >NAN<, result: float(NAN)
|
||||
>9223372036854775807< *= >1<, result: int(9223372036854775807)
|
||||
>9223372036854775807< *= ><, result: int(0)
|
||||
>9223372036854775807< *= ><, result: int(0)
|
||||
>9223372036854775807< *= >123<, result: float(1.1344747605331E+21)
|
||||
>9223372036854775807< *= >2e+5<, result: float(1.844674407371E+24)
|
||||
>9223372036854775807< *= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>9223372036854775807< *= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>9223372036854775807< *= >9223372036854775807<, result: float(8.5070591730235E+37)
|
||||
-------------------------------------
|
|
@ -0,0 +1,347 @@
|
|||
--TEST--
|
||||
|= operator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/common.inc';
|
||||
|
||||
foreach ($oper as $t)
|
||||
{
|
||||
foreach ($oper as $e2)
|
||||
{
|
||||
$e1 = $t;
|
||||
echo ">$e1< |= >$e2<, result: "; var_dump($e1 |= $e2);
|
||||
}
|
||||
echo "-------------------------------------\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
>0< |= >0<, result: int(0)
|
||||
>0< |= >-10<, result: int(-10)
|
||||
>0< |= >100<, result: int(100)
|
||||
>0< |= >-34000000000<, result: int(-34000000000)
|
||||
>0< |= >INF<, result: int(0)
|
||||
>0< |= >-INF<, result: int(0)
|
||||
>0< |= >NAN<, result: int(0)
|
||||
>0< |= >1<, result: int(1)
|
||||
>0< |= ><, result: int(0)
|
||||
>0< |= ><, result: int(0)
|
||||
>0< |= >123<, result: int(123)
|
||||
>0< |= >2e+5<, result: int(200000)
|
||||
>0< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>0< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>-10< |= >0<, result: int(-10)
|
||||
>-10< |= >-10<, result: int(-10)
|
||||
>-10< |= >100<, result: int(-10)
|
||||
>-10< |= >-34000000000<, result: int(-10)
|
||||
>-10< |= >INF<, result: int(-10)
|
||||
>-10< |= >-INF<, result: int(-10)
|
||||
>-10< |= >NAN<, result: int(-10)
|
||||
>-10< |= >1<, result: int(-9)
|
||||
>-10< |= ><, result: int(-10)
|
||||
>-10< |= ><, result: int(-10)
|
||||
>-10< |= >123<, result: int(-1)
|
||||
>-10< |= >2e+5<, result: int(-10)
|
||||
>-10< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>-10< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>-10< |= >9223372036854775807<, result: int(-1)
|
||||
-------------------------------------
|
||||
>100< |= >0<, result: int(100)
|
||||
>100< |= >-10<, result: int(-10)
|
||||
>100< |= >100<, result: int(100)
|
||||
>100< |= >-34000000000<, result: int(-33999999900)
|
||||
>100< |= >INF<, result: int(100)
|
||||
>100< |= >-INF<, result: int(100)
|
||||
>100< |= >NAN<, result: int(100)
|
||||
>100< |= >1<, result: int(101)
|
||||
>100< |= ><, result: int(100)
|
||||
>100< |= ><, result: int(100)
|
||||
>100< |= >123<, result: int(127)
|
||||
>100< |= >2e+5<, result: int(200036)
|
||||
>100< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>100< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>100< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>-34000000000< |= >0<, result: int(-34000000000)
|
||||
>-34000000000< |= >-10<, result: int(-10)
|
||||
>-34000000000< |= >100<, result: int(-33999999900)
|
||||
>-34000000000< |= >-34000000000<, result: int(-34000000000)
|
||||
>-34000000000< |= >INF<, result: int(-34000000000)
|
||||
>-34000000000< |= >-INF<, result: int(-34000000000)
|
||||
>-34000000000< |= >NAN<, result: int(-34000000000)
|
||||
>-34000000000< |= >1<, result: int(-33999999999)
|
||||
>-34000000000< |= ><, result: int(-34000000000)
|
||||
>-34000000000< |= ><, result: int(-34000000000)
|
||||
>-34000000000< |= >123<, result: int(-33999999877)
|
||||
>-34000000000< |= >2e+5<, result: int(-33999868608)
|
||||
>-34000000000< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-34000000000)
|
||||
>-34000000000< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-34000000000)
|
||||
>-34000000000< |= >9223372036854775807<, result: int(-1)
|
||||
-------------------------------------
|
||||
>INF< |= >0<, result: int(0)
|
||||
>INF< |= >-10<, result: int(-10)
|
||||
>INF< |= >100<, result: int(100)
|
||||
>INF< |= >-34000000000<, result: int(-34000000000)
|
||||
>INF< |= >INF<, result: int(0)
|
||||
>INF< |= >-INF<, result: int(0)
|
||||
>INF< |= >NAN<, result: int(0)
|
||||
>INF< |= >1<, result: int(1)
|
||||
>INF< |= ><, result: int(0)
|
||||
>INF< |= ><, result: int(0)
|
||||
>INF< |= >123<, result: int(123)
|
||||
>INF< |= >2e+5<, result: int(200000)
|
||||
>INF< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>INF< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>INF< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>-INF< |= >0<, result: int(0)
|
||||
>-INF< |= >-10<, result: int(-10)
|
||||
>-INF< |= >100<, result: int(100)
|
||||
>-INF< |= >-34000000000<, result: int(-34000000000)
|
||||
>-INF< |= >INF<, result: int(0)
|
||||
>-INF< |= >-INF<, result: int(0)
|
||||
>-INF< |= >NAN<, result: int(0)
|
||||
>-INF< |= >1<, result: int(1)
|
||||
>-INF< |= ><, result: int(0)
|
||||
>-INF< |= ><, result: int(0)
|
||||
>-INF< |= >123<, result: int(123)
|
||||
>-INF< |= >2e+5<, result: int(200000)
|
||||
>-INF< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-INF< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>-INF< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>NAN< |= >0<, result: int(0)
|
||||
>NAN< |= >-10<, result: int(-10)
|
||||
>NAN< |= >100<, result: int(100)
|
||||
>NAN< |= >-34000000000<, result: int(-34000000000)
|
||||
>NAN< |= >INF<, result: int(0)
|
||||
>NAN< |= >-INF<, result: int(0)
|
||||
>NAN< |= >NAN<, result: int(0)
|
||||
>NAN< |= >1<, result: int(1)
|
||||
>NAN< |= ><, result: int(0)
|
||||
>NAN< |= ><, result: int(0)
|
||||
>NAN< |= >123<, result: int(123)
|
||||
>NAN< |= >2e+5<, result: int(200000)
|
||||
>NAN< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>NAN< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>NAN< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>1< |= >0<, result: int(1)
|
||||
>1< |= >-10<, result: int(-9)
|
||||
>1< |= >100<, result: int(101)
|
||||
>1< |= >-34000000000<, result: int(-33999999999)
|
||||
>1< |= >INF<, result: int(1)
|
||||
>1< |= >-INF<, result: int(1)
|
||||
>1< |= >NAN<, result: int(1)
|
||||
>1< |= >1<, result: int(1)
|
||||
>1< |= ><, result: int(1)
|
||||
>1< |= ><, result: int(1)
|
||||
>1< |= >123<, result: int(123)
|
||||
>1< |= >2e+5<, result: int(200001)
|
||||
>1< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>1< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>1< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>< |= >0<, result: int(0)
|
||||
>< |= >-10<, result: int(-10)
|
||||
>< |= >100<, result: int(100)
|
||||
>< |= >-34000000000<, result: int(-34000000000)
|
||||
>< |= >INF<, result: int(0)
|
||||
>< |= >-INF<, result: int(0)
|
||||
>< |= >NAN<, result: int(0)
|
||||
>< |= >1<, result: int(1)
|
||||
>< |= ><, result: int(0)
|
||||
>< |= ><, result: int(0)
|
||||
>< |= >123<, result: int(123)
|
||||
>< |= >2e+5<, result: int(200000)
|
||||
>< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>< |= >0<, result: int(0)
|
||||
>< |= >-10<, result: int(-10)
|
||||
>< |= >100<, result: int(100)
|
||||
>< |= >-34000000000<, result: int(-34000000000)
|
||||
>< |= >INF<, result: int(0)
|
||||
>< |= >-INF<, result: int(0)
|
||||
>< |= >NAN<, result: int(0)
|
||||
>< |= >1<, result: int(1)
|
||||
>< |= ><, result: int(0)
|
||||
>< |= ><, result: int(0)
|
||||
>< |= >123<, result: int(123)
|
||||
>< |= >2e+5<, result: int(200000)
|
||||
>< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>123< |= >0<, result: int(123)
|
||||
>123< |= >-10<, result: int(-1)
|
||||
>123< |= >100<, result: int(127)
|
||||
>123< |= >-34000000000<, result: int(-33999999877)
|
||||
>123< |= >INF<, result: int(123)
|
||||
>123< |= >-INF<, result: int(123)
|
||||
>123< |= >NAN<, result: int(123)
|
||||
>123< |= >1<, result: int(123)
|
||||
>123< |= ><, result: int(123)
|
||||
>123< |= ><, result: int(123)
|
||||
>123< |= >123<, result: string(3) "123"
|
||||
>123< |= >2e+5<, result: string(4) "3w;5"
|
||||
>123< |= ><, result: string(3) "123"
|
||||
>123< |= >abc<, result: string(3) "qrs"
|
||||
>123< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>2e+5< |= >0<, result: int(200000)
|
||||
>2e+5< |= >-10<, result: int(-10)
|
||||
>2e+5< |= >100<, result: int(200036)
|
||||
>2e+5< |= >-34000000000<, result: int(-33999868608)
|
||||
>2e+5< |= >INF<, result: int(200000)
|
||||
>2e+5< |= >-INF<, result: int(200000)
|
||||
>2e+5< |= >NAN<, result: int(200000)
|
||||
>2e+5< |= >1<, result: int(200001)
|
||||
>2e+5< |= ><, result: int(200000)
|
||||
>2e+5< |= ><, result: int(200000)
|
||||
>2e+5< |= >123<, result: string(4) "3w;5"
|
||||
>2e+5< |= >2e+5<, result: string(4) "2e+5"
|
||||
>2e+5< |= ><, result: string(4) "2e+5"
|
||||
>2e+5< |= >abc<, result: string(4) "sgk5"
|
||||
>2e+5< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>< |= >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>< |= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>< |= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-34000000000)
|
||||
>< |= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>< |= >123<, result: string(3) "123"
|
||||
>< |= >2e+5<, result: string(4) "2e+5"
|
||||
>< |= ><, result: string(0) ""
|
||||
>< |= >abc<, result: string(3) "abc"
|
||||
>< |= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>abc< |= >0<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< |= >-10<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-10)
|
||||
>abc< |= >100<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(100)
|
||||
>abc< |= >-34000000000<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(-34000000000)
|
||||
>abc< |= >INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< |= >-INF<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< |= >NAN<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< |= >1<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(1)
|
||||
>abc< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(0)
|
||||
>abc< |= >123<, result: string(3) "qrs"
|
||||
>abc< |= >2e+5<, result: string(4) "sgk5"
|
||||
>abc< |= ><, result: string(3) "abc"
|
||||
>abc< |= >abc<, result: string(3) "abc"
|
||||
>abc< |= >9223372036854775807<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
-------------------------------------
|
||||
>9223372036854775807< |= >0<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= >-10<, result: int(-1)
|
||||
>9223372036854775807< |= >100<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= >-34000000000<, result: int(-1)
|
||||
>9223372036854775807< |= >INF<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= >-INF<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= >NAN<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= >1<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= ><, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= ><, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= >123<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= >2e+5<, result: int(9223372036854775807)
|
||||
>9223372036854775807< |= ><, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
>9223372036854775807< |= >abc<, result:
|
||||
Warning: A non-numeric value encountered in %s on line %d
|
||||
int(9223372036854775807)
|
||||
>9223372036854775807< |= >9223372036854775807<, result: int(9223372036854775807)
|
||||
-------------------------------------
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче