Merge commit 'a7d64bac1248a8ad2fba9bfd0e96efd6574f5d92' as 'php-langspec'

This commit is contained in:
Sara Itani 2016-10-26 19:42:47 -07:00
Родитель b074de8a00 a7d64bac12
Коммит a6d4e312e5
272 изменённых файлов: 43878 добавлений и 0 удалений

1
php-langspec/.gitignore поставляемый Normal file
Просмотреть файл

@ -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.

9
php-langspec/LICENSE Normal file
Просмотреть файл

@ -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.

29
php-langspec/README.md Normal file
Просмотреть файл

@ -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> &lt;&lt;&lt; <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> &lt;&lt;&lt; ' <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>
[ ] ( ) { } . -> ++ -- ** * + - ~ !
$ / % &lt;&lt; &gt;&gt; &lt; &gt; &lt;= &gt;= == === != !== ^ |
& && || ? : ; = **= *= /= %= += -= .= &lt;&lt;=
&gt;&gt;= &= ^= |= , ?? &lt;=&gt; ... \
</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

7
php-langspec/tests/.gitignore поставляемый Normal file
Просмотреть файл

@ -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)
}
}

Двоичные данные
php-langspec/tests/classes/__php_incomplete_class.phpt Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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 -------------------

Двоичные данные
php-langspec/tests/classes/sleep_and_wakeup.phpt Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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)
-------------------------------------

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше