# Language

# Attributes

## Attributes overview

PHP attributes provide structured, machine-readable metadata for classes, methods, functions, parameters, properties, and constants. They can be inspected at runtime via the [Reflection API](#book.reflection), enabling dynamic behavior without modifying code. Attributes provide a declarative way to annotate code with metadata.

Attributes enable the decoupling of a feature's implementation from its usage. While interfaces define structure by enforcing methods, attributes provide metadata across multiple elements, including methods, functions, properties, and constants. Unlike interfaces, which enforce method implementations, attributes annotate code without altering its structure.

Attributes can complement or replace optional interface methods by providing metadata instead of enforced structure. Consider an `ActionHandler` interface that represents an operation in an application. Some implementations may require a setup step while others do not. Instead of forcing all classes implementing `ActionHandler` to define a `setUp()` method, an attribute can indicate setup requirements. This approach increases flexibility, allowing attributes to be applied multiple times when necessary.

<div class="example">

<div class="title">

Implementing optional methods of an interface with Attributes

</div>

```
<?php
interface ActionHandler
{
    public function execute();
}

#[Attribute]
class SetUp {}

class CopyFile implements ActionHandler
{
    public string $fileName;
    public string $targetDirectory;

    #[SetUp]
    public function fileExists()
    {
        if (!file_exists($this->fileName)) {
            throw new RuntimeException("File does not exist");
        }
    }

    #[SetUp]
    public function targetDirectoryExists()
    {
        if (!file_exists($this->targetDirectory)) {
            mkdir($this->targetDirectory);
        } elseif (!is_dir($this->targetDirectory)) {
            throw new RuntimeException("Target directory $this->targetDirectory is not a directory");
        }
    }

    public function execute()
    {
        copy($this->fileName, $this->targetDirectory . '/' . basename($this->fileName));
    }
}

function executeAction(ActionHandler $actionHandler)
{
    $reflection = new ReflectionObject($actionHandler);

    foreach ($reflection->getMethods() as $method) {
        $attributes = $method->getAttributes(SetUp::class);

        if (count($attributes) > 0) {
            $methodName = $method->getName();

            $actionHandler->$methodName();
        }
    }

    $actionHandler->execute();
}

$copyAction = new CopyFile();
$copyAction->fileName = "/tmp/foo.jpg";
$copyAction->targetDirectory = "/home/user";

executeAction($copyAction);

     
```

</div>

## Attribute syntax

Attribute syntax consists of several key components. An attribute declaration starts with `#[` and ends with `]`. Inside, one or more attributes can be listed, separated by commas. The attribute name can be unqualified, qualified, or fully-qualified, as described in [Using Namespaces Basics](#language.namespaces.basics). Arguments to the attribute are optional and enclosed in parentheses `()`. Arguments can only be literal values or constant expressions. Both positional and named argument syntax are supported.

Attribute names and their arguments are resolved to a class, and the arguments are passed to its constructor when an instance of the attribute is requested through the Reflection API. Therefore, it is recommended to introduce a class for each attribute.

<div class="example">

<div class="title">

Attribute Syntax

</div>

```
<?php
// a.php
namespace MyExample;

use Attribute;

#[Attribute]
class MyAttribute
{
    const VALUE = 'value';

    private $value;

    public function __construct($value = null)
    {
        $this->value = $value;
    }
}

// b.php

namespace Another;

use MyExample\MyAttribute;

#[MyAttribute]
#[\MyExample\MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(value: 1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute(array("key" => "value"))]
#[MyAttribute(100 + 200)]
class Thing
{
}

#[MyAttribute(1234), MyAttribute(5678)]
class AnotherThing
{
}

    
```

</div>

## Reading Attributes with the Reflection API

To access attributes from classes, methods, functions, parameters, properties, and class constants, use the `getAttributes` method provided by the Reflection API. This method returns an array of `ReflectionAttribute` instances. These instances can be queried for the attribute name, arguments, and can be used to instantiate an instance of the represented attribute.

Separating the reflected attribute representation from its actual instance provides more control over error handling, such as missing attribute classes, mistyped arguments, or missing values. Objects of the attribute class are instantiated only after calling `ReflectionAttribute::newInstance`, ensuring that argument validation occurs at that point.

<div class="example">

<div class="title">

Reading Attributes using Reflection API

</div>

```
<?php

#[Attribute]
class MyAttribute
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }
}

#[MyAttribute(value: 1234)]
class Thing
{
}

function dumpAttributeData($reflection) {
    $attributes = $reflection->getAttributes();

    foreach ($attributes as $attribute) {
       var_dump($attribute->getName());
       var_dump($attribute->getArguments());
       var_dump($attribute->newInstance());
    }
}

dumpAttributeData(new ReflectionClass(Thing::class));

    
```

ENTITY

    string(11) "MyAttribute"
    array(1) {
      ["value"]=>
      int(1234)
    }
    object(MyAttribute)#3 (1) {
      ["value"]=>
      int(1234)
    }

        

</div>

Instead of iterating over all attributes on the reflection instance, you can retrieve only those of a specific attribute class by passing the attribute class name as an argument.

<div class="example">

<div class="title">

Reading Specific Attributes using Reflection API

</div>

```
<?php
#[Attribute]
class MyAttribute
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }
}

#[MyAttribute(value: 1234)]
class Thing
{
}

function dumpMyAttributeData($reflection) {
    $attributes = $reflection->getAttributes(MyAttribute::class);

    foreach ($attributes as $attribute) {
       var_dump($attribute->getName());
       var_dump($attribute->getArguments());
       var_dump($attribute->newInstance());
    }
}

dumpMyAttributeData(new ReflectionClass(Thing::class));

     
```

</div>

## Declaring Attribute Classes

It is recommended to define a separate class for each attribute. In the simplest case, an empty class with the `#[Attribute]` declaration is sufficient. The attribute can be imported from the global namespace using a `use` statement.

<div class="example">

<div class="title">

Simple Attribute Class

</div>

```
<?php

namespace Example;

use Attribute;

#[Attribute]
class MyAttribute
{
}

   
```

</div>

To restrict the types of declarations an attribute can be applied to, pass a bitmask as the first argument to the `#[Attribute]` declaration.

<div class="example">

<div class="title">

Using target specification to restrict where attributes can be used

</div>

```
<?php

namespace Example;

use Attribute;

#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class MyAttribute
{
}

    
```

Declaring `MyAttribute` on another type will now throw an exception during the call to `ReflectionAttribute::newInstance`

</div>

The following targets can be specified:

Attribute::TARGET_CLASS

Attribute::TARGET_FUNCTION

Attribute::TARGET_METHOD

Attribute::TARGET_PROPERTY

Attribute::TARGET_CLASS_CONSTANT

Attribute::TARGET_PARAMETER

Attribute::TARGET_ALL

By default, an attribute can only be used once per declaration. To allow an attribute to be repeatable, specify it in the bitmask of the `#[Attribute]` declaration using the `Attribute::IS_REPEATABLE` flag.

<div class="example">

<div class="title">

Using IS_REPEATABLE to allow attribute on a declaration multiple times

</div>

```
<?php

namespace Example;

use Attribute;

#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION | Attribute::IS_REPEATABLE)]
class MyAttribute
{
}

    
```

</div>

# Basic syntax

## PHP tags

When PHP processes a file, it recognizes the opening and closing tags, `ENTITY?php` and `?ENTITY`, to define the boundaries of PHP code execution. Content outside these tags is ignored by the PHP parser, allowing PHP to seamlessly embed in various document types.

A whitespace character (space, tab, or newline) must follow `ENTITY?php` to ensure proper token separation. Omitting this whitespace will result in a syntax error.

PHP also includes the short echo tag `ENTITY?=`, which is shorthand for `ENTITY?php echo`.

<div class="example">

<div class="title">

PHP Opening and Closing Tags

</div>

```
1.  <?php echo 'if you want to serve PHP code in XHTML or XML documents,
                use these tags'; ?>

2.  You can use the short echo tag to <?= 'print this string' ?>.
    It's equivalent to <?php echo 'print this string' ?>.

3.  <? echo 'this code is within short tags, but will only work '.
            'if short_open_tag is enabled'; ?>

     
```

</div>

Short tags (the third line in the example above) are available by default but can be disabled either via the [short_open_tag](#ini.short-open-tag) ENTITY configuration file directive, or are disabled by default if PHP is built with the `--disable-short-tags` configuration.

> [!NOTE]
> As short tags can be disabled it is recommended to only use the normal tags (`ENTITY?php ?ENTITY` and `ENTITY?= ?ENTITY`) to maximise compatibility.

If a file ends with PHP code, it is preferable to omit the PHP closing tag at the end of the file. This prevents accidental whitespace or new lines being added after the PHP closing tag, which may cause unwanted effects because PHP will start output buffering when there is no intention from the programmer to send any output at that point in the script.

<div class="example">

<div class="title">

PHP Code Only File

</div>

```
<?php
echo "Hello world\n";

// ... more code

echo "Last statement\n";

// the script ends here with no PHP closing tag

     
```

</div>

## Escaping from HTML

Everything outside of a pair of opening and closing tags is ignored by the PHP parser which allows PHP files to have mixed content. This allows PHP to be embedded in HTML documents, for example to create templates.

<div class="example">

<div class="title">

Embedding PHP in HTML

</div>

```
<p>This is going to be ignored by PHP and displayed by the browser.</p>
<?php echo 'While this is going to be parsed.'; ?>
<p>This will also be ignored by PHP and displayed by the browser.</p>

     
```

</div>

This works as expected, because when the PHP interpreter hits the ?ENTITY closing tags, it simply starts outputting whatever it finds (except for the immediately following newline - see [instruction separation](#language.basic-syntax.instruction-separation)) until it hits another opening tag unless in the middle of a conditional statement in which case the interpreter will determine the outcome of the conditional before making a decision of what to skip over. See the next example.

Using structures with conditions

<div class="example">

<div class="title">

Advanced escaping using conditions

</div>

```
<?php if (true): ?>
  This will show if the expression is true.
<?php else: ?>
  Otherwise this will show.
<?php endif; ?>

     
```

</div>

In this example PHP will skip the blocks where the condition is not met, even though they are outside of the PHP open/close tags; PHP skips them according to the condition since the PHP interpreter will jump over blocks contained within a condition that is not met.

For outputting large blocks of text, dropping out of PHP parsing mode is generally more efficient than sending all of the text through `echo` or `print`.

> [!NOTE]
> If PHP is embedded within XML or XHTML the normal PHP `ENTITY?php ?ENTITY` must be used to remain compliant with the standards.

## Instruction separation

As in C or Perl, PHP requires instructions to be terminated with a semicolon at the end of each statement. The closing tag of a block of PHP code automatically implies a semicolon; you do not need to have a semicolon terminating the last line of a PHP block. The closing tag for the block will include the immediately trailing newline if one is present.

<div class="example">

<div class="title">

Example showing the closing tag encompassing the trailing newline

</div>

```
<?php echo "Some text"; ?>
No newline
<?= "But newline now" ?>

     
```

ENTITY

    Some textNo newline
    But newline now

         

</div>

<div class="example">

<div class="title">

Examples of entering and exiting the PHP parser

</div>

```
<?php
    echo "This is a test\n";
?>

<?php echo "This is a test\n" ?>

<?php echo "We omitted the last closing tag\n";

     
```

</div>

> [!NOTE]
> The closing tag of a PHP block at the end of a file is optional, and in some cases omitting it is helpful when using `include` or `require`, so unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

## Comments

PHP supports 'C', 'C++' and Unix shell-style (Perl style) comments. For example:

<div class="example">

<div class="title">

Comments

</div>

```
<?php
    echo "This is a test\n"; // This is a one-line c++ style comment
    /* This is a multi line comment
       yet another line of comment */
    echo "This is yet another test\n";
    echo "One Final Test\n"; # This is a one-line shell-style comment
?>

     
```

</div>

The "one-line" comment styles only comment to the end of the line or the current block of PHP code, whichever comes first. This means that HTML code after `// ... ?ENTITY` or `# ... ?ENTITY` WILL be printed: ?ENTITY breaks out of PHP mode and returns to HTML mode, and `//` or `#` cannot influence that.

<div class="example">

<div class="title">

One Line Comments

</div>

```
<h1>This is an <?php # echo 'simple';?> example</h1>
<p>The header above will say 'This is an  example'.</p>

     
```

</div>

'C' style comments end at the first `*/` encountered. Make sure you don't nest 'C' style comments. It is easy to make this mistake if you are trying to comment out a large block of code.

<div class="informalexample">

```
<?php
 /*
    echo 'This is a test'; /* This comment will cause a problem */
 */
?>

     
```

</div>

# Constants

A constant is an identifier (name) for a simple value. As the name suggests, that value cannot change during the execution of the script (except for [ magic constants](#language.constants.magic), which aren't actually constants). Constants are case-sensitive. By convention, constant identifiers are always uppercase.

> [!NOTE]
> Prior to PHP 8.0.0, constants defined using the `define` function may be case-insensitive.

> [!NOTE]
> As of PHP 8.5.0, redeclaring an already-defined constant is deprecated.

The name of a constant follows the same rules as any label in PHP. A valid constant name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thusly: `^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$`

It is possible to `define` constants with reserved or even invalid names, whose value can only be retrieved with the `constant` function. However, doing so is not recommended.

ENTITY

<div class="example">

<div class="title">

Valid and invalid constant names

</div>

```
<?php

// Valid constant names
define("FOO",     "something");
define("FOO2",    "something else");
define("FOO_BAR", "something more");

// Invalid constant names
define("2FOO",    "something");

// This is valid, but should be avoided:
// PHP may one day provide a magical constant
// that will break your script
define("__FOO__", "something"); 

    
```

</div>

> [!NOTE]
> For our purposes here, a letter is a-z, A-Z, and the ASCII characters from 128 through 255 (0x80-0xff).

Like ENTITY, the scope of a constant is global. Constants can be accessed from anywhere in a script without regard to scope. For more information on scope, read the manual section on [variable scope](#language.variables.scope).

> [!NOTE]
> As of PHP 7.1.0, class constant may declare a visibility of protected or private, making them only available in the hierarchical scope of the class in which it is defined.

## Syntax

Constants can be defined using the `const` keyword, or by using the `define`-function. While `define` allows a constant to be defined to an arbitrary expression, the `const` keyword has restrictions as outlined in the next paragraph. Once a constant is defined, it can never be changed or undefined.

When using the `const` keyword, only scalar (`bool`, `int`, `float` and `string`) expressions and constant `array`s containing only scalar expressions are accepted. It is possible to define constants as a `resource`, but it should be avoided, as it can cause unexpected results.

The value of a constant is accessed simply by specifying its name. Unlike variables, a constant is *not* prepended with a `$`. It is also possible to use the `constant` function to read a constant's value if the constant's name is obtained dynamically. Use `get_defined_constants` to get a list of all defined constants.

> [!NOTE]
> Constants and (global) variables are in a different namespace. This implies that for example ENTITY and `$TRUE` are generally different.

If an undefined constant is used an `Error` is thrown. Prior to PHP 8.0.0, undefined constants would be interpreted as a bare word `string`, i.e. (CONSTANT vs "CONSTANT"). This fallback is deprecated as of PHP 7.2.0, and an error of level `E_WARNING` is issued when it happens. Prior to PHP 7.2.0, an error of level [E_NOTICE](#ref.errorfunc) has been issued instead. See also the manual entry on why [\$foo\[bar\]](#language.types.array.foo-bar) is wrong (unless `bar` is a constant). This does not apply to [(fully) qualified constants](#language.namespaces.rules), which will always raise a `Error` if undefined.

> [!NOTE]
> To check if a constant is set, use the `defined` function.

These are the differences between constants and variables:

- Constants do not have a dollar sign (`$`) before them;

- Constants may be defined and accessed anywhere without regard to variable scoping rules;

- Constants may not be redefined or undefined once they have been set; and

- Constants may only evaluate to scalar values or arrays.

<div class="example">

<div class="title">

Defining Constants

</div>

```
<?php
define("CONSTANT", "Hello world.");
echo CONSTANT; // outputs "Hello world."
echo Constant; // Emits an Error: Undefined constant "Constant"
               // Prior to PHP 8.0.0, outputs "Constant" and issues a warning.

     
```

</div>

<div class="example">

<div class="title">

Defining Constants using the `const` keyword

</div>

```
<?php
// Simple scalar value
const CONSTANT = 'Hello World';

echo CONSTANT . "\n";

// Scalar expression
const ANOTHER_CONST = CONSTANT . '; Goodbye World';
echo ANOTHER_CONST . "\n";

const ANIMALS = array('dog', 'cat', 'bird');
echo ANIMALS[1] . "\n"; // outputs "cat"

// Constant arrays
define('ANIMALS_DEF', array(
    'dog',
    'cat',
    'bird'
));
echo ANIMALS_DEF[1] . "\n"; // outputs "cat"

     
```

</div>

> [!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, `if` statements or `try`/`catch` blocks.

### 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | Added support for type casts (e.g. `(int)`, `(string)`) in constant expressions. Also added support for [Closures](#functions.anonymous) and [first-class callables](#functions.first_class_callable_syntax) in constant expressions. |

### 

ENTITY

[Class Constants](#language.oop5.constants)

## Predefined constants

PHP provides a large number of [predefined constants](#reserved.constants) to any script which it runs. Many of these constants, however, are created by various extensions, and will only be present when those extensions are available, either via dynamic loading or because they have been compiled in.

## Magic constants

Magic constants are keywords that are replaced with information about their own location in the source code: their file and line, and the function, class, trait, namespace, or property hook enclosing them. Despite their name, they are not actual constants: `defined` and `constant` do not recognize them, and a constant of the same name created with `define` does not affect them. They are case-insensitive. When used outside of the relevant context (e.g. `__CLASS__` outside of a class), they are replaced with an empty string.

| ENTITY | ENTITY |
|----|----|
| `__LINE__` | The line number on which it is written. |
| `__FILE__` | The full path and filename of the file in which it is written, with symlinks resolved. |
| `__DIR__` | The directory of the file, equivalent to `dirname(__FILE__)`. It has no trailing slash unless it is the root directory. |
| `__FUNCTION__` | The name of the function in which it is written, including its namespace (e.g. `Foo\bar`). Inside a method, only the method name. For anonymous functions, a name generated by the engine that includes where the closure was defined (as of PHP 8.4.0; previously `{closure}`). |
| `__CLASS__` | The name of the class in which it is written, including its namespace (e.g. `Foo\Bar`). Inside a trait, the name of the class using the trait. For [anonymous classes](#language.oop5.anonymous), a name generated by the engine. To get the name of the class a method was called on, use [`static::class`](#language.oop5.late-static-bindings). |
| `__TRAIT__` | The trait name, including its namespace (e.g. `Foo\Bar`). |
| `__METHOD__` | The class and method name of the method in which it is written (e.g. `Foo\Bar::baz`). Inside a trait, the trait name is used instead of the class name. Outside of a method, the same as `__FUNCTION__`. |
| `__PROPERTY__` | The name of the property, when used inside a [property hook](#language.oop5.property-hooks). Available as of PHP 8.4.0. |
| `__NAMESPACE__` | The name of the current namespace. |

PHP's magic constants

<div class="example">

<div class="title">

Using magic constants

</div>

```
<?php
namespace App;

function helper()
{
    echo __FUNCTION__, "\n";
    echo __METHOD__, "\n";
}

trait Greets
{
    public function greet()
    {
        echo __CLASS__, "\n";
        echo __TRAIT__, "\n";
        echo __METHOD__, "\n";
        echo __FUNCTION__, "\n";
    }
}

class Greeter
{
    use Greets;
}

helper();
(new Greeter)->greet();
echo __NAMESPACE__, "\n";

    
```

ENTITY

    App\helper
    App\helper
    App\Greeter
    App\Greets
    App\Greets::greet
    greet
    App

        

</div>

### 

ENTITY

[::class](#language.oop5.basic.class.class), `get_class`, `get_called_class`, `dirname`

# context

PHP offers various context options and parameters which can be used with all filesystem and stream wrappers. The context is created with `stream_context_create`. Options are set with `stream_context_set_option` and parameters with `stream_context_set_params`.

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# ftp

<div data-wrapper="1" role="stream_context_option">

FTP context options

</div>

<div data-wrapper="1" role="stream_context_option">

FTP context option listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

Context options for `ftp://` and `ftps://` transports.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`overwrite` `bool`  
Allow overwriting of already existing files on remote server. Applies to write mode (uploading) only.

Defaults to ENTITY.

`resume_pos` `int`  
File offset at which to begin transfer. Applies to read mode (downloading) only.

Defaults to `0` (Beginning of File).

`proxy` `string`  
Proxy FTP request via http proxy server. Applies to file read operations only. Ex: `tcp://squid.example.com:8000`.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

> [!NOTE]
> Additional context options may be supported by the [underlying transport](#transports.inet). For `ftp://` streams, refer to context options for the `tcp://` transport. For `ftps://` streams, refer to context options for the `ssl://` transport.

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

[???](#wrappers.ftp), [???](#context.socket), [???](#context.ssl)

</div>

# http

<div data-wrapper="1" role="stream_context_option">

HTTP context options

</div>

<div data-wrapper="1" role="stream_context_option">

HTTP context option listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

Context options for `http://` and `https://` transports.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`method` `string`  
`GET`, `POST`, or any other HTTP method supported by the remote server.

Defaults to `GET`.

`header` `array` or `string`  
Additional headers to be sent during request. Values in this option will override other values (such as `User-agent:`, `Host:`, and `Authentication:`), even when following `Location:` redirects. Thus it is not recommended to set a `Host:` header, if `follow_location` is enabled.

String value should be `Key: value` pairs delimited by `\r\n`, e.g. `"Content-Type: application/json\r\nConnection: close"`. Array value should be a list of `Key: value` pairs, e.g. `["Content-Type: application/json", "Connection: close"]`.

`user_agent` `string`  
Value to send with `User-Agent:` header. This value will only be used if user-agent is *not* specified in the `header` context option above.

By default the [user_agent](#ini.user-agent) ENTITY setting is used.

`content` `string`  
Additional data to be sent after the headers. Typically used with POST or PUT requests.

`proxy` `string`  
URI specifying address of proxy server (e.g. `tcp://proxy.example.com:5100`).

`request_fulluri` `bool`  
When set to ENTITY, the entire URI will be used when constructing the request (e.g. `GET http://www.example.com/path/to/file.html HTTP/1.0`). While this is a non-standard request format, some proxy servers require it.

Defaults to ENTITY.

`follow_location` `int`  
Follow `Location` header redirects. Set to `0` to disable.

When this option is not set, redirects are only followed for the `300`, `301`, `302`, `303`, `307` and `308` response codes. Setting it to `1` is not equivalent: any response carrying a `Location` header is then followed, whatever its response code.

`max_redirects` `int`  
The max number of redirects to follow. Value `1` or less means that no redirects are followed.

Defaults to `20`.

`protocol_version` `float`  
HTTP protocol version.

Defaults to `1.1` as of PHP 8.0.0; prior to that version the default was `1.0`.

`timeout` `float`  
Read timeout in seconds, specified by a `float` (e.g. `10.5`).

By default the [default_socket_timeout](#ini.default-socket-timeout) ENTITY setting is used.

`ignore_errors` `bool`  
Fetch the content even on failure status codes.

Defaults to ENTITY.

`uri_parser_class` `string` or `null`  
The class to use for parsing URIs. When ENTITY, the legacy behavior based on `parse_url` is used. Accepted values are `Uri\Rfc3986\Uri` (RFC 3986 compliant parser) and `Uri\WhatWg\Url` (WHATWG URL Standard parser). Custom userland implementations are not supported.

Defaults to ENTITY.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

| ENTITY | ENTITY                                   |
|--------|------------------------------------------|
| 8.5.0  | The `uri_parser_class` option was added. |

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div id="context.http.example-post" class="example" role="stream_context_option">

<div class="title">

Fetch a page and send POST data

</div>

```
<?php

$postdata = http_build_query(
    [
        'var1' => 'some content',
        'var2' => 'doh',
    ]
);

$opts = [
    'http' => [
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => $postdata,
    ]
];

$context = stream_context_create($opts);

$result = file_get_contents('http://example.com/submit.php', false, $context);

?>

    
```

</div>

<div id="context.http.example-fetch-ignore-redirect" class="example" role="stream_context_option">

<div class="title">

Ignore redirects but fetch headers and content

</div>

```
<?php

$url = "http://www.example.org/header.php";

$opts = [
    'http' => [
        'method'        => 'GET',
        'max_redirects' => '0',
        'ignore_errors' => '1',
    ]
];

$context = stream_context_create($opts);
$stream = fopen($url, 'r', false, $context);

// header information as well as meta data
// about the stream
var_dump(stream_get_meta_data($stream));

// actual data at $url
var_dump(stream_get_contents($stream));
fclose($stream);
?>

    
```

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

> [!NOTE]
> Additional context options may be supported by the [underlying transport](#transports.inet) For `http://` streams, refer to context options for the `tcp://` transport. For `https://` streams, refer to context options for the `ssl://` transport.

> [!NOTE]
> When this stream wrapper follows a redirect, the `wrapper_data` returned by `stream_get_meta_data` might not necessarily contain the HTTP status line that actually applies to the content data at index `0`.
>
>     array (
>       'wrapper_data' =>
>       array (
>         0 => 'HTTP/1.0 301 Moved Permanently',
>         1 => 'Cache-Control: no-cache',
>         2 => 'Connection: close',
>         3 => 'Location: http://example.com/foo.jpg',
>         4 => 'HTTP/1.1 200 OK',
>         ...
>
>        
>
> The first request returned a `301` (permanent redirect), so the stream wrapper automatically followed the redirect to get a `200` response (index = `4`).

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

[???](#wrappers.http), [???](#context.socket), [???](#context.ssl)

</div>

# parameters

<div data-wrapper="1" role="stream_context_option">

Context parameters

</div>

<div data-wrapper="1" role="stream_context_option">

Context parameter listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

These `parameters` can be set on a `context` using the `stream_context_set_params` function.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`notification` `callable`  
A `callable` to be called when an event occurs on a stream.

See [ stream_notification_callback](#function.stream-notification-callback) for more details.

</div>

# phar

<div data-wrapper="1" role="stream_context_option">

Phar context options

</div>

<div data-wrapper="1" role="stream_context_option">

Phar context option listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

Context options for `phar://` wrapper.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`compress` `int`  
One of [Phar compression constants](#phar.constants.compression).

`metadata` `mixed`  
Phar metadata. See `Phar::setMetadata`.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

[???](#wrappers.phar), [Phar stream wrapper](#phar.using.stream)

</div>

# socket

<div data-wrapper="1" role="stream_context_option">

Socket context options

</div>

<div data-wrapper="1" role="stream_context_option">

Socket context option listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

Socket context options are available for all wrappers that work over sockets, like `tcp`, `http` and `ftp`.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`bindto`  
Used to specify the IP address (either IPv4 or IPv6) and/or the port number that PHP will use to access the network. The syntax is `ip:port` for IPv4 addresses, and `[ip]:port` for IPv6 addresses. Setting the IP or the port to `0` will let the system choose the IP and/or port.

> [!NOTE]
> As FTP creates two socket connections during normal operation, the port number cannot be specified using this option.

`backlog`  
Used to limit the number of outstanding connections in the socket's listen queue.

> [!NOTE]
> This is only applicable to `stream_socket_server`.

`ipv6_v6only`  
Overrides the OS default regarding mapping IPv4 into IPv6.

> [!NOTE]
> This is important in particular when trying to listen on IPv4 addresses separately while there exists a binding on `[::]`.
>
> This is only applicable to `stream_socket_server`.

`so_reuseport`  
Allows multiple bindings to a same ip:port pair, even from separate processes.

> [!NOTE]
> This is only applicable to `stream_socket_server`.

`so_broadcast`  
Enables sending and receiving data to/from broadcast addresses.

> [!NOTE]
> This is only applicable to `stream_socket_server`.

`tcp_nodelay`  
Setting this option to ENTITY will set `SOL_TCP,NO_DELAY=1` appropriately, thus disabling the TCP Nagle algorithm.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

| ENTITY | ENTITY               |
|--------|----------------------|
| 7.1.0  | Added `tcp_nodelay`. |
| 7.0.1  | Added `ipv6_v6only`. |

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div id="context.socket.example-bindto" class="example" role="stream_context_option">

<div class="title">

Basic `bindto` usage example

</div>

```
<?php
// connect to the internet using the '192.168.0.100' IP
$opts = array(
    'socket' => array(
        'bindto' => '192.168.0.100:0',
    ),
);


// connect to the internet using the '192.168.0.100' IP and port '7000'
$opts = array(
    'socket' => array(
        'bindto' => '192.168.0.100:7000',
    ),
);


// connect to the internet using the '2001:db8::1' IPv6 address
// and port '7000'
$opts = array(
    'socket' => array(
        'bindto' => '[2001:db8::1]:7000',
    ),
);


// connect to the internet using port '7000'
$opts = array(
    'socket' => array(
        'bindto' => '0:7000',
    ),
);


// create the context...
$context = stream_context_create($opts);

// ...and use it to fetch the data
echo file_get_contents('http://www.example.com', false, $context);

?>

    
```

</div>

# ssl

<div data-wrapper="1" role="stream_context_option">

SSL context options

</div>

<div data-wrapper="1" role="stream_context_option">

SSL context option listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

Context options for `ssl://` and `tls://` transports.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`peer_name` `string`  
Peer name to be used. If this value is not set, then the name is guessed based on the hostname used when opening the stream.

`verify_peer` `bool`  
Require verification of SSL certificate used.

Defaults to ENTITY.

`verify_peer_name` `bool`  
Require verification of peer name.

Defaults to ENTITY.

`allow_self_signed` `bool`  
Allow self-signed certificates. Requires [`verify_peer`](#context.ssl.verify-peer).

Defaults to ENTITY

`cafile` `string`  
Location of Certificate Authority file on local filesystem which should be used with the `verify_peer` context option to authenticate the identity of the remote peer.

`capath` `string`  
If `cafile` is not specified or if the certificate is not found there, the directory pointed to by `capath` is searched for a suitable certificate. `capath` must be a correctly hashed certificate directory.

`local_cert` `string`  
Path to local certificate file on filesystem. It must be a PEM encoded file which contains your certificate and private key. It can optionally contain the certificate chain of issuers. The private key also may be contained in a separate file specified by `local_pk`.

`local_pk` `string`  
Path to local private key file on filesystem in case of separate files for certificate (`local_cert`) and private key.

`passphrase` `string`  
Passphrase with which your `local_cert` file was encoded.

`verify_depth` `int`  
Abort if the certificate chain is too deep.

Defaults to no verification.

`ciphers` `string`  
Sets the list of available ciphers. The format of the string is described in [ciphers(1)](ENTITY).

Defaults to `DEFAULT`.

`capture_peer_cert` `bool`  
If set to ENTITY a `peer_certificate` context option will be created containing the peer certificate.

`capture_peer_cert_chain` `bool`  
If set to ENTITY a `peer_certificate_chain` context option will be created containing the certificate chain.

`SNI_enabled` `bool`  
If set to ENTITY server name indication will be enabled. Enabling SNI allows multiple certificates on the same IP address.

`SNI_server_certs` `array`  
An array of server names and their corresponding certificates to be used for SNI. The keys are the server names and the values are the paths to the certificate files on the local filesystem. The certificate files must be PEM encoded and contain both the certificate and private key.

Available as of PHP 5.6.0.

`alpn_protocols` `array`  
An array of application layer protocol names to be used for ALPN (Application-Layer Protocol Negotiation). The values are the protocol names as strings (e.g. "http/1.1", "h2").

Available as of PHP 7.0.0 and OpenSSL 1.0.2.

`no_ticket` `bool`  
If set, disable TLS session tickets. This can help to enhance security by providing Perfect Forward Secrecy (PFS).

Available as of PHP 5.3.6.

`disable_compression` `bool`  
If set, disable TLS compression. This can help mitigate the CRIME attack vector.

`peer_fingerprint` `string` \| `array`  
Aborts when the remote certificate digest doesn't match the specified hash.

When a `string` is used, the length will determine which hashing algorithm is applied, either "md5" (32) or "sha1" (40).

When an `array` is used, the keys indicate the hashing algorithm name and each corresponding value is the expected digest.

`security_level` `int`  
Sets the security level. If not specified the library default security level is used. The security levels are described in [SSL_CTX_get_security_level(3)](ENTITY).

Available as of PHP 7.2.0 and OpenSSL 1.1.0.

`min_proto_version` `int`  
Sets the minimum protocol version allowed. If not specified the library default minimum protocol version is used. The protocol versions are described in [SSL_CTX_set_min_proto_version(3)](ENTITY).

Available as of PHP 7.3.0 and OpenSSL 1.1.0.

`max_proto_version` `int`  
Sets the maximum protocol version allowed. If not specified the library default maximum protocol version is used. The protocol versions are described in [SSL_CTX_set_max_proto_version(3)](ENTITY).

Available as of PHP 7.3.0 and OpenSSL 1.1.0.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 7.3.0 | Added `min_proto_version` and `max_proto_version`. Requires OpenSSL ENTITY= 1.1.0. |
| 7.2.0 | Added `security_level`. Requires OpenSSL ENTITY= 1.1.0. |
| 7.0.0 | Added `alpn_protocols`. Requires OpenSSL ENTITY= 1.0.2. |
| 5.6.0 | Added `SNI_server_certs`. |
| 5.3.6 | Added `no_ticket`. |

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

> [!NOTE]
> Because `ssl://` is the underlying transport for the [`https://`](#wrappers.http) and [`ftps://`](#wrappers.ftp) wrappers, any context options which apply to `ssl://` also apply to `https://` and `ftps://`.

> [!NOTE]
> For SNI (Server Name Indication) to be available, then PHP must be compiled with OpenSSL 0.9.8j or greater. Use the `OPENSSL_TLSEXT_SERVER_NAME` to determine whether SNI is supported.

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

# zip

<div data-wrapper="1" role="stream_context_option">

Zip context options

</div>

<div data-wrapper="1" role="stream_context_option">

Zip context option listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

Zip context options are available for `zip` wrappers.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`password`  
Used to specify password used for encrypted archive.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

| ENTITY                 | ENTITY            |
|------------------------|-------------------|
| 7.2.0, PECL zip 1.14.0 | Added `password`. |

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div id="context.zip.example-password" class="example" role="stream_context_option">

<div class="title">

Basic `password` usage example

</div>

```
<?php
// Read encrypted archive
$opts = array(
    'zip' => array(
        'password' => 'secret',
    ),
);
// create the context...
$context = stream_context_create($opts);

// ...and use it to fetch the data
echo file_get_contents('zip://test.zip#test.txt', false, $context);

?>

    
```

</div>

# zlib

<div data-wrapper="1" role="stream_context_option">

Zlib context options

</div>

<div data-wrapper="1" role="stream_context_option">

Zlib context option listing

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

Zlib context options are available for `zlib` wrappers.

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

<div data-wrapper="1" role="stream_context_option">

`level`  
Used to specify the compression level (`0` - `9`).

</div>

# 

<div data-wrapper="1" role="stream_context_option">

ENTITY

</div>

| ENTITY | ENTITY                  |
|--------|-------------------------|
| 7.3.0  | `level` has been added. |

# Control Structures

## Introduction

Any PHP script is built out of a series of statements. A statement can be an assignment, a function call, a loop, a conditional statement or even a statement that does nothing (an empty statement). Statements usually end with a semicolon. In addition, statements can be grouped into a statement-group by encapsulating a group of statements with curly braces. A statement-group is a statement by itself as well. The various statement types are described in this chapter.

### 

ENTITY

The following are also considered language constructs even though they are referenced under functions in the manual.

`list`, `array`, `echo`, `eval`, `print`

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# Alternative syntax for control structures

PHP offers an alternative syntax for some of its control structures; namely, `if`, `while`, `for`, `foreach`, `switch`, and `declare`. In each case, the basic form of the alternate syntax is to change the opening brace to a colon (:) and the closing brace to `endif;`, `endwhile;`, `endfor;`, `endforeach;`, `endswitch;`, or `enddeclare;`, respectively.

<div class="informalexample">

```
<?php
$a = 5;
if ($a == 5): ?>
A is equal to 5
<?php endif; ?>

   
```

ENTITY

    A is equal to 5

       

</div>

In the above example, the HTML block "A is equal to 5" is nested within an `if` statement written in the alternative syntax. The HTML block would be displayed only if `$a` is equal to 5.

The alternative syntax applies to `else` and `elseif` as well. The following is an `if` structure with `elseif` and `else` in the alternative format:

<div class="informalexample">

```
<?php
$a = 5;
if ($a == 5):
    echo "a equals 5";
    echo "...";
elseif ($a == 6):
    echo "a equals 6";
    echo "!!!";
else:
    echo "a is neither 5 nor 6";
endif;

   
```

ENTITY

    a equals 5...

       

</div>

> [!NOTE]
> Mixing syntaxes in the same control block is not supported.

> [!WARNING]
> Any output (including whitespace) between a `switch` statement and the first `case` will result in a syntax error. For example, this is invalid:
>
> <div class="informalexample">
>
> ```
> <?php
> $foo = 1;
> switch ($foo): ?>
>     <?php case 1: ?>
>     Foo is 1
> <?php endswitch; ?>
>
>    
> ```
>
> ENTITY
>
>     Parse error: syntax error, unexpected T_INLINE_HTML "    ", expecting "endswitch" or "case" or "default" in script on line 4
>
>        
>
> </div>
>
> Whereas this is valid, as the trailing newline after the `switch` statement is considered part of the closing `?ENTITY` and hence nothing is output between the `switch` and `case`:
>
> <div class="informalexample">
>
> ```
> <?php
> $foo = 1;
> switch ($foo): ?>
> <?php case 1: ?>
>     Foo is 1
> <?php endswitch; ?>
>
>    
> ```
>
> ENTITY
>
>         Foo is 1
>
>        
>
> </div>

See also [while](#control-structures.while), [for](#control-structures.for), and [if](#control-structures.if) for further examples.

# break

`break` ends execution of the current `for`, `foreach`, `while`, `do-while` or `switch` structure.

`break` accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of. The default value is `1`, only the immediate enclosing structure is broken out of.

<div class="informalexample">

```
<?php
$arr = array('one', 'two', 'three', 'four', 'stop', 'five');
foreach ($arr as $val) {
    if ($val == 'stop') {
        break;    /* You could also write 'break 1;' here. */
    }
    echo "$val\n";
}

   
```

ENTITY

    one
    two
    three
    four

       

</div>

Using the optional argument:

<div class="informalexample">

```
<?php
$i = 0;
while (++$i) {
    switch ($i) {
        case 5:
            echo "At 5\n";
            break 1;  /* Exit only the switch. */
        case 10:
            echo "At 10; quitting\n";
            break 2;  /* Exit the switch and the while. */
        default:
            break;
    }
    echo "$i\n";
}

   
```

ENTITY

    1
    2
    3
    4
    At 5
    5
    6
    7
    8
    9
    At 10; quitting

       

</div>

# continue

`continue` is used within looping structures to skip the rest of the current loop iteration and continue execution at the condition evaluation and then the beginning of the next iteration.

> [!NOTE]
> In PHP the [switch](#control-structures.switch) statement is considered a looping structure for the purposes of `continue`. `continue` behaves like `break` (when no arguments are passed) but will raise a warning as this is likely to be a mistake. If a `switch` is inside a loop, `continue 2` will continue with the next iteration of the outer loop.

`continue` accepts an optional numeric argument which tells it how many levels of enclosing loops it should skip to the end of. The default value is `1`, thus skipping to the end of the current loop.

<div class="informalexample">

```
<?php
$arr = ['zero', 'one', 'two', 'three', 'four', 'five', 'six'];
foreach ($arr as $key => $value) {
    if (0 === ($key % 2)) { // skip members with even key
        continue;
    }
    echo $value . "\n";
}

   
```

ENTITY

    one
    three
    five

       

```
<?php
$i = 0;
while ($i++ < 5) {
    echo "Outer\n";
    while (1) {
        echo "Middle\n";
        while (1) {
            echo "Inner\n";
            continue 3;
        }
        echo "This never gets output.\n";
    }
    echo "Neither does this.\n";
}

   
```

ENTITY

    Outer
    Middle
    Inner
    Outer
    Middle
    Inner
    Outer
    Middle
    Inner
    Outer
    Middle
    Inner
    Outer
    Middle
    Inner

       

</div>

| ENTITY | ENTITY |
|----|----|
| 7.3.0 | `continue` within a `switch` that is attempting to act like a `break` statement for the `switch` will trigger an `E_WARNING`. |

Changelog for `continue`

# declare

The `declare` construct is used to set execution directives for a block of code. The syntax of `declare` is similar to the syntax of other flow control constructs:

<div class="informalexample">

    declare (directive)
        statement

       

</div>

The `directive` section allows the behavior of the `declare` block to be set. Currently only three directives are recognized: [`ticks`](#control-structures.declare.ticks), [`encoding`](#control-structures.declare.encoding), [`strict_types`](#language.types.declarations.strict)

As directives are handled as the file is being compiled, only literals may be given as directive values. Variables and constants cannot be used. To illustrate:

<div class="informalexample">

```
<?php
// This is valid:
declare(ticks=1);

// This is invalid:
const TICK_VALUE = 1;
declare(ticks=TICK_VALUE);

   
```

</div>

The `statement` part of the `declare` block will be executed - how it is executed and what side effects occur during execution may depend on the directive set in the `directive` block.

The `declare` construct can also be used in the global scope, affecting all code following it (however if the file with `declare` was included then it does not affect the parent file).

<div class="informalexample">

```
<?php
// these are the same:

// you can use this:
declare(ticks=1) {
    // entire script here
}

// or you can use this:
declare(ticks=1);
// entire script here

   
```

</div>

## Ticks

A tick is an event that occurs for every `N` low-level tickable statements executed by the parser within the `declare` block. The value for `N` is specified using `ticks=N` within the `declare` block's `directive` section.

Not all statements are tickable. Typically, condition expressions and argument expressions are not tickable.

The event(s) that occur on each tick are specified using the `register_tick_function`. See the example below for more details. Note that more than one event can occur for each tick.

<div class="example">

<div class="title">

Tick usage example

</div>

```
<?php

declare(ticks=1);

// A function called on each tick event
function tick_handler()
{
    echo "tick_handler() called\n";
}

register_tick_function('tick_handler'); // causes a tick event

$a = 1; // causes a tick event

if ($a > 0) {
    $a += 2; // causes a tick event
    print $a . "\n"; // causes a tick event
}

   
```

ENTITY

    tick_handler() called
    tick_handler() called
    tick_handler() called
    3
    tick_handler() called

       

</div>

See also `register_tick_function` and `unregister_tick_function`.

## Encoding

A script's encoding can be specified per-script using the `encoding` directive.

<div class="example">

<div class="title">

Declaring an encoding for the script

</div>

```
<?php
declare(encoding='ISO-8859-1');
// code here

    
```

</div>

> [!CAUTION]
> When combined with namespaces, the only legal syntax for declare is `declare(encoding='...');` where `...` is the encoding value. `declare(encoding='...') {}` will result in a parse error when combined with namespaces.

See also [zend.script_encoding](#ini.zend.script-encoding).

# do-while

`do-while` loops are very similar to `while` loops, except the truth expression is checked at the end of each iteration instead of at the beginning. The main difference from regular `while` loops is that the first iteration of a `do-while` loop is guaranteed to run (the truth expression is only checked at the end of the iteration), whereas it may not necessarily run with a regular `while` loop (the truth expression is checked at the beginning of each iteration; if it evaluates to ENTITY right from the beginning, the loop execution would end immediately).

There is just one syntax for `do-while` loops:

<div class="informalexample">

```
<?php
$i = 0;
do {
    echo $i;
} while ($i > 0);

   
```

ENTITY

    0

       

</div>

The above loop would run one time exactly, since after the first iteration, when the truth expression is checked, it evaluates to ENTITY (`$i` is not bigger than 0) and the loop execution ends.

Advanced C users may be familiar with a different usage of the `do-while` loop, to allow stopping execution in the middle of code blocks, by encapsulating them with `do-while` (0), and using the [`break`](#control-structures.break) statement. The following code fragment demonstrates this:

<div class="informalexample">

```
<?php
$i = 50;
$factor = 0.5;
$minimum_limit = 20;
do {
    if ($i < 5) {
        echo "i is not big enough\n";
        break;
    }
    $i *= $factor;
    if ($i < $minimum_limit) {
        echo "i is less than minimum limit after factor\n";
        break;
    }
    echo $i ." is ok\n";

    /* process i */

} while (0);

   
```

ENTITY

    25 is ok

       

</div>

It is possible to use the [`goto`](#control-structures.goto) operator instead of this hack.

# else

Often you'd want to execute a statement if a certain condition is met, and a different statement if the condition is not met. This is what `else` is for. `else` extends an `if` statement to execute a statement in case the expression in the `if` statement evaluates to ENTITY. For example, the following code would display `a is greater than b` if `$a` is greater than `$b`, and `a is NOT greater than b` otherwise:

<div class="informalexample">

```
<?php
$a = 3;
$b = 5;
if ($a > $b) {
  echo "a is greater than b\n";
} else {
  echo "a is NOT greater than b\n";
}

   
```

ENTITY

    a is NOT greater than b

       

</div>

The `else` statement is only executed if the `if` expression evaluated to ENTITY, and if there were any `elseif` expressions - only if they evaluated to ENTITY as well (see [elseif](#control-structures.elseif)).

> [!NOTE]
> In case of nested `if`-`else` statements, an `else` is always associated with the nearest `if`.
>
> <div class="informalexample">
>
> ```
> <?php
> $a = false;
> $b = true;
> if ($a)
>     if ($b)
>         echo "b";
> else
>     echo "c";
>
>     
> ```
>
> ENTITY
>
>        
>
> </div>
>
> Despite the indentation (which does not matter for PHP), the `else` is associated with the `if ($b)`, so the example does not produce any output. While relying on this behavior is valid, it is recommended to avoid it by using curly braces to resolve potential ambiguities.

# elseif/else if

`elseif`, as its name suggests, is a combination of `if` and `else`. Like `else`, it extends an `if` statement to execute a different statement in case the original `if` expression evaluates to ENTITY. However, unlike `else`, it will execute that alternative expression only if the `elseif` conditional expression evaluates to ENTITY. For example, the following code would display `a is bigger than b`, `a equal to b` or `a is smaller than b`:

<div class="informalexample">

```
<?php
$a = 1;
$b = 1;
if ($a > $b) {
    echo "a is bigger than b";
} elseif ($a == $b) {
    echo "a is equal to b";
} else {
    echo "a is smaller than b";
}

   
```

ENTITY

    a is equal to b

       

</div>

There may be several `elseif`s within the same `if` statement. The first `elseif` expression (if any) that evaluates to ENTITY would be executed. In PHP, it's possible to write `else if` (in two words) and the behavior would be identical to that of `elseif` (in a single word). The syntactic meaning is slightly different (the same behavior as C) but the bottom line is that both would result in exactly the same behavior.

The `elseif` statement is only executed if the preceding `if` expression and any preceding `elseif` expressions evaluated to ENTITY, and the current `elseif` expression evaluated to ENTITY.

> [!NOTE]
> Note that `elseif` and `else if` will only be considered exactly the same when using curly brackets as in the above example. When using a colon to define `if`/`elseif` conditions, the use of `elseif` in a single word becomes necessary. PHP will fail with a parse error if `else if` is split into two words.

<div class="informalexample">

```
<?php
$a = 3;
$b = 1;

/* Incorrect Method: */
if ($a > $b):
    echo $a." is greater than ".$b;
else if ($a == $b): // Will not compile.
    echo "The above line causes a parse error.";
endif;

   
```

ENTITY

    Parse error: syntax error, unexpected token "if", expecting ":" in script on line 8

       

</div>

<div class="informalexample">

```
<?php
$a = 3;
$b = 1;

/* Correct Method: */
if ($a > $b):
    echo $a." is greater than ".$b;
elseif ($a == $b): // Note the combination of the words.
    echo $a." equals ".$b;
else:
    echo $a." is neither greater than or equal to ".$b;
endif;

   
```

ENTITY

    3 is greater than 1

       

</div>

# finally

A ENTITY block may also be specified after or instead of ENTITY blocks. Code within the ENTITY block will always be executed after the ENTITY and ENTITY blocks, even if a ENTITY or ENTITY statement is encountered, or if a Throwable error is not caught or is rethrown. It will be executed prior to resuming the normal execution flow. The only exception to this rule is when the script is terminated abruptly, such as by a call to `exit` or by a fatal error (for example, when the maximum execution time is exceeded).

<div class="example">

<div class="title">

Throwable error handling with a ENTITY block

</div>

```
<?php
function inverse($x) {
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
} catch (DivisionByZeroError $e) {
    echo 'Caught error: ', $e->getMessage(), "\n";
} finally {
    echo "First finally.\n";
}

try {
    echo inverse(0) . "\n";
} catch (DivisionByZeroError $e) {
    echo 'Caught error: ', $e->getMessage(), "\n";
} finally {
    echo "Second finally.\n";
}

// Continue execution
echo "Hello World\n";

  
```

ENTITY

    0.2
    First finally.
    Caught error: Division by zero
    Second finally.
    Hello World

      

</div>

When the call stack is unwound after a Throwable error has been thrown, all ENTITY blocks it encounters along the way will be executed. In other words, nested ENTITY blocks are executed even if the Throwable error is not caught by an adjacent ENTITY block.

<div class="example">

<div class="title">

All ENTITY blocks will be executed

</div>

```
   
<?php
try {
    try {
        throw new Exception();
    } finally {
        echo "Inner finally\n";
    }
} catch (Exception $e) {
} finally {
    echo "Outer finally\n";
}

  
```

ENTITY

    Inner finally
    Outer finally

      

</div>

## Interaction between a ENTITY block and a ENTITY statement

One notable interaction is between the ENTITY block and a ENTITY statement. If a ENTITY statement is encountered inside either the ENTITY or the ENTITY block, the ENTITY block will still be executed. Moreover, the ENTITY statement is evaluated when encountered, but the result will be returned after the ENTITY block is executed. Additionally, if the ENTITY block also contains a ENTITY statement, the value from the ENTITY block is returned.

<div class="example">

<div class="title">

Interaction between ENTITY in ENTITY block and a previous ENTITY

</div>

```
<?php
function testReturnTry() {
    try {
        echo 'Within try', "\n";
        return 'try';
    } finally {
        echo 'Within finally', "\n";
        return 'finally';
    }
}

function testReturnCatch() {
    try {
        throw new Exception('foo');
    } catch (Exception $e) {
        echo 'Within catch', "\n";
        return 'catch';
    } finally {
        echo 'Within finally', "\n";
        return 'finally';
    }
}

echo testReturnTry(), "\n";
echo testReturnCatch(), "\n";


   
```

ENTITY

    Within try
    Within finally
    finally
    Within catch
    Within finally
    finally

       

</div>

<div class="example">

<div class="title">

Interaction between the ENTITY block and ENTITY

</div>

```
<?php
function testReturnTry() {
    try {
        return 'try';
    } finally {
        echo 'finally ';
    }
}

function testReturnCatch() {
    try {
        throw new Exception('foo');
    } catch (Exception $e) {
        return 'catch';
    } finally {
        echo 'finally ';
    }
}

echo testReturnTry(), "\n";
echo testReturnCatch(), "\n";

   
```

ENTITY

    finally try
    finally catch

       

</div>

## Interaction between a ENTITY block and an exception thrown in a ENTITY block

If both the ENTITY block and the ENTITY block throw an exception, the exception thrown from the ENTITY block is the one that is propagated, and the exception thrown from the ENTITY block will be used as its previous exception.

<div class="example">

<div class="title">

Exception in try and in finally

</div>

```
<?php

try {
    try {
        throw new Exception(message: 'Third', previous: new Exception('Fourth'));
    } finally {
        throw new Exception(message: 'First', previous: new Exception('Second'));
    }
} catch (Exception $e) {
    var_dump(
        $e->getMessage(),
        $e->getPrevious()->getMessage(),
        $e->getPrevious()->getPrevious()->getMessage(),
        $e->getPrevious()->getPrevious()->getPrevious()->getMessage(),
    );
}

   
```

ENTITY

    string(5) "First"
    string(6) "Second"
    string(5) "Third"
    string(6) "Fourth"

       

</div>

## Behaviour of a ENTITY block in a [Generator](#language.generators)

If, during the traversal of a generator, a Throwable error is thrown, the ENTITY block within the generator will be executed, as it is the previous element of the call stack.

<div class="example">

<div class="title">

ENTITY block being run when an Exception has been thrown

</div>

```
    
<?php
function generate()
{
    try {
        yield 1;
        yield 2;
    } catch (Exception $e) {
        echo 'catch';
    } finally {
        echo "finally\n";
    }
}

try {
    foreach (generate() as $i) {
        echo $i, "\n";
        throw new Exception();
    }
} catch (Exception $e) {
    echo 'outer catch';
}

   
```

ENTITY

    1
    finally
    outer catch

       

</div>

It is possible to ENTITY within a ENTITY block, but if a Throwable error occurs and is not caught within the ENTITY, a `Cannot yield from finally in a force-closed generator` Error is thrown.

<div class="example">

<div class="title">

Error when ENTITYing in a ENTITY block when an Exception has been thrown

</div>

```
<?php
function generate()
{
    try {
        yield 1;
        yield 2;
    } catch (Exception $e) {
        echo 'catch';
    } finally {
        echo "finally\n";
        yield 3;
    }
}

try {
    foreach (generate() as $i) {
        echo $i, "\n";
        throw new Exception();
    }
} catch (Exception $e) {
    echo 'outer catch';
}

   
```

ENTITY

    1
    finally

    Fatal error: Uncaught Exception in /in/GbFmu:19
    Stack trace:
    #0 {main}

    Next Error: Cannot yield from finally in a force-closed generator in /in/GbFmu:12
    Stack trace:
    #0 /in/GbFmu(19): generate()
    #1 {main}
      thrown in /in/GbFmu on line 12

       

</div>

## Interaction between a ENTITY block and a call to `exit`

When `exit` is called within a ENTITY or a ENTITY block, all ENTITY blocks are skipped.

<div class="example">

<div class="title">

Interaction between a ENTITY block and `exit` called in a ENTITY block

</div>

```
<?php
try {
    echo 'quit';
    exit(0);
} finally {
    echo 'finally';
}

   
```

ENTITY

    quit

       

</div>

<div class="example">

<div class="title">

Interaction between a ENTITY block and `exit` called in a ENTITY block

</div>

```
<?php
try {
    throw new Exception('foo');
} catch (Exception $e) {
    echo 'catch';
    exit(0);
} finally {
    echo 'finally ';
}

   
```

ENTITY

    catch

       

</div>

<div class="example">

<div class="title">

All ENTITY blocks are skipped when `exit` is called

</div>

```
<?php
try {
    try {
        echo 'quit';
        exit(0);
    } finally {
        echo 'inner finally ';
    }
} finally {
    echo 'outer finally';
}

   
```

ENTITY

    quit

       

</div>

When `exit` is called within a ENTITY block, all outer ENTITY blocks are skipped.

<div class="example">

<div class="title">

Skipping an outer ENTITY block by calling `exit`

</div>

```
<?php
try {
    try {
        echo 'try', "\n";
    } finally {
        echo 'inner finally ';
        exit(0);
    }
} finally {
    echo 'outer finally';
}

   
```

ENTITY

    try
    inner finally

       

</div>

### Edge case of calling `exit` in a ENTITY over a generator

This one edge case behaviour is highly dependent on which version of PHP the code is executed with.

<div class="informalexample">

```
<?php
function generate()
{
    try {
        yield 1;
        yield 2;
    } catch (Exception $e) {
        echo 'catch';
    } finally {
        echo "inner finally\n";
    }
}

try {
    foreach (generate() as $i) {
        echo $i, "\n";
        exit(0);
    }
} finally {
    echo "outer finally\n";
}

    
```

Output of the above example prior to PHP 7.1.14, in PHP 7.2.0 and 7.2.1, and as of PHP 8.0.0

    1
    inner finally

        

Output of the above example as of PHP 7.1.14 and 7.2.2, and prior to PHP 8.0.0

    1

        

</div>

# for

`for` loops are the most complex loops in PHP. They behave like their C counterparts. The syntax of a `for` loop is:

<div class="informalexample">

    for (expr1; expr2; expr3)
        statement

       

</div>

The first expression (`expr1`) is evaluated (executed) once unconditionally at the beginning of the loop.

At the beginning of each iteration, `expr2` is evaluated. If it evaluates to ENTITY, the loop continues and the nested statement(s) are executed. If it evaluates to ENTITY, the execution of the loop ends.

At the end of each iteration, `expr3` is evaluated (executed).

Each of the expressions can be empty or contain multiple expressions separated by commas. In `expr2`, all expressions separated by a comma are evaluated but the result is taken from the last part. `expr2` being empty means the loop should be run indefinitely (PHP implicitly considers it as ENTITY, like C). This may not be as useless as you might think, since often you'd want to end the loop using a conditional [`break`](#control-structures.break) statement instead of using the `for` truth expression.

Consider the following examples. All of them display the numbers 1 through 10:

<div class="informalexample">

```
<?php
for ($i = 1; $i <= 10; $i++) {
    echo $i . " ";
}

   
```

ENTITY

    1 2 3 4 5 6 7 8 9 10

       

</div>

<div class="informalexample">

```
<?php
for ($i = 1; ; $i++) {
    if ($i > 10) {
        break;
    }
    echo $i . " ";
}

   
```

ENTITY

    1 2 3 4 5 6 7 8 9 10

       

</div>

<div class="informalexample">

```
<?php
$i = 1;
for (; ; ) {
    if ($i > 10) {
        break;
    }
    echo $i . " ";
    $i++;
}

   
```

ENTITY

    1 2 3 4 5 6 7 8 9 10

       

</div>

<div class="informalexample">

```
<?php
for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i . " ", $i++);

   
```

ENTITY

    1 2 3 4 5 6 7 8 9 10

       

</div>

Of course, the first example appears to be the nicest one (or perhaps the fourth), but you may find that being able to use empty expressions in `for` loops comes in handy on many occasions.

PHP also supports the alternate "colon syntax" for `for` loops.

<div class="informalexample">

    for (expr1; expr2; expr3):
        statement
        ...
    endfor;

       

</div>

Expressions `expr2` and `expr3` are evaluated every iteration. It's advisable to use simple expressions in these places to avoid performance issues. For example, if the number of iterations is known in advance, it is better to use a variable instead of a function call in `expr2`:

<div class="informalexample">

```
<?php

$people = ['Kalle', 'Pierre'];

// Bad practice: calling a function on every iteration
for($i = 0; $i < getIterationCount($people); ++$i) {
    $people[$i] .= ' is cool';
}

// Good practice: storing the count in a variable
for($i = 0, $peopleCount = getIterationCount($people); $i < $peopleCount; ++$i) {
    $people[$i] .= ' is cool';
}


   
```

</div>

In the example above, the function is called on every iteration of the first loop, even though it always returns the same value. Storing that value in a variable, as the second loop does, calls the function once. Note that the number of iterations is then fixed: if the array is modified inside the loop, the stored value no longer reflects its size.

> [!NOTE]
> The size of an `array` is stored with the array, which means that calling the built-in function `count` does not require counting the elements and does not cause performance issues. This does not apply to `COUNT_RECURSIVE`, which walks the whole array. Care should also be taken when using `count` on objects implementing Countable, as such calls can be more expensive.

> [!NOTE]
> The `for` loop is not the recommended way to iterate over arrays. The ENTITY loop is specifically designed for this purpose and is usually more convenient.

# foreach

The `foreach` construct provides an easy way to iterate over `array`s and objects. `foreach` will issue an error when used with a variable containing a different data type or with an uninitialized variable.

<div class="informalexample">

`foreach` can optionally get the `key` of each element:

    foreach (iterable_expression as $value) {
        statement_list
    }

    foreach (iterable_expression as $key => $value) {
        statement_list
    }

       

</div>

The first form traverses the value given by `iterable_expression`. On each iteration, the value of the current element is assigned to `$value`.

The second form will additionally assign the current element's key to the `$key` variable on each iteration.

Note that `foreach` does not modify the internal array pointer, which is used by functions such as `current` and `key`.

By default, an object is traversed over the properties that are [visible](#language.oop5.visibility) from the current scope. It is possible to [customize object iteration](#language.oop5.iterations).

<div class="example">

<div class="title">

Common `foreach` usages

</div>

```
<?php

echo "Value only\n";
$array = [1, 2, 3, 17];

foreach ($array as $value) {
    echo "Current element of \$array: $value.\n";
}

echo "\n\nKey and value:\n";
$array = [
    "one" => 1,
    "two" => 2,
    "three" => 3,
    "seventeen" => 17
];

foreach ($array as $key => $value) {
    echo "Key: $key => Value: $value\n";
}

echo "\n\nMulti-dimensional key-value arrays:\n";
$grid = [];
$grid[0][0] = "a";
$grid[0][1] = "b";
$grid[1][0] = "y";
$grid[1][1] = "z";

foreach ($grid as $y => $row) {
    foreach ($row as $x => $value) {
        echo "Value at position x=$x and y=$y: $value\n";
    }
}

echo "\n\nDynamic arrays:\n";
foreach (range(1, 5) as $value) {
    echo "$value\n";
}

  
```

ENTITY

    Value only
    Current element of $array: 1.
    Current element of $array: 2.
    Current element of $array: 3.
    Current element of $array: 17.


    Key and value:
    Key: one => Value: 1
    Key: two => Value: 2
    Key: three => Value: 3
    Key: seventeen => Value: 17


    Multi-dimensional key-value arrays:
    Value at position x=0 and y=0: a
    Value at position x=1 and y=0: b
    Value at position x=0 and y=1: y
    Value at position x=1 and y=1: z


    Dynamic arrays:
    1
    2
    3
    4
    5

      

</div>

> [!NOTE]
> `foreach` does not support the ability to suppress error messages using the [`@`](#language.operators.errorcontrol).

## Unpacking nested arrays

It is possible to iterate over an array of arrays and unpack the nested array into loop variables by using either [array destructuring](#language.types.array.syntax.destructuring) via `[]` or by using the `list` language construct as the value.

> [!NOTE]
> Please note that [array destructuring](#language.types.array.syntax.destructuring) via `[]` is only possible as of PHP 7.1.0.

<div class="informalexample">

In both of the following examples `$a` will be set to the first element of the nested array and `$b` will contain the second element:

```
<?php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as [$a, $b]) {
    echo "A: $a; B: $b\n";
}

foreach ($array as list($a, $b)) {
    echo "A: $a; B: $b\n";
}

    
```

ENTITY

    A: 1; B: 2
    A: 3; B: 4
    A: 1; B: 2
    A: 3; B: 4

        

</div>

When providing fewer variables than there are elements in the array, the remaining elements will be ignored. Similarly, elements can be skipped over by using a comma:

<div class="informalexample">

```
<?php
$array = [
    [1, 2, 5],
    [3, 4, 6],
];

foreach ($array as [$a, $b]) {
    // Note that there is no $c here.
    echo "$a $b\n";
}

foreach ($array as [, , $c]) {
    // Skipping over $a and $b
    echo "$c\n";
}

    
```

ENTITY

    1 2
    3 4
    5
    6

        

</div>

A notice will be generated if there aren't enough array elements to fill the `list`:

<div class="informalexample">

```
<?php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as [$a, $b, $c]) {
    echo "A: $a; B: $b; C: $c\n";
}

    
```

ENTITY

    Notice: Undefined offset: 2 in example.php on line 7
    A: 1; B: 2; C:

    Notice: Undefined offset: 2 in example.php on line 7
    A: 3; B: 4; C:

        

</div>

## foreach and references

It is possible to directly modify array elements within a loop by preceding `$value` with `ENTITY`. In that case the value will be assigned by [reference](#language.references).

<div class="informalexample">

```
<?php
$arr = [1, 2, 3, 4];
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now [2, 4, 6, 8]
var_dump($arr);
unset($value); // break the reference with the last element

    
```

ENTITY

    array(4) {
      [0]=>
      int(2)
      [1]=>
      int(4)
      [2]=>
      int(6)
      [3]=>
      &int(8)
    }

        

</div>

> [!WARNING]
> A reference to the `$value` of the last array element remains even after the `foreach` loop. It is recommended to destroy it using `unset`. Otherwise, the following behavior will occur:
>
> <div class="informalexample">
>
> ```
> <?php
> $arr = [1, 2, 3, 4];
> foreach ($arr as &$value) {
>     $value = $value * 2;
> }
> // $arr is now [2, 4, 6, 8]
> var_dump($arr);
>
> // without an unset($value), $value is still a reference to the last item: $arr[3]
>
> echo "\nAnother loop:\n";
> foreach ($arr as $key => $value) {
>     // $arr[3] will be updated with each value from $arr...
>     echo "{$key} => {$value}\n";
> }
> // ...until ultimately the second-to-last value is copied onto the last value
> var_dump($arr);
>
>     
> ```
>
> ENTITY
>
>     array(4) {
>       [0]=>
>       int(2)
>       [1]=>
>       int(4)
>       [2]=>
>       int(6)
>       [3]=>
>       &int(8)
>     }
>
>     Another loop:
>     0 => 2
>     1 => 4
>     2 => 6
>     3 => 6
>     array(4) {
>       [0]=>
>       int(2)
>       [1]=>
>       int(4)
>       [2]=>
>       int(6)
>       [3]=>
>       &int(6)
>     }
>
>         
>
> </div>

<div class="example">

<div class="title">

Iterate a constant array's values by reference

</div>

```
<?php
foreach ([1, 2, 3, 4] as &$value) {
    $value = $value * 2;
    echo $value . "\n";
}

   
```

ENTITY

    2
    4
    6
    8

       

</div>

## 

ENTITY

array

Traversable

iterable

list

# goto

![What's the worse thing that could happen if you use goto?](en/language/figures/xkcd-goto.png)

The `goto` operator can be used to jump to another section in the program. The target point is specified by a *case-sensitive* label followed by a colon, and the instruction is given as `goto` followed by the desired target label. This is not a full unrestricted `goto`. The target label must be within the same file and context, meaning that you cannot jump out of a function or method, nor can you jump into one. You also cannot jump into any sort of loop or switch structure. You may jump out of these, and a common use is to use a `goto` in place of a multi-level `break`.

<div class="example">

<div class="title">

`goto` example

</div>

```
<?php
goto a;
echo 'Foo';

a:
echo 'Bar';

   
```

ENTITY

    Bar

       

</div>

<div class="example">

<div class="title">

`goto` loop example

</div>

```
<?php
for ($i = 0, $j = 50; $i < 100; $i++) {
    while ($j--) {
        if ($j == 17) {
            goto end;
        }
    }
}
echo "i = $i";
end:
echo 'j hit 17';

   
```

ENTITY

    j hit 17

       

</div>

<div class="example">

<div class="title">

This will not work

</div>

```
<?php
goto loop;
for ($i = 0, $j = 50; $i < 100; $i++) {
    while ($j--) {
        loop:
    }
}
echo "$i = $i";

   
```

ENTITY

    Fatal error: 'goto' into loop or switch statement is disallowed in script on line 2

       

</div>

# if

The `if` construct is one of the most important features of many languages, PHP included. It allows for conditional execution of code fragments. PHP features an `if` structure that is similar to that of C:

<div class="informalexample">

    if (expr)
      statement

       

</div>

As described in [the section about expressions](#language.expressions), \<expression\> is evaluated to its Boolean value. If \<expression\> evaluates to ENTITY, PHP will execute \<statement\>, and if it evaluates to ENTITY - it'll ignore it. More information about what values evaluate to ENTITY can be found in the ['Converting to boolean'](#language.types.boolean.casting) section.

The following example would display `a is bigger than b` if `$a` is bigger than `$b`:

<div class="informalexample">

```
<?php
$a = 3;
$b = 1;
if ($a > $b)
  echo "a is bigger than b\n";

   
```

ENTITY

    a is bigger than b

       

</div>

Often you'd want to have more than one statement to be executed conditionally. Of course, there's no need to wrap each statement with an `if` clause. Instead, you can group several statements into a statement group. For example, this code would display `a is bigger than b` if `$a` is bigger than `$b`, and would then assign the value of `$a` into `$b`:

<div class="informalexample">

```
<?php
$a = 3;
$b = 1;
if ($a > $b) {
  echo "a is bigger than b\n";
  $b = $a;
}
var_dump($b);

   
```

ENTITY

    a is bigger than b
    int(3)

       

</div>

`If` statements can be nested infinitely within other `if` statements, which provides you with complete flexibility for conditional execution of the various parts of your program.

# include_once

The `include_once` expression includes and evaluates the specified file during the execution of the script. This behavior is similar to the `include` expression, with the only difference being that if the code from a file has already been included, it will not be included again, and include_once returns ENTITY. As the name suggests, the file will be included just once.

`include_once` may be used in cases where the same file might be included and evaluated more than once during a particular execution of a script, so in this case it may help avoid problems such as function redefinitions, variable value reassignments, etc.

See the `include` documentation for information about how this function works.

# include

The `include` expression includes and evaluates the specified file.

The documentation below also applies to `require`.

Files are included based on the file path given or, if none is given, the [include_path](#ini.include-path) specified. If the file isn't found in the [include_path](#ini.include-path), `include` will finally check in the calling script's own directory and the current working directory before failing. The `include` construct will emit an `E_WARNING` if it cannot find a file; this is different behavior from `require`, which will emit an `E_ERROR`.

Note that both `include` and `require` raise additional `E_WARNING`s, if the file cannot be accessed, before raising the final `E_WARNING` or `E_ERROR`, respectively.

If a path is defined — whether absolute (starting with a drive letter or `\` on Windows, or `/` on Unix/Linux systems) or relative to the current directory (starting with `.` or `..`) — the [include_path](#ini.include-path) will be ignored altogether. For example, if a filename begins with `../`, the parser will look in the parent directory to find the requested file.

For more information on how PHP handles including files and the include path, see the documentation for [include_path](#ini.include-path).

When a file is included, the code it contains inherits the [variable scope](#language.variables.scope) of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward. However, all functions and classes defined in the included file have the global scope.

<div class="example">

<div class="title">

Basic `include` example

</div>

```
vars.php
<?php

$color = 'green';
$fruit = 'apple';

?>

test.php
<?php

echo "A $color $fruit"; // A

include 'vars.php';

echo "A $color $fruit"; // A green apple

?>

   
```

</div>

If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function. An exception to this rule is [magic constants](#language.constants.magic) which are evaluated by the parser before the include occurs.

<div class="example">

<div class="title">

Including within functions

</div>

```
<?php

function foo()
{
    global $color;

    include 'vars.php';

    echo "A $color $fruit";
}

/* vars.php is in the scope of foo() so     *
* $fruit is NOT available outside of this  *
* scope.  $color is because we declared it *
* as global.                               */

foo();                    // A green apple
echo "A $color $fruit";   // A green

   
```

</div>

When a file is included, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within [valid PHP start and end tags](#language.basic-syntax.phpmode).

If "[URL include wrappers](#ini.allow-url-include)" are enabled in PHP, you can specify the file to be included using a URL (via HTTP or other supported wrapper - see [???](#wrappers) for a list of protocols) instead of a local pathname. If the target server interprets the target file as PHP code, variables may be passed to the included file using a URL request string as used with HTTP GET. This is not strictly speaking the same thing as including the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script.

<div class="example">

<div class="title">

`include` through HTTP

</div>

```
<?php

/* This example assumes that www.example.com is configured to parse .php
* files and not .txt files. Also, 'Works' here means that the variables
* $foo and $bar are available within the included file. */

// Won't work; file.txt wasn't handled by www.example.com as PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';

// Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
// local filesystem.
include 'file.php?foo=1&bar=2';

// Works.
include 'http://www.example.com/file.php?foo=1&bar=2';

   
```

</div>

> [!WARNING]
> A remote file may be processed at the remote server (depending on the file extension and whether or not the remote server runs PHP) but it still has to produce a valid PHP script because it will be processed at the local server. If the file from the remote server should be processed there and outputted only, `readfile` is a much better function to use. Otherwise, special care should be taken to secure the remote script to produce a valid and desired code.

See also [Remote files](#features.remote-files), `fopen` and `file` for related information.

Handling Returns: `include` returns ENTITY on failure and raises a warning. Successful includes, unless overridden by the included file, return `1`. It is possible to execute a `return` statement inside an included file in order to terminate processing in that file and return to the script which called it. Also, it's possible to return values from included files. You can take the value of the include call as you would for a normal function. This is not, however, possible when including remote files unless the output of the remote file has [valid PHP start and end tags](#language.basic-syntax.phpmode) (as with any local file). You can declare the needed variables within those tags and they will be introduced at whichever point the file was included.

Because `include` is a special language construct, parentheses are not needed around its argument. Take care when comparing the return value.

<div class="example">

<div class="title">

Comparing return value of include

</div>

```
<?php
// won't work, evaluated as include(('vars.php') == TRUE), i.e. include('1')
if (include('vars.php') == TRUE) {
    echo 'OK';
}

// works
if ((include 'vars.php') == TRUE) {
    echo 'OK';
}

   
```

</div>

<div class="example">

<div class="title">

`include` and the `return` statement

</div>

```
return.php
<?php

$var = 'PHP';

return $var;

?>

noreturn.php
<?php

$var = 'PHP';

?>

testreturns.php
<?php

$foo = include 'return.php';

echo $foo; // prints 'PHP'

$bar = include 'noreturn.php';

echo $bar; // prints 1

?>

   
```

</div>

`$bar` is the value `1` because the include was successful. Notice the difference between the above examples. The first uses `return` within the included file while the other does not. If the file can't be included, ENTITY is returned and `E_WARNING` is issued.

If there are functions defined in the included file, they can be used in the main file regardless of whether they are before `return` or after. If the file is included twice, PHP will raise a fatal error because the functions were already declared. It is recommended to use `include_once` instead of checking if the file was already included and conditionally returning inside the included file.

Another way to "include" a PHP file into a variable is to capture the output by using the [Output Control Functions](#ref.outcontrol) with `include`. For example:

<div class="example">

<div class="title">

Using output buffering to include a PHP file into a string

</div>

```
<?php
$string = get_include_contents('somefile.php');

function get_include_contents($filename) {
    if (is_file($filename)) {
        ob_start();
        include $filename;
        return ob_get_clean();
    }
    return false;
}

   
```

</div>

In order to automatically include files within scripts, see also the [auto_prepend_file](#ini.auto-prepend-file) and [auto_append_file](#ini.auto-append-file) configuration options in ENTITY.

ENTITY

See also `require`, `require_once`, `include_once`, `get_included_files`, `readfile`, `virtual`, and [include_path](#ini.include-path).

# match

The `match` expression branches evaluation based on an identity check of a value. Similarly to a `switch` statement, a `match` expression has a subject expression that is compared against multiple alternatives. Unlike `switch`, it will evaluate to a value much like ternary expressions. Unlike `switch`, the comparison is an identity check (`===`) rather than a weak equality check (`==`). Match expressions are available as of PHP 8.0.0.

<div class="example">

<div class="title">

Structure of a `match` expression

</div>

```
<?php
$return_value = match (subject_expression) {
    single_conditional_expression => return_expression,
    conditional_expression1, conditional_expression2 => return_expression,
};

  
```

<div class="example">

<div class="title">

Basic `match` usage

</div>

```
<?php
$food = 'cake';

$return_value = match ($food) {
    'apple' => 'This food is an apple',
    'bar' => 'This food is a bar',
    'cake' => 'This food is a cake',
};

var_dump($return_value);

  
```

ENTITY

    string(19) "This food is a cake"

       

</div>

<div class="example">

<div class="title">

Example of using `match` with comparison operators

</div>

```
<?php
$age = 18;

$output = match (true) {
    $age < 2 => "Baby",
    $age < 13 => "Child",
    $age <= 19 => "Teenager",
    $age >= 40 => "Adult",
    $age > 19 => "Young adult",
};

var_dump($output);

  
```

ENTITY

    string(8) "Teenager"

       

</div>

> [!NOTE]
> The result of a `match` expression does not need to be used.

> [!NOTE]
> When a `match` expression is used as a standalone expression, it *must* be terminated by a semicolon `;`.

</div>

The `match` expression is similar to a `switch` statement but has some key differences:

- A `match` arm compares values strictly (`===`) instead of loosely as the switch statement does.

- A `match` expression returns a value.

- `match` arms do not fall through to later cases the way `switch` statements do.

- A `match` expression must be exhaustive.

Like `switch` statements, `match` expressions are executed match arm by match arm. In the beginning, no code is executed. The conditional expressions are only evaluated if all previous conditional expressions failed to match the subject expression. Only the return expression corresponding to the matching conditional expression will be evaluated. For example:

<div class="informalexample">

```
<?php
$result = match ($x) {
    foo() => 'value',
    $this->bar() => 'value', // $this->bar() isn't called if foo() === $x
    $this->baz => beep(), // beep() isn't called unless $x === $this->baz
    // etc.
};

   
```

</div>

`match` expression arms may contain multiple expressions separated by a comma. That is a logical OR, and is a shorthand for multiple match arms with the same right-hand side.

<div class="informalexample">

```
<?php
$result = match ($x) {
    // This match arm:
    $a, $b, $c => 5,
    // Is equivalent to these three match arms:
    $a => 5,
    $b => 5,
    $c => 5,
};

   
```

</div>

A special case is the `default` pattern. This pattern matches anything that wasn't previously matched. For example:

<div class="informalexample">

```
<?php
$expressionResult = match ($condition) {
    1, 2 => foo(),
    3, 4 => bar(),
    default => baz(),
};

   
```

</div>

> [!NOTE]
> Multiple default patterns will raise an `E_FATAL_ERROR` error.

A `match` expression must be exhaustive. If the subject expression is not handled by any match arm, an `UnhandledMatchError` is thrown.

<div class="example">

<div class="title">

Example of an unhandled match expression

</div>

```
<?php
$condition = 5;

try {
    match ($condition) {
        1, 2 => foo(),
        3, 4 => bar(),
    };
} catch (UnhandledMatchError $e) {
    var_dump($e);
}

  
```

ENTITY

    object(UnhandledMatchError)#1 (7) {
      ["message":protected]=>
      string(22) "Unhandled match case 5"
      ["string":"Error":private]=>
      string(0) ""
      ["code":protected]=>
      int(0)
      ["file":protected]=>
      string(6) "script"
      ["line":protected]=>
      int(5)
      ["trace":"Error":private]=>
      array(0) {
      }
      ["previous":"Error":private]=>
      NULL
    }

      

</div>

## Using match expressions to handle non-identity checks

It is possible to use a `match` expression to handle non-identity conditional cases by using `true` as the subject expression.

<div class="example">

<div class="title">

Using a generalized match expression to branch on integer ranges

</div>

```
<?php
$age = 23;

$result = match (true) {
    $age >= 65 => 'senior',
    $age >= 25 => 'adult',
    $age >= 18 => 'young adult',
    default => 'kid',
};

var_dump($result);

   
```

ENTITY

    string(11) "young adult"

       

</div>

<div class="example">

<div class="title">

Using a generalized match expression to branch on string content

</div>

```
<?php

$text = 'Bienvenue chez nous';

$result = match (true) {
    str_contains($text, 'Welcome'), str_contains($text, 'Hello') => 'en',
    str_contains($text, 'Bienvenue'), str_contains($text, 'Bonjour') => 'fr',
    // ...
};

var_dump($result);

   
```

ENTITY

    string(2) "fr"

       

</div>

# require_once

The `require_once` expression is identical to `require` except PHP will check if the file has already been included, and if so, not include (require) it again.

See the `include_once` documentation for information about the `_once` behaviour, and how it differs from its non `_once` siblings.

# require

`require` is identical to `include` except upon failure it will also produce an `Error` exception (`E_COMPILE_ERROR` level error prior to PHP 8.0.0) whereas `include` will only produce a warning (`E_WARNING` level error).

See the `include` documentation for how this works.

# return

`return` returns program control to the calling module. Execution resumes at the expression following the called module's invocation.

If called from within a function, the `return` statement immediately ends execution of the current function, and returns its argument as the value of the function call. `return` also ends the execution of an `eval` statement or script file.

If called from the global scope, then execution of the current script file is ended. If the current script file was `include`d or `require`d, then control is passed back to the calling file. Furthermore, if the current script file was `include`d, then the value given to `return` will be returned as the value of the `include` call. If `return` is called from within the main script file, then script execution ends. If the current script file was named by the [auto_prepend_file](#ini.auto-prepend-file) or [auto_append_file](#ini.auto-append-file) configuration options in ENTITY, then that script file's execution is ended.

For more information, see [Returning values](#functions.returning-values).

> [!NOTE]
> Note that since `return` is a language construct and not a function, the parentheses surrounding its argument are not required and their use is discouraged.

> [!NOTE]
> If no parameter is supplied, then the parentheses must be omitted and ENTITY will be returned. Calling `return` with parentheses but with no arguments will result in a parse error.

As of PHP 7.1.0, return statements without an argument in functions which declare a return type trigger `E_COMPILE_ERROR`, unless the return type is `void`, in which case return statements with an argument trigger that error.

# switch

The `switch` statement is similar to a series of `if` statements on the same expression. In situations where it is necessary to compare the same variable or expression with many different values, and execute a different piece of code depending on which value it equals, the `switch` statement is often more convenient and easier to read.

> [!NOTE]
> Note that unlike some other languages, the [continue](#control-structures.continue) statement applies to `switch` and acts similarly to `break`. If you have a `switch` inside a loop and wish to continue to the next iteration of the outer loop, use `continue 2`.

> [!NOTE]
> Note that switch/case does a [loose comparison](#types.comparisions-loose).

In the following example, each code block is equivalent. One uses a series of `if` and `elseif` statements, and the other a `switch` statement. In each case, the output is the same.

<div class="example">

<div class="title">

`switch` structure

</div>

```
<?php
$i = 1;

// This switch statement:

switch ($i) {
    case 0:
        echo "i equals 0\n";
        break;
    case 1:
        echo "i equals 1\n";
        break;
    case 2:
        echo "i equals 2\n";
        break;
}

// Is equivalent to:
if ($i == 0) {
    echo "i equals 0\n";
} elseif ($i == 1) {
    echo "i equals 1\n";
} elseif ($i == 2) {
    echo "i equals 2\n";
}

   
```

ENTITY

    i equals 1
    i equals 1

       

</div>

It is important to understand how the `switch` statement is executed in order to avoid mistakes. The `switch` statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a `case` statement is found whose expression evaluates to a value that matches the value of the `switch` expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the `switch` block, or the first time it sees a `break` statement. If you don't write a `break` statement at the end of a case's statement list, PHP will go on executing the statements of the following case. For example:

<div class="informalexample">

```
<?php
$i = 1;

switch ($i) {
    case 0:
        echo "i equals 0\n";
    case 1:
        echo "i equals 1\n";
    case 2:
        echo "i equals 2\n";
}

   
```

ENTITY

    i equals 1
    i equals 2

       

</div>

Here, if `$i` is equal to 0, PHP would execute all of the echo statements! If `$i` is equal to 1, PHP would execute the last two echo statements. You would get the expected behavior ('i equals 2' would be displayed) only if `$i` is equal to 2. Thus, it is important not to forget `break` statements (even though you may want to avoid supplying them on purpose under certain circumstances).

In a `switch` statement, the condition is evaluated only once and the result is compared to each `case` statement. In an `elseif` statement, the condition is evaluated again. If your condition is more complicated than a simple comparison and/or is in a tight loop, a `switch` may be faster.

The statement list for a case can also be empty, which simply passes control into the statement list for the next case.

<div class="informalexample">

```
<?php
$i = 1;

switch ($i) {
    case 0:
    case 1:
    case 2:
        echo "i is less than 3 but not negative";
        break;
    case 3:
        echo "i is 3";
}

   
```

ENTITY

    i is less than 3 but not negative

       

</div>

A special case is the `default` case. This case matches anything that wasn't matched by the other cases. For example:

<div class="informalexample">

```
<?php
$i = 4;

switch ($i) {
    case 0:
        echo "i equals 0";
        break;
    case 1:
        echo "i equals 1";
        break;
    case 2:
        echo "i equals 2";
        break;
    default:
       echo "i is not equal to 0, 1 or 2";
}

   
```

ENTITY

    i is not equal to 0, 1 or 2

       

</div>

> [!NOTE]
> Multiple default cases will raise an `E_COMPILE_ERROR` error.

> [!NOTE]
> Technically the `default` case may be listed in any order. It will only be used if no other case matches. However, by convention it is best to place it at the end as the last branch.

If no `case` branch matches, and there is no `default` branch, then no code will be executed, just as if no `if` statement was true.

A case value may be given as an expression. However, that expression will be evaluated on its own and then loosely compared with the switch value. That means it cannot be used for complex evaluations of the switch value. For example:

<div class="informalexample">

```
<?php
$target = 1;
$start = 3;

switch ($target) {
    case $start - 1:
        print "A";
        break;
    case $start - 2:
        print "B";
        break;
    case $start - 3:
        print "C";
        break;
    case $start - 4:
        print "D";
        break;
}

   
```

ENTITY

    B

       

</div>

For more complex comparisons, the value ENTITY may be used as the switch value. Or, alternatively, `if`-`else` blocks can be used instead of `switch`.

<div class="informalexample">

```
<?php
$offset = 1;
$start = 3;

switch (true) {
    case $start - $offset === 1:
        print "A";
        break;
    case $start - $offset === 2:
        print "B";
        break;
    case $start - $offset === 3:
        print "C";
        break;
    case $start - $offset === 4:
        print "D";
        break;
}

   
```

ENTITY

    B

       

</div>

The alternative syntax for control structures is supported with switches. For more information, see [Alternative syntax for control structures](#control-structures.alternative-syntax).

<div class="informalexample">

```
<?php
$i = 1;

switch ($i):
    case 0:
        echo "i equals 0";
        break;
    case 1:
        echo "i equals 1";
        break;
    case 2:
        echo "i equals 2";
        break;
    default:
        echo "i is not equal to 0, 1 or 2";
endswitch;

   
```

ENTITY

    i equals 1

       

</div>

It's possible to use a semicolon instead of a colon after a case. As of PHP 8.5.0, this syntax is deprecated.

<div class="informalexample">

```
<?php
$beer = 'cola';

switch($beer)
{
    case 'tuborg';
    case 'carlsberg';
    case 'stella';
    case 'heineken';
        echo 'Good choice';
        break;
    default;
        echo 'Please make a new selection...';
        break;
}

   
```

ENTITY

    Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 6

    Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 7

    Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 8

    Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 9

    Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 12
    Please make a new selection...

       

</div>

ENTITY

## 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | The alternate syntax using a semicolon after `case` has been deprecated. |

## 

ENTITY

ENTITY

# throw

The ENTITY keyword is an expression and may be used in any expression context. It takes a Throwable object as an argument.

> [!CAUTION]
> Prior to PHP 8.0.0, the ENTITY keyword was a statement and not an expression.

Attempting to ENTITY a non-Throwable object will throw an Error. As user classes cannot implement Throwable directly, the thrown object must be an instance of Error or Exception, or of a subclass of one of them.

<div class="example">

<div class="title">

Throwing a non-Throwable object

</div>

```
<?php
throw new class {};

   
```

ENTITY

    PHP Fatal error:  Uncaught Error: Cannot throw objects that do not implement Throwable in Command line code:1
    Stack trace:
    #0 {main}

       

</div>

After using ENTITY, the normal flow of execution is halted and the call stack is unwound until the object is caught by a ENTITY block or the global scope is reached. All ENTITY blocks encountered along the way are executed. If the global scope is reached, the object is passed to the exception handler set with `set_exception_handler`, if one is set, and the script terminates once the handler returns. Otherwise, the program is terminated with a fatal error containing the stack trace indicating where the Throwable object was thrown.

<div class="example">

<div class="title">

Throwing an Exception in the global scope

</div>

```
<?php
echo "Before exception\n";
throw new Exception('Stop execution');
echo "After exception\n";

  
```

ENTITY

    Before exception
    PHP Fatal error:  Uncaught Exception: Stop execution in Command line code:2
    Stack trace:
    #0 {main}
      thrown in Command line code on line 2

      

</div>

<div class="example">

<div class="title">

Throwing an Exception in a function

</div>

```
   
<?php

function foo() {
    echo "Before exception\n";
    throw new Exception('Stop execution');
    echo "After exception\n";
}

foo();

  
```

ENTITY

    Before exception
    PHP Fatal error:  Uncaught Exception: Stop execution in Command line code:3
    Stack trace:
    #0 Command line code(7): foo()
    #1 {main}
      thrown in Command line code on line 3

      

</div>

As ENTITY is an expression, it can be used to branch out on the result of another expression if its value is inappropriate.

<div class="example">

<div class="title">

Using throw as an expression

</div>

Only permitted as of PHP 8.0.0.

```
<?php

function test() {
    do_something_risky() or throw new Exception('It did not work');
}

function do_something_risky() {
    return false; // Simulate failure
}

try {
    test();
} catch (Exception $e) {
    print $e->getMessage();
}

  
```

ENTITY

    It did not work

      

</div>

It is possible to handle a thrown Throwable by using a [try-catch](#control-structures.try-catch) block. See the [error handling](#language.error-handling.throwable) section for more information.

# try...catch

## try

A ENTITY block delimits a segment of code which might ENTITY a Throwable error that needs handling. A ENTITY block *must* have at least one corresponding ENTITY or ENTITY block.

When a Throwable error is thrown in a ENTITY block, PHP will attempt to find the first matching ENTITY block to handle the error. If none can be found, the call stack is unwound until a matching ENTITY block is found or the global scope is reached. An uncaught object is then passed to the exception handler set with `set_exception_handler`, if one is set; otherwise, the script terminates with a fatal error.

## catch

A ENTITY block defines how to respond to a thrown Throwable error. It specifies one or more subclasses of Throwable (most commonly Exception) it can handle, and optionally a variable to which the exception is assigned.

The first ENTITY block that matches the class of the thrown Throwable object will handle the error. Normal execution resumes after the ENTITY block without entering any other matching ENTITY blocks.

> [!NOTE]
> It is *not* recommended to catch Error objects, as they signal a programming error.

<div class="example">

<div class="title">

Catching an Exception

</div>

```
<?php
try {
    throw new Exception('Error');
} catch (Exception $e) {
    echo 'Caught exception: ', $e->getMessage(), "\n";
}

// Continue execution
echo "Hello World\n";

   
```

ENTITY

    Caught exception: Error
    Hello World

       

</div>

As of PHP 7.1.0, a ENTITY block may specify a union of Throwable subclasses that the block should handle using the pipe (`|`) character. This is useful when different exceptions from different class hierarchies are handled in the same way.

<div class="example">

<div class="title">

Catching a union of classes to handle

</div>

```
<?php

class MyException extends Exception { }

class MyOtherException extends Exception { }

class Test {
    public function testing() {
        try {
            throw new MyException();
        } catch (MyException | MyOtherException $e) {
            var_dump(get_class($e));
        }
    }
}

$foo = new Test;
$foo->testing();

   
```

ENTITY

    string(11) "MyException"

       

</div>

Multiple ENTITY blocks can be used to handle different classes of Throwable errors in different ways.

<div class="example">

<div class="title">

Multiple catch blocks

</div>

```
<?php
try {
    do_something_io_related();
} catch (FileNotFoundException $e) {
    // Only catch FileNotFoundException and do something in this case
} catch (MissingPermissionException $e) {
    // Only catch MissingPermissionException and do something different in this case
}

   
```

</div>

Throwables can be ENTITYn (or re-thrown) within a ENTITY block.

<div class="example">

<div class="title">

Nested Exception

</div>

```
<?php

class MyException extends Exception { }

class Test {
    public function testing() {
        try {
            try {
                throw new MyException('foo!');
            } catch (MyException $e) {
                // rethrow it
                throw $e;
            }
        } catch (Exception $e) {
            var_dump($e->getMessage());
        }
    }
}

$foo = new Test;
$foo->testing();

   
```

ENTITY

    string(4) "foo!"

       

</div>

> [!CAUTION]
> An object thrown inside a ENTITY block will *not* be caught by an adjacent ENTITY block.
>
> <div class="example">
>
> <div class="title">
>
> Sequential catch blocks
>
> </div>
>
> ```
> <?php
>
> class A extends Exception {}
> class B extends Exception {}
>
> try {
>     throw new A;
> } catch (A $e) {
>     throw new B;
> } catch (B) {
>     echo 'Hello';
> }
>
>
>     
> ```
>
> ENTITY
>
>     Fatal error: Uncaught B in /in/K8Tl9:9
>     Stack trace:
>     #0 {main}
>       thrown in /in/K8Tl9 on line 9
>
>         
>
> </div>

As of PHP 8.0.0, the variable name for a caught Throwable is optional. If not specified, the ENTITY block will still execute but will not have access to the thrown object.

<div class="example">

<div class="title">

Omitting the caught variable

</div>

Only permitted as of PHP 8.0.0.

```
<?php

class SpecificException extends Exception {}

function test() {
    throw new SpecificException('Oopsie');
}

try {
    test();
} catch (SpecificException) {
    print "A SpecificException was thrown, but we don't care about the details.";
}

   
```

ENTITY

    A SpecificException was thrown, but we don't care about the details.

       

</div>

See the [error handling](#language.error-handling.throwable) section for the Throwable hierarchy and how to define custom exceptions.

# while

`while` loops are the simplest type of loop in PHP. They behave just like their C counterparts. The basic form of a `while` statement is:

<div class="informalexample">

    while (expr)
        statement

       

</div>

The meaning of a `while` statement is simple. It tells PHP to execute the nested statement(s) repeatedly, as long as the `while` expression evaluates to ENTITY. The value of the expression is checked each time at the beginning of the loop, so even if this value changes during the execution of the nested statement(s), execution will not stop until the end of the iteration (each time PHP runs the statements in the loop is one iteration). If the `while` expression evaluates to ENTITY from the very beginning, the nested statement(s) won't even be run once.

Like with the `if` statement, you can group multiple statements within the same `while` loop by surrounding a group of statements with curly braces, or by using the alternate syntax:

<div class="informalexample">

    while (expr):
        statement
        ...
    endwhile;

       

</div>

The following examples are identical, and both print the numbers 1 through 10:

<div class="informalexample">

```
<?php
$i = 1;
while ($i <= 10) {
    echo $i++ . "\n";  /* the printed value would be
                          $i before the increment
                          (post-increment) */
}

   
```

ENTITY

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

       

</div>

<div class="informalexample">

```
<?php
$i = 1;
while ($i <= 10):
    echo $i . "\n";
    $i++;
endwhile;

   
```

ENTITY

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

       

</div>

# Enumerations

## Enumerations overview

Enumerations, or "Enums", allow a developer to define a custom type that is limited to one of a discrete number of possible values. That can be especially helpful when defining a domain model, as it enables "making invalid states unrepresentable."

Enums appear in many languages with a variety of different features. In PHP, Enums are a special kind of object. The Enum itself is a class, and its possible cases are all single-instance objects of that class. That means Enum cases are valid objects and may be used anywhere an object may be used, including type checks.

The most popular example of enumerations is the built-in boolean type, which is an enumerated type with legal values ENTITY and ENTITY. Enums allows developers to define their own arbitrarily robust enumerations.

## Basic enumerations

Enums are similar to classes, and share the same namespaces as classes, interfaces, and traits. They are also autoloadable the same way. An Enum defines a new type, which has a fixed, limited number of possible legal values.

```
<?php

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

   
```

This declaration creates a new enumerated type named `Suit`, which has four and only four legal values: `Suit::Hearts`, `Suit::Diamonds`, `Suit::Clubs`, and `Suit::Spades`. Variables may be assigned to one of those legal values. A function may be type checked against an enumerated type, in which case only values of that type may be passed.

<div class="informalexample">

```
<?php

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

function pick_a_card(Suit $suit)
{
    var_dump($suit);
}

$val = Suit::Diamonds;

// OK
pick_a_card($val);

// OK
pick_a_card(Suit::Clubs);

// TypeError: pick_a_card(): Argument #1 ($suit) must be of type Suit, string given
pick_a_card('Spades');

    
```

</div>

An Enumeration may have zero or more `case` definitions, with no maximum. A zero-case enum is syntactically valid, if rather useless.

For Enumeration cases, the same syntax rules apply as to any label in PHP, see [Constants](#language.constants).

By default, cases are not intrinsically backed by a scalar value. That is, `Suit::Hearts` is not equal to `"0"`. Instead, each case is backed by a singleton object of that name. That means that:

<div class="informalexample">

```
<?php

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

$a = Suit::Spades;
$b = Suit::Spades;

if ($a === $b) {
    print "Suits match using ===\n";
}

if ($a instanceof Suit) {
    print "Suits match using instanceof\n";
}

if ($a !== 'Spades') {
    print "Suit does not match the string\n";
}

    
```

</div>

It also means that enum values are never `ENTITY` or `ENTITY` each other, since those comparisons are not meaningful on objects. Those comparisons will always return ENTITY when working with enum values.

This type of case, with no related data, is called a "Pure Case." An Enum that contains only Pure Cases is called a Pure Enum.

All Pure Cases are implemented as instances of their enum type. The enum type is represented internally as a class.

All Cases have a read-only property, `name`, that is the case-sensitive name of the case itself.

<div class="informalexample">

```
<?php

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

print Suit::Spades->name;
// prints "Spades"

    
```

</div>

It is also possible to use the `defined` and `constant` functions to check for the existence of or read an enum case if the name is obtained dynamically. This is, however, discouraged as using [Backed enums](#language.enumerations.backed) should work for most use cases.

## Backed enumerations

By default, Enumerated Cases have no scalar equivalent. They are simply singleton objects. However, there are ample cases where an Enumerated Case needs to be able to round-trip to a database or similar datastore, so having a built-in scalar (and thus trivially serializable) equivalent defined intrinsically is useful.

To define a scalar equivalent for an Enumeration, the syntax is as follows:

```
<?php

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

  
```

A case that has a scalar equivalent is called a Backed Case, as it is "Backed" by a simpler value. An Enum that contains all Backed Cases is called a "Backed Enum." A Backed Enum may contain only Backed Cases. A Pure Enum may contain only Pure Cases.

A Backed Enum may be backed by types of `int` or `string`, and a given enumeration supports only a single type at a time (that is, no union of `int|string`). If an enumeration is marked as having a scalar equivalent, then all cases must have a unique scalar equivalent defined explicitly. There are no auto-generated scalar equivalents (e.g., sequential integers). Backed cases must be unique; two backed enum cases may not have the same scalar equivalent. However, a constant may refer to a case, effectively creating an alias. See [Enumeration constants](#language.enumerations.constants).

The equivalent values may be a constant scalar expression. Prior to PHP 8.2.0, the equivalent values had to be literals or literal expressions. This means that constants and constant expressions were not supported. That is, `1 + 1` was allowed, but `1 + SOME_CONST` was not.

Backed Cases have an additional read-only property, `value`, which is the value specified in the definition.

<div class="informalexample">

```
<?php

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

print Suit::Clubs->value;
// Prints "C"

   
```

</div>

In order to enforce the `value` property as read-only, a variable cannot be assigned as a reference to it. That is, the following throws an error:

<div class="informalexample">

```
<?php

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

$suit = Suit::Clubs;
$ref = &$suit->value;
// Fatal Error: Cannot indirectly modify readonly property Suit::$value

   
```

</div>

Backed enums implement an internal BackedEnum interface, which exposes two additional methods:

from(int\|string): self

will take a scalar and return the corresponding Enum Case. If one is not found, it will throw a

ValueError

. This is mainly useful in cases where the input scalar is trusted and a missing enum value should be considered an application-stopping error.

tryFrom(int\|string): ?self

will take a scalar and return the corresponding Enum Case. If one is not found, it will return ENTITY. This is mainly useful in cases where the input scalar is untrusted and the caller wants to implement their own error handling or default-value logic.

The `from()` and `tryFrom()` methods follow standard weak/strong typing rules. In weak typing mode, passing an integer or string is acceptable and the system will coerce the value accordingly. Passing a float will also work and be coerced. In strict typing mode, passing an integer to `from()` on a string-backed enum (or vice versa) will result in a `TypeError`, as will a float in all circumstances. All other parameter types will throw a TypeError in both modes.

<div class="informalexample">

```
<?php

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

function get_stuff_from_database($id) {
    return [
        'suit' => 'S',
    ];
}

$record = get_stuff_from_database(42);
print $record['suit'] . "\n";

$suit = Suit::tryFrom('A') ?? Suit::Spades;
// Invalid data returns null, so Suit::Spades is used instead.
print $suit->value . "\n";

$suit =  Suit::from('X');
// Invalid data throws a ValueError: "X" is not a valid backing scalar value for enum Suit
print $suit->value . "\n";

   
```

</div>

Manually defining a `from()` or `tryFrom()` method on a Backed Enum will result in a fatal error.

## Enumeration methods

Enums (both Pure Enums and Backed Enums) may contain methods, and may implement interfaces. If an Enum implements an interface, then any type check for that interface will also accept all cases of that Enum.

<div class="informalexample">

```
<?php

interface Colorful
{
    public function color(): string;
}

enum Suit implements Colorful
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;

    // Fulfills the interface contract.
    public function color(): string
    {
        return match ($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }

    // Not part of an interface; that's fine.
    public function shape(): string
    {
        return "Rectangle";
    }
}

function paint(Colorful $c)
{
   print $c->color() . "\n";
}

paint(Suit::Clubs);  // Works

print Suit::Diamonds->shape(); // prints "Rectangle"

   
```

</div>

In this example, all four instances of `Suit` have two methods, `color()` and `shape()`. As far as calling code and type checks are concerned, they behave exactly the same as any other object instance.

On a Backed Enum, the interface declaration goes after the backing type declaration.

```
   
<?php

interface Colorful
{
    public function color(): string;
}

enum Suit: string implements Colorful
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';

    // Fulfills the interface contract.
    public function color(): string
    {
        return match ($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }
}

  
```

Inside a method, the `$this` variable is defined and refers to the Case instance.

Methods may be arbitrarily complex, but in practice will usually return a static value or ENTITY on `$this` to provide different results for different cases.

Note that in this case it would be a better data modeling practice to also define a `SuitColor` Enum Type with values Red and Black and return that instead. However, that would complicate this example.

The above hierarchy is logically similar to the following class structure (although this is not the actual code that runs):

```
<?php

interface Colorful
{
    public function color(): string;
}

final class Suit implements UnitEnum, Colorful
{
    public const Hearts = new self('Hearts');
    public const Diamonds = new self('Diamonds');
    public const Clubs = new self('Clubs');
    public const Spades = new self('Spades');

    private function __construct(public readonly string $name) {}

    public function color(): string
    {
        return match ($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }

    public function shape(): string
    {
        return "Rectangle";
    }

    public static function cases(): array
    {
        // Illegal method, because manually defining a cases() method on an Enum is disallowed.
        // See also "Value listing" section.
    }
}

  
```

Methods may be public, private, or protected, although in practice private and protected are equivalent as inheritance is not allowed.

## Enumeration static methods

Enumerations may also have static methods. The use for static methods on the enumeration itself is primarily for alternative constructors. E.g.:

<div class="informalexample">

```
<?php

enum Size
{
    case Small;
    case Medium;
    case Large;

    public static function fromLength(int $cm): self
    {
        return match (true) {
            $cm < 50 => self::Small,
            $cm < 100 => self::Medium,
            default => self::Large,
        };
    }
}

var_dump(Size::fromLength(50));

   
```

</div>

Static methods may be public, private, or protected, although in practice private and protected are equivalent as inheritance is not allowed.

## Enumeration constants

Enumerations may include constants, which may be public, private, or protected, although in practice private and protected are equivalent as inheritance is not allowed.

An enum constant may refer to an enum case:

<div class="informalexample">

```
<?php

enum Size
{
    case Small;
    case Medium;
    case Large;

    public const Huge = self::Large;
}

var_dump(Size::Huge);

   
```

</div>

## Traits

Enumerations may leverage traits, which will behave the same as on classes. The caveat is that traits `use`d in an enum must not contain properties. They may only include methods, static methods, and constants. A trait with properties will result in a fatal error.

<div class="informalexample">

```
<?php

interface Colorful
{
    public function color(): string;
}

trait Rectangle
{
    public function shape(): string
    {
        return "Rectangle";
    }
}

enum Suit implements Colorful
{
    use Rectangle;

    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;

    public function color(): string
    {
        return match ($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }
}

$suit = Suit::Spades;
var_dump($suit->color());
var_dump($suit->shape());

   
```

</div>

## Enum values in constant expressions

Because cases are represented as constants on the enum itself, they may be used as static values in most constant expressions: property defaults, static variable defaults, parameter defaults, global and class constant values. They may not be used in other enum case values, but normal constants may refer to an enum case.

However, implicit magic method calls such as `ArrayAccess` on enums are not allowed in static or constant definitions as we cannot absolutely guarantee that the resulting value is deterministic or that the method invocation is free of side effects. Function calls, method calls, and property access continue to be invalid operations in constant expressions.

```
<?php

// This is an entirely legal Enum definition.
enum Direction implements ArrayAccess
{
    case Up;
    case Down;

    public function offsetExists($offset): bool
    {
        return false;
    }

    public function offsetGet($offset): mixed
    {
        return null;
    }

    public function offsetSet($offset, $value): void
    {
        throw new Exception();
    }

    public function offsetUnset($offset): void
    {
        throw new Exception();
    }
}

class Foo
{
    // This is allowed.
    const DOWN = Direction::Down;

    // This is disallowed, as it may not be deterministic.
    const UP = Direction::Up['short'];
    // Fatal error: Cannot use [] on enums in constant expression
}

// This is entirely legal, because it's not a constant expression.
$x = Direction::Up['short'];
var_dump("\$x is " . var_export($x, true));

$foo = new Foo();

  
```

## Differences from objects

Although Enums are built on classes and objects, they do not support all object-related functionality. In particular, Enum cases are forbidden from having state.

Constructors and Destructors are forbidden.

Inheritance is not supported. Enums may not extend or be extended.

Static or object properties are not allowed.

Cloning an Enum case is not supported, as cases must be singleton instances.

Magic methods

, except for those listed below, are disallowed.

Enums must always be declared before they are used.

The following object functionality is available, and behaves just as it does on any other object:

Public, private, and protected methods.

Public, private, and protected static methods.

Public, private, and protected constants.

Enums may implement any number of interfaces.

Enums and cases may have

attributes

attached to them. The

TARGET_CLASS

target filter includes Enums themselves. The

TARGET_CLASS_CONST

target filter includes Enum Cases.

\_\_call

,

\_\_callStatic

, and

\_\_invoke

magic methods

\_\_CLASS\_\_

and

\_\_FUNCTION\_\_

constants behave as normal

The `::class` magic constant on an Enum type evaluates to the type name including any namespace, exactly the same as an object. The `::class` magic constant on a Case instance also evaluates to the Enum type, as it is an instance of that type.

Additionally, enum cases may not be instantiated directly with `new`, nor with ReflectionClass::newInstanceWithoutConstructor in reflection. Both will result in an error.

```
<?php

$clovers = new Suit();
// Error: Cannot instantiate enum Suit

$horseshoes = (new ReflectionClass(Suit::class))->newInstanceWithoutConstructor()
// Error: Cannot instantiate enum Suit

  
```

## Value listing

Both Pure Enums and Backed Enums implement an internal interface named UnitEnum. `UnitEnum` includes a static method `cases()`. `cases()` returns a packed array of all defined Cases in the order of declaration.

<div class="informalexample">

```
<?php

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

var_dump(Suit::cases());

enum SuitBacked: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

var_dump(SuitBacked::cases());

   
```

</div>

Manually defining a `cases()` method on an Enum will result in a fatal error.

## Serialization

Enumerations are serialized differently from objects. Specifically, they have a new serialization code, `"E"`, that specifies the name of the enum case. The deserialization routine is then able to use that to set a variable to the existing singleton value. That ensures that:

<div class="informalexample">

```
<?php

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

Suit::Hearts === unserialize(serialize(Suit::Hearts));

print serialize(Suit::Hearts);
// E:11:"Suit:Hearts";

   
```

</div>

On deserialization, if an enum and case cannot be found to match a serialized value a warning will be issued and ENTITY returned.

The `allowed_classes` option of `unserialize` does not affect [Enumerations](#language.enumerations).

If a Pure Enum is serialized to JSON, an error will be thrown. If a Backed Enum is serialized to JSON, it will be represented by its scalar value only, in the appropriate type. The behavior of both may be overridden by implementing `JsonSerializable`.

For `print_r`, the output of an enum case is slightly different from objects to minimize confusion.

<div class="informalexample">

```
<?php

enum Foo
{
    case Bar;
}

enum Baz: int
{
    case Beep = 5;
}

print_r(Foo::Bar);
print_r(Baz::Beep);

/* Produces

Foo Enum (
    [name] => Bar
)
Baz Enum:int {
    [name] => Beep
    [value] => 5
}
*/

   
```

</div>

## Why enums aren't extendable

Classes have contracts on their methods:

```
<?php

class A {}
class B extends A {}

function foo(A $a) {}

function bar(B $b)
{
    foo($b);
}

 
```

This code is type-safe, as B follows the contract of A, and through the magic of co/contra-variance, any expectation one may have of the methods will be preserved, exceptions excepted.

Enums have contracts on their cases, not methods:

```
<?php

enum ErrorCode
{
    case SOMETHING_BROKE;
}

function quux(ErrorCode $errorCode)
{
    // When written, this code appears to cover all cases
    match ($errorCode) {
        ErrorCode::SOMETHING_BROKE => true,
    };
}

  
```

The ENTITY statement in the function `quux` can be static analyzed to cover all of the cases in ErrorCode.

But imagine it was allowed to extend enums:

```
<?php

// Thought experiment code where enums are not final.
// Note, this won't actually work in PHP.
enum MoreErrorCode extends ErrorCode
{
    case PEBKAC;
}

function fot(MoreErrorCode $errorCode)
{
    quux($errorCode);
}

fot(MoreErrorCode::PEBKAC);

  
```

Under normal inheritance rules, a class that extends another will pass the type check.

The problem would be that the ENTITY statement in `quux()` no longer covers all the cases. Because it doesn't know about `MoreErrorCode::PEBKAC` the match will throw an exception.

Because of this enums are final and can't be extended.

## 

ENTITY

<div class="example">

<div class="title">

Basic limited values

</div>

```
<?php

enum SortOrder
{
    case Asc;
    case Desc;
}

function query($fields, $filter, SortOrder $order = SortOrder::Asc)
{
     /* ... */
}

    
```

The `query()` function can now proceed safe in the knowledge that `$order` is guaranteed to be either `SortOrder::Asc` or `SortOrder::Desc`. Any other value would have resulted in a `TypeError`, so no further error checking or testing is needed.

</div>

<div class="example">

<div class="title">

Advanced exclusive values

</div>

```
<?php

enum UserStatus: string
{
    case Pending = 'P';
    case Active = 'A';
    case Suspended = 'S';
    case CanceledByUser = 'C';

    public function label(): string
    {
        return match ($this) {
            self::Pending => 'Pending',
            self::Active => 'Active',
            self::Suspended => 'Suspended',
            self::CanceledByUser => 'Canceled by user',
        };
    }
}

$status = UserStatus::Suspended;
var_dump($status->label());

    
```

In this example, a user's status may be one of, and exclusively, `UserStatus::Pending`, `UserStatus::Active`, `UserStatus::Suspended`, or `UserStatus::CanceledByUser`. A function can type a parameter against `UserStatus` and then only accept those four values, period.

All four values have a `label()` method, which returns a human-readable string. That string is independent of the "machine name" scalar equivalent string, which can be used in, for example, a database field or an HTML select box.

```
<?php

enum UserStatus: string
{
    case Pending = 'P';
    case Active = 'A';
    case Suspended = 'S';
    case CanceledByUser = 'C';

    public function label(): string
    {
        return match($this) {
            self::Pending => 'Pending',
            self::Active => 'Active',
            self::Suspended => 'Suspended',
            self::CanceledByUser => 'Canceled by user',
        };
    }
}

foreach (UserStatus::cases() as $case) {
    printf(
        "<option value=\"%s\">%s</option>\n",
        htmlentities($case->value),
        htmlentities($case->label())
    );
}

    
```

</div>

# Error Handling

Errors are a normal part of the development and life cycle of an application. As such, PHP provides multiple ways to report and deal with errors.

PHP has two main mechanisms for reporting errors:

- Throwable errors, which are further split into *programming* errors via the Error class hierarchy and *recoverable* errors via the Exception class hierarchy. These errors can be thrown with the ENTITY keyword and caught with the ENTITY keyword.

- Diagnostic errors, which are classified into different [severities](#errorfunc.constants).

## Throwable errors

A Throwable error is an execution event which disrupts the normal flow of instructions. When a Throwable error is ENTITYn, it will unwind the call stack until it is caught by a ENTITY block or the global scope is reached. All ENTITY blocks it encounters along the way will be executed. An uncaught Throwable error is passed to the exception handler set with `set_exception_handler`, if one is set; otherwise, the program is terminated with a fatal error.

To throw a Throwable error from within PHP code, use the ENTITY keyword.

> [!TIP]
> The [Standard PHP Library (SPL)](#intro.spl) provides various [built-in exceptions](#spl.exceptions). It is also possible to create custom exceptions by [extending the Exception class](#language.error-handling.throwable.extending).

It is possible to handle a Throwable error within PHP by surrounding the code that may throw an error in a ENTITY block.

> [!WARNING]
> Throwable objects cannot be cloned. Attempting to [clone](#language.oop5.cloning) such an object throws an Error with the following message: `Trying to clone an uncloneable object of class ClassName`. This happens even if a subclass declares its own [\_\_clone()](#object.clone) method. See Exception::\_\_clone and Error::\_\_clone.

### Global exception handler

It's possible to add a handler for any uncaught Throwable with `set_exception_handler`. This is similar to wrapping the entire code in a ENTITY-ENTITY block, except that execution does not resume afterwards: the script terminates once the handler returns.

### Extending exceptions

A user-defined exception can be defined by extending the built-in Exception class.

If a class extends the built-in Exception class and redefines the [constructor](#language.oop5.decon), it is highly recommended that it also call `parent::__construct()` to ensure all available data has been properly assigned. The [\_\_toString()](#object.tostring) method can be overridden to provide custom output when the object is used as a string.

<div class="example">

<div class="title">

Extending Exception

</div>

```
<?php
class CustomException extends Exception
{
    // Redefine the constructor so message isn't optional
    public function __construct($message, $code = 0, ?Throwable $previous = null) {
        // some code

        // Ensure everything is assigned properly
        parent::__construct($message, $code, $previous);
    }

    // Custom string representation of object
    public function __toString() {
        return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
    }

    public function customFunction() {
        echo "A custom function for this type of exception\n";
    }
}

try {
    throw new CustomException("Something happened", 5);
} catch (CustomException $e) {
    echo "Caught custom exception\n", $e;
    $e->customFunction();
}

    
```

ENTITY

    Caught custom exception
    CustomException: [5]: Something happened
    A custom function for this type of exception

        

</div>

### Throwable hierarchy

- Throwable

  - Error

    - ArithmeticError

      - DivisionByZeroError

    - AssertionError

    - CompileError

      - ParseError

    - TypeError

      - ArgumentCountError

    - ValueError

    - UnhandledMatchError

    - FiberError

  - Exception

The Exception class has many subclasses, among them the [SPL exceptions](#spl.exceptions) and those defined by extensions.

## Diagnostic errors

Diagnostic errors, also known as traditional errors, are used to signal a number of different conditions, and can be displayed and/or logged as required. By default, PHP will report all diagnostic errors. (Prior to PHP 8.0.0, `E_NOTICE` and `E_DEPRECATED` diagnostics were not reported by default.)

In contrast to Throwable errors, most diagnostic errors do *not* disrupt the normal flow of execution. Fatal diagnostics, such as `E_ERROR`, terminate the script.

Which diagnostics are reported and which are ignored is controlled by the [`error_reporting`](#ini.error-reporting) ENTITY directive, or at runtime by calling `error_reporting`. It is strongly recommended that the configuration directive be set, as some errors can occur before execution of your script begins.

> [!NOTE]
> In a development environment, [`error_reporting`](#ini.error-reporting) should always be set to `E_ALL` so that issues raised by PHP are noticed and fixed. In production, the level of verbosity can be reduced to `E_ALL ENTITY ~E_NOTICE ENTITY ~E_DEPRECATED`, although in many cases `E_ALL` is still appropriate, as it may provide early warning of potential issues.

What happens to the diagnostics depends on two further ENTITY directives. [`display_errors`](#ini.display-errors) controls whether the diagnostic is shown as part of the script's output. This should always be disabled in a production environment, as the output can include confidential information such as database passwords, but is often useful to enable in development, as it ensures immediate reporting of issues.

In addition to displaying errors, PHP can log diagnostics when the [`log_errors`](#ini.log-errors) directive is enabled. This will log any diagnostic to the file or syslog defined by [`error_log`](#ini.error-log). This can be extremely useful in a production environment, as diagnostics are logged when they occur, and reports can then be generated from those logs.

Individual diagnostics can be suppressed using the `@` operator.

> [!WARNING]
> Prior to PHP 8.0.0, it was possible to suppress critical diagnostics that would terminate the execution of the PHP script.

> [!NOTE]
> Between PHP versions, diagnostics may be added or removed, have their severity changed, or be elevated to Throwable errors.

### User-defined diagnostic handler

If PHP's default diagnostic handling is inadequate, it is possible to override the default diagnostic handler with a custom one which is set using `set_error_handler`. Some diagnostics, such as `E_ERROR` and `E_PARSE`, cannot be handled this way (see `set_error_handler` for the full list). The others can be handled in various ways. For example, a custom handler can show an error page to the user and report the error more directly than a log would, such as by sending an email.

Another typical usage is to elevate diagnostic errors to exceptions with [ErrorException](#class.errorexception).

<div class="example">

<div class="title">

Elevating diagnostic errors to exceptions

</div>

```
<?php
function exceptions_error_handler($severity, $message, $filename, $lineno) {
    if (error_reporting() & $severity) {
        throw new ErrorException($message, 0, $severity, $filename, $lineno);
    }
}

set_error_handler('exceptions_error_handler');

    
```

> [!NOTE]
> It is important to verify that the severity is included in the current list of reportable diagnostics; otherwise, the `@` operator will be broken, as an exception will be thrown for a suppressed diagnostic.

</div>

### 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | Fatal errors (such as an exceeded maximum execution time) now include a stack trace in their error message. |

# Expressions

Expressions are the most important building blocks of PHP. In PHP, almost anything you write is an expression. The simplest yet most accurate way to define an expression is "anything that has a value".

The most basic forms of expressions are constants and variables. When you type `$a = 5`, you're assigning `5` into `$a`. `5`, obviously, has the value 5, or in other words `5` is an expression with the value of 5 (in this case, `5` is an integer constant).

After this assignment, you'd expect `$a`'s value to be 5 as well, so if you wrote `$b = $a`, you'd expect it to behave just as if you wrote `$b = 5`. In other words, `$a` is an expression with the value of 5 as well. If everything works right, this is exactly what will happen.

Slightly more complex examples for expressions are functions. For instance, consider the following function:

<div class="informalexample">

```
<?php
function foo ()
{
    return 5;
}
?>

     
```

</div>

Assuming you're familiar with the concept of functions (if you're not, take a look at the chapter about [functions](#language.functions)), you'd assume that typing `$c = foo()` is essentially just like writing `$c = 5`, and you're right. Functions are expressions with the value of their return value. Since `foo()` returns 5, the value of the expression '`foo()`' is 5. Usually functions don't just return a static value but compute something.

Of course, values in PHP don't have to be integers, and very often they aren't. PHP supports four scalar value types: `int` values, floating point values (`float`), `string` values and `bool` values (scalar values are values that you can't 'break' into smaller pieces, unlike arrays, for instance). PHP also supports two composite (non-scalar) types: arrays and objects. Each of these value types can be assigned into variables or returned from functions.

PHP takes expressions much further, in the same way many other languages do. PHP is an expression-oriented language, in the sense that almost everything is an expression. Consider the example we've already dealt with, `$a = 5`. It's easy to see that there are two values involved here, the value of the integer constant `5`, and the value of `$a` which is being updated to 5 as well. But the truth is that there's one additional value involved here, and that's the value of the assignment itself. The assignment itself evaluates to the assigned value, in this case 5. In practice, it means that `$a = 5`, regardless of what it does, is an expression with the value 5. Thus, writing something like `$b = ($a = 5)` is like writing `$a = 5; $b = 5;` (a semicolon marks the end of a statement). Since assignments are parsed in a right to left order, you can also write `$b = $a = 5`.

Another good example of expression orientation is pre- and post-increment and decrement. Users of PHP and many other languages may be familiar with the notation of `variable++` and `variable--`. These are [ increment and decrement operators](#language.operators.increment). In PHP, like in C, there are two types of increment - pre-increment and post-increment. Both pre-increment and post-increment essentially increment the variable, and the effect on the variable is identical. The difference is with the value of the increment expression. Pre-increment, which is written `++$variable`, evaluates to the incremented value (PHP increments the variable before reading its value, thus the name 'pre-increment'). Post-increment, which is written `$variable++` evaluates to the original value of `$variable`, before it was incremented (PHP increments the variable after reading its value, thus the name 'post-increment').

A very common type of expressions are [comparison](#language.operators.comparison) expressions. These expressions evaluate to either ENTITY or ENTITY. PHP supports ENTITY (bigger than), ENTITY= (bigger than or equal to), == (equal), != (not equal), ENTITY (smaller than) and ENTITY= (smaller than or equal to). The language also supports a set of strict equivalence operators: === (equal to and same type) and !== (not equal to or not same type). These expressions are most commonly used inside conditional execution, such as `if` statements.

The last example of expressions we'll deal with here is combined operator-assignment expressions. You already know that if you want to increment `$a` by 1, you can simply write `$a++` or `++$a`. But what if you want to add more than one to it, for instance 3? You could write `$a++` multiple times, but this is obviously not a very efficient or comfortable way. A much more common practice is to write `$a = $a + 3`. `$a + 3` evaluates to the value of `$a` plus 3, and is assigned back into `$a`, which results in incrementing `$a` by 3. In PHP, as in several other languages like C, you can write this in a shorter way, which with time would become clearer and quicker to understand as well. Adding 3 to the current value of `$a` can be written `$a += 3`. This means exactly "take the value of `$a`, add 3 to it, and assign it back into `$a`". In addition to being shorter and clearer, this also results in faster execution. The value of `$a += 3`, like the value of a regular assignment, is the assigned value. Notice that it is NOT 3, but the combined value of `$a` plus 3 (this is the value that's assigned into `$a`). Any two-place operator can be used in this operator-assignment mode, for example `$a -= 5` (subtract 5 from the value of `$a`), `$b *= 7` (multiply the value of `$b` by 7), etc.

There is one more expression that may seem odd if you haven't seen it in other languages, the ternary conditional operator:

<div class="informalexample">

```
<?php
$first ? $second : $third
?>

     
```

</div>

If the value of the first subexpression is ENTITY (non-zero), then the second subexpression is evaluated, and that is the result of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value.

The following example should help you understand pre- and post-increment and expressions in general a bit better:

<div class="informalexample">

```
<?php
function double($i)
{
    return $i * 2;
}

$b = $a = 5;        /* assign the value five into the variable $a and $b */
$c = $a++;          /* post-increment, assign original value of $a 
                       (5) to $c */
print "a = {$a}; b = {$b}; c = {$c}" . PHP_EOL;

$e = $d = ++$b;     /* pre-increment, assign the incremented value of 
                       $b (6) to $d and $e */
print "b = {$b}; d = {$d}; e = {$e}" . PHP_EOL;

/* at this point, both $d and $e are equal to 6 */

$f = double($d++);  /* assign twice the value of $d before
                       the increment, 2*6 = 12 to $f */
print "d = {$d}; f = {$f}" . PHP_EOL;

$g = double(++$e);  /* assign twice the value of $e after
                       the increment, 2*7 = 14 to $g */
print "e = {$e}; g = {$g}" . PHP_EOL;

$h = $g += 10;      /* first, $g is incremented by 10 and ends with the 
                       value of 24. the value of the assignment (24) is 
                       then assigned into $h, and $h ends with the value 
                       of 24 as well. */
print "g = {$g}; h = {$h}" . PHP_EOL;
?>

     
```

</div>

Some expressions can be considered as statements. In this case, a statement has the form of '`expr ;`' that is, an expression followed by a semicolon. In `$b = $a = 5;`, `$a = 5` is a valid expression, but it's not a statement by itself. `$b = $a = 5;`, however, is a valid statement.

One last thing worth mentioning is the truth value of expressions. In many events, mainly in conditional execution and loops, you're not interested in the specific value of the expression, but only care about whether it means ENTITY or ENTITY. The constants ENTITY and ENTITY (case-insensitive) are the two possible boolean values. When necessary, an expression is automatically converted to boolean. See the [section about type-casting](#language.types.typecasting) for details about how.

PHP provides a full and powerful implementation of expressions, and documenting it entirely goes beyond the scope of this manual. The above examples should give you a good idea about what expressions are and how you can construct useful expressions. Throughout the rest of this manual we'll write `expr` to indicate any valid PHP expression.

# Fibers

## Fibers overview

Fibers represent full-stack, interruptible functions. Fibers may be suspended from anywhere in the call-stack, pausing execution within the fiber until the fiber is resumed at a later time.

Fibers pause the entire execution stack, so the direct caller of the function does not need to change how it invokes the function.

Execution may be interrupted anywhere in the call stack using Fiber::suspend (that is, the call to Fiber::suspend may be in a deeply nested function or not even exist at all).

Unlike stack-less `Generator`s, each `Fiber` has its own call stack, allowing them to be paused within deeply nested function calls. A function declaring an interruption point (that is, calling Fiber::suspend) need not change its return type, unlike a function using ENTITY which must return a `Generator` instance.

Fibers can be suspended in any function call, including those called from within the PHP VM, such as functions provided to `array_map` or methods called by ENTITY on an `Iterator` object.

Once suspended, execution of the fiber may be resumed with any value using Fiber::resume or by throwing an exception into the fiber using Fiber::throw. The value is returned (or exception thrown) from Fiber::suspend.

> [!NOTE]
> Prior to PHP 8.4.0, switching fibers during the execution of an object [destructor](#language.oop5.decon.destructor) was not allowed.

<div id="language.fiber.example.basic" class="example">

<div class="title">

Basic usage

</div>

```
    
<?php
$fiber = new Fiber(function (): void {
   $value = Fiber::suspend('fiber');
   echo "Value used to resume fiber: ", $value, PHP_EOL;
});

$value = $fiber->start();

echo "Value from fiber suspending: ", $value, PHP_EOL;

$fiber->resume('test');
?>

   
```

ENTITY

        
    Value from fiber suspending: fiber
    Value used to resume fiber: test

       

</div>

# Functions

## User-defined functions

A function is defined using the `function` keyword, a name, a list of parameters (which might be empty) separated by commas (`,`) enclosed in parentheses, followed by the body of the function enclosed in curly braces, such as the following:

<div class="example">

<div class="title">

Declaring a new function named `foo`

</div>

```
<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
    echo "Example function.\n";
    return $retval;
}

    
```

</div>

> [!NOTE]
> As of PHP 8.0.0, the list of parameters may have a trailing comma:
>
> <div class="informalexample">
>
> ```
> <?php
> function foo($arg_1, $arg_2,) { }
>
>       
> ```
>
> </div>

Any valid PHP code may appear inside the body of a function, even other functions and [class](#language.oop5.basic.class) definitions.

Function names follow the same rules as other labels in PHP. A valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: `^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$`.

ENTITY

Functions need not be defined before they are referenced, *except* when a function is conditionally defined as shown in the two examples below.

When a function is defined in a conditional manner such as the two examples shown. Its definition must be processed *prior* to being called.

<div class="example">

<div class="title">

Conditional functions

</div>

```
<?php
$makefoo = true;

/* We can't call foo() from here 
   since it doesn't exist yet,
   but we can call bar() */
if (function_exists('foo')) {
    foo();
} else {
    echo "Function foo does not exist (yet).\n";
}

bar();

if ($makefoo) {
  function foo()
  {
    echo "I don't exist until program execution reaches me.\n";
  }
}

/* Now we can safely call foo()
   since $makefoo evaluated to true */

if ($makefoo) foo();

function bar() 
{
  echo "I exist immediately upon program start.\n";
}

     
```

</div>

<div class="example">

<div class="title">

Functions within functions

</div>

```
<?php
function foo() 
{
  function bar() 
  {
    echo "I don't exist until foo() is called.\n";
  }
}

/* We can't call bar() yet
   since it doesn't exist. */
if (function_exists('bar')) {
    bar();
}

foo();

/* Now we can call bar(),
   foo()'s processing has
   made it accessible. */

bar();

     
```

</div>

All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.

PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions.

> [!NOTE]
> Function names are case-insensitive for the ASCII characters `A` to `Z`, though it is usually good form to call functions as they appear in their declaration.

Both [variable number of arguments](#functions.variable-arg-list) and [default arguments](#functions.arguments.default) are supported in functions. See also the function references for `func_num_args`, `func_get_arg`, and `func_get_args` for more information.

It is possible to call recursive functions in PHP.

<div class="example">

<div class="title">

Recursive functions

</div>

```
<?php
function recursion($a)
{
    if ($a < 20) {
        echo "$a\n";
        recursion($a + 1);
    }
}

recursion(17);

     
```

</div>

> [!NOTE]
> Recursive function/method calls with over 100-200 recursion levels can smash the stack and cause a termination of the current script. Especially, infinite recursion is considered a programming error.

## Function parameters and arguments

The function parameters are declared in the function signature. Information may be passed to functions via the argument list, which is a comma-delimited list of expressions. The arguments are evaluated from left to right and the result is assigned to the parameters of the function, before the function is actually called (*eager* evaluation).

PHP supports passing arguments by value (the default), [passing by reference](#functions.arguments.by-reference), and [default argument values](#functions.arguments.default). [Variable-length argument lists](#functions.variable-arg-list) and [Named Arguments](#functions.named-arguments) are also supported.

> [!NOTE]
> As of PHP 7.3.0, it is possible to have a trailing comma in the argument list for a function calls:
>
> <div class="informalexample">
>
> ```
> <?php
> $v = foo(
>     $arg_1,
>     $arg_2,
> );
>
>       
> ```
>
> </div>

As of PHP 8.0.0, the list of function parameters may include a trailing comma, which will be ignored. That is particularly useful in cases where the list of parameters is long or contains long variable names, making it convenient to list parameters vertically.

<div class="example">

<div class="title">

Function parameter list with trailing comma

</div>

```
<?php
function takes_many_args(
    $first_arg,
    $second_arg,
    $a_very_long_argument_name,
    $arg_with_default = 5,
    $again = 'a default string', // This trailing comma was not permitted before 8.0.0.
)
{
    // ...
}

    
```

</div>

### Passing arguments by reference

By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.

To have an argument to a function always passed by reference, prepend an ampersand (ENTITY) to the parameter name in the function definition:

<div class="example">

<div class="title">

Passing function arguments by reference

</div>

```
<?php
function add_some_extra(&$string)
{
    $string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str;    // outputs 'This is a string, and something extra.'

      
```

</div>

It is an error to pass a constant expression as an argument to a parameter that expects to be passed by reference.

### Default parameter values

A function may define default values for parameters using syntax similar to assigning a variable. The default is used only when the parameter's argument is not passed. Note that passing ENTITY does *not* assign the default value.

<div class="example">

<div class="title">

Use of default parameters in functions

</div>

```
<?php
function makecoffee($type = "cappuccino")
{
    return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");

      
```

ENTITY

    Making a cup of cappuccino.
    Making a cup of .
    Making a cup of espresso.

          

</div>

Default parameter values may be scalar values, `array`s, the special type ENTITY, and as of PHP 8.1.0, objects using the [new ClassName()](#language.oop5.basic.new) syntax.

<div class="example">

<div class="title">

Using non-scalar types as default values

</div>

```
<?php
function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
{
    $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker;
    return "Making a cup of ".join(", ", $types)." with $device.\n";
}
echo makecoffee();
echo makecoffee(array("cappuccino", "lavazza"), "teapot");

      
```

ENTITY

    Making a cup of cappuccino with hands.
    Making a cup of cappuccino, lavazza with teapot.

          

</div>

<div class="example">

<div class="title">

Using objects as default values (as of PHP 8.1.0)

</div>

```
<?php
class DefaultCoffeeMaker {
    public function brew() {
        return "Making coffee.\n";
    }
}
class FancyCoffeeMaker {
    public function brew() {
        return "Crafting a beautiful coffee just for you.\n";
    }
}
function makecoffee($coffeeMaker = new DefaultCoffeeMaker)
{
    return $coffeeMaker->brew();
}
echo makecoffee();
echo makecoffee(new FancyCoffeeMaker);

      
```

ENTITY

    Making coffee.
    Crafting a beautiful coffee just for you.

          

</div>

The default value must be a constant expression, not (for example) a variable, a class member or a function call.

Note that any optional parameters should be specified after any required parameters, otherwise they cannot be omitted from calls. Consider the following example:

<div class="example">

<div class="title">

Incorrect usage of default function parameters

</div>

```
<?php
function makeyogurt($container = "bowl", $flavour)
{
    return "Making a $container of $flavour yogurt.\n";
}

echo makeyogurt("raspberry"); // "raspberry" is $container, not $flavour

      
```

ENTITY

    Deprecated: makeyogurt(): Optional parameter $container declared before required parameter $flavour is implicitly treated as a required parameter in script on line 2

    Fatal error: Uncaught ArgumentCountError: Too few arguments to function makeyogurt(), 1 passed in script on line 7 and exactly 2 expected in script:2
    Stack trace:
    #0 script(7): makeyogurt('raspberry')
    #1 {main}
      thrown in script on line 2

          

</div>

Now, compare the above with this:

<div class="example">

<div class="title">

Correct usage of default function parameters

</div>

```
<?php
function makeyogurt($flavour, $container = "bowl")
{
    return "Making a $container of $flavour yogurt.\n";
}

echo makeyogurt("raspberry"); // "raspberry" is $flavour

      
```

ENTITY

    Making a bowl of raspberry yogurt.

          

</div>

As of PHP 8.0.0, [named arguments](#functions.named-arguments) can be used to skip over multiple optional parameters.

<div class="example">

<div class="title">

Correct usage of default function parameters

</div>

```
<?php
function makeyogurt($container = "bowl", $flavour = "raspberry", $style = "Greek")
{
    return "Making a $container of $flavour $style yogurt.\n";
}

echo makeyogurt(style: "natural");

      
```

ENTITY

    Making a bowl of raspberry natural yogurt.

          

</div>

As of PHP 8.0.0, declaring mandatory parameters after optional parameters is *deprecated*. This can generally be resolved by dropping the default value, since it will never be used. One exception to this rule are parameters of the form `Type $param = null`, where the ENTITY default makes the type implicitly nullable. This usage is deprecated as of PHP 8.4.0, and an explicit [nullable type](#language.types.declarations.nullable) should be used instead.

<div class="example">

<div class="title">

Declaring optional parameters after mandatory parameters

</div>

```
<?php
function foo($a = [], $b) {}     // Default not used; deprecated as of PHP 8.0.0
function foo($a, $b) {}          // Functionally equivalent, no deprecation notice

function bar(A $a = null, $b) {} // As of PHP 8.1.0, $a is implicitly required
                                 // (because it comes before the required one),
                                 // but implicitly nullable (deprecated as of PHP 8.4.0),
                                 // because the default parameter value is null
function bar(?A $a, $b) {}       // Recommended

      
```

</div>

> [!NOTE]
> As of PHP 7.1.0, omitting a parameter which does not specify a default throws an `ArgumentCountError`; in previous versions it raised a Warning.

> [!NOTE]
> Parameters that expect the argument by reference may have a default value.

### Variable-length argument lists

PHP has support for variable-length argument lists in user-defined functions by using the `...` token.

Parameter lists may include the `...` token to denote that the function accepts a variable number of arguments. The arguments will be passed into the given variable as an ENTITY:

<div class="example">

<div class="title">

Using `...` to access variable arguments

</div>

```
<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);

      
```

ENTITY

    10

          

</div>

`...` can also be used when calling functions to unpack an `array` or `Traversable` variable or literal into the argument list:

<div class="example">

<div class="title">

Using `...` to provide arguments

</div>

```
<?php
function add($a, $b) {
    return $a + $b;
}

echo add(...[1, 2])."\n";

$a = [1, 2];
echo add(...$a);

      
```

ENTITY

    3
    3

          

</div>

You may specify normal positional parameters before the `...` token. In this case, only the trailing arguments that don't match a positional argument will be added to the array generated by `...`.

It is also possible to add a [type declaration](#language.types.declarations) before the `...` token. If this is present, then all arguments captured by `...` must match that parameter type.

<div class="example">

<div class="title">

Type declared variable arguments

</div>

```
<?php
function total_intervals($unit, DateInterval ...$intervals) {
    $time = 0;
    foreach ($intervals as $interval) {
        $time += $interval->$unit;
    }
    return $time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo total_intervals('d', $a, $b).' days';

// This will fail, since null isn't a DateInterval object.
echo total_intervals('d', null);

      
```

ENTITY

    3 days
    Fatal error: Uncaught TypeError: total_intervals(): Argument #2 must be of type DateInterval, null given, called in script on line 15 and defined in script:2
    Stack trace:
    #0 script(15): total_intervals('d', NULL)
    #1 {main}
      thrown in script on line 2

          

</div>

Finally, variable arguments can also be passed [by reference](#functions.arguments.by-reference) by prefixing the `...` with an ampersand (`ENTITY`).

### Named Arguments

PHP 8.0.0 introduced named arguments as an extension of the existing positional parameters. Named arguments allow passing arguments to a function based on the parameter name, rather than the parameter position. This makes the meaning of the argument self-documenting, makes the arguments order-independent and allows skipping default values arbitrarily.

Named arguments are passed by prefixing the value with the parameter name followed by a colon. Using reserved keywords as parameter names is allowed. The parameter name must be an identifier, specifying dynamically is not allowed.

<div class="example">

<div class="title">

Named argument syntax

</div>

```
<?php
myFunction(paramName: $value);
array_foobar(array: $value);

// NOT supported.
function_name($variableStoringParamName: $value);

     
```

</div>

<div class="example">

<div class="title">

Positional arguments versus named arguments

</div>

```
<?php
// Using positional arguments:
array_fill(0, 100, 50);

// Using named arguments:
array_fill(start_index: 0, count: 100, value: 50);

     
```

</div>

The order in which the named arguments are passed does not matter.

<div class="example">

<div class="title">

Same example as above with a different order of parameters

</div>

```
<?php
array_fill(value: 50, count: 100, start_index: 0);

     
```

</div>

Named arguments can be combined with positional arguments. In this case, the named arguments must come after the positional arguments. It is also possible to specify only some of the optional arguments of a function, regardless of their order.

<div class="example">

<div class="title">

Combining named arguments with positional arguments

</div>

```
<?php
htmlspecialchars($string, double_encode: false);
// Same as
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);

     
```

</div>

Passing an argument to the same named parameter multiple times results in an `Error` exception.

<div class="example">

<div class="title">

Error thrown when passing an argument to the same named parameter multiple times

</div>

```
<?php
function foo($param) { ... }

foo(param: 1, param: 2);
// Error: Named parameter $param overwrites previous argument

foo(1, param: 2);
// Error: Named parameter $param overwrites previous argument

     
```

</div>

As of PHP 8.1.0, it is possible to use named arguments after unpacking the arguments. A named argument *must not* override an already unpacked argument.

<div class="example">

<div class="title">

Use named arguments after unpacking

</div>

```
<?php
function foo($a, $b, $c = 3, $d = 4) {
  return $a + $b + $c + $d;
}

var_dump(foo(...[1, 2], d: 40)); // 46
var_dump(foo(...['b' => 2, 'a' => 1], d: 40)); // 46

var_dump(foo(...[1, 2], b: 20)); // Fatal error. Named parameter $b overwrites previous argument

     
```

</div>

Some internal functions document an alternative signature, such as `session_set_save_handler`, whose parameter names do not exist in the function itself. These names cannot be used as named arguments and result in an error.

## Returning values

Values are returned by using the optional return statement. Any type may be returned, including arrays and objects. This causes the function to end its execution immediately and pass control back to the line from which it was called. See `return` for more information.

> [!NOTE]
> If the `return` is omitted the value ENTITY will be returned.

### Use of return

<div class="example">

<div class="title">

Use of `return`

</div>

```
<?php
function square($num)
{
    return $num * $num;
}
echo square(4);   // outputs '16'.

      
```

</div>

A function can not return multiple values, but similar results can be obtained by returning an array.

<div class="example">

<div class="title">

Returning an array to get multiple values

</div>

```
<?php
function small_numbers()
{
    return [0, 1, 2];
}
// Array destructuring will collect each member of the array individually
[$zero, $one, $two] = small_numbers();
var_dump($zero, $one, $two);

// Prior to 7.1.0, the only equivalent alternative is using list() construct
list($zero, $one, $two) = small_numbers();

      
```

</div>

To return a reference from a function, use the reference operator ENTITY in both the function declaration and when assigning the returned value to a variable:

<div class="example">

<div class="title">

Returning a reference from a function

</div>

```
<?php
function &returns_reference()
{
    return $someref;
}

$newref =& returns_reference();

      
```

</div>

For more information on references, please check out [References Explained](#language.references).

## Variable functions

PHP supports the concept of variable functions. This means that if a variable name has parentheses appended to it, PHP will look for a function with the same name as whatever the variable evaluates to, and will attempt to execute it. Among other things, this can be used to implement callbacks, function tables, and so forth.

Variable functions won't work with language constructs such as `echo`, `print`, `unset`, `isset`, `empty`, `include`, `require` and the like. Utilize wrapper functions to make use of any of these constructs as variable functions.

<div class="example">

<div class="title">

Variable function example

</div>

```
<?php
function foo() {
    echo "In foo()\n";
}

function bar($arg = '')
{
    echo "In bar(); argument was '$arg'.\n";
}

// This is a wrapper function around echo
function echoit($string)
{
    echo $string;
}

$func = 'foo';
$func();        // This calls foo()

$func = 'bar';
$func('test');  // This calls bar()

$func = 'echoit';
$func('test');  // This calls echoit()

     
```

</div>

Object methods can also be called with the variable functions syntax.

<div class="example">

<div class="title">

Variable method example

</div>

```
<?php
class Foo
{
    function Variable()
    {
        $name = 'Bar';
        $this->$name(); // This calls the Bar() method
    }
    
    function Bar()
    {
        echo "This is Bar";
    }
}

$foo = new Foo();
$funcname = "Variable";
$foo->$funcname();  // This calls $foo->Variable()

     
```

</div>

When calling static methods, the function call is stronger than the static property operator:

<div class="example">

<div class="title">

Variable method example with static properties

</div>

```
<?php
class Foo
{
    static $variable = 'static property';
    static function Variable()
    {
        echo "Method Variable called\n";
    }
}

echo Foo::$variable ."\n"; // This prints 'static property'. It does need a $variable in this scope.
$variable = "Variable";
Foo::$variable();  // This calls $foo->Variable() reading $variable in this scope.

     
```

ENTITY

    static property
    Method Variable called

         

</div>

<div class="example">

<div class="title">

Complex callables

</div>

```
<?php
class Foo
{
    static function bar()
    {
        echo "bar\n";
    }
    function baz()
    {
        echo "baz\n";
    }
}

$func = array("Foo", "bar");
$func(); // prints "bar"
$func = array(new Foo, "baz");
$func(); // prints "baz"
$func = "Foo::bar";
$func(); // prints "bar"

     
```

</div>

### 

ENTITY

`is_callable`, `call_user_func`, `function_exists`, [variable variables](#language.variables.variable)

## Internal (built-in) functions

PHP comes standard with many functions and constructs. There are also functions that require specific PHP extensions compiled in, otherwise fatal "undefined function" errors will appear. For example, to use [image](#ref.image) functions such as `imagecreatetruecolor`, PHP must be compiled with GD support. Or, to use `mysqli_connect`, PHP must be compiled with [MySQLi](#book.mysqli) support. There are many core functions that are included in every version of PHP, such as the [string](#ref.strings) and [variable](#ref.var) functions. A call to `phpinfo` or `get_loaded_extensions` will show which extensions are loaded into PHP. Also note that many extensions are enabled by default and that the PHP manual is split up by extension. See the [configuration](#configuration), [installation](#install), and individual extension chapters, for information on how to set up PHP.

Reading and understanding a function's prototype is explained within the manual section titled [how to read a function definition](#about.prototypes). It's important to realize what a function returns or if a function works directly on a passed in value. For example, `str_replace` will return the modified string while `usort` works on the actual passed in variable itself. Each manual page also has specific information for each function like information on function parameters, behavior changes, return values for both success and failure, and availability information. Knowing these important (yet often subtle) differences is crucial for writing correct PHP code.

> [!NOTE]
> If the parameters given to a function are not what it expects, such as passing an `array` where a `string` is expected, the return value of the function is undefined. In this case it will likely return ENTITY but this is just a convention, and cannot be relied upon. As of PHP 8.0.0, a `TypeError` exception is supposed to be thrown in this case.

> [!NOTE]
> Scalar types for built-in functions are nullable by default in coercive mode. As of PHP 8.1.0, passing ENTITY to an internal function parameter that is not declared nullable is discouraged and emits a deprecation notice in coercive mode to align with the behavior of user-defined functions, where scalar types need to be marked as nullable explicitly.
>
> For example, `strlen` function expects the parameter `$string` to be a non-nullable ENTITY. For historical reasons, PHP allows passing ENTITY for this parameter in coercive mode, and the parameter is implicitly cast to `string`, resulting in a `""` value. In contrast, a `TypeError` is emitted in strict mode.
>
> <div class="informalexample">
>
> ```
> <?php
> var_dump(strlen(null));
> // "Deprecated: Passing null to parameter #1 ($string) of type string is deprecated" as of PHP 8.1.0
> // int(0)
>
> var_dump(str_contains("foobar", null));
> // "Deprecated: Passing null to parameter #2 ($needle) of type string is deprecated" as of PHP 8.1.0
> // bool(true)
>
>      
> ```
>
> </div>

### 

ENTITY

`function_exists`, [the function reference](#funcref), `get_extension_funcs`, `dl`

## Anonymous functions

Anonymous functions, also known as `closures`, allow the creation of functions which have no specified name. They are most useful as the value of `callable` parameters, but they have many other uses.

Anonymous functions are implemented using the [ `Closure`](#class.closure) class.

<div class="example">

<div class="title">

Anonymous function example

</div>

```
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return strtoupper($match[1]);
}, 'hello-world');
// outputs helloWorld

    
```

</div>

Closures can also be used as the values of variables; PHP automatically converts such expressions into instances of the `Closure` internal class. Assigning a closure to a variable uses the same syntax as any other assignment, including the trailing semicolon:

<div class="example">

<div class="title">

Anonymous function variable assignment example

</div>

```
<?php
$greet = function($name) {
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');

    
```

</div>

Closures may also inherit variables from the parent scope. Any such variables must be passed to the `use` language construct. As of PHP 7.1, these variables must not include ENTITY, `$this`, or variables with the same name as a parameter. A return type declaration of the function has to be placed *after* the `use` clause.

<div class="example">

<div class="title">

Inheriting variables from the parent scope

</div>

```
<?php
// A variable defined in the parent scope
$message = 'hello';

// $message is not inherited and is undefined due to the
// lack of a "use" clause
$example = function () {
    var_dump($message);
};
$example();

// $message is inherited from the parent scope due to the
// "use" clause
$example = function () use ($message) {
    var_dump($message);
};
$example();

// Inherited variable's value is from when the function
// is defined, not when called
$message = 'world';
$example();

// Reset $message
$message = 'hello';

// Inheriting by reference: a change made in the parent scope
// after the closure is defined is visible inside it
$example = function () use (&$message) {
    var_dump($message);
};
$example();

$message = 'world';
$example();

// Closures can also accept regular arguments
$example = function ($arg) use ($message) {
    var_dump($arg . ' ' . $message);
};
$example("hello");

// Closures can return values like any other function; the
// return type declaration comes after the use clause
$example = function () use ($message): array {
    return ["hello", $message];
};
var_dump($example());

    
```

ENTITY

    Warning: Undefined variable $message in script on line 8
    NULL
    string(5) "hello"
    string(5) "hello"
    string(5) "hello"
    string(5) "world"
    string(11) "hello world"
    array(2) {
      [0]=>
      string(5) "hello"
      [1]=>
      string(5) "world"
    }

        

</div>

As of PHP 8.0.0, the list of scope-inherited variables may include a trailing comma, which will be ignored.

Inheriting variables from the parent scope is *not* the same as using global variables. Global variables exist in the global scope, which is the same no matter what function is executing. The parent scope of a closure is the function in which the closure was declared (not necessarily the function it was called from). See the following example:

<div class="example">

<div class="title">

Closures and scoping

</div>

```
<?php
// A basic shopping cart which contains a list of added products
// and the quantity of each product. Includes a method which
// calculates the total price of the items in the cart using a
// closure as a callback.
class Cart
{
    const PRICE_BUTTER  = 1.00;
    const PRICE_MILK    = 3.00;
    const PRICE_EGGS    = 6.95;

    protected $products = array();
    
    public function add($product, $quantity)
    {
        $this->products[$product] = ($this->products[$product] ?? 0) + $quantity;
    }
    
    public function getTotal($tax)
    {
        $total = 0.00;
        
        $callback =
            function ($quantity, $product) use ($tax, &$total)
            {
                $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                    strtoupper($product));
                $total += ($pricePerItem * $quantity) * ($tax + 1.0);
            };
        
        array_walk($this->products, $callback);
        return round($total, 2);
    }
}

$my_cart = new Cart;

// Add some items to the cart
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);

// Print the total with a 5% sales tax.
print $my_cart->getTotal(0.05) . "\n";
// The result is 54.29

    
```

</div>

<div class="example">

<div class="title">

Automatic binding of `$this`

</div>

```
<?php
class Test
{
    public function testing()
    {
        return function() {
            var_dump($this);
        };
    }
}

$object = new Test;
$function = $object->testing();
$function();

    
```

ENTITY

    object(Test)#1 (0) {
    }

        

</div>

When declared in the context of a class, the current class is automatically bound to it, making `$this` available inside of the function's scope. If this automatic binding of the current class is not wanted, then [static anonymous functions](#functions.anonymous-functions.static) may be used instead.

### Static anonymous functions

Anonymous functions may be declared statically. This prevents them from having the current class automatically bound to them. Objects may also not be bound to them at runtime.

<div class="example">

<div class="title">

Attempting to use `$this` inside a static anonymous function

</div>

```
<?php
class Foo
{
    function __construct()
    {
        $func = static function() {
            var_dump($this);
        };
        $func();
    }
};
new Foo();

      
```

ENTITY

    Fatal error: Uncaught Error: Using $this when not in object context in script:7
    Stack trace:
    #0 script(9): Foo::{closure:Foo::__construct():6}()
    #1 script(12): Foo->__construct()
    #2 {main}
      thrown in script on line 7

          

</div>

<div class="example">

<div class="title">

Attempting to bind an object to a static anonymous function

</div>

```
<?php
$func = static function() {
    // function body
};
$func = $func->bindTo(new stdClass);
$func();

      
```

ENTITY

    Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in script on line 5

    Fatal error: Uncaught Error: Value of type null is not callable in script:6
    Stack trace:
    #0 {main}
      thrown in script on line 6

          

</div>

### 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | Closures can now be used in constant expressions (e.g. default property values, attribute parameters, constants). |
| 8.3.0 | Closures created from [magic methods](#language.oop5.magic) can accept named parameters. |
| 7.1.0 | Anonymous functions may not close over ENTITY, `$this`, or any variable with the same name as a parameter. |

### 

ENTITY

> [!NOTE]
> It is possible to use `func_num_args`, `func_get_arg`, and `func_get_args` from within a closure.

## Arrow Functions

Arrow functions were introduced in PHP 7.4 as a more concise syntax for [anonymous functions](#functions.anonymous).

Both anonymous functions and arrow functions are implemented using the `Closure` class.

Arrow functions have the basic form `fn (argument_list) =ENTITY expr`.

Arrow functions support the same features as [anonymous functions](#functions.anonymous), except that using variables from the parent scope is always automatic.

When a variable used in the expression is defined in the parent scope it will be implicitly captured by-value. In the following example, the functions `$fn1` and `$fn2` behave the same way.

<div class="example">

<div class="title">

Arrow functions capture variables by value automatically

</div>

```
<?php
$y = 1;

$fn1 = fn($x) => $x + $y;
// equivalent to using $y by value:
$fn2 = function ($x) use ($y) {
    return $x + $y;
};

var_export($fn1(3));

     
```

ENTITY

    4

          

</div>

This also works if the arrow functions are nested:

<div class="example">

<div class="title">

Arrow functions capture variables by value automatically, even when nested

</div>

```
<?php
$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// Outputs 51
var_export($fn(5)(10));

     
```

</div>

Similarly to anonymous functions, the arrow function syntax allows arbitrary function signatures, including parameter and return types, default values, variadics, as well as by-reference passing and returning. All of the following are valid examples of arrow functions:

<div class="example">

<div class="title">

Examples of arrow functions

</div>

```
<?php
fn(array $x) => $x;
static fn($x): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

     
```

</div>

Arrow functions use by-value variable binding. This is roughly equivalent to performing a `use($x)` for every variable `$x` used inside the arrow function. A by-value binding means that it is not possible to modify any values from the outer scope. [Anonymous functions](#functions.anonymous) can be used instead for by-ref bindings.

<div class="example">

<div class="title">

Values from the outer scope cannot be modified by arrow functions

</div>

```
<?php
$x = 1;
$fn = fn() => $x++; // Has no effect
$fn();
var_export($x);  // Outputs 1

     
```

</div>

### 

ENTITY

| ENTITY | ENTITY                            |
|--------|-----------------------------------|
| 7.4.0  | Arrow functions became available. |

### 

ENTITY

> [!NOTE]
> It is possible to use `func_num_args`, `func_get_arg`, and `func_get_args` from within an arrow function.

## First class callable syntax

The first class callable syntax is introduced as of PHP 8.1.0, as a way of creating [anonymous functions](#functions.anonymous) from [callable](#language.types.callable). It supersedes existing callable syntax using strings and arrays. The advantage of this syntax is that it is accessible to static analysis, and uses the scope at the point where the callable is acquired.

`CallableExpr(...)` syntax is used to create a `Closure` object from callable. `CallableExpr` accepts any expression that can be directly called in the PHP grammar:

<div class="example">

<div class="title">

Simple first class callable syntax

</div>

```
<?php
class Foo {
   public function method() {}
   public static function staticmethod() {}
   public function __invoke() {}
}

$obj = new Foo();
$classStr = 'Foo';
$methodStr = 'method';
$staticmethodStr = 'staticmethod';


$f1 = strlen(...);
$f2 = $obj(...);  // invokable object
$f3 = $obj->method(...);
$f4 = $obj->$methodStr(...);
$f5 = Foo::staticmethod(...);
$f6 = $classStr::$staticmethodStr(...);

// traditional callable using string, array
$f7 = 'strlen'(...);
$f8 = [$obj, 'method'](...);
$f9 = [Foo::class, 'staticmethod'](...);

     
```

</div>

> [!NOTE]
> The `...` is part of the syntax, and not an omission.

`CallableExpr(...)` has the same semantics as Closure::fromCallable. That is, unlike callable using strings and arrays, `CallableExpr(...)` respects the scope at the point where it is created:

<div class="example">

<div class="title">

Scope comparison of `CallableExpr(...)` and traditional callable

</div>

```
<?php
class Foo {
    public function getPrivateMethod() {
        return [$this, 'privateMethod'];
    }

    private function privateMethod() {
        echo __METHOD__, "\n";
    }
}

$foo = new Foo;
$privateMethod = $foo->getPrivateMethod();
$privateMethod();
// Fatal error: Call to private method Foo::privateMethod() from global scope
// This is because call is performed outside from Foo and visibility will be checked from this point.

     
```

</div>

<div class="informalexample">

```
<?php
class Foo1 {
    public function getPrivateMethod() {
        // Uses the scope where the callable is acquired.
        return $this->privateMethod(...); // identical to Closure::fromCallable([$this, 'privateMethod']);
    }

    private function privateMethod() {
        echo __METHOD__, "\n";
    }
}

$foo1 = new Foo1;
$privateMethod = $foo1->getPrivateMethod();
$privateMethod();  // Foo1::privateMethod

    
```

</div>

> [!NOTE]
> Object creation by this syntax (e.g `new Foo(...)`) is not supported, because `new Foo()` syntax is not considered a call.

> [!NOTE]
> The first-class callable syntax cannot be combined with the [nullsafe operator](#language.oop5.basic.nullsafe). Both of the following result in a compile-time error:
>
> <div class="informalexample">
>
> ```
> <?php
> $obj?->method(...);
> $obj?->prop->method(...);
>
>       
> ```
>
> </div>

### 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | First-class callables can now be used in constant expressions (e.g. default property values, attribute parameters, constants). |

# Generators

## Generators overview

Generators provide an easy way to implement simple [iterators](#language.oop5.iterations) without the overhead or complexity of implementing a class that implements the `Iterator` interface.

A generator offers a convenient way to provide data to ENTITY loops without having to build an array in memory ahead of time, which may cause the program to exceed a memory limit or require a considerable amount of processing time to generate. Instead, a generator function can be used, which is the same as a normal [function](#functions.user-defined), except that instead of [return](#functions.returning-values)ing once, a generator can ENTITY as many times as it needs to in order to provide the values to be iterated over. Like with iterators, random data access is not possible.

A simple example of this is to reimplement the `range` function as a generator. The standard `range` function has to generate an array with every value in it and return it, which can result in large arrays: for example, calling `range(0, 1000000)` will result in well over 10 MB of memory being used.

As an alternative, we can implement an `xrange()` generator, which will only ever need enough memory to create an `Iterator` object and track the current state of the generator internally, which turns out to be less than 1 kilobyte.

<div class="example">

<div class="title">

Implementing `range` as a generator

</div>

```
<?php
function xrange($start, $limit, $step = 1) {
    if ($start <= $limit) {
        if ($step <= 0) {
            throw new LogicException('Step must be positive');
        }

        for ($i = $start; $i <= $limit; $i += $step) {
            yield $i;
        }
    } else {
        if ($step >= 0) {
            throw new LogicException('Step must be negative');
        }

        for ($i = $start; $i >= $limit; $i += $step) {
            yield $i;
        }
    }
}

/*
 * Note that both range() and xrange() result in the same
 * output below.
 */

echo 'Single digit odd numbers from range():  ';
foreach (range(1, 9, 2) as $number) {
    echo "$number ";
}
echo "\n";

echo 'Single digit odd numbers from xrange(): ';
foreach (xrange(1, 9, 2) as $number) {
    echo "$number ";
}

   
```

ENTITY

    Single digit odd numbers from range():  1 3 5 7 9
    Single digit odd numbers from xrange(): 1 3 5 7 9

       

</div>

### `Generator` objects

When a generator function is called, a new object of the internal `Generator` class is returned. This object implements the `Iterator` interface in much the same way as a forward-only iterator object would, and provides methods that can be called to manipulate the state of the generator, including sending values to and returning values from it.

## Generator syntax

A generator function looks just like a normal function, except that instead of returning a value, a generator ENTITYs as many values as it needs to. Any function containing ENTITY is a generator function.

When a generator function is called, it returns an object that can be iterated over. When you iterate over that object (for instance, via a ENTITY loop), PHP will call the object's iteration methods each time it needs a value, then saves the state of the generator when the generator yields a value so that it can be resumed when the next value is required.

Once there are no more values to be yielded, then the generator can simply return, and the calling code continues just as if an array has run out of values.

> [!NOTE]
> A generator can return values, which can be retrieved using Generator::getReturn.

### `yield` keyword

The heart of a generator function is the `yield` keyword. In its simplest form, a yield statement looks much like a return statement, except that instead of stopping execution of the function and returning, yield instead provides a value to the code looping over the generator and pauses execution of the generator function.

<div class="example">

<div class="title">

A simple example of yielding values

</div>

```
<?php
function gen_one_to_three() {
    for ($i = 1; $i <= 3; $i++) {
        // Note that $i is preserved between yields.
        yield $i;
    }
}

$generator = gen_one_to_three();
foreach ($generator as $value) {
    echo "$value\n";
}

    
```

ENTITY

    1
    2
    3

        

</div>

> [!NOTE]
> Internally, sequential integer keys will be paired with the yielded values, just as with a non-associative array.

#### Yielding values with keys

PHP also supports associative arrays, and generators are no different. In addition to yielding simple values, as shown above, you can also yield a key at the same time.

The syntax for yielding a key/value pair is very similar to that used to define an associative array, as shown below.

<div class="example">

<div class="title">

Yielding a key/value pair

</div>

```
<?php
/*
 * The input is semi-colon separated fields, with the first
 * field being an ID to use as a key.
 */

$input = <<<'EOF'
1;PHP;Likes dollar signs
2;Python;Likes whitespace
3;Ruby;Likes blocks
EOF;

function input_parser($input) {
    foreach (explode("\n", $input) as $line) {
        $fields = explode(';', $line);
        $id = array_shift($fields);

        yield $id => $fields;
    }
}

foreach (input_parser($input) as $id => $fields) {
    echo "$id:\n";
    echo "    $fields[0]\n";
    echo "    $fields[1]\n";
}

     
```

ENTITY

    1:
        PHP
        Likes dollar signs
    2:
        Python
        Likes whitespace
    3:
        Ruby
        Likes blocks

         

</div>

#### Yielding null values

Yield can be called without an argument to yield a ENTITY value with an automatic key.

<div class="example">

<div class="title">

Yielding ENTITYs

</div>

```
<?php
function gen_three_nulls() {
    foreach (range(1, 3) as $i) {
        yield;
    }
}

var_dump(iterator_to_array(gen_three_nulls()));

     
```

ENTITY

    array(3) {
      [0]=>
      NULL
      [1]=>
      NULL
      [2]=>
      NULL
    }

         

</div>

#### Yielding by reference

Generator functions are able to yield values by reference as well as by value. This is done in the same way as [returning references from functions](#functions.returning-values): by prepending an ampersand to the function name.

<div class="example">

<div class="title">

Yielding values by reference

</div>

```
<?php
function &gen_reference() {
    $value = 3;

    while ($value > 0) {
        yield $value;
    }
}

/*
 * Note that we can change $number within the loop, and
 * because the generator is yielding references, $value
 * within gen_reference() changes.
 */
foreach (gen_reference() as &$number) {
    echo (--$number).'... ';
}

     
```

ENTITY

    2... 1... 0...

         

</div>

#### Generator delegation via `yield from`

Generator delegation allows you to yield values from another generator, `Traversable` object, or `array` by using the `yield from` keyword. The outer generator will then yield all values from the inner generator, object, or array until that is no longer valid, after which execution will continue in the outer generator.

If a generator is used with `yield from`, the `yield from` expression will also return any value returned by the inner generator.

> [!CAUTION]
> `yield from` does not reset the keys. It preserves the keys returned by the `Traversable` object, or `array`. Thus some values may share a common key with another `yield` or `yield from`, which, upon insertion into an array, will overwrite former values with that key.
>
> A common case where this matters is `iterator_to_array` returning a keyed array by default, leading to possibly unexpected results. `iterator_to_array` has a second parameter `preserve_keys` which can be set to ENTITY to collect all the values while ignoring the keys returned by the `Generator`.
>
> <div class="example">
>
> <div class="title">
>
> `yield from` with `iterator_to_array`
>
> </div>
>
> ```
> <?php
> function inner() {
>     yield 1; // key 0
>     yield 2; // key 1
>     yield 3; // key 2
> }
> function gen() {
>     yield 0; // key 0
>     yield from inner(); // keys 0-2
>     yield 4; // key 1
> }
> // pass false as second parameter to get an array [0, 1, 2, 3, 4]
> var_dump(iterator_to_array(gen()));
>
>        
> ```
>
> ENTITY
>
>     array(3) {
>       [0]=>
>       int(1)
>       [1]=>
>       int(4)
>       [2]=>
>       int(3)
>     }
>
>            
>
> </div>

<div class="example">

<div class="title">

Basic use of `yield from`

</div>

```
<?php
function count_to_ten() {
    yield 1;
    yield 2;
    yield from [3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from seven_eight();
    yield 9;
    yield 10;
}

function seven_eight() {
    yield 7;
    yield from eight();
}

function eight() {
    yield 8;
}

foreach (count_to_ten() as $num) {
    echo "$num ";
}

     
```

ENTITY

    1 2 3 4 5 6 7 8 9 10

         

</div>

<div class="example">

<div class="title">

`yield from` and return values

</div>

```
<?php
function count_to_ten() {
    yield 1;
    yield 2;
    yield from [3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from seven_eight();
    return yield from nine_ten();
}

function seven_eight() {
    yield 7;
    yield from eight();
}

function eight() {
    yield 8;
}

function nine_ten() {
    yield 9;
    return 10;
}

$gen = count_to_ten();
foreach ($gen as $num) {
    echo "$num ";
}
echo $gen->getReturn();

     
```

ENTITY

    1 2 3 4 5 6 7 8 9 10

         

</div>

## Comparing generators with `Iterator` objects

The primary advantage of generators is their simplicity. Much less boilerplate code has to be written compared to implementing an `Iterator` class, and the code is generally much more readable. For example, the following function and class are equivalent:

<div class="informalexample">

```
<?php
function getLinesFromFile($fileName) {
    if (!$fileHandle = fopen($fileName, 'r')) {
        return;
    }

    while (false !== $line = fgets($fileHandle)) {
        yield $line;
    }

    fclose($fileHandle);
}

// versus...

class LineIterator implements Iterator {
    protected $fileHandle;

    protected $line;
    protected $i;

    public function __construct($fileName) {
        if (!$this->fileHandle = fopen($fileName, 'r')) {
            throw new RuntimeException('Couldn\'t open file "' . $fileName . '"');
        }
    }

    public function rewind() {
        fseek($this->fileHandle, 0);
        $this->line = fgets($this->fileHandle);
        $this->i = 0;
    }

    public function valid() {
        return false !== $this->line;
    }

    public function current() {
        return $this->line;
    }

    public function key() {
        return $this->i;
    }

    public function next() {
        if (false !== $this->line) {
            $this->line = fgets($this->fileHandle);
            $this->i++;
        }
    }

    public function __destruct() {
        fclose($this->fileHandle);
    }
}

   
```

</div>

This flexibility does come at a cost, however: generators are forward-only iterators, and cannot be rewound once iteration has started. This also means that the same generator can't be iterated over multiple times: the generator will need to be rebuilt by calling the generator function again.

### 

ENTITY

[Object Iteration](#language.oop5.iterations)

# Namespaces

## Namespaces overview

What are namespaces? In the broadest definition namespaces are a way of encapsulating items. This can be seen as an abstract concept in many places. For example, in any operating system directories serve to group related files, and act as a namespace for the files within them. As a concrete example, the file `foo.txt` can exist in both directory `/home/greg` and in `/home/other`, but two copies of `foo.txt` cannot co-exist in the same directory. In addition, to access the `foo.txt` file outside of the `/home/greg` directory, we must prepend the directory name to the file name using the directory separator to get `/home/greg/foo.txt`. This same principle extends to namespaces in the programming world.

In the PHP world, namespaces are designed to solve two problems that authors of libraries and applications encounter when creating re-usable code elements such as classes or functions:

1.  Name collisions between code you create, and internal PHP classes/functions/constants or third-party classes/functions/constants.

2.  Ability to alias (or shorten) Extra_Long_Names designed to alleviate the first problem, improving readability of source code.

PHP Namespaces provide a way in which to group related classes, interfaces, functions and constants. Here is an example of namespace syntax in PHP:

<div class="example">

<div class="title">

Namespace syntax example

</div>

```
   
<?php
namespace my\name; // see "Defining Namespaces" section

class MyClass {}
function myfunction() {}
const MYCONST = 1;

$a = new MyClass;
print $a::class . "\n";
$c = new \my\name\MyClass; // see "Global Space" section
print $c::class . "\n";

$a = strlen('hi'); // see "Using namespaces: fallback to global
                   // function/constant" section
print $a . "\n";

$d = namespace\MYCONST; // see "namespace operator and __NAMESPACE__
                        // constant" section
print $d . "\n";
$d = __NAMESPACE__ . '\MYCONST';
echo constant($d); // see "Namespaces and dynamic language features" section
    
   
```

</div>

> [!NOTE]
> Namespace names are case-insensitive.

> [!NOTE]
> The Namespace name `PHP`, and compound names starting with this name (like `PHP\Classes`) are reserved for internal language use and should not be used in the userspace code.

## Defining namespaces

Although any valid PHP code can be contained within a namespace, only the following types of code are affected by namespaces: classes (including abstract classes, traits and enums), interfaces, functions and constants.

Namespaces are declared using the `namespace` keyword. A file containing a namespace must declare the namespace at the top of the file before any other code - with one exception: the [???](#control-structures.declare) keyword.

<div class="example">

<div class="title">

Declaring a single namespace

</div>

```
     
<?php
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }

    
```

</div>

> [!NOTE]
> Fully qualified names (i.e. names starting with a backslash) are not allowed in namespace declarations, because such constructs are interpreted as relative namespace expressions.

The only code construct allowed before a namespace declaration is the `declare` statement, for defining encoding of a source file. In addition, no non-PHP code may precede a namespace declaration, including extra whitespace:

<div class="example">

<div class="title">

Declaring a single namespace

</div>

```
     
<html>
<?php
namespace MyProject; // fatal error - namespace must be the first statement in the script

    
```

</div>

In addition, unlike any other PHP construct, the same namespace may be defined in multiple files, allowing splitting up of a namespace's contents across the filesystem.

## Declaring sub-namespaces

Much like directories and files, PHP namespaces also contain the ability to specify a hierarchy of namespace names. Thus, a namespace name can be defined with sub-levels:

<div class="example">

<div class="title">

Declaring a single namespace with hierarchy

</div>

```
     
<?php
namespace MyProject\Sub\Level;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

    
```

</div>

The above example creates constant `MyProject\Sub\Level\CONNECT_OK`, class `MyProject\Sub\Level\Connection` and function `MyProject\Sub\Level\connect`.

## Defining multiple namespaces in the same file

Multiple namespaces may also be declared in the same file. There are two allowed syntaxes.

<div class="example">

<div class="title">

Declaring multiple namespaces, simple combination syntax

</div>

```
     
<?php
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

    
```

</div>

This syntax is not recommended for combining namespaces into a single file. Instead it is recommended to use the alternate bracketed syntax.

<div class="example">

<div class="title">

Declaring multiple namespaces, bracketed syntax

</div>

```
     
<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace AnotherProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

    
```

</div>

It is strongly discouraged as a coding practice to combine multiple namespaces into the same file. The primary use case is to combine multiple PHP scripts into the same file.

To combine global non-namespaced code with namespaced code, only bracketed syntax is supported. Global code should be encased in a namespace statement with no namespace name as in:

<div class="example">

<div class="title">

Declaring multiple namespaces and unnamespaced code

</div>

```
     
<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection {
    public static function start() {
        print __METHOD__ . "\n";
    }
}

function connect() {
    print __FUNCTION__ . "\n";
}
}

namespace { // global code
print strlen("hi") . "\n";
MyProject\connect();
MyProject\Connection::start();
}

    
```

</div>

No PHP code may exist outside of the namespace brackets except for an opening declare statement.

<div class="example">

<div class="title">

Declaring multiple namespaces and unnamespaced code

</div>

```
     
<?php
declare(strict_types=1);
namespace MyProject {

const CONNECT_OK = 1;
class Connection {
    public static function start() {
        print __METHOD__ . "\n";
    }
}

function connect() {
    print __FUNCTION__ . "\n";
}
}

namespace { // global code
print strlen("hi") . "\n";
MyProject\connect();
MyProject\Connection::start();
}

    
```

</div>

## Using namespaces: Basics

Before discussing the use of namespaces, it is important to understand how PHP knows which namespaced element your code is requesting. A simple analogy can be made between PHP namespaces and a filesystem. There are three ways to access a file in a file system:

1.  Relative file name like `foo.txt`. This resolves to `currentdirectory/foo.txt` where `currentdirectory` is the directory currently occupied. So if the current directory is `/home/foo`, the name resolves to `/home/foo/foo.txt`.

2.  Relative path name like `subdirectory/foo.txt`. This resolves to `currentdirectory/subdirectory/foo.txt`.

3.  Absolute path name like `/main/foo.txt`. This resolves to `/main/foo.txt`.

The same principle can be applied to namespaced elements in PHP. For example, a class name can be referred to in three ways:

1.  Unqualified name, or an unprefixed class name like `$a = new foo();` or `foo::staticmethod();`. If the current namespace is `currentnamespace`, this resolves to `currentnamespace\foo`. If the code is global, non-namespaced code, this resolves to `foo`.

    One caveat: unqualified names for functions and constants will resolve to global functions and constants if the namespaced function or constant is not defined. See [Using namespaces: fallback to global function/constant](#language.namespaces.fallback) for details.

2.  Qualified name, or a prefixed class name like `$a = new subnamespace\foo();` or `subnamespace\foo::staticmethod();`. If the current namespace is `currentnamespace`, this resolves to `currentnamespace\subnamespace\foo`. If the code is global, non-namespaced code, this resolves to `subnamespace\foo`.

3.  Fully qualified name, or a prefixed name with global prefix operator like `$a = new \currentnamespace\foo();` or `\currentnamespace\foo::staticmethod();`. This always resolves to the literal name specified in the code, `currentnamespace\foo`.

Here is an example of the three kinds of syntax in actual code:

<div class="informalexample">

file1.php

```
     
<?php
namespace Foo\Bar\subnamespace;

const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
     
    
```

file2.php

```
     
<?php
namespace Foo\Bar;
include 'file1.php';

const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}

/* Unqualified name */
foo(); // resolves to function Foo\Bar\foo
foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO

/* Qualified name */
subnamespace\foo(); // resolves to function Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // resolves to class Foo\Bar\subnamespace\foo,
                                  // method staticmethod
echo subnamespace\FOO; // resolves to constant Foo\Bar\subnamespace\FOO

/* Fully qualified name */
\Foo\Bar\foo(); // resolves to function Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod
echo \Foo\Bar\FOO; // resolves to constant Foo\Bar\FOO
     
    
```

</div>

Note that to access any global class, function or constant, a fully qualified name can be used, such as `\strlen` or `\Exception` or \\`INI_ALL`.

<div class="example">

<div class="title">

Accessing global classes, functions and constants from within a namespace

</div>

```
     
<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

print \strlen('hi') . "\n"; // calls global function strlen
print \INI_ALL . "\n"; // accesses global constant INI_ALL
$c = new \Exception('error'); // instantiates global class Exception
print $c::class . "\n";
     
    
```

</div>

## Namespaces and dynamic language features

PHP's implementation of namespaces is influenced by its dynamic nature as a programming language. Thus, to convert code like the following example into namespaced code:

<div class="example">

<div class="title">

Dynamically accessing elements

</div>

example1.php:

```
     
<?php
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "global";

$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global
    
    
```

</div>

One must use the fully qualified name (class name with namespace prefix). Note that because there is no difference between a qualified and a fully qualified Name inside a dynamic class name, function name, or constant name, the leading backslash is not necessary.

<div class="example">

<div class="title">

Dynamically accessing namespaced elements

</div>

```
     
<?php
namespace namespacename;
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "namespaced";

/* note that if using double quotes, "\\namespacename\\classname" must be used */
$a = '\namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // also prints namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // prints namespacename\funcname
$b = '\namespacename\funcname';
$b(); // also prints namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // prints namespaced
echo constant('namespacename\constname'), "\n"; // also prints namespaced
    
    
```

</div>

Be sure to read the [note about escaping namespace names in strings](#language.namespaces.faq.quote).

## The namespace keyword and \_\_NAMESPACE\_\_ magic constant

PHP supports two ways of abstractly accessing elements within the current namespace, the `__NAMESPACE__` magic constant, and the `namespace` keyword.

The value of `__NAMESPACE__` is a string that contains the current namespace name. In global, un-namespaced code, it contains an empty string.

<div class="example">

<div class="title">

\_\_NAMESPACE\_\_ example, namespaced code

</div>

```
     
<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; // outputs "MyProject"

    
```

</div>

<div class="example">

<div class="title">

\_\_NAMESPACE\_\_ example, global code

</div>

```
     
<?php
echo '"', __NAMESPACE__, '"'; // outputs ""

    
```

</div>

The `__NAMESPACE__` constant is useful for dynamically constructing names, for instance:

<div class="example">

<div class="title">

using \_\_NAMESPACE\_\_ for dynamic name construction

</div>

```
     
<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}

    
```

</div>

The `namespace` keyword can be used to explicitly request an element from the current namespace or a sub-namespace. It is the namespace equivalent of the `self` operator for classes.

<div class="example">

<div class="title">

the namespace operator, inside a namespace

</div>

```
     
<?php
namespace MyProject;

use blah\blah as mine; // see "Using namespaces: Aliasing/Importing"

blah\mine(); // calls function MyProject\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()

namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method "method" of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b

    
```

</div>

<div class="example">

<div class="title">

the namespace operator, in global code

</div>

```
     
<?php

namespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
namespace\cname::method(); // calls static method "method" of class cname
$a = new namespace\sub\cname(); // instantiates object of class sub\cname
$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b

    
```

</div>

## Using namespaces: Aliasing/Importing

The ability to refer to an external fully qualified name with an alias, or importing, is an important feature of namespaces. This is similar to the ability of unix-based filesystems to create symbolic links to a file or to a directory.

PHP can alias(/import) constants, functions, classes, interfaces, traits, enums and namespaces.

Aliasing is accomplished with the `use` operator. Here is an example showing all 5 kinds of importing:

<div class="example">

<div class="title">

importing/aliasing with the use operator

</div>

```
     
<?php
namespace foo;
use My\Full\Classname as Another;

// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;

// importing a global class
use ArrayObject;

// importing a function
use function My\Full\functionName;

// aliasing a function
use function My\Full\functionName as func;

// importing a constant
use const My\Full\CONSTANT;

$obj = new namespace\Another; // instantiates object of class foo\Another
$obj = new Another; // instantiates object of class My\Full\Classname
NSname\subns\func(); // calls function My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject
// without the "use ArrayObject" we would instantiate an object of class foo\ArrayObject
func(); // calls function My\Full\functionName
echo CONSTANT; // echoes the value of My\Full\CONSTANT

    
```

</div>

Note that for namespaced names (fully qualified namespace names containing namespace separator, such as `Foo\Bar` as opposed to global names that do not, such as `FooBar`), the leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace.

PHP additionally supports a convenience shortcut to place multiple use statements on the same line

<div class="example">

<div class="title">

importing/aliasing with the use operator, multiple use statements combined

</div>

```
     
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
NSname\subns\func(); // calls function My\Full\NSname\subns\func

    
```

</div>

Importing is performed at compile-time, and so does not affect dynamic class, function or constant names.

<div class="example">

<div class="title">

Importing and dynamic names

</div>

```
     
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
$a = 'Another';
$obj = new $a;      // instantiates object of class Another

    
```

</div>

In addition, importing only affects unqualified and qualified names. Fully qualified names are absolute, and unaffected by imports.

<div class="example">

<div class="title">

Importing and fully qualified names

</div>

```
     
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
$obj = new \Another; // instantiates object of class Another
$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing
$obj = new \Another\thing; // instantiates object of class Another\thing

    
```

</div>

### Scoping rules for importing

The `use` keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it cannot be block scoped. The following example will show an illegal use of the `use` keyword:

<div class="example">

<div class="title">

Illegal importing rule

</div>

```
<?php
namespace Languages;

function toGreenlandic()
{
    use Languages\Danish;

    // ...
}

     
```

</div>

> [!NOTE]
> Importing rules are per file basis, meaning included files will *NOT* inherit the parent file's importing rules.

### Group `use` declarations

Classes, functions and constants being imported from the same ENTITY can be grouped together in a single ENTITY statement.

<div class="informalexample">

```
<?php

use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;

use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;

use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;

// is equivalent to the following grouped use declaration
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};

    
```

</div>

## Global space

Without any namespace definition, all class and function definitions are placed into the global space - as it was in PHP before namespaces were supported. Prefixing a name with `\` will specify that the name is required from the global space even in the context of the namespace.

<div class="example">

<div class="title">

Using global space specification

</div>

```
     
<?php
namespace A\B\C;

/* This function is A\B\C\fopen */
function fopen() {
     /* ... */
     $f = \fopen(...); // call global fopen
     return $f;
}
    
    
```

</div>

## Using namespaces: fallback to the global space for functions and constants

Inside a namespace, when PHP encounters an unqualified Name in a class name, function or constant context, it resolves these with different priorities. Class names always resolve to the current namespace name. Thus to access internal or non-namespaced user classes, one must refer to them with their fully qualified Name as in:

<div class="example">

<div class="title">

Accessing global classes inside a namespace

</div>

```
     
<?php
namespace A\B\C;
class Exception extends \Exception {}

$a = new Exception('hi'); // $a is an object of class A\B\C\Exception
var_dump($a::class);
$b = new \Exception('hi'); // $b is an object of class Exception
var_dump($b::class);

$c = new ArrayObject; // fatal error, class A\B\C\ArrayObject not found
    
    
```

</div>

For functions and constants, PHP will fall back to global functions or constants if a namespaced function or constant does not exist.

<div class="example">

<div class="title">

global functions/constants fallback inside a namespace

</div>

```
     
<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // prints "45"
echo INI_ALL, "\n"; // prints "7" - falls back to global INI_ALL

echo strlen('hi'), "\n"; // prints "1"
if (is_array('hi')) { // prints "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}
    
    
```

</div>

## Name resolution rules

For the purposes of these resolution rules, here are some important definitions:

Unqualified name  
This is an identifier without a namespace separator, such as `Foo`

Qualified name  
This is an identifier with a namespace separator, such as `Foo\Bar`

Fully qualified name  
This is an identifier with a namespace separator that begins with a namespace separator, such as `\Foo\Bar`. The namespace `\Foo` is also a fully qualified name.

Relative name  
This is an identifier starting with `namespace`, such as `namespace\Foo\Bar`.

Names are resolved following these resolution rules:

1.  Fully qualified names always resolve to the name without leading namespace separator. For instance `\A\B` resolves to `A\B`.

2.  Relative names always resolve to the name with `namespace` replaced by the current namespace. If the name occurs in the global namespace, the `namespace\` prefix is stripped. For example `namespace\A` inside namespace `X\Y` resolves to `X\Y\A`. The same name inside the global namespace resolves to `A`.

3.  For qualified names the first segment of the name is translated according to the current class/namespace import table. For example, if the namespace `A\B\C` is imported as `C`, the name `C\D\E` is translated to `A\B\C\D\E`.

4.  For qualified names, if no import rule applies, the current namespace is prepended to the name. For example, the name `C\D\E` inside namespace `A\B`, resolves to `A\B\C\D\E`.

5.  For unqualified names, the name is translated according to the current import table for the respective symbol type. This means that class-like names are translated according to the class/namespace import table, function names according to the function import table and constants according to the constant import table. For example, after `use A\B\C;` a usage such as `new C()` resolves to the name `A\B\C()`. Similarly, after `use function A\B\foo;` a usage such as `foo()` resolves to the name `A\B\foo`.

6.  For unqualified names, if no import rule applies and the name refers to a class-like symbol, the current namespace is prepended. For example `new C()` inside namespace `A\B` resolves to name `A\B\C`.

7.  For unqualified names, if no import rule applies and the name refers to a function or constant and the code is outside the global namespace, the name is resolved at runtime. Assuming the code is in namespace `A\B`, here is how a call to function `foo()` is resolved:

    1.  It looks for a function from the current namespace: `A\B\foo()`.

    2.  It tries to find and call the *global* function `foo()`.

<div class="example">

<div class="title">

Name resolutions illustrated

</div>

```
<?php
namespace A;
use B\D, C\E as F;

// function calls

foo();      // first tries to call "foo" defined in namespace "A"
            // then calls global function "foo"

\foo();     // calls function "foo" defined in global scope

my\foo();   // calls function "foo" defined in namespace "A\my"

F();        // first tries to call "F" defined in namespace "A"
            // then calls global function "F"

// class references

new B();    // creates object of class "B" defined in namespace "A"
            // if not found, it tries to autoload class "A\B"

new D();    // using import rules, creates object of class "D" defined in namespace "B"
            // if not found, it tries to autoload class "B\D"

new F();    // using import rules, creates object of class "E" defined in namespace "C"
            // if not found, it tries to autoload class "C\E"

new \B();   // creates object of class "B" defined in global scope
            // if not found, it tries to autoload class "B"

new \D();   // creates object of class "D" defined in global scope
            // if not found, it tries to autoload class "D"

new \F();   // creates object of class "F" defined in global scope
            // if not found, it tries to autoload class "F"

// static methods/namespace functions from another namespace

B\foo();    // calls function "foo" from namespace "A\B"

B::foo();   // calls method "foo" of class "B" defined in namespace "A"
            // if class "A\B" not found, it tries to autoload class "A\B"

D::foo();   // using import rules, calls method "foo" of class "D" defined in namespace "B"
            // if class "B\D" not found, it tries to autoload class "B\D"

\B\foo();   // calls function "foo" from namespace "B"

\B::foo();  // calls method "foo" of class "B" from global scope
            // if class "B" not found, it tries to autoload class "B"

// static methods/namespace functions of current namespace

A\B::foo();   // calls method "foo" of class "B" from namespace "A\A"
              // if class "A\A\B" not found, it tries to autoload class "A\A\B"

\A\B::foo();  // calls method "foo" of class "B" from namespace "A"
              // if class "A\B" not found, it tries to autoload class "A\B"

   
```

</div>

## FAQ: things you need to know about namespaces

This FAQ is split into two sections: common questions, and some specifics of implementation that are helpful to understand fully.

First, the common questions.

1.  [If I don't use namespaces, should I care about any of this?](#language.namespaces.faq.shouldicare)

2.  [How do I use internal or global classes in a namespace?](#language.namespaces.faq.globalclass)

3.  [How do I use namespaces classes functions, or constants in their own namespace?](#language.namespaces.faq.innamespace)

4.  [ How does a name like `\my\name` or `\name` resolve? ](#language.namespaces.faq.full)

5.  [How does a name like `my\name` resolve?](#language.namespaces.faq.qualified)

6.  [How does an unqualified class name like `name` resolve?](#language.namespaces.faq.shortname1)

7.  [How does an unqualified function name or unqualified constant name like `name` resolve?](#language.namespaces.faq.shortname2)

There are a few implementation details of the namespace implementations that are helpful to understand.

1.  [Import names must not conflict with classes defined in the same file.](#language.namespaces.faq.conflict)

2.  [Nested namespaces are not allowed. ](#language.namespaces.faq.nested)

3.  [Dynamic namespace names (quoted identifiers) should escape backslash.](#language.namespaces.faq.quote)

4.  [Undefined Constants referenced using any backslash die with fatal error](#language.namespaces.faq.constants)

5.  [Cannot override special constants ENTITY, ENTITY or ENTITY](#language.namespaces.faq.builtinconst)

### If I don't use namespaces, should I care about any of this?

No. Namespaces do not affect any existing code in any way, or any as-yet-to-be-written code that does not contain namespaces. You can write this code if you wish:

<div class="example">

<div class="title">

Accessing global classes outside a namespace

</div>

```
<?php
$a = new \stdClass;
print $a::class;

     
```

</div>

This is functionally equivalent to:

<div class="example">

<div class="title">

Accessing global classes outside a namespace

</div>

```
<?php
$a = new stdClass;
print $a::class;

     
```

</div>

### How do I use internal or global classes in a namespace?

<div class="example">

<div class="title">

Accessing internal classes in namespaces

</div>

```
<?php
namespace foo;
$a = new \stdClass;
print $a::class . "\n";

function test(?\ArrayObject $parameter_type_example = null) {}

$a = \FilesystemIterator::CURRENT_AS_FILEINFO;
print $a . "\n";

// extending an internal or global class
class MyException extends \Exception {}
print MyException::class . "\n";

     
```

</div>

### How do I use namespaces classes, functions, or constants in their own namespace?

<div class="example">

<div class="title">

Accessing internal classes, functions or constants in namespaces

</div>

```
<?php
namespace foo;

class MyClass {}

// using a class from the current namespace as a parameter type
function test(?MyClass $parameter_type_example = null) {}
// another way to use a class from the current namespace as a parameter type
function test2(?\foo\MyClass $parameter_type_example = null) {}

// extending a class from the current namespace
class Extended extends MyClass {}
print Extended::class . "\n";

// accessing a global function
$a = \strlen("test");
print $a . "\n";

// accessing a global constant
$b = \INI_ALL;
print $b . "\n";

     
```

</div>

### How does a name like `\my\name` or `\name` resolve?

Names that begin with a `\` always resolve to what they look like, so `\my\name` is in fact `my\name`, and `\Exception` is `Exception`.

<div class="example">

<div class="title">

Fully Qualified names

</div>

```
<?php
namespace foo;
$a = new \my\name(); // instantiates "my\name" class
echo \strlen('hi'); // calls function "strlen"
$a = \INI_ALL; // $a is set to the value of constant "INI_ALL"

     
```

</div>

### How does a name like `my\name` resolve?

Names that contain a backslash but do not begin with a backslash like `my\name` can be resolved in 2 different ways.

If there is an import statement that aliases another name to `my`, then the import alias is applied to the `my` in `my\name`.

Otherwise, the current namespace name is prepended to `my\name`.

<div class="example">

<div class="title">

Qualified names

</div>

```
<?php
namespace foo;
use blah\blah as foo;

$a = new my\name(); // instantiates "foo\my\name" class
foo\bar::name(); // calls static method "name" in class "blah\blah\bar"
my\bar(); // calls function "foo\my\bar"
$a = my\BAR; // sets $a to the value of constant "foo\my\BAR"

     
```

</div>

### How does an unqualified class name like `name` resolve?

Class names that do not contain a backslash like `name` can be resolved in 2 different ways.

If there is an import statement that aliases another name to `name`, then the import alias is applied.

Otherwise, the current namespace name is prepended to `name`.

<div class="example">

<div class="title">

Unqualified class names

</div>

```
<?php
namespace foo;
use blah\blah as foo;

$a = new name(); // instantiates "foo\name" class
foo::name(); // calls static method "name" in class "blah\blah"

     
```

</div>

### How does an unqualified function name or unqualified constant name like `name` resolve?

Function or constant names that do not contain a backslash like `name` can be resolved in 2 different ways.

First, the current namespace name is prepended to `name`.

Finally, if the constant or function `name` does not exist in the current namespace, a global constant or function `name` is used if it exists.

<div class="example">

<div class="title">

Unqualified function or constant names

</div>

```
<?php
namespace foo;
use blah\blah as foo;

const FOO = 1;

function my() {
    print __FUNCTION__ . "\n";
}
function foo() {
    print __FUNCTION__ . "\n";
}
function sort(&$a)
{
    \sort($a); // calls the global function "sort"
    $a = array_flip($a);
    return $a;
}

my(); // calls "foo\my"
print strlen('hi') . "\n"; // calls global function "strlen" because "foo\strlen" does not exist
$arr = array(1,3,2);
$b = sort($arr); // calls function "foo\sort"
var_dump($b);
foo(); // calls function "foo\foo" - import is not applied

$a = FOO; // sets $a to value of constant "foo\FOO" - import is not applied
print $a;
$b = INI_ALL; // sets $b to value of global constant "INI_ALL"
print $b;

     
```

</div>

### Import names must not conflict with classes defined in the same file.

The following script combinations are legal:

<div class="informalexample">

file1.php

```
     
<?php
namespace my\stuff;
class MyClass {}
     
     
```

another.php

```
     
<?php
namespace another;
class thing {}
     
     
```

file2.php

```
     
<?php
namespace my\stuff;
include 'file1.php';
include 'another.php';

use another\thing as MyClass;
$a = new MyClass; // instantiates class "thing" from namespace another
     
     
```

</div>

There is no name conflict, even though the class `MyClass` exists within the `my\stuff` namespace, because the MyClass definition is in a separate file. However, the next example causes a fatal error on name conflict because MyClass is defined in the same file as the use statement.

<div class="informalexample">

```
     
<?php
namespace my\stuff;
use another\thing as MyClass;
class MyClass {} // fatal error: MyClass conflicts with import statement
$a = new MyClass;
     
     
```

</div>

### Nested namespaces are not allowed.

PHP does not allow nesting namespaces

<div class="informalexample">

```
     
<?php
namespace my\stuff {
    namespace nested {
        class foo {}
    }
}
     
     
```

</div>

However, it is easy to simulate nested namespaces like so:

<div class="informalexample">

```
     
<?php
namespace my\stuff\nested {
    class foo {}
}
     
     
```

</div>

### Dynamic namespace names (quoted identifiers) should escape backslash

It is very important to realize that because the backslash is used as an escape character within strings, it should always be doubled when used inside a string. Otherwise there is a risk of unintended consequences:

<div class="example">

<div class="title">

Dangers of using namespaced names inside a double-quoted string

</div>

```
      
<?php
$a = "dangerous\name"; // \n is a newline inside double quoted strings!
$obj = new $a;

$a = 'not\at\all\dangerous'; // no problems here.
$obj = new $a;
      
     
```

</div>

Inside a single-quoted string, the backslash escape sequence is much safer to use, but it is still recommended practice to escape backslashes in all strings as a best practice.

### Undefined Constants referenced using any backslash die with fatal error

Any undefined constant that is unqualified like `FOO` will produce a notice explaining that PHP assumed `FOO` was the value of the constant. Any constant, qualified or fully qualified, that contains a backslash will produce a fatal error if not found.

<div class="example">

<div class="title">

Undefined constants

</div>

```
      
<?php
namespace bar;
$a = FOO; // produces notice - undefined constants "FOO" assumed "FOO";
$a = \FOO; // fatal error, undefined namespace constant FOO
$a = Bar\FOO; // fatal error, undefined namespace constant bar\Bar\FOO
$a = \Bar\FOO; // fatal error, undefined namespace constant Bar\FOO
      
     
```

</div>

### Cannot override special constants ENTITY, ENTITY or ENTITY

Any attempt to define a namespaced constant that is a special, built-in constant results in a fatal error

<div class="example">

<div class="title">

Undefined constants

</div>

```
      
<?php
namespace bar;
const NULL = 0; // fatal error;
const true = 'stupid'; // also fatal error;
// etc.
      
     
```

</div>

# Classes and Objects

## Introduction

PHP includes a complete object model. Some of its features are: [visibility](#language.oop5.visibility), [abstract](#language.oop5.abstract) and [final](#language.oop5.final) classes and methods, additional [magic methods](#language.oop5.magic), [interfaces](#language.oop5.interfaces), and [cloning](#language.oop5.cloning).

PHP treats objects in the same way as references or handles, meaning that each variable contains an object reference rather than a copy of the entire object. See [Objects and References](#language.oop5.references)

ENTITY

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# Class Abstraction

PHP has abstract classes, methods, and properties. Classes defined as abstract cannot be instantiated, and any class that contains at least one abstract method or property must also be abstract. Methods defined as abstract simply declare the method's signature and whether it is public or protected; they cannot define the implementation. Properties defined as abstract may declare a requirement for `get` or `set` behavior, and may provide an implementation for one, but not both, operations.

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child class, and follow the usual [inheritance](#language.oop5.inheritance) and [signature compatibility](#language.oop.lsp) rules.

As of PHP 8.4, an abstract class may declare an abstract property, either public or protected. A protected abstract property may be satisfied by a property that is readable/writeable from either protected or public scope.

An abstract property may be satisfied either by a standard property or by a property with defined [hooks](#language.oop5.property-hooks), corresponding to the required operation.

<div class="example">

<div class="title">

Abstract method example

</div>

```
<?php

abstract class AbstractClass
{
    // Force extending class to define this method
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // Common method
    public function printOut()
    {
        print $this->getValue() . "\n";
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue()
    {
        return "ConcreteClass1";
    }

    public function prefixValue($prefix)
    {
        return "{$prefix}ConcreteClass1";
    }
}

class ConcreteClass2 extends AbstractClass
{
    public function getValue()
    {
        return "ConcreteClass2";
    }

    public function prefixValue($prefix)
    {
        return "{$prefix}ConcreteClass2";
    }
}

$class1 = new ConcreteClass1();
$class1->printOut();
echo $class1->prefixValue('FOO_'), "\n";

$class2 = new ConcreteClass2();
$class2->printOut();
echo $class2->prefixValue('FOO_'), "\n";

?>

   
```

ENTITY

    ConcreteClass1
    FOO_ConcreteClass1
    ConcreteClass2
    FOO_ConcreteClass2

       

</div>

<div class="example">

<div class="title">

Abstract method example

</div>

```
<?php

abstract class AbstractClass
{
    // An abstract method only needs to define the required arguments
    abstract protected function prefixName($name);
}

class ConcreteClass extends AbstractClass
{
    // A child class may define optional parameters which are not present in the parent's signature
    public function prefixName($name, $separator = ".")
    {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }

        return "{$prefix}{$separator} {$name}";
    }
}

$class = new ConcreteClass();
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";

?>

   
```

ENTITY

    Mr. Pacman
    Mrs. Pacwoman

       

</div>

<div class="example">

<div class="title">

Abstract property example

</div>

```
<?php

abstract class A
{
    // Extending classes must have a publicly-gettable property
    abstract public string $readable {
        get;
    }

    // Extending classes must have a protected- or public-writeable property
    abstract protected string $writeable {
        set;
    }

    // Extending classes must have a protected or public symmetric property
    abstract protected string $both {
        get;
        set;
    }
}

class C extends A
{
    // This satisfies the requirement and also makes it settable, which is valid
    public string $readable;

    // This would NOT satisfy the requirement, as it is not publicly readable
    protected string $readable;

    // This satisfies the requirement exactly, so is sufficient.
    // It may only be written to, and only from protected scope
    protected string $writeable {
        set => $value;
    }

    // This expands the visibility from protected to public, which is fine
    public string $both;
}

?>

   
```

</div>

An abstract property on an abstract class may provide implementations for any hook, but must have either `get` or `set` declared but not defined (as in the example above).

<div class="example">

<div class="title">

Abstract property with hooks example

</div>

```
<?php

abstract class A
{
    // This provides a default (but overridable) set implementation,
    // and requires child classes to provide a get implementation
    abstract public string $foo {
        get;

        set {
            $this->foo = $value;
        }
    }
}

?>
 
   
```

</div>

# Anonymous classes

Anonymous classes are useful when simple, one-off objects need to be created.

<div class="informalexample">

```
<?php

// Using an explicit class
class Logger
{
    public function log($msg)
    {
        echo $msg;
    }
}

$util->setLogger(new Logger());

// Using an anonymous class
$util->setLogger(new class {
    public function log($msg)
    {
        echo $msg;
    }
});

  
```

</div>

They can pass arguments through to their constructors, extend other classes, implement interfaces, and use traits just like a normal class can:

<div class="informalexample">

```
<?php

class SomeClass {}
interface SomeInterface {}
trait SomeTrait {}

var_dump(new class(10) extends SomeClass implements SomeInterface {
    private $num;

    public function __construct($num)
    {
        $this->num = $num;
    }

    use SomeTrait;
});

  
```

ENTITY

    object(class@anonymous)#1 (1) {
      ["Command line code0x104c5b612":"class@anonymous":private]=>
      int(10)
    }

      

</div>

Nesting an anonymous class within another class does not give it access to any private or protected methods or properties of that outer class. In order to use the outer class' protected properties or methods, the anonymous class can extend the outer class. To use the private properties of the outer class in the anonymous class, they must be passed through its constructor:

<div class="informalexample">

```
<?php

class Outer
{
    private $prop = 1;
    protected $prop2 = 2;

    protected function func1()
    {
        return 3;
    }

    public function func2()
    {
        return new class($this->prop) extends Outer {
            private $prop3;

            public function __construct($prop)
            {
                $this->prop3 = $prop;
            }

            public function func3()
            {
                return $this->prop2 + $this->prop3 + $this->func1();
            }
        };
    }
}

echo (new Outer)->func2()->func3();

  
```

ENTITY

    6

      

</div>

All objects created by the same anonymous class declaration are instances of that very class.

<div class="informalexample">

```
<?php
function anonymous_class()
{
    return new class {};
}

if (get_class(anonymous_class()) === get_class(anonymous_class())) {
    echo 'same class';
} else {
    echo 'different class';
}
 
```

ENTITY

    same class

      

</div>

> [!NOTE]
> Note that anonymous classes are assigned a name by the engine, as demonstrated in the following example. This name has to be regarded as an implementation detail, which should not be relied upon.
>
> <div class="informalexample">
>
> ```
> <?php
> echo get_class(new class {});
>
>   
> ```
>
> ENTITY
>
>     class@anonymous/in/oNi1A0x7f8636ad2021
>
>        
>
> </div>

## Readonly anonymous classes

As of PHP 8.3.0, the `readonly` modifier can be applied to anonymous classes.

<div id="language.oop5.anonymous.readonly.example" class="example">

<div class="title">

Defining a readonly anonymous class

</div>

```
    
<?php
// Using an anonymous class
var_dump(new readonly class('[DEBUG]') {
    public function __construct(private string $prefix)
    {
    }

    public function log($msg)
    {
        echo $this->prefix . ' ' . $msg;
    }
});

   
```

</div>

# Autoloading Classes

Many developers writing object-oriented applications create one PHP source file per class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).

The `spl_autoload_register` function registers any number of autoloaders, enabling classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error.

Any class-like construct may be autoloaded the same way. That includes classes, interfaces, traits, and enumerations.

> [!CAUTION]
> Prior to PHP 8.0.0, it was possible to use `__autoload` to autoload classes and interfaces. However, it is a less flexible alternative to `spl_autoload_register` and `__autoload` is deprecated as of PHP 7.2.0, and removed as of PHP 8.0.0.

> [!NOTE]
> `spl_autoload_register` may be called multiple times in order to register multiple autoloaders. Throwing an exception from an autoload function, however, will interrupt that process and not allow further autoload functions to run. For that reason, throwing exceptions from an autoload function is strongly discouraged.

<div class="example">

<div class="title">

Autoload example

</div>

This example attempts to load the classes `MyClass1` and `MyClass2` from the files `MyClass1.php` and `MyClass2.php` respectively.

```
<?php
spl_autoload_register(function ($class_name) {
    include $class_name . '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2(); 
?>

    
```

</div>

<div class="example">

<div class="title">

Autoload other example

</div>

This example attempts to load the interface `ITest`.

```
<?php

spl_autoload_register(function ($name) {
    var_dump($name);
});

class Foo implements ITest {
}

/*
string(5) "ITest"

Fatal error: Interface 'ITest' not found in ...
*/
?>

    
```

</div>

<div class="example">

<div class="title">

Using Composer's autoloader

</div>

ENTITY generates a `vendor/autoload.php` which is set up to automatically load packages that are being managed by Composer. By including this file, those packages can be used without any additional work.

```
<?php
require __DIR__ . '/vendor/autoload.php';

$uuid = Ramsey\Uuid\Uuid::uuid7();

echo "Generated new UUID -> ", $uuid->toString(), "\n";
?>

    
```

</div>

## 

ENTITY

`unserialize`, [unserialize_callback_func](#ini.unserialize-callback-func), [unserialize_max_depth](#ini.unserialize-max-depth), `spl_autoload_register`, `spl_autoload`, `__autoload`

# The Basics

## class

Basic class definitions begin with the keyword `class`, followed by a class name, followed by a pair of curly braces which enclose the definitions of the properties and methods belonging to the class.

The class name can be any valid label, provided it is not a PHP [reserved word](#reserved). As of PHP 8.4.0, using a single underscore `_` as a class name is deprecated. A valid class name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: `^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$`.

A class may contain its own [constants](#language.oop5.constants), [variables](#language.oop5.properties) (called "properties"), and functions (called "methods").

<div class="example">

<div class="title">

Simple Class definition

</div>

```
<?php
class SimpleClass
{
    // property declaration
    public $var = 'a default value';

    // method declaration
    public function displayVar() {
        echo $this->var;
    }
}
?>

    
```

</div>

The pseudo-variable `$this` is available when a method is called from within an object context. `$this` is the value of the calling object.

> [!WARNING]
> Calling a non-static method statically throws an `Error`. Prior to PHP 8.0.0, this would generate a deprecation notice, and `$this` would be undefined.
>
> <div id="language.oop5.basic.class.this" class="example">
>
> <div class="title">
>
> Some examples of the `$this` pseudo-variable
>
> </div>
>
> ```
> <?php
> class A
> {
>     function foo()
>     {
>         if (isset($this)) {
>             echo '$this is defined (';
>             echo get_class($this);
>             echo ")\n";
>         } else {
>             echo "\$this is not defined.\n";
>         }
>     }
> }
>
> class B
> {
>     function bar()
>     {
>         A::foo();
>     }
> }
>
> $a = new A();
> $a->foo();
>
> A::foo();
>
> $b = new B();
> $b->bar();
>
> B::bar();
> ?>
>
>      
> ```
>
> ENTITY
>
>     $this is defined (A)
>
>     Deprecated: Non-static method A::foo() should not be called statically in %s  on line 27
>     $this is not defined.
>
>     Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
>     $this is not defined.
>
>     Deprecated: Non-static method B::bar() should not be called statically in %s  on line 32
>
>     Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
>     $this is not defined.
>
>          
>
> ENTITY
>
>     $this is defined (A)
>
>     Fatal error: Uncaught Error: Non-static method A::foo() cannot be called statically in %s :27
>     Stack trace:
>     #0 {main}
>       thrown in %s  on line 27
>
>          
>
> </div>

### Readonly classes

As of PHP 8.2.0, a class can be marked with the readonly modifier. Marking a class as readonly will add the [readonly modifier](#language.oop5.properties.readonly-properties) to every declared property, and prevent the creation of [dynamic properties](#language.oop5.properties.dynamic-properties). Moreover, it is impossible to add support for them by using the `AllowDynamicProperties` attribute. Attempting to do so will trigger a compile-time error.

<div class="informalexample">

```
<?php
#[\AllowDynamicProperties]
readonly class Foo {
}

// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
?>

     
```

</div>

As neither untyped nor static properties can be marked with the `readonly` modifier, readonly classes cannot declare them either:

<div class="informalexample">

```
<?php
readonly class Foo
{
    public $bar;
}

// Fatal error: Readonly property Foo::$bar must have type
?>

     
```

```
<?php
readonly class Foo
{
    public static int $bar;
}

// Fatal error: Readonly class Foo cannot declare static properties
?>

     
```

</div>

A readonly class can be [extended](#language.oop5.basic.extends) if, and only if, the child class is also a readonly class.

## new

To create an instance of a class, the `new` keyword must be used. An object will always be created unless the object has a [constructor](#language.oop5.decon) defined that throws an Exception on error. Classes should be defined before instantiation (and in some cases this is a requirement).

If a variable containing a `string` with the name of a class is used with `new`, a new instance of that class will be created. If the class is in a namespace, its fully qualified name must be used when doing this.

> [!NOTE]
> If there are no arguments to be passed to the class's constructor, parentheses after the class name may be omitted.

<div class="example">

<div class="title">

Creating an instance

</div>

```
<?php
class SimpleClass {
}

$instance = new SimpleClass();
var_dump($instance);

// This can also be done with a variable:
$className = 'SimpleClass';
$instance = new $className(); // new SimpleClass()
var_dump($instance);
?>

    
```

</div>

As of PHP 8.0.0, using `new` with arbitrary expressions is supported. This allows more complex instantiation if the expression produces a `string`. The expressions must be wrapped in parentheses.

<div class="example">

<div class="title">

Creating an instance using an arbitrary expression

</div>

In the given example we show multiple examples of valid arbitrary expressions that produce a class name. This shows a call to a function, string concatenation, and the `::class` constant.

```
     
<?php

class ClassA extends \stdClass {}
class ClassB extends \stdClass {}
class ClassC extends ClassB {}
class ClassD extends ClassA {}

function getSomeClass(): string
{
    return 'ClassA';
}

var_dump(new (getSomeClass()));
var_dump(new ('Class' . 'B'));
var_dump(new ('Class' . 'C'));
var_dump(new (ClassD::class));
?>

    
```

ENTITY

         
    object(ClassA)#1 (0) {
    }
    object(ClassB)#1 (0) {
    }
    object(ClassC)#1 (0) {
    }
    object(ClassD)#1 (0) {
    }


        

</div>

In the class context, it is possible to create a new object by `new self` and `new parent`.

When assigning an already created instance of a class to a new variable, the new variable will access the same instance as the object that was assigned. This behaviour is the same when passing instances to a function. A copy of an already created object can be made by [cloning](#language.oop5.cloning) it.

<div class="example">

<div class="title">

Object Assignment

</div>

```
<?php
class SimpleClass {
    public string $var;
}

$instance = new SimpleClass();

$assigned   =  $instance;
$reference  =& $instance;

$instance->var = '$assigned will have this value';

$instance = null; // $instance and $reference become null

var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>

    
```

ENTITY

    NULL
    NULL
    object(SimpleClass)#1 (1) {
      ["var"]=>
      string(30) "$assigned will have this value"
    }

        

</div>

It's possible to create instances of an object in a couple of ways:

<div class="example">

<div class="title">

Creating new objects

</div>

```
<?php

class Test
{
    public static function getNew()
    {
        return new static();
    }
}

class Child extends Test {}

$obj1 = new Test(); // By the class name
$obj2 = new $obj1(); // Through the variable containing an object
var_dump($obj1 !== $obj2);

$obj3 = Test::getNew(); // By the class method
var_dump($obj3 instanceof Test);

$obj4 = Child::getNew(); // Through a child class method
var_dump($obj4 instanceof Child);

?>

    
```

ENTITY

    bool(true)
    bool(true)
    bool(true)

        

</div>

It is possible to access a member of a newly created object in a single expression:

<div class="example">

<div class="title">

Access member of newly created object

</div>

```
<?php
echo (new DateTime())->format('Y'), PHP_EOL;

// surrounding parentheses are optional as of PHP 8.4.0
echo new DateTime()->format('Y'), PHP_EOL;
?>

    
```

ENTITY

    2025
    2025

        

</div>

> [!NOTE]
> Prior to PHP 7.1, the arguments are not evaluated if there is no constructor function defined.

## Properties and methods

Class properties and methods live in separate "namespaces", so it is possible to have a property and a method with the same name. Referring to both a property and a method has the same notation, and whether a property will be accessed or a method will be called, solely depends on the context, i.e. whether the usage is a variable access or a function call.

<div class="example">

<div class="title">

Property access vs. method call

</div>

```
<?php
class Foo
{
    public $bar = 'property';
    
    public function bar() {
        return 'method';
    }
}

$obj = new Foo();
echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;

    
```

ENTITY

    property
    method

        

</div>

That means that calling an [anonymous function](#functions.anonymous) which has been assigned to a property is not directly possible. Instead the property has to be assigned to a variable first, for instance. It is possible to call such a property directly by enclosing it in parentheses.

<div class="example">

<div class="title">

Calling an anonymous function stored in a property

</div>

```
<?php
class Foo
{
    public $bar;
    
    public function __construct() {
        $this->bar = function() {
            return 42;
        };
    }
}

$obj = new Foo();

echo ($obj->bar)(), PHP_EOL;

    
```

ENTITY

    42

        

</div>

## extends

A class can inherit the constants, methods, and properties of another class by using the keyword `extends` in the class declaration. It is not possible to extend multiple classes; a class can only inherit from one base class.

The inherited constants, methods, and properties can be overridden by redeclaring them with the same name defined in the parent class. However, if the parent class has defined a method or constant as [final](#language.oop5.final), they may not be overridden. It is possible to access the overridden methods or static properties by referencing them with [parent::](#language.oop5.paamayim-nekudotayim).

> [!NOTE]
> As of PHP 8.1.0, constants may be declared as final.

<div class="example">

<div class="title">

Simple Class Inheritance

</div>

```
<?php
class SimpleClass
{
    function displayVar()
    {
        echo "Parent class\n";
    }
}

class ExtendClass extends SimpleClass
{
    // Redefine the parent method
    function displayVar()
    {
        echo "Extending class\n";
        parent::displayVar();
    }
}

$extended = new ExtendClass();
$extended->displayVar();
?>

    
```

ENTITY

    Extending class
    Parent class

        

</div>

### Signature compatibility rules

When overriding a method, its signature must be compatible with the parent method. Otherwise, a fatal error is emitted, or, prior to PHP 8.0.0, an `E_WARNING` level error is generated. A signature is compatible if it respects the [variance](#language.oop5.variance) rules, makes a mandatory parameter optional, adds only optional new parameters and doesn't restrict but only relaxes the visibility. This is known as the Liskov Substitution Principle, or LSP for short. The [constructor](#language.oop5.decon.constructor), and `private` methods are exempt from these signature compatibility rules, and thus won't emit a fatal error in case of a signature mismatch.

<div class="example">

<div class="title">

Compatible child methods

</div>

```
<?php

class Base
{
    public function foo(int $a) {
        echo "Valid\n";
    }
}

class Extend1 extends Base
{
    function foo(int $a = 5)
    {
        parent::foo($a);
    }
}

class Extend2 extends Base
{
    function foo(int $a, $b = 5)
    {
        parent::foo($a);
    }
}

$extended1 = new Extend1();
$extended1->foo();
$extended2 = new Extend2();
$extended2->foo(1);

     
```

ENTITY

    Valid
    Valid

         

</div>

The following examples demonstrate that a child method which removes a parameter, or makes an optional parameter mandatory, is not compatible with the parent method.

<div class="example">

<div class="title">

Fatal error when a child method removes a parameter

</div>

```
<?php

class Base
{
    public function foo(int $a = 5) {
        echo "Valid\n";
    }
}

class Extend extends Base
{
    function foo()
    {
        parent::foo(1);
    }
}

     
```

ENTITY

    Fatal error: Declaration of Extend::foo() must be compatible with Base::foo(int $a = 5) in /in/evtlq on line 13

         

</div>

<div class="example">

<div class="title">

Fatal error when a child method makes an optional parameter mandatory

</div>

```
<?php

class Base
{
    public function foo(int $a = 5) {
        echo "Valid\n";
    }
}

class Extend extends Base
{
    function foo(int $a)
    {
        parent::foo($a);
    }
}

     
```

ENTITY

    Fatal error: Declaration of Extend::foo(int $a) must be compatible with Base::foo(int $a = 5) in /in/qJXVC on line 13

         

</div>

> [!WARNING]
> Renaming a method's parameter in a child class is not a signature incompatibility. However, this is discouraged as it will result in a runtime `Error` if [named arguments](#functions.named-arguments) are used.
>
> <div class="example">
>
> <div class="title">
>
> Error when using named arguments and parameters were renamed in a child class
>
> </div>
>
> ```
> <?php
>
> class A {
>     public function test($foo, $bar) {}
> }
>
> class B extends A {
>     public function test($a, $b) {}
> }
>
> $obj = new B;
>
> // Pass parameters according to A::test() contract
> $obj->test(foo: "foo", bar: "bar"); // ERROR!
>
>       
> ```
>
> ENTITY
>
>     Fatal error: Uncaught Error: Unknown named parameter $foo in /in/XaaeN:14
>     Stack trace:
>     #0 {main}
>       thrown in /in/XaaeN on line 14
>
>           
>
> </div>

## ::class

The `class` keyword is also used for class name resolution. To obtain the fully qualified name of a class `ClassName` use `ClassName::class`. This is particularly useful with [namespaced](#language.namespaces) classes.

<div id="language.oop5.basic.class.class.name" class="example">

<div class="title">

Class name resolution

</div>

```
<?php
namespace NS {
    class ClassName {
    }
    
    echo ClassName::class;
}
?>

     
```

ENTITY

    NS\ClassName

         

</div>

> [!NOTE]
> The class name resolution using `::class` is a compile time transformation. That means at the time the class name string is created no autoloading has happened yet. As a consequence, class names are expanded even if the class does not exist. No error is issued in that case.
>
> <div id="language.oop5.basic.class.class.fail" class="example">
>
> <div class="title">
>
> Missing class name resolution
>
> </div>
>
> ```
> <?php
> print Does\Not\Exist::class;
> ?>
>
>      
> ```
>
> ENTITY
>
>     Does\Not\Exist
>
>          
>
> </div>

As of PHP 8.0.0, `::class` may also be used on objects. This resolution happens at runtime, not compile time. Its effect is the same as calling `get_class` on the object.

<div id="language.oop5.basic.class.class.object" class="example">

<div class="title">

Object name resolution

</div>

```
<?php
namespace NS {
    class ClassName {
    }

    $c = new ClassName();
    print $c::class;
}
?>

    
```

ENTITY

    NS\ClassName

        

</div>

## Nullsafe methods and properties

As of PHP 8.0.0, properties and methods may also be accessed with the "nullsafe" operator instead: `?->`. The nullsafe operator works the same as property or method access as above, except that if the object being dereferenced is ENTITY then ENTITY will be returned rather than an exception thrown. If the dereference is part of a chain, the rest of the chain is skipped.

The effect is similar to wrapping each access in an `is_null` check first, but more compact.

<div class="example">

<div class="title">

Nullsafe Operator

</div>

```
<?php

// As of PHP 8.0.0, this line:
$result = $repository?->getUser(5)?->name;

// Is equivalent to the following code block:
if (is_null($repository)) {
    $result = null;
} else {
    $user = $repository->getUser(5);
    if (is_null($user)) {
        $result = null;
    } else {
        $result = $user->name;
    }
}
?>

    
```

</div>

> [!NOTE]
> The nullsafe operator is best used when null is considered a valid and expected possible value for a property or method return. For indicating an error, a thrown exception is preferable.

# OOP Changelog

Changes to the PHP OOP model are logged here. Descriptions and other notes regarding these features are documented within the OOP model documentation.

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | Changed: A method that returns `static` may now be overridden in a final class to declare `self` or the class's own type as its return type, as these are equivalent to `static` in a class that cannot be extended further. |
| 8.5.0 | Changed: [Traits](#language.oop5.traits) are now bound to a class before its parent class. |
| 8.4.0 | Added: Support for [Property Hooks](#language.oop5.property-hooks). |
| 8.4.0 | Added: Support for [Lazy Objects](#language.oop5.lazy-objects). |
| 8.1.0 | Added: Support for the final modifier for class constants. Also, interface constants become overridable by default. |
| 8.0.0 | Added: Support for the [nullsafe operator](#language.oop5.basic.nullsafe) *?-ENTITY* to access properties and methods on objects that may be null. |
| 7.4.0 | Changed: It is now possible to throw an exception within `__toString`. |
| 7.4.0 | Added: Support for limited return type covariance and argument type contravariance. Full variance support is only available if autoloading is used. Inside a single file only non-cyclic type references are possible. |
| 7.4.0 | Added: It is now possible to type class properties. |
| 7.3.0 | Incompatibility: Argument unpacking of `Traversable`s with non-ENTITY keys is no longer supported. This behaviour was not intended and thus has been removed. |
| 7.3.0 | Incompatibility: In previous versions it was possible to separate the static properties by assigning a reference. This has been removed. |
| 7.3.0 | Changed: The [instanceof](#language.operators.type) operator now allows literals as the first operand, in which case the result is always ENTITY. |
| 7.2.0 | Deprecated: The `__autoload` method has been deprecated in favour of `spl_autoload_register`. |
| 7.2.0 | Changed: The following name cannot be used to name classes, interfaces, or traits: `object`. |
| 7.2.0 | Changed: A trailing comma can now be added to the group-use syntax for namespaces. |
| 7.2.0 | Changed: Parameter type widening. Parameter types from overridden methods and from interface implementations may now be omitted. |
| 7.2.0 | Changed: Abstract methods can now be overridden when an abstract class extends another abstract class. |
| 7.1.0 | Changed: The following names cannot be used to name classes, interfaces, or traits: `void` and `iterable`. |
| 7.1.0 | Added: It is now possible to specify the [visibility of class constants](#language.oop5.visiblity-constants). |
| 7.0.0 | Deprecated: [Static](#language.oop5.static) calls to methods that are not declared static. |
| 7.0.0 | Deprecated: PHP 4 style [ constructor](#language.oop5.decon). I.e. methods that have the same name as the class they are defined in. |
| 7.0.0 | Added: Group *use* declaration: classes, functions and constants being imported from the same namespace can now be grouped together in a single use statement. |
| 7.0.0 | Added: Support for [anonymous classes](#language.oop5.anonymous) has been added via `new class`. |
| 7.0.0 | Incompatibility: Iterating over a non-`Traversable` ENTITY will now have the same behaviour as iterating over by-reference ENTITYs. |
| 7.0.0 | Changed: Defining (compatible) properties in two used [traits](#language.oop5.traits) no longer triggers an error. |
| 5.6.0 | Added: The [\_\_debugInfo()](#object.debuginfo) method. |
| 5.5.0 | Added: The [::class](#language.oop5.basic.class.class) magic constant. |
| 5.5.0 | Added: [finally](#control-structures.finally) to handle exceptions. |
| 5.4.0 | Added: [traits](#language.oop5.traits). |
| 5.4.0 | Changed: If an [abstract](#language.oop5.abstract) class defines a signature for the [ constructor](#language.oop5.decon) it will now be enforced. |
| 5.3.3 | Changed: Methods with the same name as the last element of a [namespaced](#language.namespaces) class name will no longer be treated as [constructor](#language.oop5.decon). This change doesn't affect non-namespaced classes. |
| 5.3.0 | Changed: Classes that implement interfaces with methods that have default values in the prototype are no longer required to match the interface's default value. |
| 5.3.0 | Changed: It's now possible to reference the class using a variable (e.g., `echo $classname::constant;`). The variable's value can not be a keyword (e.g., `self`, `parent` or `static`). |
| 5.3.0 | Changed: An `E_WARNING` level error is issued if the magic [overloading](#language.oop5.overloading) methods are declared [static](#language.oop5.static). It also enforces the public visibility requirement. |
| 5.3.0 | Changed: Prior to 5.3.0, exceptions thrown in the `__autoload` function could not be caught in the [catch](#control-structures.catch) block, and would result in a fatal error. Exceptions now thrown in the \_\_autoload function can be caught in the [catch](#control-structures.catch) block, with one provision. If throwing a custom exception, then the custom exception class must be available. The \_\_autoload function may be used recursively to autoload the custom exception class. |
| 5.3.0 | Added: The [\_\_callStatic](#language.oop5.overloading) method. |
| 5.3.0 | Added: [heredoc](#language.types.string.syntax.heredoc) and [nowdoc](#language.types.string.syntax.nowdoc) support for class *const* and property definitions. Note: heredoc values must follow the same rules as double-quoted strings, (e.g. no variables within). |
| 5.3.0 | Added: [Late Static Bindings](#language.oop5.late-static-bindings). |
| 5.3.0 | Added: The [\_\_invoke()](#object.invoke) method. |
| 5.2.0 | Changed: The [\_\_toString()](#object.tostring) method was only called when it was directly combined with `echo` or `print`. But now, it is called in any ENTITY context (e.g. in `printf` with `%s` modifier) but not in other type contexts (e.g. with `%d` modifier). As of PHP 5.2.0, converting ENTITYs without a [\_\_toString](#object.tostring) method to ENTITY emits a `E_RECOVERABLE_ERROR` level error. |
| 5.1.3 | Changed: In previous versions of PHP 5, the use of `var` was considered deprecated and would issue an `E_STRICT` level error. It's no longer deprecated, therefore does not emit the error. |
| 5.1.0 | Changed: The [\_\_set_state()](#object.set-state) static method is now called for classes exported by `var_export`. |
| 5.1.0 | Added: The [\_\_isset()](#object.isset) and [\_\_unset()](#object.unset) methods. |

# Object Cloning

Creating a copy of an object with fully replicated properties is not always the wanted behavior. A good example of the need for copy constructors is if you have an object which represents a GTK window and the object holds the resource of this GTK window, when you create a duplicate you might want to create a new window with the same properties and have the new object hold the resource of the new window. Another example is if your object holds a reference to another object which it uses and when you replicate the parent object you want to create a new instance of this other object so that the replica has its own separate copy.

An object copy is created by using the `clone` keyword (which calls the object's [\_\_clone()](#object.clone) method if possible).

<div class="informalexample">

    $copy_of_object = clone $object;

       

</div>

When an object is cloned, PHP will perform a shallow copy of all of the object's properties. Any properties that are references to other variables will remain references.

void

\_\_clone

Once the cloning is complete, if a [\_\_clone()](#object.clone) method is defined, then the newly created object's [\_\_clone()](#object.clone) method will be called, to allow any necessary properties to be changed.

<div class="example">

<div class="title">

Cloning an object

</div>

```
<?php
class SubObject
{
    static $instances = 0;
    public $instance;

    public function __construct() {
        $this->instance = ++self::$instances;
    }

    public function __clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {
        // Force a copy of this->object, otherwise
        // it will point to same object.
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print "Original Object:\n";
print_r($obj);

print "Cloned Object:\n";
print_r($obj2);

?> 

   
```

ENTITY

```
Original Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 1
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)
Cloned Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 3
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)


   
```

</div>

It is possible to access a member of a freshly cloned object in a single expression:

<div class="example">

<div class="title">

Access member of freshly cloned object

</div>

```
<?php
$dateTime = new DateTime();
echo (clone $dateTime)->format('Y');
?>

   
```

ENTITY

    2016

       

</div>

## Cloning with property overrides

As of PHP 8.5.0, `clone` is also available as a function, whose second parameter `withProperties` takes an array mapping property names to the values the copy receives. Only the listed properties are overridden, every other property keeps the value it was copied with.

The overrides are applied after [\_\_clone()](#object.clone) has run, and they honour the visibility of all properties. [Readonly](#language.oop5.properties.readonly-properties) properties can be updated on the copy even if they were already set on the original object, which makes the function suited to methods returning a modified copy.

<div class="example">

<div class="title">

Cloning an object with property overrides

</div>

```
<?php
class Point {
    public function __construct(
        public readonly int $x,
        public readonly int $y,
    ) {}

    public function withX(int $x): static
    {
        return clone($this, ['x' => $x]);
    }
}

$p = new Point(1, 2);
$q = $p->withX(10);

echo $q->x, ' ', $q->y;
?>

    
```

ENTITY

    10 2

        

</div>

# Class Constants

It is possible to define [constants](#language.constants) on a per-class basis. The default visibility of class constants is `public`.

> [!NOTE]
> Class constants can be redefined by a child class. As of PHP 8.1.0, class constants cannot be redefined by a child class if it is defined as [final](#language.oop5.final).

It's also possible for interfaces to have constants. Look at the [interface documentation](#language.oop5.interfaces) for examples.

It's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. `self`, `parent` and `static`).

Note that class constants are allocated once per class, and not for each class instance.

As of PHP 8.3.0, class constants can have a scalar type such as `bool`, `int`, `float`, `string`, or even `array`. When using `array`, the contents can only be other scalar types.

<div class="example">

<div class="title">

Defining and using a constant

</div>

```
<?php
class MyClass
{
    const CONSTANT = 'constant value';

    function showConstant() {
        echo  self::CONSTANT . "\n";
    }
}

echo MyClass::CONSTANT . "\n";

$classname = "MyClass";
echo $classname::CONSTANT . "\n";

$class = new MyClass();
$class->showConstant();

echo $class::CONSTANT."\n";
?>

  
```

</div>

The special `::class` constant allows for fully qualified class name resolution at compile time, this is useful for namespaced classes:

<div class="example">

<div class="title">

Namespaced ::class example

</div>

```
<?php
namespace foo {
    class bar {
    }

    echo bar::class; // foo\bar
}
?>

  
```

</div>

<div class="example">

<div class="title">

Class constant expression example

</div>

```
<?php
const ONE = 1;
class foo {
    const TWO = ONE * 2;
    const THREE = ONE + self::TWO;
    const SENTENCE = 'The value of THREE is '.self::THREE;
}
?>

  
```

</div>

<div class="example">

<div class="title">

Class constant visibility modifiers, as of PHP 7.1.0

</div>

```
<?php
class Foo {
    public const BAR = 'bar';
    private const BAZ = 'baz';
}
echo Foo::BAR, PHP_EOL;
echo Foo::BAZ, PHP_EOL;
?>

  
```

ENTITY

    bar

    Fatal error: Uncaught Error: Cannot access private const Foo::BAZ in …

       

</div>

> [!NOTE]
> As of PHP 7.1.0 visibility modifiers are allowed for class constants.

<div class="example">

<div class="title">

Class constant visibility variance check, as of PHP 8.3.0

</div>

```
<?php

interface MyInterface
{
    public const VALUE = 42;
}

class MyClass implements MyInterface
{
    protected const VALUE = 42;
}
?>

  
```

ENTITY

    Fatal error: Access level to MyClass::VALUE must be public (as in interface MyInterface) …

      

</div>

> [!NOTE]
> As of PHP 8.3.0 visibility variance is checked more strictly. Prior to this version, the visibility of a class constant could be different from the visibility of the constant in the implemented interface.

<div class="example">

<div class="title">

Fetch class constant syntax, as of PHP 8.3.0

</div>

```
<?php
class Foo {
    public const BAR = 'bar';
    private const BAZ = 'baz';
}

$name = 'BAR';
echo Foo::{$name}, PHP_EOL; // bar
?>

  
```

</div>

> [!NOTE]
> As of PHP 8.3.0, class constants can be fetched dynamically using a variable.

<div class="example">

<div class="title">

Assigning types to class constants, as of PHP 8.3.0

</div>

```
<?php

class MyClass {
    public const bool MY_BOOL = true;
    public const int MY_INT = 1;
    public const float MY_FLOAT = 1.01;
    public const string MY_STRING = 'one';
    public const array MY_ARRAY = [self::MY_BOOL, self::MY_INT, self::MY_FLOAT, self::MY_STRING];
}

var_dump(MyClass::MY_BOOL);
var_dump(MyClass::MY_INT);
var_dump(MyClass::MY_FLOAT);
var_dump(MyClass::MY_STRING);
var_dump(MyClass::MY_ARRAY);
?>

  
```

ENTITY

    bool(true)
    int(1)
    float(1.01)
    string(3) "one"
    array(4) {
      [0]=>
      bool(true)
      [1]=>
      int(1)
      [2]=>
      float(1.01)
      [3]=>
      string(3) "one"
    }
       
      

</div>

# Constructors and Destructors

## Constructor

void

\_\_construct

mixed

values

""

PHP allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.

> [!NOTE]
> Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to `parent::__construct` within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).

<div class="example">

<div class="title">

Constructors in inheritance

</div>

```
<?php
class BaseClass {
    function __construct() {
        print "In BaseClass constructor\n";
    }
}

class SubClass extends BaseClass {
    function __construct() {
        parent::__construct();
        print "In SubClass constructor\n";
    }
}

class OtherSubClass extends BaseClass {
    // inherits BaseClass's constructor
}

// In BaseClass constructor
$obj = new BaseClass();

// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();

// In BaseClass constructor
$obj = new OtherSubClass();
?> 

    
```

</div>

Unlike other methods, [\_\_construct()](#object.construct) is exempt from the usual [signature compatibility rules](#language.oop.lsp) when being extended.

Constructors are ordinary methods which are called during the instantiation of their corresponding object. As such, they may define an arbitrary number of arguments, which may be required, may have a type, and may have a default value. Constructor arguments are called by placing the arguments in parentheses after the class name.

<div class="example">

<div class="title">

Using constructor arguments

</div>

```
<?php
class Point {
    protected int $x;
    protected int $y;

    public function __construct(int $x, int $y = 0) {
        $this->x = $x;
        $this->y = $y;
    }
}

// Pass both parameters.
$p1 = new Point(4, 5);
// Pass only the required parameter. $y will take its default value of 0.
$p2 = new Point(4);
// With named parameters (as of PHP 8.0):
$p3 = new Point(y: 5, x: 4);
?>

    
```

</div>

If a class has no constructor, or the constructor has no required arguments, the parentheses may be omitted.

### Old-style constructors

Prior to PHP 8.0.0, classes in the global namespace will interpret a method named the same as the class as an old-style constructor. That syntax is deprecated, and will result in an `E_DEPRECATED` error but still call that function as a constructor. If both [\_\_construct()](#object.construct) and a same-name method are defined, [\_\_construct()](#object.construct) will be called.

In namespaced classes, or any class as of PHP 8.0.0, a method named the same as the class never has any special meaning.

Always use [\_\_construct()](#object.construct) in new code.

### Constructor Promotion

As of PHP 8.0.0, constructor parameters may also be promoted to correspond to an object property. It is very common for constructor parameters to be assigned to a property in the constructor but otherwise not operated upon. Constructor promotion provides a short-hand for that use case. The example above could be rewritten as the following.

<div class="example">

<div class="title">

Using constructor property promotion

</div>

```
<?php
class Point {
    public function __construct(protected int $x, protected int $y = 0) {
    }
}

     
```

</div>

When a constructor argument includes a modifier, PHP will interpret it as both an object property and a constructor argument, and assign the argument value to the property. The constructor body may then be empty or may contain other statements. Any additional statements will be executed after the argument values have been assigned to the corresponding properties.

Not all arguments need to be promoted. It is possible to mix and match promoted and not-promoted arguments, in any order. Promoted arguments have no impact on code calling the constructor.

> [!NOTE]
> Using a [visibility modifier](#language.oop5.visibility) (`public`, `protected` or `private`) is the most likely way to apply property promotion, but any other single modifier (such as `readonly`) will have the same effect.

> [!NOTE]
> Object properties may not be typed `callable` due to engine ambiguity that this would introduce. Promoted arguments, therefore, may not be typed `callable` either. Any other [type declaration](#language.types.declarations) is permitted, however.

> [!NOTE]
> As promoted properties are desugared to both a property as well as a function parameter, any and all naming restrictions for both properties as well as parameters apply.

> [!NOTE]
> [Attributes](#language.attributes) placed on a promoted constructor argument will be replicated to both the property and argument. Default values on a promoted constructor argument will be replicated only to the argument and not the property.

### New in initializers

As of PHP 8.1.0, objects can be used as default parameter values, static variables, and global constants, as well as in attribute arguments. Objects can also be passed to `define` now.

> [!NOTE]
> The use of a dynamic or non-string class name or an anonymous class is not allowed. The use of argument unpacking is not allowed. The use of unsupported expressions as arguments is not allowed.

<div class="example">

<div class="title">

Using new in initializers

</div>

```
<?php

// All allowed:
static $x = new Foo;

const C = new Foo;
 
function test($param = new Foo) {}
 
#[AnAttribute(new Foo)]
class Test {
    public function __construct(
        public $prop = new Foo,
    ) {}
}

// All not allowed (compile-time error):
function test(
    $a = new (CLASS_NAME_CONSTANT)(), // dynamic class name
    $b = new class {}, // anonymous class
    $c = new A(...[]), // argument unpacking
    $d = new B($abc), // unsupported constant expression
) {}
?>

     
```

</div>

### Static creation methods

PHP only supports a single constructor per class. In some cases, however, it may be desirable to allow an object to be constructed in different ways with different inputs. The recommended way to do so is by using static methods as constructor wrappers.

<div class="example">

<div class="title">

Using static creation methods

</div>

```
<?php
$some_json_string = '{ "id": 1004, "name": "Elephpant" }';
$some_xml_string = "<animal><id>1005</id><name>Elephpant</name></animal>";

class Product {

    private ?int $id;
    private ?string $name;

    private function __construct(?int $id = null, ?string $name = null) {
        $this->id = $id;
        $this->name = $name;
    }

    public static function fromBasicData(int $id, string $name): static {
        $new = new static($id, $name);
        return $new;
    }

    public static function fromJson(string $json): static {
        $data = json_decode($json, true);
        return new static($data['id'], $data['name']);
    }

    public static function fromXml(string $xml): static {
        $data = simplexml_load_string($xml);
        $new = new static();
        $new->id = (int) $data->id;
        $new->name = $data->name;
        return $new;
    }
}

$p1 = Product::fromBasicData(5, 'Widget');
$p2 = Product::fromJson($some_json_string);
$p3 = Product::fromXml($some_xml_string);

var_dump($p1, $p2, $p3);

     
```

</div>

The constructor may be made private or protected to prevent it from being called externally. If so, only a static method will be able to instantiate the class. Because they are in the same class definition they have access to private methods, even if not of the same object instance. The private constructor is optional and may or may not make sense depending on the use case.

The three public static methods then demonstrate different ways of instantiating the object.

fromBasicData()

takes the exact parameters that are needed, then creates the object by calling the constructor and returning the result.

fromJson()

accepts a JSON string and does some pre-processing on it itself to convert it into the format desired by the constructor. It then returns the new object.

fromXml()

accepts an XML string, preprocesses it, and then creates a bare object. The constructor is still called, but as all of the parameters are optional the method skips them. It then assigns values to the object properties directly before returning the result.

In all three cases, the `static` keyword is translated into the name of the class the code is in. In this case, `Product`.

## Destructor

void

\_\_destruct

PHP possesses a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

<div class="example">

<div class="title">

Destructor Example

</div>

```
<?php

class MyDestructableClass 
{
    function __construct() {
        print "In constructor\n";
    }

    function __destruct() {
        print "Destroying " . __CLASS__ . "\n";
    }
}

$obj = new MyDestructableClass();
 

    
```

</div>

Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call `parent::__destruct` in the destructor body. Also like constructors, a child class may inherit the parent's destructor if it does not implement one itself.

The destructor will be called even if script execution is stopped using `exit`. Calling `exit` in a destructor will prevent the remaining shutdown routines from executing.

If a destructor creates new references to its object, it will not be called a second time when the reference count reaches zero again or during the shutdown sequence.

As of PHP 8.4.0, when [cycle collection](#features.gc.collecting-cycles) occurs during the execution of a [Fiber](#language.fibers), the destructors of objects scheduled for collection are executed in a separate Fiber, called the `gc_destructor_fiber`. If this Fiber is suspended, a new one will be created to execute any remaining destructors. The previous `gc_destructor_fiber` will no longer be referenced by the garbage collector and may be collected if it is not referenced elsewhere. Objects whose destructor is suspended will not be collected until the destructor returns or the Fiber itself is collected.

> [!NOTE]
> Destructors called during the script shutdown have HTTP headers already sent. The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).

> [!NOTE]
> Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error.

# Final Keyword

The final keyword prevents child classes from overriding a method, property, or constant by prefixing the definition with `final`. If the class itself is being defined final then it cannot be extended.

<div class="example">

<div class="title">

Final methods example

</div>

```
<?php
class BaseClass {
   public function test() {
       echo "BaseClass::test() called\n";
   }
   
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called\n";
   }
}

class ChildClass extends BaseClass {
   public function moreTesting() {
       echo "ChildClass::moreTesting() called\n";
   }
}
// Results in Fatal error: Cannot override final method BaseClass::moreTesting()
?> 

   
```

</div>

<div class="example">

<div class="title">

Final class example

</div>

```
<?php
final class BaseClass {
   public function test() {
       echo "BaseClass::test() called\n";
   }

   // As the class is already final, the final keyword is redundant
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called\n";
   }
}

class ChildClass extends BaseClass {
}
// Results in Fatal error: Class ChildClass may not inherit from final class (BaseClass)
?> 

   
```

</div>

<div class="example">

<div class="title">

Final property example as of PHP 8.4.0

</div>

```
<?php
class BaseClass {
   final protected string $test;
}

class ChildClass extends BaseClass {
    public string $test;
}
// Results in Fatal error: Cannot override final property BaseClass::$test
?>

  
```

</div>

<div id="language.oop5.final.example.php81" class="example">

<div class="title">

Final constants example as of PHP 8.1.0

</div>

```
<?php
class Foo
{
    final public const X = "foo";
}

class Bar extends Foo
{
    public const X = "bar";
}

// Fatal error: Bar::X cannot override final constant Foo::X
?>

  
```

</div>

> [!NOTE]
> As of PHP 8.0.0, private methods may not be declared final except for the [constructor](#language.oop5.decon.constructor).

> [!NOTE]
> A property that is declared [`private(set)`](#language.oop5.visibility-members-aviz) is implicitly `final`.

# Object Inheritance

Inheritance is a well-established programming principle, and PHP makes use of this principle in its object model. This principle will affect the way many classes and objects relate to one another.

For example, when extending a class, the subclass inherits all of the public and protected methods, properties and constants from the parent class. Unless a class overrides those methods, they will retain their original functionality.

This is useful for defining and abstracting functionality, and permits the implementation of additional functionality in similar objects without the need to reimplement all of the shared functionality.

Private methods of a parent class are not accessible to a child class. As a result, child classes may reimplement a private method themselves without regard for normal inheritance rules. Prior to PHP 8.0.0, however, `final` and `static` restrictions were applied to private methods. As of PHP 8.0.0, the only private method restriction that is enforced is `private final` constructors, as that is a common way to "disable" the constructor when using static factory methods instead.

The [visibility](#language.oop5.visibility) of methods, properties and constants can be relaxed, e.g. a `protected` method can be marked as `public`, but they cannot be restricted, e.g. marking a `public` property as `private`. One exception is constructors, whose visibility can be restricted, e.g. a `public` constructor can be marked as `private` in a child class.

> [!NOTE]
> Unless autoloading is used, the classes must be defined before they are used. If a class extends another, then the parent class must be declared before the child class structure. This rule applies to classes that inherit other classes and interfaces.

> [!NOTE]
> It is not allowed to override a read-write property with a [readonly property](#language.oop5.properties.readonly-properties) or vice versa.
>
> <div class="informalexample">
>
> ```
> <?php
>
> class A {
>     public int $prop;
> }
> class B extends A {
>     // Illegal: read-write -> readonly
>     public readonly int $prop;
> }
> ?>
>
>      
> ```
>
> </div>

<div class="example">

<div class="title">

Inheritance Example

</div>

```
<?php

class Foo
{
    public function printItem($string)
    {
        echo 'Foo: ' . $string . PHP_EOL;
    }
    
    public function printPHP()
    {
        echo 'PHP is great.' . PHP_EOL;
    }
}

class Bar extends Foo
{
    public function printItem($string)
    {
        echo 'Bar: ' . $string . PHP_EOL;
    }
}

$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Output: 'Foo: baz'
$foo->printPHP();       // Output: 'PHP is great.'
$bar->printItem('baz'); // Output: 'Bar: baz'
$bar->printPHP();       // Output: 'PHP is great.'

?>

  
```

</div>

## Return Type Compatibility with Internal Classes

Prior to PHP 8.1, most internal classes or methods didn't declare their return types, and any return type was allowed when extending them.

As of PHP 8.1.0, most internal methods started to "tentatively" declare their return type, in that case the return type of methods should be compatible with the parent being extended; otherwise, a deprecation notice is emitted. Note that lack of an explicit return declaration is also considered a signature mismatch, and thus results in the deprecation notice.

If the return type cannot be declared for an overriding method due to PHP cross-version compatibility concerns, a `ReturnTypeWillChange` attribute can be added to silence the deprecation notice.

<div class="example">

<div class="title">

The overriding method does not declare any return type

</div>

```
<?php
class MyDateTime extends DateTime
{
    public function modify(string $modifier) { return false; }
}
 
// "Deprecated: Return type of MyDateTime::modify(string $modifier) should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0
?> 

    
```

</div>

<div class="example">

<div class="title">

The overriding method declares a wrong return type

</div>

```
<?php
class MyDateTime extends DateTime
{
    public function modify(string $modifier): ?DateTime { return null; }
}
 
// "Deprecated: Return type of MyDateTime::modify(string $modifier): ?DateTime should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0
?> 

    
```

</div>

<div class="example">

<div class="title">

The overriding method declares a wrong return type without a deprecation notice

</div>

```
<?php
class MyDateTime extends DateTime
{
    /**
     * @return DateTime|false
     */
    #[\ReturnTypeWillChange]
    public function modify(string $modifier) { return false; }
}
 
// No notice is triggered 
?> 

    
```

</div>

# Object Interfaces

Object interfaces allow you to create code which specifies which methods and properties a class must implement, without having to define how these methods or properties are implemented. Interfaces share a namespace with classes, traits, and enumerations, so they may not use the same name.

Interfaces are defined in the same way as a class, but with the `interface` keyword replacing the `class` keyword and without any of the methods having their contents defined.

All methods declared in an interface must be public; this is the nature of an interface.

In practice, interfaces serve two complementary purposes:

To allow developers to create objects of different classes that may be used interchangeably because they implement the same interface or interfaces. A common example is multiple database access services, multiple payment gateways, or different caching strategies. Different implementations may be swapped out without requiring any changes to the code that uses them.

To allow a function or method to accept and operate on a parameter that conforms to an interface, while not caring what else the object may do or how it is implemented. These interfaces are often named like

Iterable

,

Cacheable

,

Renderable

, and so on to describe the significance of the behavior.

Interfaces may define [magic methods](#language.oop5.magic) to require implementing classes to implement those methods.

> [!NOTE]
> Although they are supported, including [constructors](#language.oop5.decon.constructor) in interfaces is strongly discouraged. Doing so significantly reduces the flexibility of the object implementing the interface. Additionally, constructors are not enforced by inheritance rules, which can cause inconsistent and unexpected behavior.

## `implements`

To implement an interface, the `implements` operator is used. All methods in the interface must be implemented within a class; failure to do so will result in a fatal error. Classes may implement more than one interface if desired by separating each interface with a comma.

> [!WARNING]
> A class that implements an interface may use a different name for its parameters than the interface. However, as of PHP 8.0 the language supports [named arguments](#functions.named-arguments), which means callers may rely on the parameter name in the interface. For that reason, it is strongly recommended that developers use the same parameter names as the interface being implemented.

> [!NOTE]
> Interfaces can be extended like classes using the [extends](#language.oop5.inheritance) operator.

> [!NOTE]
> The class implementing the interface must declare all methods in the interface with a [compatible signature](#language.oop.lsp). A class can implement multiple interfaces which declare a method with the same name. In this case, the implementation must follow the [signature compatibility rules](#language.oop.lsp) for all the interfaces. So [covariance and contravariance](#language.oop5.variance) can be applied.

## Constants

It's possible for interfaces to have constants. Interface constants work exactly like [class constants](#language.oop5.constants). Prior to PHP 8.1.0, they cannot be overridden by a class/interface that inherits them.

## Properties

As of PHP 8.4.0, interfaces may also declare properties. If they do, the declaration must specify if the property is to be readable, writeable, or both. The interface declaration applies only to public read and write access.

A class may satisfy an interface property in multiple ways. It may define a public property. It may define a public [virtual property](#language.oop5.property-hooks.virtual) that implements only the corresponding hook. Or a read property may be satisfied by a `readonly` property. However, an interface property that is settable may not be `readonly`.

<div class="example">

<div class="title">

Interface properties example

</div>

```
<?php
interface I
{
    // An implementing class MUST have a publicly-readable property,
    // but whether or not it's publicly settable is unrestricted.
    public string $readable { get; }

    // An implementing class MUST have a publicly-writeable property,
    // but whether or not it's publicly readable is unrestricted.
    public string $writeable { set; }

    // An implementing class MUST have a property that is both publicly
    // readable and publicly writeable.
    public string $both { get; set; }
}

// This class implements all three properties as traditional, un-hooked
// properties. That's entirely valid.
class C1 implements I
{
    public string $readable;

    public string $writeable;

    public string $both;
}

// This class implements all three properties using just the hooks
// that are requested.  This is also entirely valid.
class C2 implements I
{
    private string $written = '';
    private string $all = '';

    // Uses only a get hook to create a virtual property.
    // This satisfies the "public get" requirement.
    // It is not writeable, but that is not required by the interface.
    public string $readable { get => strtoupper($this->writeable); }

    // The interface only requires the property be settable,
    // but also including get operations is entirely valid.
    // This example creates a virtual property, which is fine.
    public string $writeable {
        get => $this->written;
        set {
            $this->written = $value;
        }
    }

    // This property requires both read and write be possible,
    // so we need to either implement both, or allow it to have
    // the default behavior.
    public string $both {
        get => $this->all;
        set {
            $this->all = strtoupper($value);
        }
    }
}
?>

    
```

</div>

## 

ENTITY

<div id="language.oop5.interfaces.examples.ex1" class="example">

<div class="title">

Interface example

</div>

```
<?php

// Declare the interface 'Template'
interface Template
{
    public function setVariable($name, $var);
    public function getHtml($template);
}

// Implement the interface
// This will work
class WorkingTemplate implements Template
{
    private $vars = [];
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
  
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }
 
        return $template;
    }
}

// This will not work
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (Template::getHtml)
class BadTemplate implements Template
{
    private $vars = [];
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
}
?>

    
```

</div>

<div id="language.oop5.interfaces.examples.ex2" class="example">

<div class="title">

Extendable Interfaces

</div>

```
<?php
interface A
{
    public function foo();
}

interface B extends A
{
    public function baz(Baz $baz);
}

// This will work
class C implements B
{
    public function foo()
    {
    }

    public function baz(Baz $baz)
    {
    }
}

// This will not work and result in a fatal error
class D implements B
{
    public function foo()
    {
    }

    public function baz(Foo $foo)
    {
    }
}
?>

     
```

</div>

<div id="language.oop5.interfaces.examples.variance.multiple.interfaces" class="example">

<div class="title">

Variance compatibility with multiple interfaces

</div>

```
<?php
class Foo {}
class Bar extends Foo {}

interface A {
    public function myfunc(Foo $arg): Foo;
}

interface B {
    public function myfunc(Bar $arg): Bar;
}

class MyClass implements A, B
{
    public function myfunc(Foo $arg): Bar
    {
        return new Bar();
    }
}
?>

     
```

</div>

<div id="language.oop5.interfaces.examples.ex3" class="example">

<div class="title">

Multiple interface inheritance

</div>

```
<?php
interface A
{
    public function foo();
}

interface B
{
    public function bar();
}

interface C extends A, B
{
    public function baz();
}

class D implements C
{
    public function foo()
    {
    }

    public function bar()
    {
    }

    public function baz()
    {
    }
}
?>

     
```

</div>

<div id="language.oop5.interfaces.examples.ex4" class="example">

<div class="title">

Interfaces with constants

</div>

```
<?php
interface A
{
    const B = 'Interface constant';
}

// Prints: Interface constant
echo A::B;


class B implements A
{
    const B = 'Class constant';
}

// Prints: Class constant
// Prior to PHP 8.1.0, this will however not work because it was not
// allowed to override constants.
echo B::B;
?>

     
```

</div>

<div id="language.oop5.interfaces.examples.ex5" class="example">

<div class="title">

Interfaces with abstract classes

</div>

```
<?php
interface A
{
    public function foo(string $s): string;

    public function bar(int $i): int;
}

// An abstract class may implement only a portion of an interface.
// Classes that extend the abstract class must implement the rest.
abstract class B implements A
{
    public function foo(string $s): string
    {
        return $s . PHP_EOL;
    }
}

class C extends B
{
    public function bar(int $i): int
    {
        return $i * 2;
    }
}
?>

     
```

</div>

<div id="language.oop5.interfaces.examples.ex6" class="example">

<div class="title">

Extending and implementing simultaneously

</div>

```
<?php

class One
{
    /* ... */
}

interface Usable
{
    /* ... */
}

interface Updatable
{
    /* ... */
}

// The keyword order here is important. 'extends' must come first.
class Two extends One implements Usable, Updatable
{
    /* ... */
}
?>

     
```

</div>

An interface, together with type declarations, provides a good way to make sure that a particular object contains particular methods. See [instanceof](#language.operators.type) operator and [type declarations](#language.types.declarations).

# Object Iteration

PHP provides a way for objects to be defined so it is possible to iterate through a list of items with, for example, a ENTITY statement. By default, all [visible](#language.oop5.visibility) properties will be used for the iteration.

<div class="example">

<div class="title">

Simple Object Iteration

</div>

```
<?php
class MyClass
{
    public $var1 = 'value 1';
    public $var2 = 'value 2';
    public $var3 = 'value 3';

    protected $protected = 'protected var';
    private   $private   = 'private var';

    function iterateVisible() {
       echo "MyClass::iterateVisible:\n";
       foreach ($this as $key => $value) {
           print "$key => $value\n";
       }
    }
}

$class = new MyClass();

foreach($class as $key => $value) {
    print "$key => $value\n";
}
echo "\n";


$class->iterateVisible();

?>

   
```

ENTITY

```
var1 => value 1
var2 => value 2
var3 => value 3

MyClass::iterateVisible:
var1 => value 1
var2 => value 2
var3 => value 3
protected => protected var
private => private var

   
```

</div>

As the output shows, the ENTITY iterated through all of the [visible](#language.oop5.visibility) properties that could be accessed.

## 

ENTITY

[Generators](#language.generators), Iterator, IteratorAggregate, [SPL Iterators](#spl.iterators)

# Late Static Bindings

PHP implements a feature called late static bindings which can be used to reference the called class in the context of static inheritance.

More precisely, late static bindings work by storing the class named in the last "non-forwarding call". In case of static method calls, this is the class explicitly named (usually the one on the left of the [`::`](#language.oop5.paamayim-nekudotayim) operator); in case of non static method calls, it is the class of the object. A "forwarding call" is a static one that is introduced by `self::`, `parent::`, `static::`, or, if going up in the class hierarchy, `forward_static_call`. The function `get_called_class` can be used to retrieve a string with the name of the called class and `static::` introduces its scope.

This feature was named "late static bindings" with an internal perspective in mind. "Late binding" comes from the fact that `static::` will not be resolved using the class where the method is defined but it will rather be computed using runtime information. It was also called a "static binding" as it can be used for (but is not limited to) static method calls.

## Limitations of `self::`

Static references to the current class like `self::` or `__CLASS__` are resolved using the class in which the function belongs, as in where it was defined:

<div class="example">

<div class="title">

`self::` usage

</div>

```
<?php

class A
{
    public static function who()
    {
        echo __CLASS__;
    }

    public static function test()
    {
        self::who();
    }
}

class B extends A
{
    public static function who()
    {
        echo __CLASS__;
    }
}

B::test();

?>

    
```

ENTITY

    A

        

</div>

## Late Static Bindings' usage

Late static bindings tries to solve that limitation by introducing a keyword that references the class that was initially called at runtime. Basically, a keyword that would allow referencing `B` from `test()` in the previous example. It was decided not to introduce a new keyword but rather use `static` that was already reserved.

<div class="example">

<div class="title">

`static::` simple usage

</div>

```
<?php

class A
{
    public static function who()
    {
        echo __CLASS__;
    }

    public static function test()
    {
        static::who(); // Here comes Late Static Bindings
    }
}

class B extends A
{
    public static function who()
    {
        echo __CLASS__;
    }
}

B::test();

?>

    
```

ENTITY

    B

        

</div>

> [!NOTE]
> In non-static contexts, the called class will be the class of the object instance. Since `$this->` will try to call private methods from the same scope, using `static::` may give different results. Another difference is that `static::` can only refer to static properties.

<div class="example">

<div class="title">

`static::` usage in a non-static context

</div>

```
<?php

class A
{
    private function foo()
    {
        echo "Success!\n";
    }

    public function test()
    {
        $this->foo();
        static::foo();
    }
}

class B extends A
{
    /* foo() will be copied to B, hence its scope will still be A and
    * the call be successful */
}

class C extends A
{
    private function foo()
    {
        /* Original method is replaced; the scope of the new one is C */
    }
}

$b = new B();
$b->test();

$c = new C();
try {
    $c->test();
} catch (Error $e) {
    echo $e->getMessage();
}

?>

    
```

ENTITY

    Success!
    Success!
    Success!
    Call to private method C::foo() from scope A

        

</div>

> [!NOTE]
> Late static bindings' resolution will stop at a fully resolved static call with no fallback. On the other hand, static calls using keywords like `parent::` or `self::` will forward the calling information.
>
> <div class="example">
>
> <div class="title">
>
> Forwarding and non-forwarding calls
>
> </div>
>
> ```
> <?php
>
> class A
> {
>     public static function foo()
>     {
>         static::who();
>     }
>
>     public static function who()
>     {
>         echo __CLASS__ . "\n";
>     }
> }
>
> class B extends A
> {
>     public static function test()
>     {
>         A::foo();
>         parent::foo();
>         self::foo();
>     }
>
>     public static function who()
>     {
>         echo __CLASS__ . "\n";
>     }
> }
>
> class C extends B
> {
>     public static function who()
>     {
>         echo __CLASS__ . "\n";
>     }
> }
>
> C::test();
>
> ?>
>
>      
> ```
>
> ENTITY
>
>     A
>     C
>     C
>
>          
>
> </div>

# Lazy Objects

A lazy object is an object whose initialization is deferred until its state is observed or modified. Some use-case examples include dependency injection components that provide lazy services fully initialized only if needed, ORMs providing lazy entities that hydrate themselves from the database only when accessed, or a JSON parser that delays parsing until elements are accessed.

Two lazy object strategies are supported: Ghost Objects and Virtual Proxies, hereafter referred to as ENTITYlazy ghostsENTITY and ENTITYlazy proxiesENTITY. In both strategies, the lazy object is attached to an initializer or factory that is called automatically when its state is observed or modified for the first time. From an abstraction point of view, lazy ghost objects are indistinguishable from non-lazy ones: they can be used without knowing they are lazy, allowing them to be passed to and used by code that is unaware of laziness. Lazy proxies are similarly transparent, but care must be taken when their identity is used, as the proxy and its real instance have different identities.

> [!NOTE]
> Lazy objects were introduced in PHP 8.4.

## Creating Lazy Objects

It is possible to create a lazy instance of any user defined class or the `stdClass` class (other internal classes are not supported), or to reset an instance of these classes to make it lazy. The entry points for creating a lazy object are the ReflectionClass::newLazyGhost and ReflectionClass::newLazyProxy methods.

Both methods accept a function that is called when the object requires initialization. The function's expected behavior varies depending on the strategy in use, as described in the reference documentation for each method.

<div class="example">

<div class="title">

Creating a Lazy Ghost

</div>

```
<?php
class Example
{
    public function __construct(public int $prop)
    {
        echo __METHOD__, "\n";
    }
}

$reflector = new ReflectionClass(Example::class);
$lazyObject = $reflector->newLazyGhost(function (Example $object) {
    // Initialize object in-place
    $object->__construct(1);
});

var_dump($lazyObject);
var_dump(get_class($lazyObject));

// Triggers initialization
var_dump($lazyObject->prop);
?>

   
```

ENTITY

    lazy ghost object(Example)#3 (0) {
      ["prop"]=>
      uninitialized(int)
    }
    string(7) "Example"
    Example::__construct
    int(1)

       

</div>

<div class="example">

<div class="title">

Creating a Lazy Proxy

</div>

```
<?php
class Example
{
    public function __construct(public int $prop)
    {
        echo __METHOD__, "\n";
    }
}

$reflector = new ReflectionClass(Example::class);
$lazyObject = $reflector->newLazyProxy(function (Example $object) {
    // Create and return the real instance
    return new Example(1);
});

var_dump($lazyObject);
var_dump(get_class($lazyObject));

// Triggers initialization
var_dump($lazyObject->prop);
?>

   
```

ENTITY

    lazy proxy object(Example)#3 (0) {
      ["prop"]=>
      uninitialized(int)
    }
    string(7) "Example"
    Example::__construct
    int(1)

       

</div>

Any access to properties of a lazy object triggers its initialization (including via `ReflectionProperty`). However, certain properties might be known in advance and should not trigger initialization when accessed:

<div class="example">

<div class="title">

Initializing Properties Eagerly

</div>

```
<?php
class BlogPost
{
    public function __construct(
        public int $id,
        public string $title,
        public string $content,
    ) { }
}

$reflector = new ReflectionClass(BlogPost::class);

$post = $reflector->newLazyGhost(function ($post) {
    $data = fetch_from_store($post->id);
    $post->__construct($data['id'], $data['title'], $data['content']);
});

// Without this line, the following call to ReflectionProperty::setValue() would
// trigger initialization.
$reflector->getProperty('id')->skipLazyInitialization($post);
$reflector->getProperty('id')->setValue($post, 123);

// Alternatively, one can use this directly:
$reflector->getProperty('id')->setRawValueWithoutLazyInitialization($post, 123);

// The id property can be accessed without triggering initialization
var_dump($post->id);
?>

   
```

</div>

The ReflectionProperty::skipLazyInitialization and ReflectionProperty::setRawValueWithoutLazyInitialization methods offer ways to bypass lazy-initialization when accessing a property.

## About Lazy Object Strategies

*Lazy ghosts* are objects that initialize in-place and, once initialized, are indistinguishable from an object that was never lazy. This strategy is suitable when we control both the instantiation and initialization of the object, making it unsuitable if either of these is managed by another party.

*Lazy proxies*, once initialized, act as proxies to a real instance: any operation on an initialized lazy proxy is forwarded to the real instance. The creation of the real instance can be delegated to another party, making this strategy useful in cases where lazy ghosts are unsuitable. Although lazy proxies are nearly as transparent as lazy ghosts, caution is needed when their identity is used, as the proxy and its real instance have distinct identities.

## Lifecycle of Lazy Objects

Objects can be made lazy at instantiation time using ReflectionClass::newLazyGhost or ReflectionClass::newLazyProxy, or after instantiation by using ReflectionClass::resetAsLazyGhost or ReflectionClass::resetAsLazyProxy. Following this, a lazy object can become initialized through one of the following operations:

Interacting with the object in a way that triggers automatic initialization. See

Initialization triggers

.

Marking all its properties as non-lazy using

ReflectionProperty::skipLazyInitialization

or

ReflectionProperty::setRawValueWithoutLazyInitialization

.

Calling explicitly

ReflectionClass::initializeLazyObject

or

ReflectionClass::markLazyObjectAsInitialized

.

As lazy objects become initialized when all their properties are marked non-lazy, the above methods will not mark an object as lazy if no properties could be marked as lazy.

## Initialization Triggers

Lazy objects are designed to be fully transparent to their consumers, so normal operations that observe or modify the object's state will automatically trigger initialization before the operation is performed. This includes, but is not limited to, the following operations:

Reading or writing a property.

Testing if a property is set or unsetting it.

Accessing or modifying a property via

ReflectionProperty::getValue

,

ReflectionProperty::getRawValue

,

ReflectionProperty::setValue

, or

ReflectionProperty::setRawValue

.

Listing properties with

ReflectionObject::getProperties

,

ReflectionObject::getProperty

,

get_object_vars

.

Iterating over properties of an object that does not implement

Iterator

or

IteratorAggregate

using

foreach

.

Serializing the object with

serialize

,

json_encode

, etc.

Cloning

the object.

Method calls that do not access the object state will not trigger initialization. Similarly, interactions with the object that invoke magic methods or hook functions will not trigger initialization if these methods or functions do not access the object's state.

### Non-Triggering Operations

The following specific methods or low-level operations allow access or modification of lazy objects without triggering initialization:

Marking properties as non-lazy with

ReflectionProperty::skipLazyInitialization

or

ReflectionProperty::setRawValueWithoutLazyInitialization

.

Retrieving the internal representation of properties using

get_mangled_object_vars

or by

casting the object to an array

.

Using

serialize

when

ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE

is set, unless

\_\_serialize()

or

\_\_sleep()

trigger initialization.

Calling

ReflectionObject::\_\_toString

.

Using

var_dump

or

debug_zval_dump

, unless

\_\_debugInfo()

triggers initialization.

## Initialization Sequence

This section outlines the sequence of operations performed when initialization is triggered, based on the strategy in use.

### Ghost Objects

The object is marked as non-lazy.

Properties not initialized with

ReflectionProperty::skipLazyInitialization

or

ReflectionProperty::setRawValueWithoutLazyInitialization

are set to their default values, if any. At this stage, the object resembles one created with

ReflectionClass::newInstanceWithoutConstructor

, except for already initialized properties.

The initializer function is then called with the object as its first parameter. The function is expected, but not required, to initialize the object state, and must return ENTITY or no value. The object is no longer lazy at this point, so the function can access its properties directly.

After initialization, the object is indistinguishable from an object that was never lazy.

### Proxy Objects

The object is marked as non-lazy.

Unlike ghost objects, the properties of the object are not modified at this stage.

The factory function is called with the object as its first parameter and must return a non-lazy instance of a compatible class (see

ReflectionClass::newLazyProxy

).

The returned instance is referred to as the

real instance

and is attached to the proxy.

The proxy's property values are discarded as though

unset

was called.

After initialization, accessing any property on the proxy will yield the same result as accessing the corresponding property on the real instance; all property accesses on the proxy are forwarded to the real instance, including declared, dynamic, non-existing, or properties marked with ReflectionProperty::skipLazyInitialization or ReflectionProperty::setRawValueWithoutLazyInitialization.

The proxy object itself is *not* replaced or substituted for the real instance.

While the factory receives the proxy as its first parameter, it is not expected to modify it (modifications are allowed but will be lost during the final initialization step). However, the proxy can be used for decisions based on the values of initialized properties, the class, the object itself, or its identity. For instance, the initializer might use an initialized property's value when creating the real instance.

### Common Behavior

The scope and `$this` context of the initializer or factory function remains unchanged, and usual visibility constraints apply.

After successful initialization, the initializer or factory function is no longer referenced by the object and may be released if it has no other references.

If the initializer throws an exception, the object state is reverted to its pre-initialization state and the object is marked as lazy again. In other words, all effects on the object itself are reverted. Other side effects, such as effects on other objects, are not reverted. This prevents exposing a partially initialized instance in case of failure.

## Cloning

[Cloning](#language.oop5.cloning) a lazy object triggers its initialization before the clone is created, resulting in an initialized object.

For proxy objects, both the proxy and its real instance are cloned, and the clone of the proxy is returned. The [`__clone`](#object.clone) method is called on the real instance, not on the proxy. The cloned proxy and real instance are linked as they are during initialization, so accesses to the proxy clone are forwarded to the real instance clone.

This behavior ensures that the clone and the original object maintain separate states. Changes to the original object or its initializer's state after cloning do not affect the clone. Cloning both the proxy and its real instance, rather than returning a clone of the real instance alone, ensures that the clone operation consistently returns an object of the same class.

## Destructors

For lazy ghosts, the destructor is only called if the object has been initialized. For proxies, the destructor is only called on the real instance, if one exists.

The ReflectionClass::resetAsLazyGhost and ReflectionClass::resetAsLazyProxy methods may invoke the destructor of the object being reset.

# Magic Methods

Magic methods are special methods which override PHP's default action when certain actions are performed on an object.

> [!CAUTION]
> All method names starting with `__` are reserved by PHP. Therefore, it is not recommended to use such method names unless overriding PHP's behavior.

The following method names are considered magical: [\_\_construct()](#object.construct), [\_\_destruct()](#object.destruct), [\_\_call()](#object.call), [\_\_callStatic()](#object.callstatic), [\_\_get()](#object.get), [\_\_set()](#object.set), [\_\_isset()](#object.isset), [\_\_unset()](#object.unset), [\_\_serialize()](#object.serialize), [\_\_unserialize()](#object.unserialize), [\_\_sleep()](#object.sleep), [\_\_wakeup()](#object.wakeup), [\_\_toString()](#object.tostring), [\_\_invoke()](#object.invoke), [\_\_set_state()](#object.set-state), [\_\_clone()](#object.clone), and [\_\_debugInfo()](#object.debuginfo).

> [!WARNING]
> All magic methods, with the exception of [\_\_construct()](#object.construct), [\_\_destruct()](#object.destruct), and [\_\_clone()](#object.clone), *must* be declared as `public`, otherwise an `E_WARNING` is emitted. Prior to PHP 8.0.0, no diagnostic was emitted for the magic methods [\_\_sleep()](#object.sleep), [\_\_wakeup()](#object.wakeup), [\_\_serialize()](#object.serialize), [\_\_unserialize()](#object.unserialize), and [\_\_set_state()](#object.set-state).

> [!WARNING]
> If type declarations are used in the definition of a magic method, they must be identical to the signature described in this document. Otherwise, a fatal error is emitted. Prior to PHP 8.0.0, no diagnostic was emitted. However, [\_\_construct()](#object.construct) and [\_\_destruct()](#object.destruct) must not declare a return type; otherwise a fatal error is emitted.

## [\_\_serialize()](#object.serialize) and [\_\_unserialize()](#object.unserialize)

public

array

\_\_serialize

public

void

\_\_unserialize

array

data

`serialize` checks if the class has a function with the magic name [\_\_serialize()](#object.serialize). If so, that function is executed prior to any serialization. It must construct and return an associative array of key/value pairs that represent the serialized form of the object. If no array is returned a `TypeError` will be thrown.

> [!NOTE]
> If both [\_\_serialize()](#object.serialize) and [\_\_sleep()](#object.sleep) are defined in the same object, only [\_\_serialize()](#object.serialize) will be called. [\_\_sleep()](#object.sleep) will be ignored. If the object implements the [Serializable](#class.serializable) interface, the interface's `serialize()` method will be ignored and [\_\_serialize()](#object.serialize) used instead.

The intended use of [\_\_serialize()](#object.serialize) is to define a serialization-friendly arbitrary representation of the object. Elements of the array may correspond to properties of the object but that is not required.

Conversely, `unserialize` checks for the presence of a function with the magic name [\_\_unserialize()](#object.unserialize). If present, this function will be passed the restored array that was returned from [\_\_serialize()](#object.serialize). It may then restore the properties of the object from that array as appropriate.

> [!NOTE]
> If both [\_\_unserialize()](#object.unserialize) and [\_\_wakeup()](#object.wakeup) are defined in the same object, only [\_\_unserialize()](#object.unserialize) will be called. [\_\_wakeup()](#object.wakeup) will be ignored.

> [!NOTE]
> This feature is available as of PHP 7.4.0.

<div class="example">

<div class="title">

Serialize and unserialize

</div>

```
<?php
class Connection
{
    protected $link;
    private $dsn, $username, $password;

    public function __construct($dsn, $username, $password)
    {
        $this->dsn = $dsn;
        $this->username = $username;
        $this->password = $password;
        $this->connect();
    }

    private function connect()
    {
        $this->link = new PDO($this->dsn, $this->username, $this->password);
    }

    public function __serialize(): array
    {
        return [
          'dsn' => $this->dsn,
          'user' => $this->username,
          'pass' => $this->password,
        ];
    }

    public function __unserialize(array $data): void
    {
        $this->dsn = $data['dsn'];
        $this->username = $data['user'];
        $this->password = $data['pass'];

        $this->connect();
    }
}?>

    
```

</div>

## [\_\_sleep()](#object.sleep) and [\_\_wakeup()](#object.wakeup)

> [!WARNING]
> This serialization mechanism is soft-deprecated as of PHP 8.5.0. It is maintained for backward compatibility. However, new and existing code should be migrated to use the [\_\_serialize()](#object.serialize) and [\_\_unserialize()](#object.unserialize) magic methods instead.

public

array

\_\_sleep

public

void

\_\_wakeup

`serialize` checks if the class has a function with the magic name [\_\_sleep()](#object.sleep). If so, that function is executed prior to any serialization. It can clean up the object and is supposed to return an array with the names of all variables of that object that should be serialized. If the method doesn't return anything then ENTITY is serialized and `E_NOTICE` is issued.

> [!NOTE]
> It is not possible for [\_\_sleep()](#object.sleep) to return names of private properties in parent classes. Doing this will result in an `E_NOTICE` level error. Use [\_\_serialize()](#object.serialize) instead.

> [!NOTE]
> As of PHP 8.0.0, returning a value which is not an array from [\_\_sleep()](#object.sleep) generates a warning. Previously, it generated a notice.

The intended use of [\_\_sleep()](#object.sleep) is to commit pending data or perform similar cleanup tasks. Also, the function is useful if a very large object doesn't need to be saved completely.

Conversely, `unserialize` checks for the presence of a function with the magic name [\_\_wakeup()](#object.wakeup). If present, this function can reconstruct any resources that the object may have.

The intended use of [\_\_wakeup()](#object.wakeup) is to reestablish any database connections that may have been lost during serialization and perform other reinitialization tasks.

<div class="example">

<div class="title">

Sleep and wakeup

</div>

```
<?php
class Connection
{
    protected $link;
    private $dsn, $username, $password;

    public function __construct($dsn, $username, $password)
    {
        $this->dsn = $dsn;
        $this->username = $username;
        $this->password = $password;
        $this->connect();
    }

    private function connect()
    {
        $this->link = new PDO($this->dsn, $this->username, $this->password);
    }

    public function __sleep()
    {
        return array('dsn', 'username', 'password');
    }

    public function __wakeup()
    {
        $this->connect();
    }
}?>

   
```

</div>

## [\_\_toString()](#object.tostring)

public

string

\_\_toString

The [\_\_toString()](#object.tostring) method allows a class to decide how it will react when it is treated like a string. For example, what `echo $obj;` will print.

> [!WARNING]
> As of PHP 8.0.0, the return value follows standard PHP type semantics, meaning it will be coerced into a `string` if possible and if [strict typing](#language.types.declarations.strict) is disabled.
>
> A Stringable object will *not* be accepted by a `string` type declaration if [strict typing](#language.types.declarations.strict) is enabled. If such behaviour is wanted the type declaration must accept Stringable and `string` via a union type.
>
> As of PHP 8.0.0, any class that contains a [\_\_toString()](#object.tostring) method will also implicitly implement the Stringable interface, and will thus pass type checks for that interface. Explicitly implementing the interface anyway is recommended.
>
> In PHP 7.4, the returned value *must* be a `string`, otherwise an `Error` is thrown.
>
> Prior to PHP 7.4.0, the returned value *must* be a `string`, otherwise a fatal `E_RECOVERABLE_ERROR` is emitted.

> [!WARNING]
> It was not possible to throw an exception from within a [\_\_toString()](#object.tostring) method prior to PHP 7.4.0. Doing so will result in a fatal error.

<div class="example">

<div class="title">

Simple example

</div>

```
<?php
// Declare a simple class
class TestClass
{
    public $foo;

    public function __construct($foo)
    {
        $this->foo = $foo;
    }

    public function __toString()
    {
        return $this->foo;
    }
}

$class = new TestClass('Hello');
echo $class;
?>

    
```

ENTITY

    Hello

        

</div>

## [\_\_invoke()](#object.invoke)

mixed

\_\_invoke

values

The [\_\_invoke()](#object.invoke) method is called when a script tries to call an object as a function.

<div class="example">

<div class="title">

Using [\_\_invoke()](#object.invoke)

</div>

```
<?php
class CallableClass
{
    public function __invoke($x)
    {
        var_dump($x);
    }
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>

    
```

ENTITY

    int(5)
    bool(true)

        

</div>

<div class="example">

<div class="title">

Using [\_\_invoke()](#object.invoke)

</div>

```
<?php
class Sort
{
    private $key;

    public function __construct(string $key)
    {
        $this->key = $key;
    }

    public function __invoke(array $a, array $b): int
    {
        return $a[$this->key] <=> $b[$this->key];
    }
}

$customers = [
    ['id' => 1, 'first_name' => 'John', 'last_name' => 'Do'],
    ['id' => 3, 'first_name' => 'Alice', 'last_name' => 'Gustav'],
    ['id' => 2, 'first_name' => 'Bob', 'last_name' => 'Filipe']
];

// sort customers by first name
usort($customers, new Sort('first_name'));
print_r($customers);

// sort customers by last name
usort($customers, new Sort('last_name'));
print_r($customers);
?>

    
```

ENTITY

    Array
    (
        [0] => Array
            (
                [id] => 3
                [first_name] => Alice
                [last_name] => Gustav
            )

        [1] => Array
            (
                [id] => 2
                [first_name] => Bob
                [last_name] => Filipe
            )

        [2] => Array
            (
                [id] => 1
                [first_name] => John
                [last_name] => Do
            )

    )
    Array
    (
        [0] => Array
            (
                [id] => 1
                [first_name] => John
                [last_name] => Do
            )

        [1] => Array
            (
                [id] => 2
                [first_name] => Bob
                [last_name] => Filipe
            )

        [2] => Array
            (
                [id] => 3
                [first_name] => Alice
                [last_name] => Gustav
            )

    )

        

</div>

## [\_\_set_state()](#object.set-state)

static

object

\_\_set_state

array

properties

This [static](#language.oop5.static) method is called for classes exported by `var_export`.

The only parameter of this method is an array containing exported properties in the form `['property' => value, ...]`.

<div class="example">

<div class="title">

Using [\_\_set_state()](#object.set-state)

</div>

```
<?php

class A
{
    public $var1;
    public $var2;

    public static function __set_state($an_array)
    {
        $obj = new A;
        $obj->var1 = $an_array['var1'];
        $obj->var2 = $an_array['var2'];
        return $obj;
    }
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';

$b = var_export($a, true);
var_dump($b);
eval('$c = ' . $b . ';');
var_dump($c);
?>

    
```

ENTITY

    string(60) "A::__set_state(array(
       'var1' => 5,
       'var2' => 'foo',
    ))"
    object(A)#2 (2) {
      ["var1"]=>
      int(5)
      ["var2"]=>
      string(3) "foo"
    }

        

</div>

> [!NOTE]
> When exporting an object, `var_export` does not check whether [\_\_set_state()](#object.set-state) is implemented by the object's class, so re-importing objects will result in an `Error` exception, if \_\_set_state() is not implemented. Particularly, this affects some internal classes.
>
> It is the responsibility of the programmer to verify that only objects whose class implements \_\_set_state will be re-imported.

## [\_\_debugInfo()](#object.debuginfo)

array

\_\_debugInfo

This method is called by `var_dump` when dumping an object to get the properties that should be shown. If the method isn't defined on an object, then all public, protected and private properties will be shown.

As of PHP 8.5.0, returning ENTITY from [\_\_debugInfo()](#object.debuginfo) is deprecated. Return an empty `array` instead.

<div class="example">

<div class="title">

Using [\_\_debugInfo()](#object.debuginfo)

</div>

```
<?php
class C {
    private $prop;

    public function __construct($val) {
        $this->prop = $val;
    }

    public function __debugInfo() {
        return [
            'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));
?>

    
```

ENTITY

    object(C)#1 (1) {
      ["propSquared"]=>
      int(1764)
    }

        

</div>

# Comparing Objects

When using the comparison operator (`==`), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with `==`), and are instances of the same class.

When using the identity operator (`===`), object variables are identical if and only if they refer to the same instance of the same class.

An example will clarify these rules.

<div class="example">

<div class="title">

Example of object comparison

</div>

```
<?php
function bool2str($bool)
{
    if ($bool === false) {
        return 'FALSE';
    } else {
        return 'TRUE';
    }
}

function compareObjects($o1, $o2)
{
    echo 'o1 == o2 : ' . bool2str($o1 == $o2) . "\n";
    echo 'o1 != o2 : ' . bool2str($o1 != $o2) . "\n";
    echo 'o1 === o2 : ' . bool2str($o1 === $o2) . "\n";
    echo 'o1 !== o2 : ' . bool2str($o1 !== $o2) . "\n";
}

class Flag
{
    public $flag;

    function __construct($flag = true) {
        $this->flag = $flag;
    }
}

class OtherFlag
{
    public $flag;

    function __construct($flag = true) {
        $this->flag = $flag;
    }
}

$o = new Flag();
$p = new Flag();
$q = $o;
$r = new OtherFlag();

echo "Two instances of the same class\n";
compareObjects($o, $p);

echo "\nTwo references to the same instance\n";
compareObjects($o, $q);

echo "\nInstances of two different classes\n";
compareObjects($o, $r);
?>

     
```

ENTITY

    Two instances of the same class
    o1 == o2 : TRUE
    o1 != o2 : FALSE
    o1 === o2 : FALSE
    o1 !== o2 : TRUE

    Two references to the same instance
    o1 == o2 : TRUE
    o1 != o2 : FALSE
    o1 === o2 : TRUE
    o1 !== o2 : FALSE

    Instances of two different classes
    o1 == o2 : FALSE
    o1 != o2 : TRUE
    o1 === o2 : FALSE
    o1 !== o2 : TRUE

         

</div>

> [!NOTE]
> Extensions can define their own rules for comparing their objects (`==`).

# Overloading

Overloading in PHP provides means to dynamically “create” properties and methods. These dynamic entities are processed via magic methods one can establish in a class for various action types.

The overloading methods are invoked when interacting with properties or methods that have not been declared or are not [visible](#language.oop5.visibility) in the current scope. The rest of this section will use the terms “inaccessible properties” and “inaccessible methods” to refer to this combination of declaration and visibility.

All overloading methods must be defined as `public`.

> [!NOTE]
> None of the arguments of these magic methods can be [passed by reference](#functions.arguments.by-reference).

> [!NOTE]
> PHP's interpretation of “overloading” is different than most object-oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments.

## Property overloading

public

void

\_\_set

string

name

mixed

value

public

mixed

\_\_get

string

name

public

bool

\_\_isset

string

name

public

void

\_\_unset

string

name

[\_\_set()](#object.set) is run when writing data to inaccessible (protected or private) or non-existing properties.

[\_\_get()](#object.get) is utilized for reading data from inaccessible (protected or private) or non-existing properties.

[\_\_isset()](#object.isset) is triggered by calling `isset` or `empty` on inaccessible (protected or private) or non-existing properties.

[\_\_unset()](#object.unset) is invoked when `unset` is used on inaccessible (protected or private) or non-existing properties.

The `$name` argument is the name of the property being interacted with. The [\_\_set()](#object.set) method's `$value` argument specifies the value the `$name`'ed property should be set to.

Property overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods should not be declared [static](#language.oop5.static). A warning is issued if one of the magic overloading methods is declared `static`.

> [!NOTE]
> The return value of [\_\_set()](#object.set) is ignored because of the way PHP processes the assignment operator. Similarly, [\_\_get()](#object.get) is never called when chaining assignments together like this: `$a = $obj->b = 8;`

> [!NOTE]
> PHP will not call an overloaded method from within the same overloaded method. That means, for example, writing `return $this->foo` inside of [\_\_get()](#object.get) will return ENTITY and raise an `E_WARNING` if there is no `foo` property defined, rather than calling [\_\_get()](#object.get) a second time. However, overload methods may invoke other overload methods implicitly (such as [\_\_set()](#object.set) triggering [\_\_get()](#object.get)).

<div class="example">

<div class="title">

Overloading properties via the [\_\_get()](#object.get), [\_\_set()](#object.set), [\_\_isset()](#object.isset) and [\_\_unset()](#object.unset) methods

</div>

```
<?php
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;
    }

    public function __isset($name)
    {
        echo "Is '$name' set?\n";
        return isset($this->data[$name]);
    }

    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;

$obj->a = 1;
echo $obj->a . "\n\n";

var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";

echo $obj->declared . "\n\n";

echo "Let's experiment with the private property named 'hidden':\n";
echo "Privates are visible inside the class, so __get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so __get() is used...\n";
echo $obj->hidden . "\n";
?>

    
```

ENTITY

```
Setting 'a' to '1'
Getting 'a'
1

Is 'a' set?
bool(true)
Unsetting 'a'
Is 'a' set?
bool(false)

1

Let's experiment with the private property named 'hidden':
Privates are visible inside the class, so __get() not used...
2
Privates not visible outside of class, so __get() is used...
Getting 'hidden'

Notice: Undefined property via __get(): hidden in script on line 71 in script on line 27

    
```

</div>

## Method overloading

public

mixed

\_\_call

string

name

array

arguments

public static

mixed

\_\_callStatic

string

name

array

arguments

[\_\_call()](#object.call) is triggered when invoking inaccessible methods in an object context.

[\_\_callStatic()](#object.callstatic) is triggered when invoking inaccessible methods in a static context.

The `$name` argument is the name of the method being called. The `$arguments` argument is an enumerated array containing the parameters passed to the `$name`'ed method.

<div class="example">

<div class="title">

Overloading methods via the [\_\_call()](#object.call) and [\_\_callStatic()](#object.callstatic) methods

</div>

```
  
<?php
class MethodTest
{
    public function __call($name, $arguments)
    {
        // Note: value of $name is case sensitive.
        echo "Calling object method '$name' "
             . implode(', ', $arguments). "\n";
    }

    public static function __callStatic($name, $arguments)
    {
        // Note: value of $name is case sensitive.
        echo "Calling static method '$name' "
             . implode(', ', $arguments). "\n";
    }
}

$obj = new MethodTest;
$obj->runTest('in object context');

MethodTest::runTest('in static context');
?>

    
```

ENTITY

```
Calling object method 'runTest' in object context
Calling static method 'runTest' in static context

    
```

</div>

# Scope Resolution Operator (::)

The Scope Resolution Operator (also called Paamayim Nekudotayim) or in simpler terms, the double colon, is a token that allows access to a [constant](#language.oop5.constants), [static](#language.oop5.static) property, or [static](#language.oop5.static) method of a class or one of its parents. Moreover, static properties or methods can be overridden via [late static binding](#language.oop5.late-static-bindings).

When referencing these items from outside the class definition, use the name of the class.

It's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. `self`, `parent` and `static`).

Paamayim Nekudotayim would, at first, seem like a strange choice for naming a double-colon. However, while writing the Zend Engine 0.5 (which powers PHP 3), that's what the Zend team decided to call it. It actually does mean double-colon - in Hebrew!

<div class="example">

<div class="title">

:: from outside the class definition

</div>

```
<?php
class MyClass {
    const CONST_VALUE = 'A constant value';
}

$classname = 'MyClass';
echo $classname::CONST_VALUE;

echo MyClass::CONST_VALUE;
?>

  
```

</div>

Three special keywords `self`, `parent` and `static` are used to access properties or methods from inside the class definition.

<div class="example">

<div class="title">

:: from inside the class definition

</div>

```
<?php
class MyClass {
    const CONST_VALUE = 'A constant value';
}

class OtherClass extends MyClass
{
    public static $my_static = 'static var';

    public static function doubleColon() {
        echo parent::CONST_VALUE . "\n";
        echo self::$my_static . "\n";
    }
}

$classname = 'OtherClass';
$classname::doubleColon();

OtherClass::doubleColon();
?>

  
```

</div>

When an extending class overrides the parent's definition of a method, PHP will not call the parent's method. It's up to the extended class whether or not the parent's method is called. This also applies to [Constructors and Destructors](#language.oop5.decon), [Overloading](#language.oop5.overloading), and [Magic](#language.oop5.magic) method definitions.

<div class="example">

<div class="title">

Calling a parent's method

</div>

```
<?php
class MyClass
{
    protected function myFunc() {
        echo "MyClass::myFunc()\n";
    }
}

class OtherClass extends MyClass
{
    // Override parent's definition
    public function myFunc()
    {
        // But still call the parent function
        parent::myFunc();
        echo "OtherClass::myFunc()\n";
    }
}

$class = new OtherClass();
$class->myFunc();
?>

  
```

</div>

See also [some examples of static call trickery](#language.oop5.basic.class.this).

# Properties

Class member variables are called *properties*. They may be referred to using other terms such as *fields*, but for the purposes of this reference *properties* will be used. They are defined by using at least one modifier (such as [???](#language.oop5.visibility), [???](#language.oop5.static), or, as of PHP 8.1.0, [readonly](#language.oop5.properties.readonly-properties)), optionally (except for `readonly` properties), as of PHP 7.4, followed by a type declaration, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a [constant](#language.constants) value.

> [!NOTE]
> An obsolete way of declaring class properties is by using the `var` keyword instead of a modifier.

> [!NOTE]
> A property declared without a [???](#language.oop5.visibility) modifier will be declared as `public`.

Within class methods non-static properties may be accessed by using `-ENTITY` (Object Operator): `$this-ENTITYproperty` (where `property` is the name of the property). Static properties are accessed by using the `::` (Double Colon): `self::$property`. See [???](#language.oop5.static) for more information on the difference between static and non-static properties.

The pseudo-variable `$this` is available inside any class method when that method is called from within an object context. `$this` is the value of the calling object.

<div class="example">

<div class="title">

Property declarations

</div>

```
<?php
class SimpleClass
{
   public $var1 = 'hello ' . 'world';
   public $var2 = <<<EOD
hello world
EOD;
   public $var3 = 1+2;
   // invalid property declarations:
   public $var4 = self::myStaticMethod();
   public $var5 = $myVar;

   // valid property declarations:
   public $var6 = myConstant;
   public $var7 = [true, false];

   public $var8 = <<<'EOD'
hello world
EOD;

   // Without visibility modifier:
   static $var9;
   readonly int $var10;
}
?>

    
```

</div>

> [!NOTE]
> There are various functions to handle classes and objects. See the [Class/Object Functions](#ref.classobj) reference.

## Type declarations

As of PHP 7.4.0, property definitions can include [???](#language.types.declarations), with the exception of `callable`.

<div class="example">

<div class="title">

Example of typed properties

</div>

```
<?php

class User
{
    public int $id;
    public ?string $name;

    public function __construct(int $id, ?string $name)
    {
        $this->id = $id;
        $this->name = $name;
    }
}

$user = new User(1234, null);

var_dump($user->id);
var_dump($user->name);

?>

     
```

ENTITY

    int(1234)
    NULL

         

</div>

Typed properties must be initialized before accessing, otherwise an `Error` is thrown.

<div class="example">

<div class="title">

Accessing properties

</div>

```
<?php

class Shape
{
    public int $numberOfSides;
    public string $name;

    public function setNumberOfSides(int $numberOfSides): void
    {
        $this->numberOfSides = $numberOfSides;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getNumberOfSides(): int
    {
        return $this->numberOfSides;
    }

    public function getName(): string
    {
        return $this->name;
    }
}

$triangle = new Shape();
$triangle->setName("triangle");
$triangle->setNumberOfSides(3);
var_dump($triangle->getName());
var_dump($triangle->getNumberOfSides());

$circle = new Shape();
$circle->setName("circle");
var_dump($circle->getName());
var_dump($circle->getNumberOfSides());
?>

     
```

ENTITY

    string(8) "triangle"
    int(3)
    string(6) "circle"

    Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initialization

         

</div>

## Readonly properties

As of PHP 8.1.0, a property can be declared with the `readonly` modifier, which prevents modification of the property after initialization. Prior to PHP 8.4.0 a `readonly` property is implicitly private-set, and may only be written to from the same class. As of PHP 8.4.0, `readonly` properties are implicitly [`protected(set)`](#language.oop5.visibility-members-aviz), so may be set from child classes. That may be overridden explicitly if desired.

<div class="example">

<div class="title">

Example of readonly properties

</div>

```
<?php

class Test {
   public readonly string $prop;

   public function __construct(string $prop) {
       // Legal initialization.
       $this->prop = $prop;
   }
}

$test = new Test("foobar");
// Legal read.
var_dump($test->prop); // string(6) "foobar"

// Illegal reassignment. It does not matter that the assigned value is the same.
$test->prop = "foobar";
// Error: Cannot modify readonly property Test::$prop
?>

     
```

</div>

> [!NOTE]
> The readonly modifier can only be applied to [typed properties](#language.oop5.properties.typed-properties). A readonly property without type constraints can be created using the [???](#language.types.mixed) type.

> [!NOTE]
> Readonly static properties are not supported.

A readonly property can only be initialized once, and only from the scope where it has been declared. Any other assignment or modification of the property will result in an `Error` exception.

<div class="example">

<div class="title">

Illegal initialization of readonly properties

</div>

```
<?php
class Test1 {
    public readonly string $prop;
}

$test1 = new Test1;
// Illegal initialization outside of private scope.
$test1->prop = "foobar";
// Error: Cannot initialize readonly property Test1::$prop from global scope
?>

     
```

</div>

> [!NOTE]
> Readonly properties can only be initialized by a direct assignment. An uninitialized readonly property cannot be initialized by reference, not even from the scope where it has been declared: passing it to a function parameter that expects to be passed by reference, or assigning it by reference, results in an Error exception.
>
> <div class="informalexample">
>
> ```
> <?php
>
> class Test {
>     public readonly array $matches;
>
>     public function __construct(string $subject) {
>         // Illegal initialization by reference.
>         preg_match('/\d+/', $subject, $this->matches);
>         // Error: Cannot indirectly modify readonly property Test::$matches
>     }
> }
>
> new Test('abc 42');
> ?>
>
>       
> ```
>
> </div>

> [!NOTE]
> Specifying an explicit default value on readonly properties is not allowed, because a readonly property with a default value is essentially the same as a constant, and thus not particularly useful.
>
> <div class="informalexample">
>
> ```
> <?php
>
> class Test {
>     // Fatal error: Readonly property Test::$prop cannot have default value
>     public readonly int $prop = 42;
> }
> ?>
>
>       
> ```
>
> </div>

> [!NOTE]
> Readonly properties cannot be `unset` once they are initialized. However, it is possible to unset a readonly property prior to initialization, from the scope where the property has been declared.

Modifications are not necessarily plain assignments, all of the following will also result in an `Error` exception:

<div class="informalexample">

```
<?php

class Test {
    public function __construct(
        public readonly int $i = 0,
        public readonly array $ary = [],
    ) {}
}

$test = new Test;
$test->i += 1;
$test->i++;
++$test->i;
$test->ary[] = 1;
$test->ary[0][] = 1;
unset($test->ary[0]);
$ref =& $test->i;
$test->i =& $ref;
byRef($test->i);
foreach ($test as &$prop);
?>

     
```

</div>

However, readonly properties do not preclude interior mutability. Objects (or resources) stored in readonly properties may still be modified internally:

<div class="informalexample">

```
<?php

class Test {
    public function __construct(public readonly object $obj) {}
}

$test = new Test(new stdClass);
// Legal interior mutation.
$test->obj->foo = 1;
// Illegal reassignment.
$test->obj = new stdClass;
?>

     
```

</div>

As of PHP 8.3.0, readonly properties can be reinitialized when cloning an object using the [\_\_clone()](#object.clone) method.

<div class="example">

<div class="title">

Readonly properties and cloning

</div>

```
<?php
class Test1 {
    public readonly ?string $prop;

    public function __clone() {
        $this->prop = null;
    }

    public function setProp(string $prop): void {
        $this->prop = $prop;
    }
}

$test1 = new Test1;
$test1->setProp('foobar');

$test2 = clone $test1;
var_dump($test2->prop); // NULL
?>

     
```

</div>

> [!NOTE]
> As of PHP 8.4.0, indirect modification of a readonly property within [\_\_clone()](#object.clone), such as acquiring a reference to it (`$ref = ENTITY$this->prop`), is no longer allowed. This was already forbidden during readonly initialization.

## Dynamic properties

If trying to assign to a non-existent property on an ENTITY, PHP will automatically create a corresponding property. This dynamically created property will *only* be available on this class instance.

Dynamic properties are supported by [stdClass](#stdclass.intro) and its subclasses. Other classes may enable similar behavior with [AllowDynamicProperties](#allowdynamicproperties.intro) or [property overloading](#language.oop5.overloading).

> [!WARNING]
> Creating a dynamic property is deprecated as of PHP 8.2.0, unless the class is marked with the `#[\AllowDynamicProperties]` attribute. It is recommended to declare the property instead. To handle arbitrary property names, the class should implement the magic methods [\_\_get()](#object.get) and [\_\_set()](#object.set). Marking the class with the attribute remains an option, but is generally considered a last resort.

# Property Hooks

Property hooks, also known as "property accessors" in some other languages, are a way to intercept and override the read and write behavior of a property. This functionality serves two purposes:

1.  It allows for properties to be used directly, without get- and set- methods, while leaving the option open to add additional behavior in the future. That renders most boilerplate get/set methods unnecessary, even without using hooks.

2.  It allows for properties that describe an object without needing to store a value directly.

There are two hooks available on non-static properties: `get` and `set`. They allow overriding the read and write behavior of a property, respectively. Hooks are available for both typed and untyped properties.

A property may be "backed" or "virtual". A backed property is one that actually stores a value. Any property that has no hooks is backed. A virtual property is one that has hooks and those hooks do not interact with the property itself. In this case, the hooks are effectively the same as methods, and the object does not use any space to store a value for that property.

Property hooks are incompatible with `readonly` properties. If there is a need to restrict access to a `get` or `set` operation in addition to altering its behavior, use [asymmetric property visibility](#language.oop5.visibility-members-aviz).

> [!NOTE]
> Property hooks were introduced in PHP 8.4.

## Basic Hook Syntax

The general syntax for declaring a hook is as follows.

<div class="example">

<div class="title">

Property hooks (full version)

</div>

```
<?php
class Example
{
    private bool $modified = false;

    public string $foo = 'default value' {
        get {
            if ($this->modified) {
                return $this->foo . ' (modified)';
            }
            return $this->foo;
        }
        set(string $value) {
            $this->foo = strtolower($value);
            $this->modified = true;
        }
    }
}

$example = new Example();
$example->foo = 'changed';
print $example->foo;
?>

   
```

</div>

The `$foo` property ends in `{}`, rather than a semicolon. That indicates the presence of hooks. Both a `get` and `set` hook are defined, although it is allowed to define only one or the other. Both hooks have a body, denoted by `{}`, that may contain arbitrary code.

The `set` hook additionally allows specifying the type and name of an incoming value, using the same syntax as a method. The type must be either the same as the type of the property, or [contravariant](#language.oop5.variance.contravariance) (wider) to it. For instance, a property of type `string` could have a `set` hook that accepts `stringStringable`, but not one that only accepts `array`.

At least one of the hooks references `$this->foo`, the property itself. That means the property will be "backed". When calling `$example->foo = 'changed'`, the provided string will be first cast to lowercase, then saved to the backing value. When reading from the property, the previously saved value may conditionally be appended with additional text.

There are a number of shorthand syntax variants as well to handle common cases.

If the `get` hook is a single expression, then the `{}` may be omitted and replaced with an arrow expression.

<div class="example">

<div class="title">

Property get expression

</div>

This example is equivalent to the previous.

```
<?php
class Example
{
    private bool $modified = false;

    public string $foo = 'default value' {
        get => $this->foo . ($this->modified ? ' (modified)' : '');

        set(string $value) {
            $this->foo = strtolower($value);
            $this->modified = true;
        }
    }
}
?>

   
```

</div>

If the `set` hook's parameter type is the same as the property type (which is typical), it may be omitted. In that case, the value to set is automatically given the name `$value`.

<div class="example">

<div class="title">

Property set defaults

</div>

This example is equivalent to the previous.

```
<?php
class Example
{
    private bool $modified = false;

    public string $foo = 'default value' {
        get => $this->foo . ($this->modified ? ' (modified)' : '');

        set {
            $this->foo = strtolower($value);
            $this->modified = true;
        }
    }
}
?>

   
```

</div>

If the `set` hook is only setting a modified version of the passed in value, then it may also be simplified to an arrow expression. The value the expression evaluates to will be set on the backing value.

<div class="example">

<div class="title">

Property set expression

</div>

```
<?php
class Example
{
    private bool $modified = false;

    public string $foo = 'default value' {
        get => $this->foo . ($this->modified ? ' (modified)' : '');
        set => strtolower($value);
    }
}
?>

   
```

</div>

This example is not quite equivalent to the previous, as it does not also modify `$this->modified`. If multiple statements are needed in the set hook body, use the braces version.

A property may implement zero, one, or both hooks as the situation requires. All shorthand versions are mutually-independent. That is, using a short-get with a long-set, a short-set with an explicit type, and so on is all valid.

On a backed property, omitting a `get` or `set` hook means the default read or write behavior will be used.

> [!NOTE]
> Hooks can be defined when using [constructor property promotion](#language.oop5.decon.constructor.promotion). However, when doing so, values provided to the constructor must match the type associated with the property, regardless of what the `set` hook might allow.
>
> Consider the following:
>
> ```
> <?php
> class Example
> {
>     public function __construct(
>         public private(set) DateTimeInterface $created {
>             set (string|DateTimeInterface $value) {
>                 if (is_string($value)) {
>                     $value = new DateTimeImmutable($value);
>                 }
>                 $this->created = $value;
>             }
>         },
>     ) {
>     }
> }
>
>    
> ```
>
> Internally, the engine decomposes this to the following:
>
> ```
> <?php
> class Example
> {
>     public private(set) DateTimeInterface $created {
>         set (string|DateTimeInterface $value) {
>             if (is_string($value)) {
>                 $value = new DateTimeImmutable($value);
>             }
>             $this->created = $value;
>         }
>     }
>
>     public function __construct(
>         DateTimeInterface $created,
>     ) {
>         $this->created = $created;
>     }
> }
>
>    
> ```
>
> Any attempts to set the property outside the constructor will allow either `string` or DateTimeInterface values, but the constructor will only allow DateTimeInterface. This is because the defined type for the property (DateTimeInterface) is used as the parameter type within the constructor signature, regardless of what the `set` hook allows.
>
> If this kind of behavior is needed from the constructor, constructor property promotion cannot be used.

## Virtual properties

Virtual properties are properties that have no backing value. A property is virtual if neither its `get` nor `set` hook references the property itself using exact syntax. That is, a property named `$foo` whose hook contains `$this->foo` will be backed. But the following is not a backed property, and will error:

<div class="example">

<div class="title">

Invalid virtual property

</div>

```
<?php
class Example
{
    public string $foo {
        get {
            $temp = __PROPERTY__;
            return $this->$temp; // Doesn't refer to $this->foo, so it doesn't count.
        }
    }
}
?>

   
```

</div>

For virtual properties, if a hook is omitted then that operation does not exist and trying to use it will produce an error. Virtual properties take up no memory space in an object. Virtual properties are suited for "derived" properties, such as those that are the combination of two other properties.

<div class="example">

<div class="title">

Virtual property

</div>

```
<?php
class Rectangle
{
    // A virtual property.
    public int $area {
        get => $this->h * $this->w;
    }

    public function __construct(public int $h, public int $w) {}
}

$s = new Rectangle(4, 5);
print $s->area; // prints 20
$s->area = 30; // Error, as there is no set operation defined.
?>

   
```

</div>

Defining both a `get` and `set` hook on a virtual property is also allowed.

## Scoping

All hooks operate in the scope of the object being modified. That means they have access to all public, private, or protected methods of the object, as well as any public, private, or protected properties, including properties that may have their own property hooks. Accessing another property from within a hook does not bypass the hooks defined on that property.

The most notable implication of this is that non-trivial hooks may sub-call to an arbitrarily complex method if they wish.

<div class="example">

<div class="title">

Calling a method from a hook

</div>

```
<?php
class Person {
    public string $phone {
        set => $this->sanitizePhone($value);
    }

    private function sanitizePhone(string $value): string {
        $value = ltrim($value, '+');
        $value = ltrim($value, '1');

        if (!preg_match('/\d\d\d\-\d\d\d\-\d\d\d\d/', $value)) {
            throw new \InvalidArgumentException();
        }
        return $value;
    }
}
?>

   
```

</div>

## References

Because the presence of hooks intercepts the read and write process for properties, they cause issues when acquiring a reference to a property or with indirect modification, such as `$this->arrayProp['key'] = 'value';`. That is because any attempted modification of the value by reference would bypass a set hook, if one is defined.

In the rare case that getting a reference to a property that has hooks defined is necessary, the `get` hook may be prefixed with `ENTITY` to cause it to return by reference. Defining both `get` and `ENTITYget` on the same property is a syntax error.

Defining both `ENTITYget` and `set` hooks on a backed property is not allowed. As noted above, writing to the value returned by reference would bypass the `set` hook. On virtual properties, there is no necessary common value shared between the two hooks, so defining both is allowed.

Writing to an index of an array property also involves an implicit reference. For that reason, writing to a backed array property with hooks defined is allowed if and only if it defines only a `ENTITYget` hook. On a virtual property, writing to the array returned from either `get` or `ENTITYget` is legal, but whether that has any impact on the object depends on the hook implementation.

Overwriting the entire array property is fine, and behaves the same as any other property. Only working with elements of the array requires special care.

## Inheritance

### Final hooks

Hooks may also be declared [final](#language.oop5.final), in which case they may not be overridden.

<div class="example">

<div class="title">

Final hooks

</div>

```
<?php
class User
{
    public string $username {
        final set => strtolower($value);
    }
}

class Manager extends User
{
    public string $username {
        // This is allowed
        get => strtoupper($this->username);

        // But this is NOT allowed, because set is final in the parent.
        set => strtoupper($value);
    }
}
?>

    
```

</div>

A property may also be declared [final](#language.oop5.final). A final property may not be redeclared by a child class in any way, which precludes altering hooks or widening its access.

Declaring hooks final on a property that is declared final is redundant, and will be silently ignored. This is the same behavior as final methods.

A child class may define or redefine individual hooks on a property by redefining the property and just the hooks it wishes to override. A child class may also add hooks to a property that had none. This is essentially the same as if the hooks were methods.

<div class="example">

<div class="title">

Hook inheritance

</div>

```
<?php
class Point
{
    public int $x;
    public int $y;
}

class PositivePoint extends Point
{
    public int $x {
        set {
            if ($value < 0) {
                throw new \InvalidArgumentException('Too small');
            }
            $this->x = $value;
        }
    }
}
?>

    
```

</div>

Each hook overrides parent implementations independently of each other. If a child class adds hooks, any default value set on the property is removed, and must be redeclared. That is consistent with how inheritance works on hook-less properties.

### Accessing parent hooks

A hook in a child class may access the parent class's property using the `parent::$prop` keyword, followed by the desired hook. For example, `parent::$propName::get()`. It may be read as "access the `prop` defined on the parent class, and then run its get operation" (or set operation, as appropriate).

If not accessed this way, the parent class's hook is ignored. This behavior is consistent with how all methods work. This also offers a way to access the parent class's storage, if any. If there is no hook on the parent property, its default get/set behavior will be used. Hooks may not access any other hook except their own parent on their own property.

The example above could be rewritten as follows, which would allow for the `Point` class to add its own `set` hook in the future without issues (in the previous example, a hook added to the parent class would be ignored in the child).

<div class="example">

<div class="title">

Parent hook access (set)

</div>

```
<?php
class Point
{
    public int $x;
    public int $y;
}

class PositivePoint extends Point
{
    public int $x {
        set {
            if ($value < 0) {
                throw new \InvalidArgumentException('Too small');
            }
            parent::$x::set($value);
        }
    }
}
?>

    
```

</div>

An example of overriding only a get hook could be:

<div class="example">

<div class="title">

Parent hook access (get)

</div>

```
<?php
class Strings
{
    public string $val;
}

class CaseFoldingStrings extends Strings
{
    public bool $uppercase = true;

    public string $val {
        get => $this->uppercase
            ? strtoupper(parent::$val::get())
            : strtolower(parent::$val::get());
    }
}
?>

    
```

</div>

## Serialization

PHP has a number of different ways in which an object may be serialized, either for public consumption or for debugging purposes. The behavior of hooks varies depending on the use case. In some cases, the raw backing value of a property will be used, bypassing any hooks. In others, the property will be read or written "through" the hook, just like any other normal read/write action.

var_dump

: Use raw value

serialize

: Use raw value

unserialize

: Use raw value

\_\_serialize()

/

\_\_unserialize()

: Custom logic, uses get/set hook

Array casting: Use raw value

var_export

: Use get hook

json_encode

: Use get hook

JsonSerializable

: Custom logic, uses get hook

get_object_vars

: Use get hook

get_mangled_object_vars

: Use raw value

# Objects and references

One of the key-points of PHP OOP that is often mentioned is that "objects are passed by reference by default". This is not completely true. This section rectifies that general thought using some examples.

A PHP reference is an alias, which allows two different variables to write to the same value. In PHP, an object variable doesn't contain the object itself as value. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.

<div class="example">

<div class="title">

References and Objects

</div>

```
<?php
class A {
    public $foo = 1;
}  

$a = new A;
$b = $a;     // $a and $b are copies of the same identifier
             // ($a) = ($b) = <id>
$b->foo = 2;
echo $a->foo."\n";


$c = new A;
$d = &$c;    // $c and $d are references
             // ($c,$d) = <id>

$d->foo = 2;
echo $c->foo."\n";


$e = new A;

function foo($obj) {
    // ($obj) = ($e) = <id>
    $obj->foo = 2;
}

foo($e);
echo $e->foo."\n";

?>  

   
```

ENTITY

    2
    2
    2

       

</div>

# Serializing objects - objects in sessions

`serialize` returns a string containing a byte-stream representation of any value that can be stored in PHP. `unserialize` can use this string to recreate the original variable values. Using serialize to save an object will save all variables in an object. The methods in an object will not be saved, only the name of the class.

In order to be able to `unserialize` an object, the class of that object needs to be defined. That is, if you have an object of class A and serialize this, you'll get a string that refers to class A and contains all values of variables contained in it. If you want to be able to unserialize an object of class A in another file, the definition of class A must be present in that file first. This can be done for example by storing the class definition of class A in an include file and including this file or making use of the `spl_autoload_register` function.

<div class="informalexample">

```
<?php
// A.php:
  
  class A {
      public $one = 1;
    
      public function show_one() {
          echo $this->one;
      }
  }
  
// page1.php:

  include "A.php";
  
  $a = new A;
  $s = serialize($a);
  // store $s somewhere where page2.php can find it.
  file_put_contents('store', $s);

// page2.php:
  
  // this is needed for the unserialize to work properly.
  include "A.php";

  $s = file_get_contents('store');
  $a = unserialize($s);

  // now use the function show_one() of the $a object.  
  $a->show_one();
?>

   
```

</div>

It is strongly recommended that if an application serializes objects, for use later in the application, the application includes the class definition for that object throughout the application. Not doing so might result in an object being unserialized without a class definition, which will result in PHP giving the object a class of `__PHP_Incomplete_Class_Name`, which has no methods and would render the object useless.

So if in the example above `$a` became part of a session by adding a new key to the `$_SESSION` superglobal array, you should include the file `A.php` on all of your pages, not only `page1.php` and `page2.php`.

Beyond the above advice, note that you can also hook into the serialization and unserialization events on an object using the [\_\_sleep()](#object.sleep) and [\_\_wakeup()](#object.wakeup) methods. Using [\_\_sleep()](#object.sleep) also allows you to only serialize a subset of the object's properties.

# Static Keyword

> [!TIP]
> This page describes the use of the `static` keyword to define static methods and properties. `static` can also be used to [define static variables](#language.variables.scope.static), [define static anonymous functions](#functions.anonymous-functions.static) and for [late static bindings](#language.oop5.late-static-bindings). Please refer to those pages for information on those meanings of `static`.

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. These can also be accessed statically within an instantiated class object.

## Static methods

Because static methods are callable without an instance of the object created, the pseudo-variable `$this` is not available inside methods declared as static.

> [!WARNING]
> Calling non-static methods statically throws an `Error`.
>
> Prior to PHP 8.0.0, calling non-static methods statically was deprecated, and generated an `E_DEPRECATED` warning.

<div class="example">

<div class="title">

Static method example

</div>

```
<?php
class Foo {
    public static function aStaticMethod() {
        // ...
    }
}

Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod();
?> 

     
```

</div>

## Static properties

Static properties are accessed using the [Scope Resolution Operator](#language.oop5.paamayim-nekudotayim) (`::`) and cannot be accessed through the object operator (`-ENTITY`).

It's possible to reference the class using a variable. The variable's value cannot be a keyword (e.g. `self`, `parent` and `static`).

<div class="example">

<div class="title">

Static property example

</div>

```
<?php
class Foo
{
    public static $my_static = 'foo';

    public function staticValue() {
        return self::$my_static;
    }
}

class Bar extends Foo
{
    public function fooStatic() {
        return parent::$my_static;
    }
}


print Foo::$my_static . "\n";

$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n";      // Undefined "Property" my_static 

print $foo::$my_static . "\n";
$classname = 'Foo';
print $classname::$my_static . "\n";

print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() . "\n";
?>

    
```

ENTITY

    foo
    foo

    Notice: Accessing static property Foo::$my_static as non static in /in/V0Rvv on line 23

    Warning: Undefined property: Foo::$my_static in /in/V0Rvv on line 23

    foo
    foo
    foo
    foo

        

</div>

# Traits

PHP implements a way to reuse code called Traits.

Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.

A Trait is similar to a class, but only intended to group functionality in a fine-grained and consistent way. It is not possible to instantiate a Trait on its own. It is an addition to traditional inheritance and enables horizontal composition of behavior; that is, the application of class members without requiring inheritance.

<div id="language.oop5.traits.basicexample" class="example">

<div class="title">

Trait example

</div>

```
<?php

trait TraitA {
    public function sayHello() {
        echo 'Hello';
    }
}

trait TraitB {
    public function sayWorld() {
        echo 'World';
    }
}

class MyHelloWorld
{
    use TraitA, TraitB; // A class can use multiple traits

    public function sayHelloWorld() {
        $this->sayHello();
        echo ' ';
        $this->sayWorld();
        echo "!\n";
    }
}

$myHelloWorld = new MyHelloWorld();
$myHelloWorld->sayHelloWorld();

?>

    
```

ENTITY

    Hello World!

        

</div>

## Precedence

An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.

> [!NOTE]
> As of PHP 8.5.0, traits are bound to a class before its parent class; previously they were bound after. This more closely reflects the copy and paste semantics of traits. In particular, when a trait and the parent class both declare a property or constant of the same name, the trait's definition now takes precedence over the inherited one, whereas earlier versions raised a fatal error about an incompatible composition. Method resolution is unaffected. See [the migration guide](#migration85.incompatible.core.trait-binding) for details.

<div id="language.oop5.traits.precedence.examples.ex1" class="example">

<div class="title">

Precedence Order Example

</div>

An inherited method from a base class is overridden by the method inserted into MyHelloWorld from the SayWorld Trait. The behavior is the same for methods defined in the MyHelloWorld class. The precedence order is that methods from the current class override Trait methods, which in turn override methods from the base class.

```
<?php
class Base {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait SayWorld {
    public function sayHello() {
        parent::sayHello();
        echo 'World!';
    }
}

class MyHelloWorld extends Base {
    use SayWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
?>

    
```

ENTITY

    Hello World!

        

</div>

<div id="language.oop5.traits.precedence.examples.ex2" class="example">

<div class="title">

Alternate Precedence Order Example

</div>

```
<?php
trait HelloWorld {
    public function sayHello() {
        echo 'Hello World!';
    }
}

class TheWorldIsNotEnough {
    use HelloWorld;
    public function sayHello() {
        echo 'Hello Universe!';
    }
}

$o = new TheWorldIsNotEnough();
$o->sayHello();
?>

    
```

ENTITY

    Hello Universe!

        

</div>

## Multiple Traits

Multiple Traits can be inserted into a class by listing them in the `use` statement, separated by commas.

<div id="language.oop5.traits.multiple.ex1" class="example">

<div class="title">

Multiple Traits Usage

</div>

```
<?php
trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World';
    }
}

class MyHelloWorld {
    use Hello, World;
    public function sayExclamationMark() {
        echo '!';
    }
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
?>

    
```

ENTITY

    Hello World!

        

</div>

## Conflict Resolution

If two Traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.

To resolve naming conflicts between Traits used in the same class, the `insteadof` operator needs to be used to choose exactly one of the conflicting methods.

Since this only allows one to exclude methods, the `as` operator can be used to add an alias to one of the methods. Note the `as` operator does not rename the method and it does not affect any other method either.

<div id="language.oop5.traits.conflict.ex1" class="example">

<div class="title">

Conflict Resolution

</div>

In this example, Talker uses the traits A and B. Since A and B have conflicting methods, it specifies that it uses the variant of smallTalk from trait B, and the variant of bigTalk from trait A.

The Aliased_Talker makes use of the `as` operator to be able to use B's bigTalk implementation under an additional alias `talk`.

```
<?php
trait A {
    public function smallTalk() {
        echo 'a';
    }
    public function bigTalk() {
        echo 'A';
    }
}

trait B {
    public function smallTalk() {
        echo 'b';
    }
    public function bigTalk() {
        echo 'B';
    }
}

class Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
    }
}

class Aliased_Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
        B::bigTalk as talk;
    }
}
?>

    
```

</div>

## Changing Method Visibility

Using the `as` syntax, one can also adjust the visibility of the method in the exhibiting class.

<div id="language.oop5.traits.visibility.ex1" class="example">

<div class="title">

Changing Method Visibility

</div>

```
<?php
trait HelloWorld {
    public function sayHello() {
        echo 'Hello World!';
    }
}

// Change visibility of sayHello
class MyClass1 {
    use HelloWorld { sayHello as protected; }
}

// Alias method with changed visibility
// sayHello visibility not changed
class MyClass2 {
    use HelloWorld { sayHello as private myPrivateHello; }
}
?>

    
```

</div>

## Traits Composed from Traits

Just as classes can make use of traits, so can other traits. By using one or more traits in a trait definition, it can be composed partially or entirely of the members defined in those other traits.

<div id="language.oop5.traits.composition.ex1" class="example">

<div class="title">

Traits Composed from Traits

</div>

```
<?php
trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World!';
    }
}

trait HelloWorld {
    use Hello, World;
}

class MyHelloWorld {
    use HelloWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
?>

    
```

ENTITY

    Hello World!

        

</div>

## Abstract Trait Members

Traits support the use of abstract methods in order to impose requirements upon the exhibiting class. Public, protected, and private methods are supported. Prior to PHP 8.0.0, only public and protected abstract methods were supported.

> [!CAUTION]
> As of PHP 8.0.0, the signature of a concrete method must follow the [signature compatibility rules](#language.oop.lsp). Previously, its signature might be different.

<div id="language.oop5.traits.abstract.ex1" class="example">

<div class="title">

Express Requirements by Abstract Methods

</div>

```
<?php
trait Hello {
    public function sayHelloWorld() {
        echo 'Hello'.$this->getWorld();
    }
    abstract public function getWorld();
}

class MyHelloWorld {
    private $world;
    use Hello;
    public function getWorld() {
        return $this->world;
    }
    public function setWorld($val) {
        $this->world = $val;
    }
}
?>

    
```

</div>

## Static Trait Members

Traits can define static variables, static methods and static properties.

> [!NOTE]
> As of PHP 8.1.0, calling a static method, or accessing a static property directly on a trait is deprecated. Static methods and properties should only be accessed on a class using the trait.

<div id="language.oop5.traits.static.ex1" class="example">

<div class="title">

Static Variables

</div>

```
<?php

trait Counter
{
    public function inc()
    {
        static $c = 0;
        $c = $c + 1;
        echo "$c\n";
    }
}

class C1
{
    use Counter;
}

class C2
{
    use Counter;
}

$o = new C1();
$o->inc();
$p = new C2();
$p->inc();

?>

    
```

ENTITY

    1
    1

        

</div>

<div id="language.oop5.traits.static.ex2" class="example">

<div class="title">

Static Methods

</div>

```
<?php

trait StaticExample
{
    public static function doSomething()
    {
        return 'Doing something';
    }
}

class Example
{
    use StaticExample;
}

echo Example::doSomething();

?>

    
```

ENTITY

    Doing something

        

</div>

<div id="language.oop5.traits.static.ex3" class="example">

<div class="title">

Static Properties

</div>

> [!CAUTION]
> Prior to PHP 8.3.0, static properties defined in a trait were shared across all classes in the same inheritance hierarchy which used that trait. As of PHP 8.3.0, if a child class uses a trait with a static property, it will be considered distinct from the one defined in the parent class.

```
     
<?php

trait T
{
    public static $counter = 1;
}

class A
{
    use T;

    public static function incrementCounter()
    {
        static::$counter++;
    }
}

class B extends A
{
    use T;
}

A::incrementCounter();

echo A::$counter, "\n";
echo B::$counter, "\n";

?>

    
```

ENTITY

    2
    1

        

</div>

## Properties

Traits can also define properties.

<div id="language.oop5.traits.properties.example" class="example">

<div class="title">

Defining Properties

</div>

```
<?php

trait PropertiesTrait
{
    public $x = 1;
}

class PropertiesExample
{
    use PropertiesTrait;
}

$example = new PropertiesExample();
$example->x;

?>

    
```

</div>

If a trait defines a property then a class can not define a property with the same name unless it is compatible (same visibility and type, readonly modifier, and initial value), otherwise a fatal error is issued.

<div id="language.oop5.traits.properties.conflicts" class="example">

<div class="title">

Conflict Resolution

</div>

```
<?php
trait PropertiesTrait {
    public $same = true;
    public $different1 = false;
    public bool $different2;
    public bool $different3;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = true;
    public $different1 = true; // Fatal error
    public string $different2; // Fatal error
    readonly protected bool $different3; // Fatal error
}
?>

    
```

</div>

## ENTITY

Traits can, as of PHP 8.2.0, also define constants.

<div id="language.oop5.traits.constants.example" class="example">

<div class="title">

Defining Constants

</div>

```
<?php
trait ConstantsTrait {
    public const FLAG_MUTABLE = 1;
    final public const FLAG_IMMUTABLE = 5;
}

class ConstantsExample {
    use ConstantsTrait;
}

$example = new ConstantsExample;
echo $example::FLAG_MUTABLE;
?>

   
```

ENTITY

    1

        

</div>

If a trait defines a constant then a class can not define a constant with the same name unless it is compatible (same visibility, initial value, and finality), otherwise a fatal error is issued.

<div id="language.oop5.traits.constants.conflicts" class="example">

<div class="title">

Conflict Resolution

</div>

```
<?php
trait ConstantsTrait {
    public const FLAG_MUTABLE = 1;
    final public const FLAG_IMMUTABLE = 5;
}

class ConstantsExample {
    use ConstantsTrait;
    public const FLAG_IMMUTABLE = 5; // Fatal error
}
?>

   
```

</div>

## Final methods

As of PHP 8.3.0, the [final](#language.oop5.final) modifier can be applied using the `as` operator to methods imported from traits. This can be used to prevent child classes from overriding the method. However, the class that uses the trait can still override the method.

<div id="language.oop5.traits.final-methods.example" class="example">

<div class="title">

Defining a method coming from a trait as `final`

</div>

```
    
<?php

trait CommonTrait
{
    public function method()
    {
        echo 'Hello';
    }
}

class FinalExampleA
{
    use CommonTrait {
        CommonTrait::method as final; // The 'final' prevents child classes from overriding the method
    }
}

class FinalExampleB extends FinalExampleA
{
    public function method() {}
}

?>

   
```

ENTITY

    Fatal error: Cannot override final method FinalExampleA::method() in ...

        

</div>

# Covariance and Contravariance

In PHP 7.2.0, partial contravariance was introduced by removing type restrictions on parameters in a child method. As of PHP 7.4.0, full covariance and contravariance support was added.

Covariance allows a child's method to return a more specific type than the return type of its parent's method. Contravariance allows a parameter type to be less specific in a child method, than that of its parent.

A type declaration is considered more specific in the following case:

- A type is removed from a [union type](#language.types.type-system.composite.union)

- A type is added to an [intersection type](#language.types.type-system.composite.intersection)

- A class type is changed to a child class type

- `iterable` is changed to `array` or `Traversable`

A type declaration is considered less specific if the opposite is true.

## Covariance

To illustrate how covariance works, a simple abstract parent class, `Animal` is created. `Animal` will be extended by child classes, `Cat`, and `Dog`.

<div class="informalexample">

```
<?php

abstract class Animal
{
    protected string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    abstract public function speak();
}

class Dog extends Animal
{
    public function speak()
    {
        echo $this->name . " barks";
    }
}

class Cat extends Animal 
{
    public function speak()
    {
        echo $this->name . " meows";
    }
}

   
```

</div>

Note that there aren't any methods which return values in this example. A few factories will be added which return a new object of class type `Animal`, `Cat`, or `Dog`.

<div class="informalexample">

```
<?php

interface AnimalShelter
{
    public function adopt(string $name): Animal;
}

class CatShelter implements AnimalShelter
{
    public function adopt(string $name): Cat // instead of returning class type Animal, it can return class type Cat
    {
        return new Cat($name);
    }
}

class DogShelter implements AnimalShelter
{
    public function adopt(string $name): Dog // instead of returning class type Animal, it can return class type Dog
    {
        return new Dog($name);
    }
}

$kitty = (new CatShelter)->adopt("Ricky");
$kitty->speak();
echo "\n";

$doggy = (new DogShelter)->adopt("Mavrick");
$doggy->speak();

   
```

ENTITY

    Ricky meows
    Mavrick barks

       

</div>

> [!NOTE]
> As of PHP 8.5.0, when a parent method declares `static` as its return type, an overriding method in a final class may declare `self` or the class's own type as its return type instead, since these are equivalent to `static` in a class that cannot be extended further. See [the migration guide](#migration85.incompatible.core.substitute-final-subclasses) for details.

## Contravariance

Continuing with the previous example with the classes `Animal`, `Cat`, and `Dog`, a class called `Food` and `AnimalFood` will be included, and a method `eat(AnimalFood $food)` is added to the `Animal` abstract class.

<div class="informalexample">

```
<?php

class Food {}

class AnimalFood extends Food {}

abstract class Animal
{
    protected string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function eat(AnimalFood $food)
    {
        echo $this->name . " eats " . get_class($food);
    }
}

   
```

</div>

In order to see the behavior of contravariance, the `eat` method is overridden in the `Dog` class to allow any `Food` type object. The `Cat` class remains unchanged.

<div class="informalexample">

```
<?php

class Dog extends Animal
{
    public function eat(Food $food) {
        echo $this->name . " eats " . get_class($food);
    }
}

   
```

</div>

The next example will show the behavior of contravariance.

<div class="informalexample">

```
<?php

$kitty = (new CatShelter)->adopt("Ricky");
$catFood = new AnimalFood();
$kitty->eat($catFood);
echo "\n";

$doggy = (new DogShelter)->adopt("Mavrick");
$banana = new Food();
$doggy->eat($banana);

   
```

ENTITY

    Ricky eats AnimalFood
    Mavrick eats Food

       

But what happens if `$kitty` tries to eat the `$banana`?

```
$kitty->eat($banana);

   
```

ENTITY

    Fatal error: Uncaught TypeError: Argument 1 passed to Animal::eat() must be an instance of AnimalFood, instance of Food given

       

</div>

## Property variance

By default, properties are neither covariant nor contravariant, hence invariant. That is, their type may not change in a child class at all. The reason for that is "get" operations must be covariant, and "set" operations must be contravariant. The only way for a property to satisfy both requirements is to be invariant.

As of PHP 8.4.0, with the addition of abstract properties (on an interface or abstract class) and [virtual properties](#language.oop5.property-hooks.virtual), it is possible to declare a property that has only a get or set operation. As a result, abstract properties or virtual properties that have only a "get" operation required may be covariant. Similarly, an abstract property or virtual property that has only a "set" operation required may be contravariant.

Once a property has both a get and set operation, however, it is no longer covariant or contravariant for further extension. That is, it is now invariant.

<div class="example">

<div class="title">

Property type variance

</div>

```
<?php
class Animal {}
class Dog extends Animal {}
class Poodle extends Dog {}

interface PetOwner
{
    // Only a get operation is required, so this may be covariant.
    public Animal $pet { get; }
}

class DogOwner implements PetOwner
{
    // This may be a more restrictive type since the "get" side
    // still returns an Animal.  However, as a native property
    // children of this class may not change the type anymore.
    public Dog $pet;
}

class PoodleOwner extends DogOwner
{
    // This is NOT ALLOWED, because DogOwner::$pet has both
    // get and set operations defined and required.
    public Poodle $pet;
}
?>

   
```

</div>

# Visibility

The visibility of a property, a method or (as of PHP 7.1.0) a constant can be defined by prefixing the declaration with the keywords `public`, `protected` or `private`. Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inheriting and parent classes. Members declared as private may only be accessed by the class that defines the member.

## Property Visibility

Class properties may be defined as public, private, or protected. Properties declared without any explicit visibility keyword are defined as public.

<div class="example">

<div class="title">

Property declaration

</div>

```
<?php
/**
 * Define MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // We can redeclare the public and protected properties, but not private
    public $public = 'Public2';
    protected $protected = 'Protected2';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->protected; // Fatal Error
echo $obj2->private; // Undefined
$obj2->printHello(); // Shows Public2, Protected2, Undefined

?> 

    
```

</div>

### Asymmetric Property Visibility

As of PHP 8.4, object properties may also have their visibility set asymmetrically, with a different scope for reading (`get`) and writing (`set`). Specifically, the `set` visibility may be specified separately, provided it is not more permissive than the default visibility.

<div class="example">

<div class="title">

Asymmetric Property visibility

</div>

```
<?php
class Book
{
    public function __construct(
        public private(set) string $title,
        public protected(set) string $author,
        protected private(set) int $pubYear,
    ) {}
}

class SpecialBook extends Book
{
    public function update(string $author, int $year): void
    {
        $this->author = $author; // OK
        $this->pubYear = $year; // Fatal Error
    }
}

$b = new Book('How to PHP', 'Peter H. Peterson', 2024);

echo $b->title; // Works
echo $b->author; // Works
echo $b->pubYear; // Fatal Error

$b->title = 'How not to PHP'; // Fatal Error
$b->author = 'Pedro H. Peterson'; // Fatal Error
$b->pubYear = 2023; // Fatal Error
?>

     
```

</div>

As of PHP 8.5, `set` visibility may also be applied to static properties of classes.

<div class="example">

<div class="title">

Asymmetric Static Property Visibility

</div>

```
<?php
class Manager
{
    public private(set) static int $calls = 0;

    public function doAThing(): string
    {
        self::$calls++;
        // Do other stuff.
        return "some string";
    }
}

$m = new Manager();

$m->doAThing(); // Works
echo Manager::$calls; // Works
Manager::$calls = 5; // Fatal error
?>

     
```

ENTITY

    1
    Fatal error: Uncaught Error: Cannot modify private(set) property Manager::$calls from global scope in /some/file.php

         

</div>

There are a few caveats regarding asymmetric visibility:

- Only typed properties may have a separate `set` visibility.

- The `set` visibility must be the same as `get` or more restrictive. That is, `public protected(set)` and `protected protected(set)` are allowed, but `protected public(set)` will cause a syntax error.

- If a property is `public`, then the main visibility may be omitted. That is, `public private(set)` and `private(set)` will have the same result.

- A property with `private(set)` visibility is automatically `final`, and may not be redeclared in a child class.

- Obtaining a reference to a property follows `set` visibility, not `get`. That is because a reference may be used to modify the property value.

- Similarly, trying to write to an array property involves both a `get` and `set` operation internally, and therefore will follow the `set` visibility, as that is always the more restrictive.

> [!NOTE]
> Spaces are not allowed in the set-visibility declaration. `private(set)` is correct. `private( set )` is not correct and will result in a parse error.

When a class extends another, the child class may redefine any property that is not `final`. When doing so, it may widen either the main visibility or the `set` visibility, provided that the new visibility is the same or wider than the parent class. However, be aware that if a `private` property is overridden, it does not actually change the parent's property but creates a new property with a different internal name.

<div class="example">

<div class="title">

Asymmetric Property inheritance

</div>

```
<?php
class Book
{
    protected string $title;
    public protected(set) string $author;
    protected private(set) int $pubYear;
}

class SpecialBook extends Book
{
    public protected(set) string $title; // OK, as reading is wider and writing the same.
    public string $author; // OK, as reading is the same and writing is wider.
    public protected(set) int $pubYear; // Fatal Error. private(set) properties are final.
}
?>

     
```

</div>

## Method Visibility

Class methods may be defined as public, private, or protected. Methods declared without any explicit visibility keyword are defined as public.

<div class="example">

<div class="title">

Method Declaration

</div>

```
<?php
/**
 * Define MyClass
 */
class MyClass
{
    // Declare a public constructor
    public function __construct() { }

    // Declare a public method
    public function MyPublic() { }

    // Declare a protected method
    protected function MyProtected() { }

    // Declare a private method
    private function MyPrivate() { }

    // This is public
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}

$myclass = new MyClass;
$myclass->MyPublic(); // Works
$myclass->MyProtected(); // Fatal Error
$myclass->MyPrivate(); // Fatal Error
$myclass->Foo(); // Public, Protected and Private work


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // This is public
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // Fatal Error
    }
}

$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Works
$myclass2->Foo2(); // Public and Protected work, not Private

class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }

    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}

class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}

$myFoo = new Foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?>

    
```

</div>

## Constant Visibility

As of PHP 7.1.0, class constants may be defined as public, private, or protected. Constants declared without any explicit visibility keyword are defined as public.

<div class="example">

<div class="title">

Constant Declaration as of PHP 7.1.0

</div>

```
<?php
/**
 * Define MyClass
 */
class MyClass
{
    // Declare a public constant
    public const MY_PUBLIC = 'public';

    // Declare a protected constant
    protected const MY_PROTECTED = 'protected';

    // Declare a private constant
    private const MY_PRIVATE = 'private';

    public function foo()
    {
        echo self::MY_PUBLIC;
        echo self::MY_PROTECTED;
        echo self::MY_PRIVATE;
    }
}

$myclass = new MyClass();
MyClass::MY_PUBLIC; // Works
MyClass::MY_PROTECTED; // Fatal Error
MyClass::MY_PRIVATE; // Fatal Error
$myclass->foo(); // Public, Protected and Private work


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // This is public
    function foo2()
    {
        echo self::MY_PUBLIC;
        echo self::MY_PROTECTED;
        echo self::MY_PRIVATE; // Fatal Error
    }
}

$myclass2 = new MyClass2;
echo MyClass2::MY_PUBLIC; // Works
$myclass2->foo2(); // Public and Protected work, not Private
?>

    
```

</div>

## Visibility from other objects

Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects.

<div class="example">

<div class="title">

Accessing private members of the same object type

</div>

```
<?php
class Test
{
    private $foo;

    public function __construct($foo)
    {
        $this->foo = $foo;
    }

    private function bar()
    {
        echo 'Accessed the private method.';
    }

    public function baz(Test $other)
    {
        // We can change the private property:
        $other->foo = 'hello';
        var_dump($other->foo);

        // We can also call the private method:
        $other->bar();
    }
}

$test = new Test('test');

$test->baz(new Test('other'));
?>

    
```

ENTITY

    string(5) "hello"
    Accessed the private method.

        

</div>

# Operators

An operator is something that takes one or more values (or expressions, in programming jargon) and yields another value (so that the construction itself becomes an expression).

Operators can be grouped according to the number of values they take. Unary operators take only one value, for example `!` (the [logical not operator](#language.operators.logical)) or `++` (the [increment operator](#language.operators.increment)). Binary operators take two values, such as the familiar [arithmetical operators](#language.operators.arithmetic) `+` (plus) and `-` (minus), and the majority of PHP operators fall into this category. Finally, there is a single [ternary operator](#language.operators.comparison.ternary), `? :`, which takes three values; this is usually referred to simply as "the ternary operator" (although it could perhaps more properly be called the conditional operator).

A full list of PHP operators follows in the section [Operator Precedence](#language.operators.precedence). The section also explains operator precedence and associativity, which govern exactly how expressions containing several different operators are evaluated.

There is a PECL extension that allows for overloading of some operators for objects. For more information, see the [Operator Overloading for Objects](#book.operator) section.

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# Arithmetic Operators

Remember basic arithmetic from school? These work just like those.

| Example | Name | Result |
|----|----|----|
| `+$a` | Identity | Conversion of `$a` to `int` or `float` as appropriate. |
| `-$a` | Negation | Opposite of `$a`. |
| `$a + $b` | Addition | Sum of `$a` and `$b`. |
| `$a - $b` | Subtraction | Difference of `$a` and `$b`. |
| `$a * $b` | Multiplication | Product of `$a` and `$b`. |
| `$a / $b` | Division | Quotient of `$a` and `$b`. |
| `$a % $b` | Modulo | Remainder of `$a` divided by `$b`. |
| `$a ** $b` | Exponentiation | Result of raising `$a` to the `$b`'th power. |

Arithmetic Operators

The division operator `/` returns a `float` value unless the two operands are `int` (or [numeric strings](#language.types.numeric-strings) which are type juggled to `int`) and the numerator is a multiple of the divisor, in which case an integer value will be returned. For integer division, see `intdiv`.

Operands of modulo are converted to `int` before processing. For floating-point modulo, see `fmod`.

The result of the modulo operator `%` has the same sign as the dividend — that is, the result of `$a % $b` will have the same sign as `$a`. For example:

<div class="example">

<div class="title">

The Modulo Operator

</div>

```
<?php
var_dump(5 % 3);
var_dump(5 % -3);
var_dump(-5 % 3);
var_dump(-5 % -3);
?>

   
```

ENTITY

    int(2)
    int(2)
    int(-2)
    int(-2)

       

</div>

## 

ENTITY

[Math functions](#ref.math)

# Array Operators

| Example | Name | Result |
|----|----|----|
| \$a + \$b | Union | Union of `$a` and `$b`. |
| \$a == \$b | Equality | ENTITY if `$a` and `$b` have the same key/value pairs. |
| \$a === \$b | Identity | ENTITY if `$a` and `$b` have the same key/value pairs in the same order and of the same types. |
| \$a != \$b | Inequality | ENTITY if `$a` is not equal to `$b`. |
| \$a ENTITYENTITY \$b | Inequality | ENTITY if `$a` is not equal to `$b`. |
| \$a !== \$b | Non-identity | ENTITY if `$a` is not identical to `$b`. |

Array Operators

The `+` operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored.

<div class="example">

<div class="title">

Array Append Operator

</div>

```
<?php
$a = array("a" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");

$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);

$c = $b + $a; // Union of $b and $a
echo "Union of \$b and \$a: \n";
var_dump($c);

$a += $b; // Union of $a += $b is $a and $b
echo "Union of \$a += \$b: \n";
var_dump($a);
?>

   
```

ENTITY

```
Union of $a and $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}
Union of $b and $a:
array(3) {
  ["a"]=>
  string(4) "pear"
  ["b"]=>
  string(10) "strawberry"
  ["c"]=>
  string(6) "cherry"
}
Union of $a += $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}

   
```

</div>

Elements of arrays are equal for the comparison if they have the same key and value.

<div class="example">

<div class="title">

Comparing arrays

</div>

```
<?php
$a = array("apple", "banana");
$b = array(1 => "banana", "0" => "apple");

var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>

   
```

</div>

## 

ENTITY

[Array type](#language.types.array), [Array functions](#ref.array)

# Assignment Operators

The basic assignment operator is "=". Your first inclination might be to think of this as "equal to". Don't. It really means that the left operand gets set to the value of the expression on the right (that is, "gets set to").

The value of an assignment expression is the value assigned. That is, the value of "`$a = 3`" is 3. This allows you to do some tricky things:

<div class="example">

<div class="title">

Nested Assignments

</div>

```
<?php
$a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.
var_dump($a);
?>

   
```

</div>

In addition to the basic assignment operator, there are "combined operators" for all of the [binary arithmetic](#language.operators), array union and string operators that allow you to use a value in an expression and then set its value to the result of that expression. For example:

<div class="example">

<div class="title">

Combined Assignments

</div>

```
<?php
$a = 3;
$a += 5; // sets $a to 8, as if we had said: $a = $a + 5;
$b = "Hello ";
$b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!";

var_dump($a, $b);
?>

   
```

</div>

Note that the assignment copies the original variable to the new one (assignment by value), so changes to one will not affect the other. This may also have relevance if you need to copy something like a large array inside a tight loop.

An exception to the usual assignment by value behaviour within PHP occurs with `object`s, which are assigned by reference. Objects may be explicitly copied via the [clone](#language.oop5.cloning) keyword.

## Assignment by Reference

Assignment by reference is also supported, using the "`$var = ENTITY$othervar;`" syntax. Assignment by reference means that both variables end up pointing at the same data, and nothing is copied anywhere.

<div class="example">

<div class="title">

Assigning by reference

</div>

```
<?php
$a = 3;
$b = &$a; // $b is a reference to $a

print "$a\n"; // prints 3
print "$b\n"; // prints 3

$a = 4; // change $a

print "$a\n"; // prints 4
print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has
              // been changed
?>

    
```

</div>

The [new](#language.oop5.basic.new) operator returns a reference automatically, as such assigning the result of [new](#language.oop5.basic.new) by reference is an error.

<div class="example">

<div class="title">

new Operator By-Reference

</div>

```
<?php
class C {}

$o = &new C;
?>

    
```

ENTITY

    Parse error: syntax error, unexpected token ";", expecting "("

        

</div>

More information on references and their potential uses can be found in the [References Explained](#language.references) section of the manual.

## Arithmetic Assignment Operators

| Example       | Equivalent         | Operation      |
|---------------|--------------------|----------------|
| \$a += \$b    | \$a = \$a + \$b    | Addition       |
| \$a -= \$b    | \$a = \$a - \$b    | Subtraction    |
| \$a \*= \$b   | \$a = \$a \* \$b   | Multiplication |
| \$a /= \$b    | \$a = \$a / \$b    | Division       |
| \$a %= \$b    | \$a = \$a % \$b    | Modulus        |
| \$a \*\*= \$b | \$a = \$a \*\* \$b | Exponentiation |

## Bitwise Assignment Operators

| Example               | Equivalent                 | Operation   |
|-----------------------|----------------------------|-------------|
| \$a ENTITY= \$b       | \$a = \$a ENTITY \$b       | Bitwise And |
| \$a \|= \$b           | \$a = \$a \| \$b           | Bitwise Or  |
| \$a ^= \$b            | \$a = \$a ^ \$b            | Bitwise Xor |
| \$a ENTITYENTITY= \$b | \$a = \$a ENTITYENTITY \$b | Left Shift  |
| \$a ENTITYENTITY= \$b | \$a = \$a ENTITYENTITY \$b | Right Shift |

## Other Assignment Operators

| Example     | Equivalent       | Operation            |
|-------------|------------------|----------------------|
| \$a .= \$b  | \$a = \$a . \$b  | String Concatenation |
| \$a ??= \$b | \$a = \$a ?? \$b | Null Coalesce        |

## 

ENTITY

[arithmetic operators](#language.operators.arithmetic), [bitwise operators](#language.operators.bitwise), [null coalescing operator](#language.operators.comparison.coalesce)

# Bitwise Operators

Bitwise operators allow evaluation and manipulation of specific bits within an integer.

| Example | Name | Result |
|----|----|----|
| `$a ENTITY $b` | And | Bits that are set in both `$a` and `$b` are set. |
| `$a | $b` | Or (inclusive or) | Bits that are set in either `$a` or `$b` are set. |
| `$a ^ $b` | Xor (exclusive or) | Bits that are set in `$a` or `$b` but not both are set. |
| `~ $a` | Not | Bits that are set in `$a` are not set, and vice versa. |
| `$a ENTITYENTITY $b` | Shift left | Shift the bits of `$a` `$b` steps to the left (each step means "multiply by two") |
| `$a ENTITYENTITY $b` | Shift right | Shift the bits of `$a` `$b` steps to the right (each step means "divide by two") |

Bitwise Operators

Bit shifting in PHP is arithmetic. Bits shifted off either end are discarded. Left shifts have zeros shifted in on the right while the sign bit is shifted out on the left, meaning the sign of an operand is not preserved. Right shifts have copies of the sign bit shifted in on the left, meaning the sign of an operand is preserved.

Use parentheses to ensure the desired [precedence](#language.operators.precedence). For example, `$a ENTITY $b == true` evaluates the equivalency then the bitwise and; while `($a ENTITY $b) == true` evaluates the bitwise and then the equivalency.

If both operands for the `ENTITY`, `|` and `^` operators are strings, then the operation will be performed on the ASCII values of the characters that make up the strings and the result will be a string. In all other cases, both operands will be [converted to integers](#language.types.integer.casting) and the result will be an integer.

If the operand for the `~` operator is a string, the operation will be performed on the ASCII values of the characters that make up the string and the result will be a string, otherwise the operand and the result will be treated as integers.

Both operands and the result for the `ENTITYENTITY` and `ENTITYENTITY` operators are always treated as integers.

PHP's error_reporting ini setting uses bitwise values, providing a real-world demonstration of turning bits off. To show all errors, except for notices, the php.ini file instructions say to use: `E_ALL ENTITY ~E_NOTICE`

<div class="informalexample">

\
     This works by starting with E_ALL:\
     `00000000000000000111011111111111`\
     Then taking the value of E_NOTICE...\
     `00000000000000000000000000001000`\
     ... and inverting it via `~`:\
     `11111111111111111111111111110111`\
     Finally, it uses AND (ENTITY) to find the bits turned\
     on in both values:\
     `00000000000000000111011111110111`\
    

</div>

Another way to accomplish that is using XOR (`^`) to find bits that are on in only one value or the other: `E_ALL ^ E_NOTICE`

error_reporting can also be used to demonstrate turning bits on. The way to show just errors and recoverable errors is: `E_ERROR | E_RECOVERABLE_ERROR`

<div class="informalexample">

\
     This process combines E_ERROR\
     `00000000000000000000000000000001`\
     and\
     `00000000000000000001000000000000`\
     using the OR (`|`) operator\
     to get the bits turned on in either value:\
     `00000000000000000001000000000001`\
    

</div>

<div class="example">

<div class="title">

Bitwise AND, OR and XOR operations on integers

</div>

```
<?php
/*
 * Ignore the top section,
 * it is just formatting to make output clearer.
 */

$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
        . ' %3$s (%4$2d = %4$04b)' . "\n";

echo <<<EOH
 ---------     ---------  -- ---------
 result        value      op test
 ---------     ---------  -- ---------
EOH;


/*
 * Here are the examples.
 */

$values = array(0, 1, 2, 4, 8);
$test = 1 + 4;

echo "\n Bitwise AND \n";
foreach ($values as $value) {
    $result = $value & $test;
    printf($format, $result, $value, '&', $test);
}

echo "\n Bitwise Inclusive OR \n";
foreach ($values as $value) {
    $result = $value | $test;
    printf($format, $result, $value, '|', $test);
}

echo "\n Bitwise Exclusive OR (XOR) \n";
foreach ($values as $value) {
    $result = $value ^ $test;
    printf($format, $result, $value, '^', $test);
}
?>

   
```

ENTITY

     ---------     ---------  -- ---------
     result        value      op test
     ---------     ---------  -- ---------
     Bitwise AND
    ( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
    ( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
    ( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
    ( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
    ( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)

     Bitwise Inclusive OR
    ( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
    ( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
    ( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
    ( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
    (13 = 1101) = ( 8 = 1000) | ( 5 = 0101)

     Bitwise Exclusive OR (XOR)
    ( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
    ( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
    ( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
    ( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
    (13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)

       

</div>

<div class="example">

<div class="title">

Bitwise XOR operations on strings

</div>

```
<?php
echo 12 ^ 9, PHP_EOL; // Outputs '5'

echo "12" ^ "9", PHP_EOL; // Outputs the Backspace character (ascii 8)
                          // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8

echo "hallo" ^ "hello", PHP_EOL; // Outputs the ascii values #0 #4 #0 #0 #0
                                 // 'a' ^ 'e' = #4

echo 2 ^ "3", PHP_EOL; // Outputs 1
                       // 2 ^ ((int) "3") == 1

echo "2" ^ 3, PHP_EOL; // Outputs 1
                       // ((int) "2") ^ 3 == 1
?>

   
```

</div>

<div class="example">

<div class="title">

Bit shifting on integers

</div>

```
<?php
/*
 * Here are the examples.
 */

echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";

$val = 4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');

$val = 4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places);

$val = 4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');

$val = 4;
$places = 4;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0');


echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";

$val = -4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');

$val = -4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');

$val = -4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');


echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";

$val = 4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 4;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = 4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places, 'sign bits get shifted out');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side');


echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";

$val = -4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');

$val = -4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = -4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');


/*
 * Ignore this bottom section,
 * it is just formatting to make output clearer.
 */

function p($res, $val, $op, $places, $note = '') {
    $format = '%0' . (PHP_INT_SIZE * 8) . "b\n";

    printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);

    echo " Decimal:\n";
    printf("  val=%d\n", $val);
    printf("  res=%d\n", $res);

    echo " Binary:\n";
    printf('  val=' . $format, $val);
    printf('  res=' . $format, $res);

    if ($note) {
        echo " NOTE: $note\n";
    }

    echo "\n\n";
}
?>

   
```

ENTITY

    --- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
    Expression: 2 = 4 >> 1
     Decimal:
      val=4
      res=2
     Binary:
      val=00000000000000000000000000000100
      res=00000000000000000000000000000010
     NOTE: copy of sign bit shifted into left side

    Expression: 1 = 4 >> 2
     Decimal:
      val=4
      res=1
     Binary:
      val=00000000000000000000000000000100
      res=00000000000000000000000000000001

    Expression: 0 = 4 >> 3
     Decimal:
      val=4
      res=0
     Binary:
      val=00000000000000000000000000000100
      res=00000000000000000000000000000000
     NOTE: bits shift out right side

    Expression: 0 = 4 >> 4
     Decimal:
      val=4
      res=0
     Binary:
      val=00000000000000000000000000000100
      res=00000000000000000000000000000000
     NOTE: same result as above; can not shift beyond 0


    --- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
    Expression: -2 = -4 >> 1
     Decimal:
      val=-4
      res=-2
     Binary:
      val=11111111111111111111111111111100
      res=11111111111111111111111111111110
     NOTE: copy of sign bit shifted into left side

    Expression: -1 = -4 >> 2
     Decimal:
      val=-4
      res=-1
     Binary:
      val=11111111111111111111111111111100
      res=11111111111111111111111111111111
     NOTE: bits shift out right side

    Expression: -1 = -4 >> 3
     Decimal:
      val=-4
      res=-1
     Binary:
      val=11111111111111111111111111111100
      res=11111111111111111111111111111111
     NOTE: same result as above; can not shift beyond -1


    --- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
    Expression: 8 = 4 << 1
     Decimal:
      val=4
      res=8
     Binary:
      val=00000000000000000000000000000100
      res=00000000000000000000000000001000
     NOTE: zeros fill in right side

    Expression: 1073741824 = 4 << 28
     Decimal:
      val=4
      res=1073741824
     Binary:
      val=00000000000000000000000000000100
      res=01000000000000000000000000000000

    Expression: -2147483648 = 4 << 29
     Decimal:
      val=4
      res=-2147483648
     Binary:
      val=00000000000000000000000000000100
      res=10000000000000000000000000000000
     NOTE: sign bits get shifted out

    Expression: 0 = 4 << 30
     Decimal:
      val=4
      res=0
     Binary:
      val=00000000000000000000000000000100
      res=00000000000000000000000000000000
     NOTE: bits shift out left side


    --- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
    Expression: -8 = -4 << 1
     Decimal:
      val=-4
      res=-8
     Binary:
      val=11111111111111111111111111111100
      res=11111111111111111111111111111000
     NOTE: zeros fill in right side

    Expression: -2147483648 = -4 << 29
     Decimal:
      val=-4
      res=-2147483648
     Binary:
      val=11111111111111111111111111111100
      res=10000000000000000000000000000000

    Expression: 0 = -4 << 30
     Decimal:
      val=-4
      res=0
     Binary:
      val=11111111111111111111111111111100
      res=00000000000000000000000000000000
     NOTE: bits shift out left side, including sign bit

       

ENTITY

    --- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
    Expression: 2 = 4 >> 1
     Decimal:
      val=4
      res=2
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=0000000000000000000000000000000000000000000000000000000000000010
     NOTE: copy of sign bit shifted into left side

    Expression: 1 = 4 >> 2
     Decimal:
      val=4
      res=1
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=0000000000000000000000000000000000000000000000000000000000000001

    Expression: 0 = 4 >> 3
     Decimal:
      val=4
      res=0
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=0000000000000000000000000000000000000000000000000000000000000000
     NOTE: bits shift out right side

    Expression: 0 = 4 >> 4
     Decimal:
      val=4
      res=0
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=0000000000000000000000000000000000000000000000000000000000000000
     NOTE: same result as above; can not shift beyond 0


    --- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
    Expression: -2 = -4 >> 1
     Decimal:
      val=-4
      res=-2
     Binary:
      val=1111111111111111111111111111111111111111111111111111111111111100
      res=1111111111111111111111111111111111111111111111111111111111111110
     NOTE: copy of sign bit shifted into left side

    Expression: -1 = -4 >> 2
     Decimal:
      val=-4
      res=-1
     Binary:
      val=1111111111111111111111111111111111111111111111111111111111111100
      res=1111111111111111111111111111111111111111111111111111111111111111
     NOTE: bits shift out right side

    Expression: -1 = -4 >> 3
     Decimal:
      val=-4
      res=-1
     Binary:
      val=1111111111111111111111111111111111111111111111111111111111111100
      res=1111111111111111111111111111111111111111111111111111111111111111
     NOTE: same result as above; can not shift beyond -1


    --- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
    Expression: 8 = 4 << 1
     Decimal:
      val=4
      res=8
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=0000000000000000000000000000000000000000000000000000000000001000
     NOTE: zeros fill in right side

    Expression: 4611686018427387904 = 4 << 60
     Decimal:
      val=4
      res=4611686018427387904
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=0100000000000000000000000000000000000000000000000000000000000000

    Expression: -9223372036854775808 = 4 << 61
     Decimal:
      val=4
      res=-9223372036854775808
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=1000000000000000000000000000000000000000000000000000000000000000
     NOTE: sign bits get shifted out

    Expression: 0 = 4 << 62
     Decimal:
      val=4
      res=0
     Binary:
      val=0000000000000000000000000000000000000000000000000000000000000100
      res=0000000000000000000000000000000000000000000000000000000000000000
     NOTE: bits shift out left side


    --- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
    Expression: -8 = -4 << 1
     Decimal:
      val=-4
      res=-8
     Binary:
      val=1111111111111111111111111111111111111111111111111111111111111100
      res=1111111111111111111111111111111111111111111111111111111111111000
     NOTE: zeros fill in right side

    Expression: -9223372036854775808 = -4 << 61
     Decimal:
      val=-4
      res=-9223372036854775808
     Binary:
      val=1111111111111111111111111111111111111111111111111111111111111100
      res=1000000000000000000000000000000000000000000000000000000000000000

    Expression: 0 = -4 << 62
     Decimal:
      val=-4
      res=0
     Binary:
      val=1111111111111111111111111111111111111111111111111111111111111100
      res=0000000000000000000000000000000000000000000000000000000000000000
     NOTE: bits shift out left side, including sign bit

       

</div>

> [!WARNING]
> Use functions from the [gmp](#book.gmp) extension for bitwise manipulation on numbers beyond `PHP_INT_MAX`.

## 

ENTITY

`pack`, `unpack`, `gmp_and`, `gmp_or`, `gmp_xor`, `gmp_testbit`, `gmp_clrbit`

# Comparison Operators

Comparison operators, as their name implies, allow you to compare two values. You may also be interested in viewing [the type comparison tables](#types.comparisons), as they show examples of various type related comparisons.

| Example | Name | Result |
|----|----|----|
| \$a == \$b | Equal | ENTITY if `$a` is equal to `$b` after type juggling. |
| \$a === \$b | Identical | ENTITY if `$a` is equal to `$b`, and they are of the same type. |
| \$a != \$b | Not equal | ENTITY if `$a` is not equal to `$b` after type juggling. |
| \$a ENTITYENTITY \$b | Not equal | ENTITY if `$a` is not equal to `$b` after type juggling. |
| \$a !== \$b | Not identical | ENTITY if `$a` is not equal to `$b`, or they are not of the same type. |
| \$a ENTITY \$b | Less than | ENTITY if `$a` is strictly less than `$b`. |
| \$a ENTITY \$b | Greater than | ENTITY if `$a` is strictly greater than `$b`. |
| \$a ENTITY= \$b | Less than or equal to | ENTITY if `$a` is less than or equal to `$b`. |
| \$a ENTITY= \$b | Greater than or equal to | ENTITY if `$a` is greater than or equal to `$b`. |
| \$a ENTITY=ENTITY \$b | Spaceship | An `int` less than, equal to, or greater than zero when `$a` is less than, equal to, or greater than `$b`, respectively. |

Comparison Operators

If both operands are [numeric strings](#language.types.numeric-strings), or one operand is a number and the other one is a [numeric string](#language.types.numeric-strings), then the comparison is done numerically. These rules also apply to the [switch](#control-structures.switch) statement. The type conversion does not take place when the comparison is `===` or `!==` as this involves comparing the type as well as the value.

> [!WARNING]
> Prior to PHP 8.0.0, if a `string` is compared to a number or a numeric string then the `string` was converted to a number before performing the comparison. This can lead to surprising results as can be seen with the following example:
>
> <div class="informalexample">
>
> ```
> <?php
> var_dump(0 == "a");
> var_dump("1" == "01");
> var_dump("10" == "1e1");
> var_dump(100 == "1e2");
>
> switch ("a") {
> case 0:
>     echo "0";
>     break;
> case "a":
>     echo "a";
>     break;
> }
> ?>
>
>     
> ```
>
> ENTITY
>
>     bool(true)
>     bool(true)
>     bool(true)
>     bool(true)
>     0
>
>         
>
> ENTITY
>
>     bool(false)
>     bool(true)
>     bool(true)
>     bool(true)
>     a
>
>         
>
> </div>

<div class="example">

<div class="title">

Comparison Operators

</div>

```
<?php
// Integers
echo 1 <=> 1, ' '; // 0
echo 1 <=> 2, ' '; // -1
echo 2 <=> 1, ' '; // 1

// Floats
echo 1.5 <=> 1.5, ' '; // 0
echo 1.5 <=> 2.5, ' '; // -1
echo 2.5 <=> 1.5, ' '; // 1

// Strings
echo "a" <=> "a", ' '; // 0
echo "a" <=> "b", ' '; // -1
echo "b" <=> "a", ' '; // 1

echo "a" <=> "aa", ' ';  // -1
echo "zz" <=> "aa", ' '; // 1

// Arrays
echo [] <=> [], ' ';               // 0
echo [1, 2, 3] <=> [1, 2, 3], ' '; // 0
echo [1, 2, 3] <=> [], ' ';        // 1
echo [1, 2, 3] <=> [1, 2, 1], ' '; // 1
echo [1, 2, 3] <=> [1, 2, 4], ' '; // -1

// Objects
$a = (object) ["a" => "b"];
$b = (object) ["a" => "b"];
echo $a <=> $b, ' '; // 0

$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo $a <=> $b, ' '; // -1

$a = (object) ["a" => "c"];
$b = (object) ["a" => "b"];
echo $a <=> $b, ' '; // 1

// not only values are compared; keys must match
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo $a <=> $b, ' '; // 1

?>

   
```

</div>

For various types, comparison is done according to the following table (in order).

| Type of Operand 1 | Type of Operand 2 | Result |
|----|----|----|
| `null` or `string` | `string` | Convert ENTITY to "", numerical or lexical comparison |
| `bool` or `null` | anything | Convert both sides to `bool`, ENTITY ENTITY ENTITY |
| `object` | `object` | Built-in classes can define its own comparison, different classes are incomparable, same class see [Object Comparison](#language.oop5.object-comparison) |
| `string`, `resource`, `int` or `float` | `string`, `resource`, `int` or `float` | Translate strings and resources to numbers, usual math |
| `array` | `array` | Array with fewer members is smaller, if key from operand 1 is not found in operand 2 then arrays are incomparable, otherwise - compare value by value (see following example) |
| `object` | anything | `object` is always greater |
| `array` | anything | `array` is always greater |

Comparison with Various Types {#language.operators.comparison.types}

<div class="example">

<div class="title">

Boolean/null comparison

</div>

```
<?php
// Bool and null are compared as bool always
var_dump(1 == TRUE);  // TRUE - same as (bool) 1 == TRUE
var_dump(0 == FALSE); // TRUE - same as (bool) 0 == FALSE
var_dump(100 < TRUE); // FALSE - same as (bool) 100 < TRUE
var_dump(-10 < FALSE);// FALSE - same as (bool) -10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool) NULL < (bool) -100 is FALSE < TRUE
?>

   
```

</div>

<div class="example">

<div class="title">

Transcription of standard array comparison

</div>

```
<?php
// Arrays are compared like this with standard comparison operators as well as the spaceship operator.
function standard_array_compare($op1, $op2)
{
    if (count($op1) < count($op2)) {
        return -1; // $op1 < $op2
    } elseif (count($op1) > count($op2)) {
        return 1; // $op1 > $op2
    }
    foreach ($op1 as $key => $val) {
        if (!array_key_exists($key, $op2)) {
            return 1;
        } elseif ($val < $op2[$key]) {
            return -1;
        } elseif ($val > $op2[$key]) {
            return 1;
        }
    }
    return 0; // $op1 == $op2
}
?>

   
```

</div>

> [!WARNING]
> Because of the way `float`s are represented internally, you should not test two `float`s for equality.
>
> See the documentation for `float` for more information.

> [!NOTE]
> Be aware that PHP's type juggling is not always obvious when comparing values of different types, particularly comparing ENTITYs to ENTITYs or ENTITYs to ENTITYs. It is therefore generally advisable to use `===` and `!==` comparisons rather than `==` and `!=` in most cases.

> [!NOTE]
> Encountering recursion during comparison, for example when comparing an array or object that contains a reference to itself, throws an Error as of PHP 8.4.0; previously, it resulted in a fatal error.

## Incomparable Values

While identity comparison (`===` and `!==`) can be applied to arbitrary values, the other comparison operators should only be applied to comparable values. The result of comparing incomparable values is undefined, and should not be relied upon.

> [!NOTE]
> As of PHP 8.5.0, loosely comparing an `object` that is not comparable (such as an enum, `CurlHandle`, or another internal class) against a `bool` using `==` or `!=` consistently evaluates as if the object were cast to `bool`, that is `(bool) $object`. Because such an object always casts to ENTITY, it is equal to ENTITY and not equal to ENTITY. Prior to PHP 8.5.0, this only applied when comparing against a boolean literal (`$object == true`); comparing against a boolean value held in a variable always returned ENTITY. See [the migration guide](#migration85.incompatible.core.loosely-comparing-object) for details.

## 

ENTITY

`strcasecmp`, `strcmp`, [Array operators](#language.operators.array), [Types](#language.types)

## Ternary Operator

Another conditional operator is the "?:" (or ternary) operator.

<div class="example">

<div class="title">

Assigning a default value

</div>

```
<?php
// Example usage for: Ternary Operator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];

// The above is identical to this if/else statement
if (empty($_POST['action'])) {
    $action = 'default';
} else {
    $action = $_POST['action'];
}
?>

    
```

</div>

The expression `(expr1) ? (expr2) : (expr3)` evaluates to \<expr2\> if \<expr1\> evaluates to ENTITY, and \<expr3\> if \<expr1\> evaluates to ENTITY.

It is possible to leave out the middle part of the ternary operator. Expression `expr1 ?: expr3` evaluates to the result of \<expr1\> if \<expr1\> evaluates to ENTITY, and \<expr3\> otherwise. \<expr1\> is only evaluated once in this case.

> [!NOTE]
> Please note that the ternary operator is an expression, and that it doesn't evaluate to a variable, but to the result of an expression. This is important to know if you want to return a variable by reference. The statement `return $var == 42 ? $a : $b;` in a return-by-reference function will therefore not work and a warning is issued.

> [!NOTE]
> It is recommended to avoid "stacking" ternary expressions. PHP's behaviour when using more than one unparenthesized ternary operator within a single expression is non-obvious compared to other languages. Indeed prior to PHP 8.0.0, ternary expressions were evaluated left-associative, instead of right-associative like most other programming languages. Relying on left-associativity is deprecated as of PHP 7.4.0. As of PHP 8.0.0, the ternary operator is non-associative.
>
> <div class="example">
>
> <div class="title">
>
> Non-obvious Ternary Behaviour
>
> </div>
>
> ```
> <?php
> // on first glance, the following appears to output 'true'
> echo (true ? 'true' : false ? 't' : 'f');
>
> // however, the actual output of the above is 't' prior to PHP 8.0.0
> // this is because ternary expressions are left-associative
>
> // the following is a more obvious version of the same code as above
> echo ((true ? 'true' : false) ? 't' : 'f');
>
> // here, one can see that the first expression is evaluated to 'true', which
> // in turn evaluates to (bool) true, thus returning the true branch of the
> // second ternary expression.
> ?>
>
>      
> ```
>
> </div>

> [!NOTE]
> Chaining of short-ternaries (`?:`), however, is stable and behaves reasonably. It will evaluate to the first argument that evaluates to a non-falsy value. Note that undefined values will still raise a warning.
>
> <div class="example">
>
> <div class="title">
>
> Short-ternary chaining
>
> </div>
>
> ```
> <?php
> echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
> echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2
> echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
> ?>
>
>      
> ```
>
> </div>

## Null Coalescing Operator

Another useful shorthand operator is the "??" (or null coalescing) operator.

<div class="example">

<div class="title">

Assigning a default value

</div>

```
<?php
// Example usage for: Null Coalesce Operator
$action = $_POST['action'] ?? 'default';

// The above is identical to this if/else statement
if (isset($_POST['action'])) {
    $action = $_POST['action'];
} else {
    $action = 'default';
}
?>

    
```

</div>

The expression `(expr1) ?? (expr2)` evaluates to \<expr2\> if \<expr1\> is ENTITY, and \<expr1\> otherwise.

In particular, this operator does not emit a notice or warning if the left-hand side value does not exist, just like `isset`. This is especially useful on array keys.

> [!NOTE]
> Please note that the null coalescing operator is an expression, and that it doesn't evaluate to a variable, but to the result of an expression. This is important to know if you want to return a variable by reference. The statement `return $foo ?? $bar;` in a return-by-reference function will therefore not work and a warning is issued.

> [!NOTE]
> The null coalescing operator has low precedence. That means if mixing it with other operators (such as string concatenation or arithmetic operators) parentheses will likely be required.
>
> ```
> <?php
> // Raises a warning that $name is undefined.
> print 'Mr. ' . $name ?? 'Anonymous';
>
> // Prints "Mr. Anonymous"
> print 'Mr. ' . ($name ?? 'Anonymous');
> ?>
>
>    
> ```

> [!NOTE]
> Please note that the null coalescing operator allows for simple nesting:
>
> <div class="example">
>
> <div class="title">
>
> Nesting null coalescing operator
>
> </div>
>
> ```
> <?php
>
> $foo = null;
> $bar = null;
> $baz = 1;
> $qux = 2;
>
> echo $foo ?? $bar ?? $baz ?? $qux; // outputs 1
>
> ?>
>
>      
> ```
>
> </div>

# Error Control Operators

PHP supports one error control operator: the at sign (`@`). When prepended to an expression in PHP, any diagnostic error that might be generated by that expression will be suppressed.

If a custom error handler function is set with `set_error_handler`, it will still be called even though the diagnostic has been suppressed.

> [!WARNING]
> Prior to PHP 8.0.0, the `error_reporting` called inside the custom error handler always returned `0` if the error was suppressed by the `@` operator. As of PHP 8.0.0, it returns the value of this (bitwise) expression: `E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE`.

Any error message generated by the expression is available in the `"message"` element of the array returned by `error_get_last`. The result of that function will change on each error, so it needs to be checked early.

<div class="example">

<div class="title">

Intentional file error

</div>

```
<?php
$my_file = @file ('non_existent_file') or
    die ("Failed opening file: error was '" . error_get_last()['message'] . "'");
?>

   
```

</div>

<div class="example">

<div class="title">

Suppressing Expressions

</div>

```
<?php
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?>

   
```

</div>

> [!NOTE]
> The `@`-operator works only on [expressions](#language.expressions). A simple rule of thumb is: if one can take the value of something, then one can prepend the `@` operator to it. For instance, it can be prepended to variables, functions calls, certain language construct calls (e.g. `include`), and so forth. It cannot be prepended to function or class definitions, or conditional structures such as `if` and ENTITY, and so forth.

> [!WARNING]
> Prior to PHP 8.0.0, it was possible for the `@` operator to disable critical errors that will terminate script execution. For example, prepending `@` to a call of a function which did not exist, by being unavailable or mistyped, would cause the script to terminate with no indication as to why.

## 

ENTITY

`error_reporting`, [Error Handling and Logging functions](#ref.errorfunc)

# Execution Operators

PHP supports one execution operator: backticks (``` `` ```). Note that these are not single-quotes! PHP will attempt to execute the contents of the backticks as a shell command; the output will be returned (i.e., it won't simply be dumped to output; it can be assigned to a variable). Use of the backtick operator is identical to `shell_exec`.

<div class="example">

<div class="title">

Backtick Operator

</div>

```
<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>

   
```

</div>

> [!NOTE]
> The backtick operator is disabled when `shell_exec` is disabled.

> [!NOTE]
> Unlike some other languages, backticks have no special meaning within double-quoted strings.

## 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | The backtick operator as an alias for `shell_exec` has been deprecated. |

## 

ENTITY

[Program Execution functions](#ref.exec), `popen`, `proc_open`, [Using PHP from the commandline](#features.commandline)

# Functional Operators

PHP 8.5 and later supports one operator that works directly on callables. The `|ENTITY` operator, or “pipe,” accepts a single-parameter callable on the right and passes the left-side value to it, evaluating to the callable's result. The callable on the right may be any valid PHP callable: a `Closure`, a [first-class callable](#functions.first_class_callable_syntax), an object that implements [\_\_invoke()](#object.invoke), etc.

That means the following two lines are logically equivalent.

<div class="example">

<div class="title">

Using `|ENTITY`

</div>

```
<?php
$result = "Hello World" |> strlen(...);
echo $result, PHP_EOL;

$result = strlen("Hello World");
echo $result, PHP_EOL;
?>

   
```

ENTITY

    11
    11

       

</div>

For a single call that is not especially useful. It becomes useful when multiple calls are chained together. That is, the following two code fragments are logically equivalent:

<div class="example">

<div class="title">

Chaining \|ENTITY calls

</div>

```
<?php
$result = "PHP Rocks"
    |> htmlentities(...)
    |> str_split(...)
    |> (fn($x) => array_map(strtoupper(...), $x))
    |> (fn($x) => array_filter($x, fn($v) => $v != 'O'))
;
print_r($result);

$temp = "PHP Rocks";
$temp = htmlentities($temp);
$temp = str_split($temp);
$temp = array_map(strtoupper(...), $temp);
$temp = array_filter($temp, fn($v) => $v != 'O');
$result = $temp;
print_r($result);
?>

   
```

ENTITY

    Array
    (
        [0] => P
        [1] => H
        [2] => P
        [3] =>
        [4] => R
        [6] => C
        [7] => K
        [8] => S
    )
    Array
    (
        [0] => P
        [1] => H
        [2] => P
        [3] =>
        [4] => R
        [6] => C
        [7] => K
        [8] => S
    )

       

</div>

The left-hand side of the pipe may be any value or expression. The right-hand side may be any valid PHP callable that takes a single parameter, or any expression that evaluates to such a callable. Functions with more than one required parameter are not allowed and will fail as if the function were called normally with insufficient arguments. Functions that take a variable by reference are not allowed. If the right-hand side does not evaluate to a valid callable it will throw an Error.

> [!NOTE]
> Be aware that, to avoid syntax ambiguity, [arrow functions](#functions.arrow) MUST be wrapped in parentheses when used with a pipe operator, as in the examples above. Failing to do so will result in a fatal error.

## 

ENTITY

`Closure`

# Incrementing/Decrementing Operators

PHP supports pre- and post-increment and decrement operators. Those unary operators allow to increment or decrement the value by one.

| Example | Name           | Effect                                     |
|---------|----------------|--------------------------------------------|
| ++\$a   | Pre-increment  | Increments `$a` by one, then returns `$a`. |
| \$a++   | Post-increment | Returns `$a`, then increments `$a` by one. |
| --\$a   | Pre-decrement  | Decrements `$a` by one, then returns `$a`. |
| \$a--   | Post-decrement | Returns `$a`, then decrements `$a` by one. |

Increment/decrement Operators

<div class="example">

<div class="title">

Examples of Increment/Decrement

</div>

```
<?php
echo 'Post-increment:', PHP_EOL;
$a = 5;
var_dump($a++);
var_dump($a);

echo 'Pre-increment:', PHP_EOL;
$a = 5;
var_dump(++$a);
var_dump($a);

echo 'Post-decrement:', PHP_EOL;
$a = 5;
var_dump($a--);
var_dump($a);

echo 'Pre-decrement:', PHP_EOL;
$a = 5;
var_dump(--$a);
var_dump($a);
?>

   
```

ENTITY

    Post-increment:
    int(5)
    int(6)
    Pre-increment:
    int(6)
    int(6)
    Post-decrement:
    int(5)
    int(4)
    Pre-decrement:
    int(4)
    int(4)

       

</div>

> [!WARNING]
> The increment and decrement operators have no effect on values of type `bool`. A `E_WARNING` is emitted as of PHP 8.3.0, because this will implicitly cast the value to `int` in the future.
>
> The decrement operator has no effect on values of type `null`. A `E_WARNING` is emitted as of PHP 8.3.0, because this will implicitly cast the value to `int` in the future.
>
> The decrement operator has no effect on non- [numeric string](#language.types.numeric-strings), except the empty string, which becomes `-1`. A `E_DEPRECATED` is emitted as of PHP 8.3.0, because a `TypeError` will be thrown in the future.

> [!NOTE]
> Internal objects that support overloading addition and/or subtraction can also be incremented and/or decremented. One such internal object is `GMP`.

## PERL string increment feature

> [!WARNING]
> This feature is soft-deprecated as of PHP 8.3.0. The `str_increment` function should be used instead. As of PHP 8.5.0, incrementing non-numeric strings emits a deprecation warning.

It is possible to increment a non- [numeric string](#language.types.numeric-strings) in PHP. The string must be an alphanumerical ASCII string. Which increments letters up to the next letter, when reaching the letter `Z` the increment is carried to the value on the left. For example, `$a = 'Z'; $a++;` turns `$a` into `'AA'`.

As of PHP 8.3.0, incrementing empty or non-alphanumeric strings emits `E_DEPRECATED`. As of PHP 8.5.0, this applies to all non-numeric strings.

<div class="example">

<div class="title">

PERL string increment example

</div>

```
<?php
echo '== Alphabetic strings ==' . PHP_EOL;
$s = 'W';
for ($n=0; $n<6; $n++) {
    echo ++$s . PHP_EOL;
}
// Alphanumeric strings behave differently
echo '== Alphanumeric strings ==' . PHP_EOL;
$d = 'A8';
for ($n=0; $n<6; $n++) {
    echo ++$d . PHP_EOL;
}
$d = 'A08';
for ($n=0; $n<6; $n++) {
    echo ++$d . PHP_EOL;
}
?>

   
```

ENTITY

    == Alphabetic strings ==
    X
    Y
    Z
    AA
    AB
    AC
    == Alphanumeric strings ==
    A9
    B0
    B1
    B2
    B3
    B4
    A09
    A10
    A11
    A12
    A13
    A14

       

</div>

> [!WARNING]
> If the alphanumerical string can be interpreted as a [numeric string](#language.types.numeric-strings) it will be cast to an `int` or `float`. This is particularly an issue with strings that look like a floating point numbers written in exponential notation. The `str_increment` function does not suffer from these implicit type cast.
>
> <div class="example">
>
> <div class="title">
>
> Alphanumerical string converted to float
>
> </div>
>
> ```
> <?php
> $s = "5d9";
> var_dump(++$s);
> var_dump(++$s);
> ?>
>
>     
> ```
>
> ENTITY
>
>     string(3) "5e0"
>     float(6)
>
>         
>
> This is because the value `"5e0"` is interpreted as a `float` and cast to the value `5.0` before being incremented.
>
> </div>

# Logical Operators

| Example | Name | Result |
|----|----|----|
| \$a and \$b | And | ENTITY if both `$a` and `$b` are ENTITY. |
| \$a or \$b | Or | ENTITY if either `$a` or `$b` is ENTITY. |
| \$a xor \$b | Xor | ENTITY if either `$a` or `$b` is ENTITY, but not both. |
| ! \$a | Not | ENTITY if `$a` is not ENTITY. |
| \$a ENTITYENTITY \$b | And | ENTITY if both `$a` and `$b` are ENTITY. |
| \$a \|\| \$b | Or | ENTITY if either `$a` or `$b` is ENTITY. |

Logical Operators

The reason for the two different variations of "and" and "or" operators is that they operate at different precedences. (See [Operator Precedence](#language.operators.precedence).)

<div class="example">

<div class="title">

Logical operators illustrated

</div>

```
<?php

// --------------------
// foo() will never get called as those operators are short-circuit

$a = (false && foo());
$b = (true  || foo());
$c = (false and foo());
$d = (true  or  foo());

// --------------------
// "||" has a greater precedence than "or"

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f before the "or" operation occurs
// Acts like: (($f = false) or true)
$f = false or true;

var_dump($e, $f);

// --------------------
// "&&" has a greater precedence than "and"

// The result of the expression (true && false) is assigned to $g
// Acts like: ($g = (true && false))
$g = true && false;

// The constant true is assigned to $h before the "and" operation occurs
// Acts like: (($h = true) and false)
$h = true and false;

var_dump($g, $h);
?>

  
```

ENTITY

    bool(true)
    bool(false)
    bool(false)
    bool(true)

      

</div>

# Operator Precedence

The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression `1 + 5 * 3`, the answer is `16` and not `18` because the multiplication ("\*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary. For instance: `(1 + 5) * 3` evaluates to `18`.

When operators have equal precedence their associativity decides how the operators are grouped. For example "-" is left-associative, so `1 - 2 - 3` is grouped as `(1 - 2) - 3` and evaluates to `-4`. "=" on the other hand is right-associative, so `$a = $b = $c` is grouped as `$a = ($b = $c)`.

Operators of equal precedence that are non-associative cannot be used next to each other, for example `1 ENTITY 2 ENTITY 1` is illegal in PHP. The expression `1 ENTITY= 1 == 1` on the other hand is legal, because the `==` operator has a lower precedence than the `ENTITY=` operator.

Associativity is only meaningful for binary (and ternary) operators. Unary operators are either prefix or postfix so this notion is not applicable. For example `!!$a` can only be grouped as `!(!$a)`.

Use of parentheses, even when not strictly necessary, can often increase readability of the code by making grouping explicit rather than relying on the implicit operator precedence and associativity.

The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides grouping.

| Associativity | Operators | Additional Information |
|----|----|----|
| (n/a) | `clone` `new` | [clone](#language.oop5.cloning) and [new](#language.oop5.basic.new) |
| right | `**` | [arithmetic](#language.operators.arithmetic) |
| (n/a) | `+` `-` `++` `--` `~` `(int)` `(float)` `(string)` `(array)` `(object)` `(bool)` `@` | [arithmetic](#language.operators.arithmetic) (unary `+` and `-`), [increment/decrement](#language.operators.increment), [bitwise](#language.operators.bitwise), [type casting](#language.types.typecasting)ENTITY [error control](#language.operators.errorcontrol) |
| left | `instanceof` | [type](#language.operators.type) |
| (n/a) | `!` | [logical](#language.operators.logical) |
| left | `*` `/` `%` | [arithmetic](#language.operators.arithmetic) |
| left | `+` `-` `.` | [arithmetic](#language.operators.arithmetic) (binary `+` and `-`), [array](#language.operators.array)ENTITY [string](#language.operators.string) (`.` prior to PHP 8.0.0) |
| left | `ENTITYENTITY` `ENTITYENTITY` | [bitwise](#language.operators.bitwise) |
| left | `.` | [string](#language.operators.string) (as of PHP 8.0.0) |
| left | `|ENTITY` | [pipe](#language.operators.functional) |
| non-associative | `ENTITY` `ENTITY=` `ENTITY` `ENTITY=` | [comparison](#language.operators.comparison) |
| non-associative | `==` `!=` `===` `!==` `ENTITYENTITY` `ENTITY=ENTITY` | [comparison](#language.operators.comparison) |
| left | `ENTITY` | [bitwise](#language.operators.bitwise)ENTITY [references](#language.references) |
| left | `^` | [bitwise](#language.operators.bitwise) |
| left | `|` | [bitwise](#language.operators.bitwise) |
| left | `ENTITYENTITY` | [logical](#language.operators.logical) |
| left | `||` | [logical](#language.operators.logical) |
| right | `??` | [null coalescing](#language.operators.comparison.coalesce) |
| non-associative | `? :` | [ternary](#language.operators.comparison.ternary) (left-associative prior to PHP 8.0.0) |
| right | `=` `+=` `-=` `*=` `**=` `/=` `.=` `%=` `ENTITY=` `|=` `^=` `ENTITYENTITY=` `ENTITYENTITY=` `??=` | [assignment](#language.operators.assignment) |
| (n/a) | `yield from` | [yield from](#control-structures.yield.from) |
| (n/a) | `=ENTITY` | [yield with keys](#language.generators.syntax) |
| (n/a) | `yield` | [yield](#control-structures.yield) |
| (n/a) | `print` | `print` |
| left | `and` | [logical](#language.operators.logical) |
| left | `xor` | [logical](#language.operators.logical) |
| left | `or` | [logical](#language.operators.logical) |
| (n/a) | `include` `include_once` `require` `require_once` | `include`, `include_once`, `require`ENTITY `require_once` |
| (n/a) | `fn (...) =ENTITY` | [fn arrow](#functions.arrow) disambiguity |
| (n/a) | `throw` | [throw](#control-structures.throw) |

Operator Precedence

> [!NOTE]
> The unary operators sharing the row with the cast operators (`~`, `@`, and unary `+`/`-`) bind more tightly than `instanceof`, whereas `!` binds less tightly. Consequently `(int) $x instanceof Foo` is grouped as `((int) $x) instanceof Foo`, while `!$x instanceof Foo` is grouped as `!($x instanceof Foo)`.

<div class="example">

<div class="title">

Associativity

</div>

```
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
var_dump($a);

$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
var_dump($a, $b);
?>

   
```

</div>

The ternary operator specifically requires the use of parenthesis to disambiguate precedence.

<div class="example">

<div class="title">

Explicit Precedence

</div>

```
<?php
$a = true ? 0 : (true ? 1 : 2);
var_dump($a);

// this is not allowed since PHP 8
// $a = true ? 0 : true ? 1 : 2;
?>

   
```

</div>

Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation. PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided, because the behavior can change between versions of PHP or depending on the surrounding code.

<div class="example">

<div class="title">

Undefined order of evaluation

</div>

```
<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3

$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>

   
```

</div>

<div class="example">

<div class="title">

`+`, `-` and `.` precedence

</div>

```
<?php
$x = 4;
// this line might result in unexpected output:
echo "x minus one equals " . $x-1 . ", or so I hope\n";

// the desired precedence can be enforced by using parentheses:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";

// this is not allowed, and throws a TypeError:
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
?>

   
```

ENTITY

    -1, or so I hope
    -1, or so I hope
    Fatal error: Uncaught TypeError: Unsupported operand types: string - int

       

</div>

<div class="example">

<div class="title">

Prior to PHP 8, `+`, `-` and `.` had the same precedence

</div>

```
<?php
$x = 4;
// this line might result in unexpected output:
echo "x minus one equals " . $x-1 . ", or so I hope\n";

// because it is evaluated like this line (prior to PHP 8.0.0):
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";

// the desired precedence can be enforced by using parentheses:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
?>

   
```

ENTITY

    -1, or so I hope
    -1, or so I hope
    x minus one equals 3, or so I hope

       

</div>

> [!NOTE]
> Although `=` has a lower precedence than most other operators, PHP will still allow expressions similar to the following: `if (!$a = foo())`, in which case the return value of `foo()` is put into `$a`.
>
> This is possible because the left-hand side of an assignment must be a variable, so the assignment is grouped with that variable rather than with the surrounding higher-precedence prefix operator. The same applies to the other prefix operators that take an expression operand, such as `clone`, the cast operators, `@` and `~`: for instance `clone $a = $b` is grouped as `clone ($a = $b)`, not `(clone $a) = $b`.

## 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.0.0 | String concatenation (`.`) now has a lower precedence than arithmetic addition/subtraction (`+` and `-`) and bitwise shift left/right (`ENTITYENTITY` and `ENTITYENTITY`); previously it had the same precedence as `+` and `-` and a higher precedence than `ENTITYENTITY` and `ENTITYENTITY`. |
| 8.0.0 | The ternary operator (`? :`) is non-associative now; previously it was left-associative. |
| 7.4.0 | Relying on the precedence of string concatenation (`.`) relative to arithmetic addition/subtraction (`+` or `-`) or bitwise shift left/right (`ENTITYENTITY` or `ENTITYENTITY`), i.e. using them together in an unparenthesized expression, is deprecated. |
| 7.4.0 | Relying on left-associativity of the ternary operator (`? :`), i.e. nesting multiple unparenthesized ternary operators, is deprecated. |

# String Operators

There are two `string` operators. The first is the concatenation operator ('.'), which returns the concatenation of its right and left arguments. The second is the concatenating assignment operator ('`.=`'), which appends the argument on the right side to the argument on the left side. Please read [Assignment Operators](#language.operators.assignment) for more information.

<div class="example">

<div class="title">

String Concatenating

</div>

```
<?php
$a = "Hello ";
$b = $a . "World!"; // now $b contains "Hello World!"
var_dump($b);

$a = "Hello ";
$a .= "World!";     // now $a contains "Hello World!"
var_dump($a);
?>

   
```

</div>

## 

ENTITY

[String type](#language.types.string), [String functions](#ref.strings)

# Type Operators

`instanceof` is used to determine whether a PHP variable is an instantiated object of a certain [class](#language.oop5.basic.class):

<div class="example">

<div class="title">

Using `instanceof` with classes

</div>

```
<?php
class MyClass
{
}

class NotMyClass
{
}
$a = new MyClass;

var_dump($a instanceof MyClass);
var_dump($a instanceof NotMyClass);
?>

   
```

ENTITY

    bool(true)
    bool(false)

       

</div>

`instanceof` can also be used to determine whether a variable is an instantiated object of a class that inherits from a parent class:

<div class="example">

<div class="title">

Using `instanceof` with inherited classes

</div>

```
<?php
class ParentClass
{
}

class MyClass extends ParentClass
{
}

$a = new MyClass;

var_dump($a instanceof MyClass);
var_dump($a instanceof ParentClass);
?>

   
```

ENTITY

    bool(true)
    bool(true)

       

</div>

To check if an object is *not* an instanceof a class, the [logical `not` operator](#language.operators.logical) can be used.

<div class="example">

<div class="title">

Using `instanceof` to check if object is *not* an instanceof a class

</div>

```
<?php
class MyClass
{
}

$a = new MyClass;
var_dump(!($a instanceof stdClass));
?>

   
```

ENTITY

    bool(true)

       

</div>

Lastly, `instanceof` can also be used to determine whether a variable is an instantiated object of a class that implements an [interface](#language.oop5.interfaces):

<div class="example">

<div class="title">

Using `instanceof` with interfaces

</div>

```
<?php
interface MyInterface
{
}

class MyClass implements MyInterface
{
}

$a = new MyClass;

var_dump($a instanceof MyClass);
var_dump($a instanceof MyInterface);
?>

   
```

ENTITY

    bool(true)
    bool(true)

       

</div>

Although `instanceof` is usually used with a literal classname, it can also be used with another object or a string variable:

<div class="example">

<div class="title">

Using `instanceof` with other variables

</div>

```
<?php
interface MyInterface
{
}

class MyClass implements MyInterface
{
}

$a = new MyClass;
$b = new MyClass;
$c = 'MyClass';
$d = 'NotMyClass';

var_dump($a instanceof $b); // $b is an object of class MyClass
var_dump($a instanceof $c); // $c is a string 'MyClass'
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
?>

   
```

ENTITY

    bool(true)
    bool(true)
    bool(false)

       

</div>

instanceof does not throw any error if the variable being tested is not an object, it simply returns ENTITY. Constants, however, were not allowed prior to PHP 7.3.0.

<div class="example">

<div class="title">

Using `instanceof` to test other variables

</div>

```
<?php
$a = 1;
$b = NULL;
$c = fopen('/tmp/', 'r');
var_dump($a instanceof stdClass); // $a is an integer
var_dump($b instanceof stdClass); // $b is NULL
var_dump($c instanceof stdClass); // $c is a resource
var_dump(FALSE instanceof stdClass);
?>

   
```

ENTITY

    bool(false)
    bool(false)
    bool(false)
    PHP Fatal error:  instanceof expects an object instance, constant given

       

</div>

As of PHP 7.3.0, constants are allowed on the left-hand-side of the `instanceof` operator.

<div class="example">

<div class="title">

Using `instanceof` to test constants

</div>

```
<?php
var_dump(FALSE instanceof stdClass);
?>

   
```

ENTITY

    bool(false)

       

</div>

As of PHP 8.0.0, `instanceof` can now be used with arbitrary expressions. The expression must be wrapped in parentheses and produce a `string`.

<div class="example">

<div class="title">

Using `instanceof` with an arbitrary expression

</div>

```
<?php

class ClassA extends \stdClass {}
class ClassB extends \stdClass {}
class ClassC extends ClassB {}
class ClassD extends ClassA {}

function getSomeClass(): string
{
    return ClassA::class;
}

var_dump(new ClassA instanceof ('std' . 'Class'));
var_dump(new ClassB instanceof ('Class' . 'B'));
var_dump(new ClassC instanceof ('Class' . 'A'));
var_dump(new ClassD instanceof (getSomeClass()));
?>

   
```

ENTITY

    bool(true)
    bool(true)
    bool(false)
    bool(true)

       

</div>

The `instanceof` operator has a functional variant with the `is_a` function.

## 

ENTITY

`get_class`, `is_a`

# construct

AllowDynamicProperties::\_\_construct

Construct a new AllowDynamicProperties attribute instance

# 

ENTITY

<div data-wrapper="1" role="AllowDynamicProperties">

public

</div>

<div data-wrapper="1" role="AllowDynamicProperties">

AllowDynamicProperties::\_\_construct

</div>

Constructs a new `AllowDynamicProperties` instance.

# 

ENTITY ENTITY

# argumentcounterror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`ArgumentCountError` is thrown when too few arguments are passed to a user-defined function or method.

</div>

<div data-wrapper="1" role="exception">

This error is also thrown when too many arguments are passed to a non-variadic built-in function.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

ArgumentCountError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

TypeError

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# arithmeticerror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`ArithmeticError` is thrown when an error occurs while performing mathematical operations. These errors include attempting to perform a bitshift by a negative amount, and any call to `intdiv` that would result in a value outside the possible bounds of an `int`.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

ArithmeticError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Error

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# arrayaccess

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Interface to provide access to objects as arrays.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

ArrayAccess

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div id="arrayaccess.example.basic" class="example" role="class">

<div class="title">

Basic usage

</div>

```
<?php
class Obj implements ArrayAccess {
    public $container = [
        "one"   => 1,
        "two"   => 2,
        "three" => 3,
    ];

    public function offsetSet($offset, $value): void {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetExists($offset): bool {
        return isset($this->container[$offset]);
    }

    public function offsetUnset($offset): void {
        unset($this->container[$offset]);
    }

    public function offsetGet($offset): mixed {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}

$obj = new Obj;

var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);

    
```

ENTITY

    bool(true)
    int(2)
    bool(false)
    string(7) "A value"
    Obj Object
    (
        [container] => Array
            (
                [one] => 1
                [three] => 3
                [two] => A value
                [0] => Append 1
                [1] => Append 2
                [2] => Append 3
            )

    )

        

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY

</div>

# offsetexists

ArrayAccess::offsetExists

Whether an offset exists

# 

ENTITY

<div data-wrapper="1" role="ArrayAccess">

public

</div>

<div data-wrapper="1" role="ArrayAccess">

bool

</div>

<div data-wrapper="1" role="ArrayAccess">

ArrayAccess::offsetExists

</div>

<div data-wrapper="1" role="ArrayAccess">

mixed

</div>

<div data-wrapper="1" role="ArrayAccess">

offset

</div>

Whether or not an offset exists.

This method is executed when using `isset` or `empty` on objects implementing `ArrayAccess`.

> [!NOTE]
> When using `empty` `ArrayAccess::offsetGet` will be called and checked if empty only if `ArrayAccess::offsetExists` returns ENTITY.

# 

ENTITY

`offset`  
An offset to check for.

# 

ENTITY

ENTITY

> [!NOTE]
> The return value will be casted to `bool` if non-boolean was returned.

# 

ENTITY

<div class="example">

<div class="title">

`ArrayAccess::offsetExists` example

</div>

```
<?php
class obj implements ArrayAccess {
    public function offsetSet($offset, $value): void {
        var_dump(__METHOD__);
    }
    public function offsetExists($var): bool {
        var_dump(__METHOD__);
        if ($var == "foobar") {
            return true;
        }
        return false;
    }
    public function offsetUnset($var): void {
        var_dump(__METHOD__);
    }
    #[\ReturnTypeWillChange]
    public function offsetGet($var) {
        var_dump(__METHOD__);
        return "value";
    }
}

$obj = new obj;

echo "Runs obj::offsetExists()\n";
var_dump(isset($obj["foobar"]));

echo "\nRuns obj::offsetExists() and obj::offsetGet()\n";
var_dump(empty($obj["foobar"]));

echo "\nRuns obj::offsetExists(), *not* obj:offsetGet() as there is nothing to get\n";
var_dump(empty($obj["foobaz"]));
?>

    
```

ENTITY

    Runs obj::offsetExists()
    string(17) "obj::offsetExists"
    bool(true)

    Runs obj::offsetExists() and obj::offsetGet()
    string(17) "obj::offsetExists"
    string(14) "obj::offsetGet"
    bool(false)

    Runs obj::offsetExists(), *not* obj:offsetGet() as there is nothing to get
    string(17) "obj::offsetExists"
    bool(true)

        

</div>

# offsetget

ArrayAccess::offsetGet

Offset to retrieve

# 

ENTITY

<div data-wrapper="1" role="ArrayAccess">

public

</div>

<div data-wrapper="1" role="ArrayAccess">

mixed

</div>

<div data-wrapper="1" role="ArrayAccess">

ArrayAccess::offsetGet

</div>

<div data-wrapper="1" role="ArrayAccess">

mixed

</div>

<div data-wrapper="1" role="ArrayAccess">

offset

</div>

Returns the value at specified offset.

This method is executed when checking if offset is `empty`.

# 

ENTITY

`offset`  
The offset to retrieve.

# 

ENTITY

Can return all value types.

# 

ENTITY

> [!NOTE]
> It's possible for implementations of this method to return by reference. This makes indirect modifications to the overloaded array dimensions of `ArrayAccess` objects possible.
>
> A direct modification is one that replaces completely the value of the array dimension, as in `$obj[6] = 7`. An indirect modification, on the other hand, only changes part of the dimension, or attempts to assign the dimension by reference to another variable, as in `$obj[6][7] = 7` or `$var =ENTITY $obj[6]`. Increments with `++` and decrements with `--` are also implemented in a way that requires indirect modification.
>
> While direct modification triggers a call to `ArrayAccess::offsetSet`, indirect modification triggers a call to `ArrayAccess::offsetGet`. In that case, the implementation of `ArrayAccess::offsetGet` must be able to return by reference, otherwise an `E_NOTICE` message is raised.

# 

ENTITY

ArrayAccess::offsetExists

# offsetset

ArrayAccess::offsetSet

Assign a value to the specified offset

# 

ENTITY

<div data-wrapper="1" role="ArrayAccess">

public

</div>

<div data-wrapper="1" role="ArrayAccess">

void

</div>

<div data-wrapper="1" role="ArrayAccess">

ArrayAccess::offsetSet

</div>

<div data-wrapper="1" role="ArrayAccess">

mixed

</div>

<div data-wrapper="1" role="ArrayAccess">

offset

</div>

<div data-wrapper="1" role="ArrayAccess">

mixed

</div>

<div data-wrapper="1" role="ArrayAccess">

value

</div>

Assigns a value to the specified offset.

# 

ENTITY

`offset`  
The offset to assign the value to.

`value`  
The value to set.

# 

ENTITY

ENTITY

# 

ENTITY

> [!NOTE]
> The `offset` parameter will be set to ENTITY if another value is not available, like in the following example.
>
> <div class="informalexample">
>
> ```
> <?php
> $arrayaccess[] = "first value";
> $arrayaccess[] = "second value";
> print_r($arrayaccess);
> ?>
>
>      
> ```
>
> ENTITY
>
>     Array
>     (
>         [0] => first value
>         [1] => second value
>     )
>
>          
>
> </div>

> [!NOTE]
> This function is not called in assignments by reference and otherwise indirect changes to array dimensions overloaded with `ArrayAccess` (indirect in the sense they are made not by changing the dimension directly, but by changing a sub-dimension or sub-property or assigning the array dimension by reference to another variable). Instead, `ArrayAccess::offsetGet` is called. The operation will only be successful if that method returns by reference.

# offsetunset

ArrayAccess::offsetUnset

Unset an offset

# 

ENTITY

<div data-wrapper="1" role="ArrayAccess">

public

</div>

<div data-wrapper="1" role="ArrayAccess">

void

</div>

<div data-wrapper="1" role="ArrayAccess">

ArrayAccess::offsetUnset

</div>

<div data-wrapper="1" role="ArrayAccess">

mixed

</div>

<div data-wrapper="1" role="ArrayAccess">

offset

</div>

Unsets an offset.

> [!NOTE]
> This method will *not* be called when type-casting to [(unset)](#language.types.typecasting)

# 

ENTITY

`offset`  
The offset to unset.

# 

ENTITY

ENTITY

# assertionerror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`AssertionError` is thrown when an assertion made via `assert` fails.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

AssertionError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Error

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# construct

Attribute::\_\_construct

Construct a new Attribute instance

# 

ENTITY

<div data-wrapper="1" role="Attribute">

public

</div>

<div data-wrapper="1" role="Attribute">

Attribute::\_\_construct

</div>

<div data-wrapper="1" role="Attribute">

int

</div>

<div data-wrapper="1" role="Attribute">

flags

</div>

<div data-wrapper="1" role="Attribute">

Attribute::TARGET_ALL

</div>

Constructs a new `Attribute` instance.

# 

ENTITY

`flags`

# Predefined Attributes

PHP provides some predefined attributes that can be used.

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# allowdynamicproperties

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

This attribute is used to mark classes that allow [dynamic properties](#language.oop5.properties.dynamic-properties).

</div>

> [!NOTE]
> Although attributes themselves are not inherited, the effect of the `AllowDynamicProperties` attribute *is* inherited. Child classes of a class marked with this attribute will also allow dynamic properties, even if they do not explicitly declare the attribute.

> [!NOTE]
> This attribute was introduced in PHP 8.2.0 as the explicit way to allow dynamic properties. Creating a dynamic property on a class that does not use this attribute, and that does not implement [\_\_get()](#object.get) or [\_\_set()](#object.set), is deprecated.

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_CLASS)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

AllowDynamicProperties

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div class="example" role="class">

<div class="title">

AllowDynamicProperties with a dynamic property

</div>

To enable dynamic properties, add `#[\AllowDynamicProperties]`.

```
<?php
#[\AllowDynamicProperties]
class ValidExample { }

$obj = new ValidExample();
$obj->myDynamicProp = 1234;
?>

    
```

</div>

<div class="example" role="class">

<div class="title">

AllowDynamicProperties with non-existing property

</div>

As of PHP 8.2.0, the declaration is required unless the class uses this attribute. Creating an undeclared property on such a class emits a deprecation notice.

```
<?php
class InvalidExample { }

$obj = new InvalidExample();
$obj->myUnknownProperty = 1234;
?>

    
```

ENTITY

    Deprecated: Creation of dynamic property InvalidExample::$myUnknownProperty is deprecated in file on line 5

        

</div>

<div class="example" role="class">

<div class="title">

AllowDynamicProperties with non-existing property in inherited class

</div>

```
     
<?php
class DefaultBehaviour { }

#[\AllowDynamicProperties]
class ClassAllowsDynamicProperties { }

class InheritedClassAllowsDynamicProperties extends ClassAllowsDynamicProperties { }

$o1 = new DefaultBehaviour();
$o2 = new InheritedClassAllowsDynamicProperties();

$o1->nonExistingProp = true;
$o2->nonExistingProp = true;
?>

    
```

ENTITY

         
    Deprecated: Creation of dynamic property DefaultBehaviour::$nonExistingProp is deprecated in file on line 12

        

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

[Attributes overview](#language.attributes)

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# attribute

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Attributes offer the ability to add structured, machine-readable metadata information on declarations in code: Classes, methods, functions, parameters, properties and class constants can be the target of an attribute. The metadata defined by attributes can then be inspected at runtime using the [Reflection APIs](#book.reflection). Attributes could therefore be thought of as a configuration language embedded directly into code.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_CLASS)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

Attribute

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_CLASS

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_FUNCTION

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_METHOD

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_PROPERTY

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_CLASS_CONSTANT

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_PARAMETER

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_CONSTANT

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::TARGET_ALL

</div>

<div data-wrapper="1" role="class">

const

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

Attribute::IS_REPEATABLE

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

public

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

flags

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`Attribute::TARGET_CLASS`  

`Attribute::TARGET_FUNCTION`  

`Attribute::TARGET_METHOD`  

`Attribute::TARGET_PROPERTY`  

`Attribute::TARGET_CLASS_CONSTANT`  

`Attribute::TARGET_PARAMETER`  

`Attribute::TARGET_CONSTANT`  

`Attribute::TARGET_ALL`  

`Attribute::IS_REPEATABLE`  

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`flags`  

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | Added `Attribute::TARGET_CONSTANT`. Applying `#[\Attribute]` to an abstract class, enum, interface, or trait now triggers a compile-time error (previously it was only reported at runtime when ReflectionAttribute::newInstance was called). |

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

[Attributes overview](#language.attributes)

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# delayedtargetvalidation

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

This attribute delays target validation errors for internal attributes from compile time to when the attribute is instantiated via the Reflection API.

</div>

<div data-wrapper="1" role="class">

When applied to a declaration, any invalid usage of internal attributes on the same target will not trigger a compile time error. Instead, the validation is deferred and performed when the attribute is instantiated via [ReflectionAttribute::newInstance()](#reflectionattribute.newinstance).

</div>

<div data-wrapper="1" role="class">

This is primarily intended for forward compatibility, allowing code to use attributes that may gain additional valid targets in future PHP versions without breaking on older versions.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_ALL)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

DelayedTargetValidation

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div class="example" role="class">

<div class="title">

Delaying validation of an invalid target

</div>

```
<?php

class Base {
    protected function foo(): void {}
}

class Child extends Base {

    #[\DelayedTargetValidation]
    #[\Override]
    public const NAME = 'child';

    #[\Override]
    protected function foo(): void {}
}
```

On PHP versions where `Override` is not allowed on class constants, this does not produce a compile time error.

</div>

<div class="example" role="class">

<div class="title">

Validation occurs during reflection

</div>

```
<?php

$reflection = new ReflectionClassConstant(Child::class, 'NAME');

foreach ($reflection->getAttributes() as $attribute) {
    $attribute->newInstance(); // May throw if invalid
}
```

When any attribute applied to the same target (other than DelayedTargetValidation itself) is instantiated via reflection using [ReflectionAttribute::newInstance()](#reflectionattribute.newinstance), target validation is performed and an exception may be thrown if the attribute is used on an unsupported target.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

This attribute only affects target validation of internal attributes.

</div>

<div data-wrapper="1" role="class">

It does not suppress functional validation performed by those attributes. For example, `Override` will still emit an error if a method does not actually override a parent method.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Attributes overview

</div>

<div data-wrapper="1" role="class">

Override

</div>

# deprecated

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

This attribute is used to mark functionality as deprecated. Using deprecated functionality will cause an `E_USER_DEPRECATED` error to be emitted.

</div>

<div data-wrapper="1" role="class">

As of PHP 8.5.0, this attribute can also be applied to traits and to compile-time constants declared outside of a class.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_METHOD \| \Attribute::TARGET_FUNCTION \| \Attribute::TARGET_CLASS_CONSTANT \| \Attribute::TARGET_CONSTANT \| \Attribute::TARGET_CLASS)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

Deprecated

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

public

</div>

<div data-wrapper="1" role="class">

readonly

</div>

<div data-wrapper="1" role="class">

string

</div>

<div data-wrapper="1" role="class">

null

</div>

<div data-wrapper="1" role="class">

message

</div>

<div data-wrapper="1" role="class">

public

</div>

<div data-wrapper="1" role="class">

readonly

</div>

<div data-wrapper="1" role="class">

string

</div>

<div data-wrapper="1" role="class">

null

</div>

<div data-wrapper="1" role="class">

since

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`message`  
An optional message explaining the reason for the deprecation and possible replacement functionality. Will be included in the emitted deprecation message.

`since`  
An optional string indicating since when the functionality is deprecated. The contents are not validated by PHP and may contain a version number, a date or any other value that is considered appropriate. Will be included in the emitted deprecation message.

Functionality that is part of PHP will use Major.Minor as the `since` value, for example `'8.4'`.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div class="informalexample" role="class">

```
<?php

#[\Deprecated(message: "use safe_replacement() instead", since: "1.5")]
function unsafe_function()
{
   echo "This is unsafe", PHP_EOL;
}

unsafe_function();

?>

    
```

ENTITY

    Deprecated: Function unsafe_function() is deprecated since 1.5, use safe_replacement() instead in example.php on line 9
    This is unsafe

        

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | `Deprecated` can now be applied to traits and to compile-time constants declared outside of a class, the latter through the new `Attribute::TARGET_CONSTANT` target. |

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Attributes overview

</div>

<div data-wrapper="1" role="class">

ReflectionFunctionAbstract::isDeprecated

</div>

<div data-wrapper="1" role="class">

ReflectionClassConstant::isDeprecated

</div>

<div data-wrapper="1" role="class">

E_USER_DEPRECATED

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# construct

Deprecated::\_\_construct

Construct a new Deprecated attribute instance

# 

ENTITY

<div data-wrapper="1" role="Deprecated">

public

</div>

<div data-wrapper="1" role="Deprecated">

Deprecated::\_\_construct

</div>

<div data-wrapper="1" role="Deprecated">

string

</div>

<div data-wrapper="1" role="Deprecated">

null

</div>

<div data-wrapper="1" role="Deprecated">

message

</div>

<div data-wrapper="1" role="Deprecated">

ENTITY

</div>

<div data-wrapper="1" role="Deprecated">

string

</div>

<div data-wrapper="1" role="Deprecated">

null

</div>

<div data-wrapper="1" role="Deprecated">

since

</div>

<div data-wrapper="1" role="Deprecated">

ENTITY

</div>

Constructs a new `Deprecated` instance.

# 

ENTITY

`message`  
The value of the message property.

`since`  
The value of the since property.

# nodiscard

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

This attribute can be used to indicate that the return value of a function or a method should not be discarded. If the return value is not used in any way, a warning will be emitted.

</div>

<div data-wrapper="1" role="class">

This is useful for functions where not checking the return value is likely to be a bug.

</div>

<div data-wrapper="1" role="class">

To intentionally discard the return value of such a function, use (void) cast to suppress the warning.

</div>

> [!NOTE]
> Since attributes are designed to be backwards compatible, `#[\NoDiscard]` can be added to functions and methods even when PHP 8.4 or below are supported, it just won't do anything. On PHP 8.5 and above a warning will be emitted if the result is unused. To suppress the warning without using `(void)`, which is not supported before PHP 8.5, consider using a variable like `$_`.

> [!NOTE]
> `#[\NoDiscard]` applies to the specific function or method declaration it is written on, and the warning is emitted based on the declaration that is actually called. As a result, adding `#[\NoDiscard]` to an interface method or an abstract method does not emit a warning, because the method that is invoked is the implementing or overriding method. Likewise, a method that overrides a `#[\NoDiscard]` method does not emit the warning unless it is itself marked with the attribute. In contrast, a method imported from a trait keeps the attribute, because the trait method is copied into the using class as if declared there.

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_METHOD \| \Attribute::TARGET_FUNCTION)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

NoDiscard

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

public

</div>

<div data-wrapper="1" role="class">

readonly

</div>

<div data-wrapper="1" role="class">

string

</div>

<div data-wrapper="1" role="class">

null

</div>

<div data-wrapper="1" role="class">

message

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`message`  
An optional message explaining why the return value should not be discarded.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div class="example" role="class">

<div class="title">

Basic usage

</div>

```
<?php

/**
 * Processes all the given items and returns an array with the results of the
 * operation for each item. `null` indicates success and an Exception indicates
 * an error. The keys of the result array match the keys of the $items array.
 *
 * @param array<string> $items
 * @return array<null|Exception>
 */
#[\NoDiscard("as processing might fail for individual items")]
function bulk_process(array $items): array {
    $results = [];

    foreach ($items as $key => $item) {
        if (\random_int(0, 9999) < 9999) {
            // Pretend to do something useful with $item,
            // which will succeed in 99.99% of cases.
            echo "Processing {$item}", PHP_EOL;
            $error = null;
        } else {
            $error = new \Exception("Failed to process {$item}.");
        }

        $results[$key] = $error;
    }

    return $results;
}

bulk_process($items);

?>

    
```

ENTITY

    Warning: The return value of function bulk_process() should either be used or intentionally ignored by casting it as (void), as processing might fail for individual items

        

</div>

<div class="example" role="class">

<div class="title">

Intentionally discarding the return value

</div>

```
<?php

#[\NoDiscard]
function some_command(): int {
    return 1;
}

// Suppress the warning using (void) - PHP 8.5+
(void) some_command();

// For compatibility with PHP versions before 8.5, use a temporary variable
$_ = some_command();

?>

    
```

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Attributes overview

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# construct

NoDiscard::\_\_construct

Construct a new NoDiscard attribute instance

# 

ENTITY

<div data-wrapper="1" role="NoDiscard">

public

</div>

<div data-wrapper="1" role="NoDiscard">

NoDiscard::\_\_construct

</div>

<div data-wrapper="1" role="NoDiscard">

string

</div>

<div data-wrapper="1" role="NoDiscard">

null

</div>

<div data-wrapper="1" role="NoDiscard">

message

</div>

<div data-wrapper="1" role="NoDiscard">

ENTITY

</div>

Constructs a new `NoDiscard` instance.

# 

ENTITY

`message`  
The value of the message property.

# override

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

This attribute is used to indicate that a method or a property is intended to override a method or a property of a parent class or that it implements a method or a property defined in an interface.

</div>

<div data-wrapper="1" role="class">

If no method or property with the same name exists in a parent class or in an implemented interface a compile-time error will be emitted.

</div>

<div data-wrapper="1" role="class">

The attribute cannot be used on the [\_\_construct()](#object.construct) method, which is exempt from signature checks.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_METHOD \| \Attribute::TARGET_PROPERTY)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

Override

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY                                   |
|--------|------------------------------------------|
| 8.5.0  | `Override` can be applied to properties. |

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div class="example" role="class">

<div class="title">

Usage with methods

</div>

```
<?php

class Base {
    protected function foo(): void {}
}

final class Extended extends Base {
    #[\Override]
    protected function boo(): void {}
}

?>

    
```

ENTITY

    Fatal error: Extended::boo() has #[\Override] attribute, but no matching parent method exists

        

</div>

<div class="example" role="class">

<div class="title">

Usage with properties

</div>

```
<?php

class Base {
    protected string $foo;
}

final class Extended extends Base {
    #[\Override]
    protected string $boo;
}

?>

    
```

ENTITY

    Fatal error: Extended::$boo has #[\Override] attribute, but no matching parent property exists

        

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Attributes overview

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# construct

Override::\_\_construct

Construct a new Override attribute instance

# 

ENTITY

<div data-wrapper="1" role="Override">

public

</div>

<div data-wrapper="1" role="Override">

Override::\_\_construct

</div>

Constructs a new `Override` instance.

# 

ENTITY ENTITY

# returntypewillchange

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

As of PHP 8.1.0, a tentative phase of transitioning to return type declarations for internal class methods began.

</div>

<div data-wrapper="1" role="class">

Most non-final internal methods now require overriding methods to declare a compatible return type. Otherwise, a deprecation notice is emitted during inheritance validation warning that the signature violates covariance rules.

</div>

<div data-wrapper="1" role="class">

In a future PHP version, method signature checking will become strict, and mismatches will cause a fatal error.

</div>

<div data-wrapper="1" role="class">

In case the return type cannot be declared for an overriding method due to PHP cross-version compatibility concerns, or the overriding method declares an incompatible return type, a `#[\ReturnTypeWillChange]` attribute can be added to silence the deprecation notice.

</div>

> [!WARNING]
> When overriding methods defined in user-defined classes, return types are checked strictly. A fatal error is emitted on mismatch, even if the overriding method is marked with the attribute.
>
> The `ReturnTypeWillChange` attribute suppresses deprecation warnings *only* during the tentative return type phase. After strict type checking is enforced, the attribute will stop working and a mismatch in the overriding method signature of an internal class will cause a fatal error.

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_METHOD)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

ReturnTypeWillChange

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

[Attributes overview](#language.attributes)

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# sensitiveparameter

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

This attribute is used to mark a parameter that is sensitive and should have its value redacted if present in a stack trace.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\Attribute(\Attribute::TARGET_PARAMETER)\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

SensitiveParameter

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div class="informalexample" role="class">

```
<?php

function defaultBehavior(
    string $secret,
    string $normal
) {
    throw new Exception('Error!');
}

function sensitiveParametersWithAttribute(
    #[\SensitiveParameter]
    string $secret,
    string $normal
) {
    throw new Exception('Error!');
}

try {
    defaultBehavior('password', 'normal');
} catch (Exception $e) {
    echo $e, PHP_EOL, PHP_EOL;
}

try {
    sensitiveParametersWithAttribute('password', 'normal');
} catch (Exception $e) {
    echo $e, PHP_EOL, PHP_EOL;
}

?>

    
```

ENTITY

    Exception: Error! in example.php:7
    Stack trace:
    #0 example.php(19): defaultBehavior('password', 'normal')
    #1 {main}

    Exception: Error! in example.php:15
    Stack trace:
    #0 example.php(25): sensitiveParametersWithAttribute(Object(SensitiveParameterValue), 'normal')
    #1 {main}

        

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

[Attributes overview](#language.attributes), `SensitiveParameterValue`

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# backedenum

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

The `BackedEnum` interface is automatically applied to backed enumerations by the engine. It may not be implemented by user-defined classes. Enumerations may not override its methods, as default implementations are provided by the engine. It is available only for type checks.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

BackedEnum

</div>

<div data-wrapper="1" role="class">

extends

</div>

<div data-wrapper="1" role="class">

UnitEnum

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY

</div>

# from

BackedEnum::from

Maps a scalar to an enum instance

# 

ENTITY

<div data-wrapper="1" role="BackedEnum">

public

</div>

<div data-wrapper="1" role="BackedEnum">

static

</div>

<div data-wrapper="1" role="BackedEnum">

static

</div>

<div data-wrapper="1" role="BackedEnum">

BackedEnum::from

</div>

<div data-wrapper="1" role="BackedEnum">

int

</div>

<div data-wrapper="1" role="BackedEnum">

string

</div>

<div data-wrapper="1" role="BackedEnum">

value

</div>

The from method translates a `string` or `int` into the corresponding Enum case, if any. If there is no matching case defined, it will throw a ValueError.

# 

ENTITY

`value`  
The scalar value to map to an enum case.

# 

ENTITY

A case instance of this enumeration.

# 

ENTITY

<div class="example">

<div class="title">

Basic usage

</div>

The following example illustrates how enum cases are returned.

```
<?php
enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

$h = Suit::from('H');

var_dump($h);

$b = Suit::from('B');
?>

   
```

ENTITY

    enum(Suit::Hearts)

    Fatal error: Uncaught ValueError: "B" is not a valid backing value for enum "Suit" in /file.php:15

       

</div>

# 

ENTITY

UnitEnum::cases, BackedEnum::tryFrom

# tryfrom

BackedEnum::tryFrom

Maps a scalar to an enum instance or null

# 

ENTITY

<div data-wrapper="1" role="BackedEnum">

public

</div>

<div data-wrapper="1" role="BackedEnum">

static

</div>

<div data-wrapper="1" role="BackedEnum">

static

</div>

<div data-wrapper="1" role="BackedEnum">

null

</div>

<div data-wrapper="1" role="BackedEnum">

BackedEnum::tryFrom

</div>

<div data-wrapper="1" role="BackedEnum">

int

</div>

<div data-wrapper="1" role="BackedEnum">

string

</div>

<div data-wrapper="1" role="BackedEnum">

value

</div>

The tryFrom method translates a `string` or `int` into the corresponding Enum case, if any. If there is no matching case defined, it will return null.

# 

ENTITY

`value`  
The scalar value to map to an enum case.

# 

ENTITY

A case instance of this enumeration, or `null` if not found.

# 

ENTITY

<div class="example">

<div class="title">

Basic usage

</div>

The following example illustrates how enum cases are returned.

```
<?php
enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

$h = Suit::tryFrom('H');

var_dump($h);

$b = Suit::tryFrom('B') ?? Suit::Spades;

var_dump($b);
?>

   
```

ENTITY

    enum(Suit::Hearts)
    enum(Suit::Spades)

       

</div>

# 

ENTITY

UnitEnum::cases, BackedEnum::from

# closedgeneratorexception

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

A ClosedGeneratorException is thrown when trying to retrieve a value from a closed `Generator`.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

ClosedGeneratorException

</div>

<div data-wrapper="1" role="class">

extends

</div>

<div data-wrapper="1" role="class">

Exception

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# closure

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Class used to represent [anonymous functions](#functions.anonymous).

</div>

<div data-wrapper="1" role="class">

Anonymous functions yield objects of this type. This class has methods that allow further control of the anonymous function after it has been created.

</div>

<div data-wrapper="1" role="class">

Besides the methods listed here, this class also has an `__invoke` method. This is for consistency with other classes that implement [calling magic](#language.oop5.magic.invoke), as this method is not used for calling the function.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

Closure

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 8.4.0 | The output of Closure::\_\_debugInfo now includes the name, line, and file of the closure. |

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

> [!NOTE]
> `Closure` objects cannot be serialized as closures may contain bound variables and a specific execution context. Attempting to serialize a closure will throw an Exception.

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# bind

Closure::bind

Duplicates a closure with a specific bound object and class scope

# 

ENTITY

<div data-wrapper="1" role="Closure">

public

</div>

<div data-wrapper="1" role="Closure">

static

</div>

<div data-wrapper="1" role="Closure">

Closure

</div>

<div data-wrapper="1" role="Closure">

null

</div>

<div data-wrapper="1" role="Closure">

Closure::bind

</div>

<div data-wrapper="1" role="Closure">

Closure

</div>

<div data-wrapper="1" role="Closure">

closure

</div>

<div data-wrapper="1" role="Closure">

object

</div>

<div data-wrapper="1" role="Closure">

null

</div>

<div data-wrapper="1" role="Closure">

newThis

</div>

<div data-wrapper="1" role="Closure">

object

</div>

<div data-wrapper="1" role="Closure">

string

</div>

<div data-wrapper="1" role="Closure">

null

</div>

<div data-wrapper="1" role="Closure">

newScope

</div>

<div data-wrapper="1" role="Closure">

"static"

</div>

This method is a static version of Closure::bindTo. See the documentation of that method for more information.

# 

ENTITY

`closure`  
The anonymous functions to bind.

`newThis`  
The object to which the given anonymous function should be bound, or ENTITY for the closure to be unbound.

`newScope`  
The class scope to which the closure is to be associated, or 'static' to keep the current one. If an object is given, the type of the object will be used instead. This determines the visibility of protected and private methods of the bound object. It is not allowed to pass (an object of) an internal class as this parameter.

# 

ENTITY

Returns a new `Closure` object, or ENTITY on failure.

# 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | Binding an instance to a static closure, or binding a method from an incompatible class hierarchy, is now deprecated (these cases already emitted an `E_WARNING`). |

# 

ENTITY

<div class="example">

<div class="title">

`Closure::bind` example

</div>

```
<?php
class A {
    private static $sfoo = 1;
    private $ifoo = 2;
}
$cl1 = static function() {
    return A::$sfoo;
};
$cl2 = function() {
    return $this->ifoo;
};

$bcl1 = Closure::bind($cl1, null, 'A');
$bcl2 = Closure::bind($cl2, new A(), 'A');
echo $bcl1(), "\n";
echo $bcl2(), "\n";
?>

   
```

ENTITY

    1
    2

       

</div>

# 

ENTITY

Anonymous functions

Closure::bindTo

# bindto

Closure::bindTo

Duplicates the closure with a new bound object and class scope

# 

ENTITY

<div data-wrapper="1" role="Closure">

public

</div>

<div data-wrapper="1" role="Closure">

Closure

</div>

<div data-wrapper="1" role="Closure">

null

</div>

<div data-wrapper="1" role="Closure">

Closure::bindTo

</div>

<div data-wrapper="1" role="Closure">

object

</div>

<div data-wrapper="1" role="Closure">

null

</div>

<div data-wrapper="1" role="Closure">

newThis

</div>

<div data-wrapper="1" role="Closure">

object

</div>

<div data-wrapper="1" role="Closure">

string

</div>

<div data-wrapper="1" role="Closure">

null

</div>

<div data-wrapper="1" role="Closure">

newScope

</div>

<div data-wrapper="1" role="Closure">

"static"

</div>

Create and return a new [anonymous function](#functions.anonymous) with the same body and bound variables as this one, but possibly with a different bound object and a new class scope.

The “bound object” determines the value `$this` will have in the function body and the “class scope” represents a class which determines which private and protected members the anonymous function will be able to access. Namely, the members that will be visible are the same as if the anonymous function were a method of the class given as value of the `newScope` parameter.

Static closures cannot have any bound object (the value of the parameter `newThis` should be ENTITY), but this method can nevertheless be used to change their class scope.

This method will ensure that for a non-static closure, having a bound instance will imply being scoped and vice-versa. To this end, non-static closures that are given a scope but a ENTITY instance are made static and non-static non-scoped closures that are given a non-null instance are scoped to an unspecified class.

> [!NOTE]
> If you only want to duplicate the anonymous functions, you can use [cloning](#language.oop5.cloning) instead.

# 

ENTITY

`newThis`  
The object to which the given anonymous function should be bound, or ENTITY for the closure to be unbound.

`newScope`  
The class scope to which the closure is to be associated, or 'static' to keep the current one. If an object is given, the type of the object will be used instead. This determines the visibility of protected and private methods of the bound object. It is not allowed to pass (an object of) an internal class as this parameter.

# 

ENTITY

Returns the newly created `Closure` object or ENTITY on failure.

# 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.5.0 | Binding an instance to a static closure, or binding a method from an incompatible class hierarchy, is now deprecated (these cases already emitted an `E_WARNING`). |

# 

ENTITY

<div class="example">

<div class="title">

`Closure::bindTo` example

</div>

```
<?php

class A
{
    private $val;

    public function __construct($val)
    {
        $this->val = $val;
    }

    public function getClosure()
    {
        // Returns closure bound to this object and scope
        return function() {
            return $this->val;
        };
    }
}

$ob1 = new A(1);
$ob2 = new A(2);

$cl = $ob1->getClosure();
echo $cl(), "\n";

$cl = $cl->bindTo($ob2);
echo $cl(), "\n";

?>

   
```

ENTITY

    1
    2

       

</div>

# 

ENTITY

Anonymous functions

Closure::bind

# call

Closure::call

Binds and calls the closure

# 

ENTITY

<div data-wrapper="1" role="Closure">

public

</div>

<div data-wrapper="1" role="Closure">

mixed

</div>

<div data-wrapper="1" role="Closure">

Closure::call

</div>

<div data-wrapper="1" role="Closure">

object

</div>

<div data-wrapper="1" role="Closure">

newThis

</div>

<div data-wrapper="1" role="Closure">

mixed

</div>

<div data-wrapper="1" role="Closure">

args

</div>

Temporarily binds the closure to `newThis`, and calls it with any given parameters.

# 

ENTITY

`newThis`  
The `object` to bind the closure to for the duration of the call.

`args`  
Zero or more parameters, which will be given as parameters to the closure.

# 

ENTITY

Returns the return value of the closure.

# 

ENTITY

<div class="example">

<div class="title">

`Closure::call` example

</div>

```
<?php
class Value {
    protected $value;

    public function __construct($value) {
        $this->value = $value;
    }

    public function getValue() {
        return $this->value;
    }
}

$three = new Value(3);
$four = new Value(4);

$closure = function ($delta) { var_dump($this->getValue() + $delta); };
$closure->call($three, 4);
$closure->call($four, 4);
?>

   
```

ENTITY

    int(7)
    int(8)

       

</div>

# construct

Closure::\_\_construct

Constructor that disallows instantiation

# 

ENTITY

<div data-wrapper="1" role="Closure">

private

</div>

<div data-wrapper="1" role="Closure">

Closure::\_\_construct

</div>

This method exists only to disallow instantiation of the `Closure` class. Objects of this class are created in the fashion described on the [anonymous functions](#functions.anonymous) page.

# 

ENTITY ENTITY

# 

ENTITY

Anonymous functions

# fromcallable

Closure::fromCallable

Converts a callable into a closure

# 

ENTITY

<div data-wrapper="1" role="Closure">

public

</div>

<div data-wrapper="1" role="Closure">

static

</div>

<div data-wrapper="1" role="Closure">

Closure

</div>

<div data-wrapper="1" role="Closure">

Closure::fromCallable

</div>

<div data-wrapper="1" role="Closure">

callable

</div>

<div data-wrapper="1" role="Closure">

callback

</div>

Create and return a new [anonymous function](#functions.anonymous) from given `callback` using the current scope. This method checks if the `callback` is callable in the current scope and throws a TypeError if it is not.

> [!NOTE]
> As of PHP 8.1.0, [First class callable syntax](#functions.first_class_callable_syntax) has the same semantics as this method.

# 

ENTITY

`callback`  
The callable to convert.

# 

ENTITY

Returns the newly created `Closure` or throws a TypeError if the `callback` is not callable in the current scope.

# 

ENTITY

Anonymous functions

First class callable syntax

# getcurrent

Closure::getCurrent

Returns the currently executing closure

# 

ENTITY

<div data-wrapper="1" role="Closure">

public

</div>

<div data-wrapper="1" role="Closure">

static

</div>

<div data-wrapper="1" role="Closure">

Closure

</div>

<div data-wrapper="1" role="Closure">

Closure::getCurrent

</div>

Returns the currently executing closure. This method is primarily useful for implementing recursive closures without needing to capture a reference to the closure variable using the `use` keyword.

This method must be called from within a closure; calling it outside of a closure context will result in `Error: Current function is not a closure.`

# 

ENTITY ENTITY

# 

ENTITY

Returns the currently executing `Closure` instance.

# 

ENTITY

Throws an Error if called outside of a closure context.

# 

ENTITY

<div id="closure.getcurrent.example.basic" class="example">

<div class="title">

Closure::getCurrent example

</div>

Using Closure::getCurrent to implement a recursive Fibonacci function:

```
<?php
$fibonacci = function (int $n) {
    if ($n === 0 || $n === 1) {
        return $n;
    }

    $fn = Closure::getCurrent();
    return $fn($n - 1) + $fn($n - 2);
};

echo $fibonacci(10); // Outputs: 55
?>

   
```

</div>

<div id="closure.getcurrent.example.comparison" class="example">

<div class="title">

Comparison with traditional approach

</div>

Prior to PHP 8.5, implementing recursive closures required capturing a reference to the closure variable using the `use` keyword:

```
<?php
// Traditional approach (still works in PHP 8.5)
$fibonacci = function (int $n) use (&$fibonacci) {
    if ($n === 0) return 0;
    if ($n === 1) return 1;
    return $fibonacci($n - 1) + $fibonacci($n - 2);
};

echo $fibonacci(10); // Outputs: 55
?>

   
```

The Closure::getCurrent approach eliminates the need to declare the variable with a reference in the `use` clause, making the code cleaner and less error-prone.

</div>

# compileerror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`CompileError` is thrown for some compilation errors, which formerly issued a fatal error.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

CompileError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Error

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# countable

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Classes implementing `Countable` can be used with the `count` function.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Countable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# count

Countable::count

Count elements of an object

# 

ENTITY

<div data-wrapper="1" role="Countable">

public

</div>

<div data-wrapper="1" role="Countable">

int

</div>

<div data-wrapper="1" role="Countable">

Countable::count

</div>

This method is executed when the `value` for `count` is an object implementing `Countable`.

# 

ENTITY ENTITY

# 

ENTITY

The custom count as an `int`.

# 

ENTITY

<div class="example">

<div class="title">

`Countable::count` example

</div>

```
<?php

class Counter implements Countable
{
    private $count = 0;

    public function count(): int
    {
        return ++$this->count;
    }
}

$counter = new Counter;

for ($i = 0; $i < 10; ++$i) {
    echo "I have been count()ed " . count($counter) . " times\n";
}

?>

   
```

ENTITY

    I have been count()ed 1 times
    I have been count()ed 2 times
    I have been count()ed 3 times
    I have been count()ed 4 times
    I have been count()ed 5 times
    I have been count()ed 6 times
    I have been count()ed 7 times
    I have been count()ed 8 times
    I have been count()ed 9 times
    I have been count()ed 10 times

       

</div>

# divisionbyzeroerror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`DivisionByZeroError` is thrown when an attempt is made to divide a number by zero.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

DivisionByZeroError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

ArithmeticError

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# error

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`Error` is the base class for errors that indicate programming mistakes. Such errors generally require a correction to the program rather than being handled during normal operation.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Error

</div>

<div data-wrapper="1" role="class">

implements

</div>

<div data-wrapper="1" role="class">

Throwable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

protected

</div>

<div data-wrapper="1" role="class">

string

</div>

<div data-wrapper="1" role="class">

message

</div>

<div data-wrapper="1" role="class">

""

</div>

<div data-wrapper="1" role="class">

private

</div>

<div data-wrapper="1" role="class">

string

</div>

<div data-wrapper="1" role="class">

string

</div>

<div data-wrapper="1" role="class">

""

</div>

<div data-wrapper="1" role="class">

protected

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

code

</div>

<div data-wrapper="1" role="class">

protected

</div>

<div data-wrapper="1" role="class">

string

</div>

<div data-wrapper="1" role="class">

file

</div>

<div data-wrapper="1" role="class">

""

</div>

<div data-wrapper="1" role="class">

protected

</div>

<div data-wrapper="1" role="class">

int

</div>

<div data-wrapper="1" role="class">

line

</div>

<div data-wrapper="1" role="class">

private

</div>

<div data-wrapper="1" role="class">

array

</div>

<div data-wrapper="1" role="class">

trace

</div>

<div data-wrapper="1" role="class">

\[\]

</div>

<div data-wrapper="1" role="class">

private

</div>

<div data-wrapper="1" role="class">

Throwable

</div>

<div data-wrapper="1" role="class">

null

</div>

<div data-wrapper="1" role="class">

previous

</div>

<div data-wrapper="1" role="class">

null

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`message`  
The error message

`code`  
The error code

`file`  
The filename where the error happened

`line`  
The line where the error happened

`previous`  
The previously thrown exception

`string`  
The string representation of the stack trace

`trace`  
The stack trace as an array

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# clone

Error::\_\_clone

Clone the error

# 

ENTITY

<div data-wrapper="1" role="Error">

private

</div>

<div data-wrapper="1" role="Error">

void

</div>

<div data-wrapper="1" role="Error">

Error::\_\_clone

</div>

Errors do not support cloning; this method exists only to prevent it.

> [!WARNING]
> Errors cannot be cloned, whether they are instances of Error or of a subclass. Attempting to [clone](#language.oop5.cloning) an error throws an Error, which may be caught.

# 

ENTITY ENTITY

# 

ENTITY

ENTITY

# 

ENTITY

Attempting to clone an error throws an Error with the following message: `Trying to clone an uncloneable object of class ClassName`.

# 

ENTITY

| ENTITY | ENTITY                               |
|--------|--------------------------------------|
| 8.1.0  | Error::\_\_clone is no longer final. |

# construct

Error::\_\_construct

Construct the error object

# 

ENTITY

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

Error::\_\_construct

</div>

<div data-wrapper="1" role="Error">

string

</div>

<div data-wrapper="1" role="Error">

message

</div>

<div data-wrapper="1" role="Error">

""

</div>

<div data-wrapper="1" role="Error">

int

</div>

<div data-wrapper="1" role="Error">

code

</div>

<div data-wrapper="1" role="Error">

0

</div>

<div data-wrapper="1" role="Error">

Throwable

</div>

<div data-wrapper="1" role="Error">

null

</div>

<div data-wrapper="1" role="Error">

previous

</div>

<div data-wrapper="1" role="Error">

ENTITY

</div>

Constructs the Error.

# 

ENTITY

`message`  
The error message.

`code`  
The error code.

`previous`  
The previous throwable used for the exception chaining.

# 

ENTITY

> [!NOTE]
> The `message` is *NOT* binary safe.

# getcode

Error::getCode

Gets the error code

# 

ENTITY

<div data-wrapper="1" role="Error">

final

</div>

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

int

</div>

<div data-wrapper="1" role="Error">

Error::getCode

</div>

Returns the error code.

# 

ENTITY ENTITY

# 

ENTITY

Returns the error code as `int`

# 

ENTITY

<div class="example">

<div class="title">

`Error::getCode` example

</div>

```
<?php
try {
    throw new Error("Some error message", 30);
} catch(Error $e) {
    echo "The Error code is: " . $e->getCode();
}
?>

    
```

ENTITY

    The Error code is: 30

        

</div>

# 

ENTITY

Throwable::getCode

# getfile

Error::getFile

Gets the file in which the error occurred

# 

ENTITY

<div data-wrapper="1" role="Error">

final

</div>

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

string

</div>

<div data-wrapper="1" role="Error">

Error::getFile

</div>

Get the name of the file the error occurred.

# 

ENTITY ENTITY

# 

ENTITY

Returns the filename in which the error occurred.

# 

ENTITY

<div class="example">

<div class="title">

`Error::getFile` example

</div>

```
<?php
try {
    throw new Error;
} catch(Error $e) {
    echo $e->getFile();
}
?>

    
```

ENTITY

    /home/bjori/tmp/ex.php

        

</div>

# 

ENTITY

Throwable::getFile

# getline

Error::getLine

Gets the line in which the error occurred

# 

ENTITY

<div data-wrapper="1" role="Error">

final

</div>

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

int

</div>

<div data-wrapper="1" role="Error">

Error::getLine

</div>

Get line number where the error occurred.

# 

ENTITY ENTITY

# 

ENTITY

Returns the line number where the error occurred.

# 

ENTITY

<div class="example">

<div class="title">

`Error::getLine` example

</div>

```
<?php
try {
    throw new Error("Some error message");
} catch(Error $e) {
    echo "The error was created on line: " . $e->getLine();
}
?>

    
```

ENTITY

    The error was created on line: 3

        

</div>

# 

ENTITY

Throwable::getLine

# getmessage

Error::getMessage

Gets the error message

# 

ENTITY

<div data-wrapper="1" role="Error">

final

</div>

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

string

</div>

<div data-wrapper="1" role="Error">

Error::getMessage

</div>

Returns the error message.

# 

ENTITY ENTITY

# 

ENTITY

Returns the error message as a string.

# 

ENTITY

<div class="example">

<div class="title">

`Error::getMessage` example

</div>

```
<?php
try {
    throw new Error("Some error message");
} catch(Error $e) {
    echo $e->getMessage();
}
?>

    
```

ENTITY

    Some error message

        

</div>

# 

ENTITY

Throwable::getMessage

# getprevious

Error::getPrevious

Returns previous Throwable

# 

ENTITY

<div data-wrapper="1" role="Error">

final

</div>

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

Throwable

</div>

<div data-wrapper="1" role="Error">

null

</div>

<div data-wrapper="1" role="Error">

Error::getPrevious

</div>

Returns previous Throwable (the third parameter of Error::\_\_construct).

# 

ENTITY ENTITY

# 

ENTITY

Returns the previous `Throwable` if available or ENTITY otherwise.

# 

ENTITY

<div class="example">

<div class="title">

Error::getPrevious example

</div>

Looping over, and printing out, error trace.

```
<?php
class MyCustomError extends Error {}

function doStuff() {
    try {
        throw new TypeError("You are doing it wrong!", 112);
    } catch(Error $e) {
        throw new MyCustomError("Something happened", 911, $e);
    }
}


try {
    doStuff();
} catch(Error $e) {
    do {
        printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
    } while($e = $e->getPrevious());
}
?>

    
```

ENTITY

    /home/bjori/ex.php:8 Something happened (911) [MyCustomError]
    /home/bjori/ex.php:6 You are doing it wrong! (112) [TypeError]

        

</div>

# 

ENTITY

Throwable::getPrevious

# gettrace

Error::getTrace

Gets the stack trace

# 

ENTITY

<div data-wrapper="1" role="Error">

final

</div>

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

array

</div>

<div data-wrapper="1" role="Error">

Error::getTrace

</div>

Returns the stack trace.

# 

ENTITY ENTITY

# 

ENTITY

Returns the stack trace as an `array`.

# 

ENTITY

<div class="example">

<div class="title">

`Error::getTrace` example

</div>

```
<?php
function test() {
 throw new Error;
}

try {
 test();
} catch(Error $e) {
 var_dump($e->getTrace());
}
?>

    
```

ENTITY

    array(1) {
      [0]=>
      array(4) {
        ["file"]=>
        string(22) "/home/bjori/tmp/ex.php"
        ["line"]=>
        int(7)
        ["function"]=>
        string(4) "test"
        ["args"]=>
        array(0) {
        }
      }
    }

        

</div>

# 

ENTITY

Throwable::getTrace

# gettraceasstring

Error::getTraceAsString

Gets the stack trace as a string

# 

ENTITY

<div data-wrapper="1" role="Error">

final

</div>

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

string

</div>

<div data-wrapper="1" role="Error">

Error::getTraceAsString

</div>

Returns the stack trace as a string.

# 

ENTITY ENTITY

# 

ENTITY

Returns the stack trace as a string.

# 

ENTITY

<div class="example">

<div class="title">

`Error::getTraceAsString` example

</div>

```
<?php
function test() {
    throw new Error;
}

try {
    test();
} catch(Error $e) {
    echo $e->getTraceAsString();
}
?>

    
```

ENTITY

    #0 /home/bjori/tmp/ex.php(7): test()
    #1 {main}

        

</div>

# 

ENTITY

Throwable::getTraceAsString

# tostring

Error::\_\_toString

String representation of the error

# 

ENTITY

<div data-wrapper="1" role="Error">

public

</div>

<div data-wrapper="1" role="Error">

string

</div>

<div data-wrapper="1" role="Error">

Error::\_\_toString

</div>

Returns the `string` representation of the error.

# 

ENTITY ENTITY

# 

ENTITY

Returns the `string` representation of the error.

# 

ENTITY

<div class="example">

<div class="title">

`Error::__toString` example

</div>

```
<?php
try {
    throw new Error("Some error message");
} catch(Error $e) {
    echo $e;
}
?>

    
```

ENTITY

    Error: Some error message in /home/bjori/tmp/ex.php:3
    Stack trace:
    #0 {main}

        

</div>

# 

ENTITY

Throwable::\_\_toString

# errorexception

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

An Error Exception.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

ErrorException

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Exception

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="exception">

protected

</div>

<div data-wrapper="1" role="exception">

int

</div>

<div data-wrapper="1" role="exception">

severity

</div>

<div data-wrapper="1" role="exception">

E_ERROR

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`severity`  
The severity of the exception

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div id="errorexception.example.error-handler" class="example" role="exception">

<div class="title">

Use `set_error_handler` to change error messages into ErrorException

</div>

```
 
<?php

set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
    if (!(error_reporting() & $errno)) {
        // This error code is not included in error_reporting.
        return;
    }

    if ($errno === E_DEPRECATED || $errno === E_USER_DEPRECATED) {
        // Do not throw an Exception for deprecation warnings as new or unexpected
        // deprecations would break the application.
        return;
    }

    throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
});

// Unserializing broken data triggers a warning which will be turned into an
// ErrorException by the error handler.
unserialize('broken data');

?>

     
```

ENTITY

    Fatal error: Uncaught ErrorException: unserialize(): Error at offset 0 of 11 bytes in test.php:16
    Stack trace:
    #0 [internal function]: {closure}(2, 'unserialize(): ...', 'test.php', 16)
    #1 test.php(16): unserialize('broken data')
    #2 {main}
      thrown in test.php on line 16

         

</div>

<div data-wrapper="1" role="exception">

ENTITY ENTITY

</div>

# construct

ErrorException::\_\_construct

Constructs the exception

# 

ENTITY

<div data-wrapper="1" role="ErrorException">

public

</div>

<div data-wrapper="1" role="ErrorException">

ErrorException::\_\_construct

</div>

<div data-wrapper="1" role="ErrorException">

string

</div>

<div data-wrapper="1" role="ErrorException">

message

</div>

<div data-wrapper="1" role="ErrorException">

""

</div>

<div data-wrapper="1" role="ErrorException">

int

</div>

<div data-wrapper="1" role="ErrorException">

code

</div>

<div data-wrapper="1" role="ErrorException">

0

</div>

<div data-wrapper="1" role="ErrorException">

int

</div>

<div data-wrapper="1" role="ErrorException">

severity

</div>

<div data-wrapper="1" role="ErrorException">

E_ERROR

</div>

<div data-wrapper="1" role="ErrorException">

string

</div>

<div data-wrapper="1" role="ErrorException">

null

</div>

<div data-wrapper="1" role="ErrorException">

filename

</div>

<div data-wrapper="1" role="ErrorException">

ENTITY

</div>

<div data-wrapper="1" role="ErrorException">

int

</div>

<div data-wrapper="1" role="ErrorException">

null

</div>

<div data-wrapper="1" role="ErrorException">

line

</div>

<div data-wrapper="1" role="ErrorException">

ENTITY

</div>

<div data-wrapper="1" role="ErrorException">

Throwable

</div>

<div data-wrapper="1" role="ErrorException">

null

</div>

<div data-wrapper="1" role="ErrorException">

previous

</div>

<div data-wrapper="1" role="ErrorException">

ENTITY

</div>

Constructs the Exception.

# 

ENTITY

`message`  
The Exception message to throw.

`code`  
The Exception code.

`severity`  
The severity level of the exception.

> [!NOTE]
> While the severity can be any `int` value, it is intended that the [error constants](#errorfunc.constants) be used.

`filename`  
The filename where the exception is thrown.

`line`  
The line number where the exception is thrown.

`previous`  
The previous exception used for the exception chaining.

# 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.0.0 | `filename` and `line` are nullable now. Previously, their defaults were `__FILE__` and `__LINE__`, respectively. |

# getseverity

ErrorException::getSeverity

Gets the exception severity

# 

ENTITY

<div data-wrapper="1" role="ErrorException">

final

</div>

<div data-wrapper="1" role="ErrorException">

public

</div>

<div data-wrapper="1" role="ErrorException">

int

</div>

<div data-wrapper="1" role="ErrorException">

ErrorException::getSeverity

</div>

Returns the severity of the exception.

# 

ENTITY ENTITY

# 

ENTITY

Returns the severity level of the exception.

# 

ENTITY

<div class="example">

<div class="title">

`ErrorException::getSeverity` example

</div>

```
<?php
try {
    throw new ErrorException("Exception message", 0, E_USER_ERROR);
} catch(ErrorException $e) {
    echo "This exception severity is: " . $e->getSeverity();
    var_dump($e->getSeverity() === E_USER_ERROR);
}
?>

    
```

ENTITY

    This exception severity is: 256
    bool(true)

        

</div>

# exception

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`Exception` is the base class for exceptions that can be handled during normal operation.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

Exception

</div>

<div data-wrapper="1" role="exception">

implements

</div>

<div data-wrapper="1" role="exception">

Throwable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="exception">

protected

</div>

<div data-wrapper="1" role="exception">

string

</div>

<div data-wrapper="1" role="exception">

message

</div>

<div data-wrapper="1" role="exception">

""

</div>

<div data-wrapper="1" role="exception">

private

</div>

<div data-wrapper="1" role="exception">

string

</div>

<div data-wrapper="1" role="exception">

string

</div>

<div data-wrapper="1" role="exception">

""

</div>

<div data-wrapper="1" role="exception">

protected

</div>

<div data-wrapper="1" role="exception">

int

</div>

<div data-wrapper="1" role="exception">

code

</div>

<div data-wrapper="1" role="exception">

protected

</div>

<div data-wrapper="1" role="exception">

string

</div>

<div data-wrapper="1" role="exception">

file

</div>

<div data-wrapper="1" role="exception">

""

</div>

<div data-wrapper="1" role="exception">

protected

</div>

<div data-wrapper="1" role="exception">

int

</div>

<div data-wrapper="1" role="exception">

line

</div>

<div data-wrapper="1" role="exception">

private

</div>

<div data-wrapper="1" role="exception">

array

</div>

<div data-wrapper="1" role="exception">

trace

</div>

<div data-wrapper="1" role="exception">

\[\]

</div>

<div data-wrapper="1" role="exception">

private

</div>

<div data-wrapper="1" role="exception">

Throwable

</div>

<div data-wrapper="1" role="exception">

null

</div>

<div data-wrapper="1" role="exception">

previous

</div>

<div data-wrapper="1" role="exception">

null

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`message`  
The exception message

`code`  
The exception code

`file`  
The filename where the exception was created

`line`  
The line where the exception was created

`previous`  
The previously thrown exception

`string`  
The string representation of the stack trace

`trace`  
The stack trace as an array

</div>

<div data-wrapper="1" role="exception">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# clone

Exception::\_\_clone

Clone the exception

# 

ENTITY

<div data-wrapper="1" role="Exception">

private

</div>

<div data-wrapper="1" role="Exception">

void

</div>

<div data-wrapper="1" role="Exception">

Exception::\_\_clone

</div>

Exceptions do not support cloning; this method exists only to prevent it.

> [!WARNING]
> Exceptions cannot be cloned, whether they are instances of Exception or of a subclass. Attempting to [clone](#language.oop5.cloning) an exception throws an Error, which may be caught.

# 

ENTITY ENTITY

# 

ENTITY

ENTITY

# 

ENTITY

Attempting to clone an exception throws an Error with the following message: `Trying to clone an uncloneable object of class ClassName`.

# 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.1.0 | Exception::\_\_clone is no longer declared final, because [declaring a private method final](#language.oop5.final) emits a warning as of PHP 8.0.0. Exceptions remain uncloneable. |

# construct

Exception::\_\_construct

Construct the exception

# 

ENTITY

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

Exception::\_\_construct

</div>

<div data-wrapper="1" role="Exception">

string

</div>

<div data-wrapper="1" role="Exception">

message

</div>

<div data-wrapper="1" role="Exception">

""

</div>

<div data-wrapper="1" role="Exception">

int

</div>

<div data-wrapper="1" role="Exception">

code

</div>

<div data-wrapper="1" role="Exception">

0

</div>

<div data-wrapper="1" role="Exception">

Throwable

</div>

<div data-wrapper="1" role="Exception">

null

</div>

<div data-wrapper="1" role="Exception">

previous

</div>

<div data-wrapper="1" role="Exception">

ENTITY

</div>

Constructs the Exception.

# 

ENTITY

`message`  
The Exception message to throw.

`code`  
The Exception code.

`previous`  
The previous exception used for the exception chaining.

> [!NOTE]
> Calling the constructor of class Exception from a subclass ignores the default arguments, if the properties \$code and \$message are already set.

# 

ENTITY

> [!NOTE]
> The `message` is *NOT* binary safe.

# getcode

Exception::getCode

Gets the Exception code

# 

ENTITY

<div data-wrapper="1" role="Exception">

final

</div>

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

int

</div>

<div data-wrapper="1" role="Exception">

Exception::getCode

</div>

Returns the Exception code.

# 

ENTITY ENTITY

# 

ENTITY

Returns the exception code as `int` in `Exception` but possibly as other type in `Exception` descendants (for example as `string` in `PDOException`).

# 

ENTITY

<div class="example">

<div class="title">

`Exception::getCode` example

</div>

```
<?php
try {
    throw new Exception("Some error message", 30);
} catch(Exception $e) {
    echo "The exception code is: " . $e->getCode();
}
?>

    
```

ENTITY

    The exception code is: 30

        

</div>

# 

ENTITY

Throwable::getCode

# getfile

Exception::getFile

Gets the file in which the exception was created

# 

ENTITY

<div data-wrapper="1" role="Exception">

final

</div>

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

string

</div>

<div data-wrapper="1" role="Exception">

Exception::getFile

</div>

Get the name of the file in which the exception was created.

# 

ENTITY ENTITY

# 

ENTITY

Returns the filename in which the exception was created.

# 

ENTITY

<div class="example">

<div class="title">

`Exception::getFile` example

</div>

```
<?php
try {
    throw new Exception;
} catch(Exception $e) {
    echo $e->getFile();
}
?>

    
```

ENTITY

    /home/bjori/tmp/ex.php

        

</div>

# 

ENTITY

Throwable::getFile

# getline

Exception::getLine

Gets the line in which the exception was created

# 

ENTITY

<div data-wrapper="1" role="Exception">

final

</div>

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

int

</div>

<div data-wrapper="1" role="Exception">

Exception::getLine

</div>

Get line number where the exception was created.

# 

ENTITY ENTITY

# 

ENTITY

Returns the line number where the exception was created.

# 

ENTITY

<div class="example">

<div class="title">

`Exception::getLine` example

</div>

```
<?php
try {
    throw new Exception("Some error message");
} catch(Exception $e) {
    echo "The exception was created on line: " . $e->getLine();
}
?>

    
```

ENTITY

    The exception was created on line: 3

        

</div>

# 

ENTITY

Throwable::getLine

# getmessage

Exception::getMessage

Gets the Exception message

# 

ENTITY

<div data-wrapper="1" role="Exception">

final

</div>

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

string

</div>

<div data-wrapper="1" role="Exception">

Exception::getMessage

</div>

Returns the Exception message.

# 

ENTITY ENTITY

# 

ENTITY

Returns the Exception message as a string.

# 

ENTITY

<div class="example">

<div class="title">

`Exception::getMessage` example

</div>

```
<?php
try {
    throw new Exception("Some error message");
} catch(Exception $e) {
    echo $e->getMessage();
}
?>

    
```

ENTITY

    Some error message

        

</div>

# 

ENTITY

Throwable::getMessage

# getprevious

Exception::getPrevious

Returns previous Throwable

# 

ENTITY

<div data-wrapper="1" role="Exception">

final

</div>

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

Throwable

</div>

<div data-wrapper="1" role="Exception">

null

</div>

<div data-wrapper="1" role="Exception">

Exception::getPrevious

</div>

Returns previous `Throwable` (which had been passed as the third parameter of Exception::\_\_construct).

# 

ENTITY ENTITY

# 

ENTITY

Returns the previous `Throwable` if available or ENTITY otherwise.

# 

ENTITY

<div class="example">

<div class="title">

Exception::getPrevious example

</div>

Looping over, and printing out, exception trace.

```
<?php
class MyCustomException extends Exception {}

function doStuff() {
    try {
        throw new InvalidArgumentException("You are doing it wrong!", 112);
    } catch(Exception $e) {
        throw new MyCustomException("Something happened", 911, $e);
    }
}


try {
    doStuff();
} catch(Exception $e) {
    do {
        printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
    } while($e = $e->getPrevious());
}
?>

    
```

ENTITY

    /home/bjori/ex.php:8 Something happened (911) [MyCustomException]
    /home/bjori/ex.php:6 You are doing it wrong! (112) [InvalidArgumentException]

        

</div>

# 

ENTITY

Throwable::getPrevious

# gettrace

Exception::getTrace

Gets the stack trace

# 

ENTITY

<div data-wrapper="1" role="Exception">

final

</div>

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

array

</div>

<div data-wrapper="1" role="Exception">

Exception::getTrace

</div>

Returns the Exception stack trace.

# 

ENTITY ENTITY

# 

ENTITY

Returns the Exception stack trace as an `array`.

# 

ENTITY

<div class="example">

<div class="title">

`Exception::getTrace` example

</div>

```
<?php
function test() {
 throw new Exception;
}

try {
 test();
} catch(Exception $e) {
 var_dump($e->getTrace());
}
?>

    
```

ENTITY

    array(1) {
      [0]=>
      array(4) {
        ["file"]=>
        string(22) "/home/bjori/tmp/ex.php"
        ["line"]=>
        int(7)
        ["function"]=>
        string(4) "test"
        ["args"]=>
        array(0) {
        }
      }
    }

        

</div>

# 

ENTITY

Throwable::getTrace

# gettraceasstring

Exception::getTraceAsString

Gets the stack trace as a string

# 

ENTITY

<div data-wrapper="1" role="Exception">

final

</div>

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

string

</div>

<div data-wrapper="1" role="Exception">

Exception::getTraceAsString

</div>

Returns the Exception stack trace as a string.

# 

ENTITY ENTITY

# 

ENTITY

Returns the Exception stack trace as a string.

# 

ENTITY

<div class="example">

<div class="title">

`Exception::getTraceAsString` example

</div>

```
<?php
function test() {
    throw new Exception;
}

try {
    test();
} catch(Exception $e) {
    echo $e->getTraceAsString();
}
?>

    
```

ENTITY

    #0 /home/bjori/tmp/ex.php(7): test()
    #1 {main}

        

</div>

# 

ENTITY

Throwable::getTraceAsString

# tostring

Exception::\_\_toString

String representation of the exception

# 

ENTITY

<div data-wrapper="1" role="Exception">

public

</div>

<div data-wrapper="1" role="Exception">

string

</div>

<div data-wrapper="1" role="Exception">

Exception::\_\_toString

</div>

Returns the `string` representation of the exception.

# 

ENTITY ENTITY

# 

ENTITY

Returns the `string` representation of the exception.

# 

ENTITY

<div class="example">

<div class="title">

`Exception::__toString` example

</div>

```
<?php
try {
    throw new Exception("Some error message");
} catch(Exception $e) {
    echo $e;
}
?>

    
```

ENTITY

    exception 'Exception' with message 'Some error message' in /home/bjori/tmp/ex.php:3
    Stack trace:
    #0 {main}

        

</div>

# 

ENTITY

Throwable::\_\_toString

# Predefined Exceptions

See also the [SPL Exceptions](#spl.exceptions).

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# fiber

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Fibers represent full-stack, interruptible functions. Fibers may be suspended from anywhere in the call-stack, pausing execution within the fiber until the fiber is resumed at a later time.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

Fiber

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

[Fibers overview](#language.fibers)

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# construct

Fiber::\_\_construct

Creates a new Fiber instance

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

Fiber::\_\_construct

</div>

<div data-wrapper="1" role="Fiber">

callable

</div>

<div data-wrapper="1" role="Fiber">

callback

</div>

# 

ENTITY

`callback`  
The `callable` to invoke when starting the fiber. Arguments given to Fiber::start will be provided as arguments to the given callable.

# getcurrent

Fiber::getCurrent

Gets the currently executing Fiber instance

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

static

</div>

<div data-wrapper="1" role="Fiber">

Fiber

</div>

<div data-wrapper="1" role="Fiber">

null

</div>

<div data-wrapper="1" role="Fiber">

Fiber::getCurrent

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns the currently executing `Fiber` instance or ENTITY if this method is called from outside a fiber.

# getreturn

Fiber::getReturn

Gets the value returned by the Fiber

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

Fiber::getReturn

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns the value returned by the `callable` provided to Fiber::\_\_construct. If the fiber has not returned a value, either because it has not been started, has not terminated, or threw an exception, a FiberError will be thrown.

# isrunning

Fiber::isRunning

Determines if the fiber is running

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

bool

</div>

<div data-wrapper="1" role="Fiber">

Fiber::isRunning

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns ENTITY only if the fiber is running. A fiber is considered running after a call to Fiber::start, Fiber::resume, or Fiber::throw that has not yet returned. Returns ENTITY if the fiber is not running.

# isstarted

Fiber::isStarted

Determines if the fiber has started

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

bool

</div>

<div data-wrapper="1" role="Fiber">

Fiber::isStarted

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns ENTITY only after the fiber has been started; otherwise ENTITY is returned.

# issuspended

Fiber::isSuspended

Determines if the fiber is suspended

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

bool

</div>

<div data-wrapper="1" role="Fiber">

Fiber::isSuspended

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns ENTITY if the fiber is currently suspended; otherwise ENTITY is returned.

# isterminated

Fiber::isTerminated

Determines if the fiber has terminated

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

bool

</div>

<div data-wrapper="1" role="Fiber">

Fiber::isTerminated

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns ENTITY only after the fiber has terminated, either by returning or throwing an exception; otherwise ENTITY is returned.

# resume

Fiber::resume

Resumes execution of the fiber with a value

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

Fiber::resume

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

value

</div>

<div data-wrapper="1" role="Fiber">

ENTITY

</div>

Resumes the fiber using the given value as the result of the current Fiber::suspend call.

If the fiber is not suspended when this method is called, a FiberError will be thrown.

# 

ENTITY

`value`  
The value to resume the fiber. This value will be the return value of the current Fiber::suspend call.

# 

ENTITY

The value provided to the next call to Fiber::suspend or ENTITY if the fiber returns. If the fiber throws an exception before suspending, it will be thrown from the call to this method.

# start

Fiber::start

Start execution of the fiber

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

Fiber::start

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

args

</div>

A variadic list of arguments to provide to the callable used when constructing the fiber.

If the fiber has already been started when this method is called, a FiberError will be thrown.

# 

ENTITY

`args`  
The arguments to use when invoking the callable given to the fiber constructor.

# 

ENTITY

The value provided to the first call to Fiber::suspend or ENTITY if the fiber returns. If the fiber throws an exception before suspending, it will be thrown from the call to this method.

# suspend

Fiber::suspend

Suspends execution of the current fiber

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

static

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

Fiber::suspend

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

value

</div>

<div data-wrapper="1" role="Fiber">

ENTITY

</div>

Suspends execution of the current fiber. The value provided to this method will be returned from the call to Fiber::start, Fiber::resume, or Fiber::throw that switched execution into the current fiber.

When the fiber is resumed, this method returns the value provided to Fiber::resume. If the fiber is resumed using Fiber::throw, the exception given to that method will be thrown from the call to this method.

If this method is called from outside a fiber, a FiberError will be thrown.

# 

ENTITY

`value`  
The value to return from the call to Fiber::start, Fiber::resume, or Fiber::throw that switched execution into the current fiber.

# 

ENTITY

The value provided to Fiber::resume.

# throw

Fiber::throw

Resumes execution of the fiber with an exception

# 

ENTITY

<div data-wrapper="1" role="Fiber">

public

</div>

<div data-wrapper="1" role="Fiber">

mixed

</div>

<div data-wrapper="1" role="Fiber">

Fiber::throw

</div>

<div data-wrapper="1" role="Fiber">

Throwable

</div>

<div data-wrapper="1" role="Fiber">

exception

</div>

Resumes the fiber by throwing the given exception from the current Fiber::suspend call.

If the fiber is not suspended when this method is called, a FiberError will be thrown.

# 

ENTITY

`exception`  
The exception to throw into the fiber from the current Fiber::suspend call.

# 

ENTITY

The value provided to the next call to Fiber::suspend or ENTITY if the fiber returns. If the fiber throws an exception before suspending, it will be thrown from the call to this method.

# 

ENTITY

<div class="informalexample">

```
<?php

$fiber = new Fiber(function () {
   try {
       // Suspend execution of the fiber declaring an interruption point
       Fiber::suspend();
   } catch (Throwable $e) {
       echo $e->getMessage();
   }
});

$fiber->start();

// Resumes execution of the fiber with
// passing the Exception to throw at the interruption point
$fiber->throw(new Exception('Message of an exception thrown at the current interrupt point'));

?>

   
```

ENTITY

    Message of an exception thrown at the current interrupt point

       

</div>

# fibererror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`FiberError` is thrown when an invalid operation is performed on a `Fiber`.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

final

</div>

<div data-wrapper="1" role="exception">

FiberError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Error

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="exception">

ENTITY

</div>

# construct

FiberError::\_\_construct

Constructor to disallow direct instantiation

# 

ENTITY

<div data-wrapper="1" role="FiberError">

public

</div>

<div data-wrapper="1" role="FiberError">

FiberError::\_\_construct

</div>

# 

ENTITY ENTITY

# 

ENTITY

Throws an Error exception when called.

# generator

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`Generator` objects are returned from [generators](#language.generators).

</div>

> [!CAUTION]
> `Generator` objects cannot be instantiated via [new](#language.oop5.basic.new).

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

Generator

</div>

<div data-wrapper="1" role="class">

implements

</div>

<div data-wrapper="1" role="class">

Iterator

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

See also [object iteration](#language.oop5.iterations).

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# current

Generator::current

Get the yielded value

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

mixed

</div>

<div data-wrapper="1" role="Generator">

Generator::current

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns the yielded value.

# getreturn

Generator::getReturn

Get the return value of a generator

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

mixed

</div>

<div data-wrapper="1" role="Generator">

Generator::getReturn

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns the generator's return value once it has finished executing.

# 

ENTITY

<div class="example">

<div class="title">

Generator::getReturn example

</div>

```
<?php

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;

    
```

ENTITY

    1
    2
    3

        

</div>

# key

Generator::key

Get the yielded key

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

mixed

</div>

<div data-wrapper="1" role="Generator">

Generator::key

</div>

Gets the key of the yielded value.

# 

ENTITY ENTITY

# 

ENTITY

Returns the yielded key.

# 

ENTITY

<div class="example">

<div class="title">

Generator::key example

</div>

```
<?php

function Gen()
{
    yield 'key' => 'value';
}

$gen = Gen();

echo "{$gen->key()} => {$gen->current()}";

    
```

ENTITY

    key => value

        

</div>

# next

Generator::next

Resume execution of the generator

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

void

</div>

<div data-wrapper="1" role="Generator">

Generator::next

</div>

Calling Generator::next has the same effect as calling Generator::send with ENTITY as argument.

# 

ENTITY ENTITY

# 

ENTITY

ENTITY

# rewind

Generator::rewind

Execute the generator up to and including the first yield

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

void

</div>

<div data-wrapper="1" role="Generator">

Generator::rewind

</div>

Executes the generator up to and including the *first* ENTITY. If the generator is already at the *first* ENTITY, no action will be taken. If the generator has ever advanced beyond a ENTITY expression, this method will throw an `Exception`.

> [!NOTE]
> This is the *first* method called when starting a ENTITY loop. It will *not* be executed *after* ENTITY loops.

# 

ENTITY ENTITY

# 

ENTITY

ENTITY

# 

ENTITY

<div class="example">

<div class="title">

Generator::rewind example

</div>

```
<?php

function generator(): Generator
{
    echo "I'm a generator!\n";

    for ($i = 1; $i <= 3; $i++) {
        yield $i;
    }
}

// Initialize the generator
$generator = generator();

// Rewind the generator to the beginning of the first yield expression,
// if it's not already there
$generator->rewind(); // I'm a generator!

// Nothing happens here; the generator is already rewound
$generator->rewind(); // No output (NULL)

// This rewinds the generator to the first yield expression,
// if it's not already there, and iterates over the generator
foreach ($generator as $value) {
    // After yielding the first value, the generator remains at
    // the first yield expression until it resumes execution and advances to the next yield
    echo $value, PHP_EOL; // 1

    break;
}

// Resume and rewind again. No error occurs because the generator has not advanced beyond the first yield
$generator->rewind();

echo $generator->current(), PHP_EOL; // 1

// No error occurs, the generator is still at the first yield
$generator->rewind();

// This advances the generator to the second yield expression
$generator->next();

try {
    // This will throw an Exception,
    // because the generator has already advanced to the second yield
    $generator->rewind(); // Fatal error: Uncaught Exception: Cannot rewind a generator that was already run
} catch (Exception $e) {
    echo $e->getMessage();
}

?>

    
```

ENTITY

    I'm a generator!
    1
    1
    Cannot rewind a generator that was already run

        

</div>

# send

Generator::send

Send a value to the generator

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

mixed

</div>

<div data-wrapper="1" role="Generator">

Generator::send

</div>

<div data-wrapper="1" role="Generator">

mixed

</div>

<div data-wrapper="1" role="Generator">

value

</div>

Sends the given value to the generator as the result of the current ENTITY expression and resumes execution of the generator.

If the generator is not at a ENTITY expression when this method is called, it will first be let to advance to the first ENTITY expression before sending the value. As such it is not necessary to "prime" PHP generators with a Generator::next call (like it is done in Python).

# 

ENTITY

`value`  
Value to send into the generator. This value will be the return value of the ENTITY expression the generator is currently at.

# 

ENTITY

Returns the yielded value.

# 

ENTITY

<div class="example">

<div class="title">

Using Generator::send to inject values

</div>

```
<?php
function printer() {
    echo "I'm printer!".PHP_EOL;
    while (true) {
        $string = yield;
        echo $string.PHP_EOL;
    }
}

$printer = printer();
$printer->send('Hello world!');
$printer->send('Bye world!');
?>

    
```

ENTITY

    I'm printer!
    Hello world!
    Bye world!

        

</div>

# throw

Generator::throw

Throw an exception into the generator

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

mixed

</div>

<div data-wrapper="1" role="Generator">

Generator::throw

</div>

<div data-wrapper="1" role="Generator">

Throwable

</div>

<div data-wrapper="1" role="Generator">

exception

</div>

Throws an exception into the generator and resumes execution of the generator. The behavior will be the same as if the current ENTITY expression was replaced with a `throw $exception` statement.

If the generator is already closed when this method is invoked, the exception will be thrown in the caller's context instead.

# 

ENTITY

`exception`  
Exception to throw into the generator.

# 

ENTITY

Returns the yielded value.

# 

ENTITY

<div class="example">

<div class="title">

Throwing an exception into a generator

</div>

```
<?php
function gen() {
    echo "Foo\n";
    try {
        yield;
    } catch (Exception $e) {
        echo "Exception: {$e->getMessage()}\n";
    }
    echo "Bar\n";
}
 
$gen = gen();
$gen->rewind();
$gen->throw(new Exception('Test'));
?>

    
```

ENTITY

    Foo
    Exception: Test
    Bar

        

</div>

# valid

Generator::valid

Check if the iterator has been closed

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

bool

</div>

<div data-wrapper="1" role="Generator">

Generator::valid

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns ENTITY if the iterator has been closed. Otherwise returns ENTITY.

# wakeup

Generator::\_\_wakeup

Serialize callback

# 

ENTITY

<div data-wrapper="1" role="Generator">

public

</div>

<div data-wrapper="1" role="Generator">

void

</div>

<div data-wrapper="1" role="Generator">

Generator::\_\_wakeup

</div>

Throws an exception as generators can't be serialized.

# 

ENTITY ENTITY

# 

ENTITY

ENTITY

# Predefined Interfaces and Classes

See also the [SPL Interfaces](#spl.interfaces) and [reserved classes](#reserved.classes).

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# internaliterator

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Class to ease implementing IteratorAggregate for *internal* classes.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

InternalIterator

</div>

<div data-wrapper="1" role="class">

implements

</div>

<div data-wrapper="1" role="class">

Iterator

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# construct

InternalIterator::\_\_construct

Private constructor to disallow direct instantiation

# 

ENTITY

<div data-wrapper="1" role="InternalIterator">

private

</div>

<div data-wrapper="1" role="InternalIterator">

InternalIterator::\_\_construct

</div>

# 

ENTITY ENTITY

# current

InternalIterator::current

Return the current element

# 

ENTITY

<div data-wrapper="1" role="InternalIterator">

public

</div>

<div data-wrapper="1" role="InternalIterator">

mixed

</div>

<div data-wrapper="1" role="InternalIterator">

InternalIterator::current

</div>

Returns the current element.

# 

ENTITY ENTITY

# 

ENTITY

Returns the current element.

# key

InternalIterator::key

Return the key of the current element

# 

ENTITY

<div data-wrapper="1" role="InternalIterator">

public

</div>

<div data-wrapper="1" role="InternalIterator">

mixed

</div>

<div data-wrapper="1" role="InternalIterator">

InternalIterator::key

</div>

Returns the key of the current element.

# 

ENTITY ENTITY

# 

ENTITY

Returns the key of the current element.

# next

InternalIterator::next

Move forward to next element

# 

ENTITY

<div data-wrapper="1" role="InternalIterator">

public

</div>

<div data-wrapper="1" role="InternalIterator">

void

</div>

<div data-wrapper="1" role="InternalIterator">

InternalIterator::next

</div>

Moves the current position to the next element.

# 

ENTITY ENTITY

# 

ENTITY

ENTITY

# rewind

InternalIterator::rewind

Rewind the Iterator to the first element

# 

ENTITY

<div data-wrapper="1" role="InternalIterator">

public

</div>

<div data-wrapper="1" role="InternalIterator">

void

</div>

<div data-wrapper="1" role="InternalIterator">

InternalIterator::rewind

</div>

Rewinds back to the first element of the Iterator.

# 

ENTITY ENTITY

# 

ENTITY

ENTITY

# valid

InternalIterator::valid

Check if current position is valid

# 

ENTITY

<div data-wrapper="1" role="InternalIterator">

public

</div>

<div data-wrapper="1" role="InternalIterator">

bool

</div>

<div data-wrapper="1" role="InternalIterator">

InternalIterator::valid

</div>

Checks if current position is valid.

# 

ENTITY ENTITY

# 

ENTITY

Returns whether the current position is valid.

# iterator

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Interface for external iterators or objects that can be iterated themselves internally.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Iterator

</div>

<div data-wrapper="1" role="class">

extends

</div>

<div data-wrapper="1" role="class">

Traversable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# Predefined iterators

<div data-wrapper="1" role="class">

PHP already provides a number of iterators for many day-to-day tasks. See [SPL iterators](#spl.iterators) for a list.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div id="iterator.example.basic" class="example" role="class">

<div class="title">

Basic usage

</div>

This example demonstrates in which order methods are called when using ENTITY with an iterator.

```
<?php
class myIterator implements Iterator {
    private $position = 0;
    private $array = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );  

    public function __construct() {
        $this->position = 0;
    }

    public function rewind(): void {
        var_dump(__METHOD__);
        $this->position = 0;
    }

    #[\ReturnTypeWillChange]
    public function current() {
        var_dump(__METHOD__);
        return $this->array[$this->position];
    }

    #[\ReturnTypeWillChange]
    public function key() {
        var_dump(__METHOD__);
        return $this->position;
    }

    public function next(): void {
        var_dump(__METHOD__);
        ++$this->position;
    }

    public function valid(): bool {
        var_dump(__METHOD__);
        return isset($this->array[$this->position]);
    }
}

$it = new myIterator;

foreach($it as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}
?>

    
```

ENTITY

    string(18) "myIterator::rewind"
    string(17) "myIterator::valid"
    string(19) "myIterator::current"
    string(15) "myIterator::key"
    int(0)
    string(12) "firstelement"

    string(16) "myIterator::next"
    string(17) "myIterator::valid"
    string(19) "myIterator::current"
    string(15) "myIterator::key"
    int(1)
    string(13) "secondelement"

    string(16) "myIterator::next"
    string(17) "myIterator::valid"
    string(19) "myIterator::current"
    string(15) "myIterator::key"
    int(2)
    string(11) "lastelement"

    string(16) "myIterator::next"
    string(17) "myIterator::valid"

        

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

See also [object iteration](#language.oop5.iterations).

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# current

Iterator::current

Return the current element

# 

ENTITY

<div data-wrapper="1" role="Iterator">

public

</div>

<div data-wrapper="1" role="Iterator">

mixed

</div>

<div data-wrapper="1" role="Iterator">

Iterator::current

</div>

Returns the current element.

# 

ENTITY ENTITY

# 

ENTITY

Can return any type.

# key

Iterator::key

Return the key of the current element

# 

ENTITY

<div data-wrapper="1" role="Iterator">

public

</div>

<div data-wrapper="1" role="Iterator">

mixed

</div>

<div data-wrapper="1" role="Iterator">

Iterator::key

</div>

Returns the key of the current element.

# 

ENTITY ENTITY

# 

ENTITY

Returns `scalar` on success, or ENTITY on failure.

# 

ENTITY

Issues `E_NOTICE` on failure.

# next

Iterator::next

Move forward to next element

# 

ENTITY

<div data-wrapper="1" role="Iterator">

public

</div>

<div data-wrapper="1" role="Iterator">

void

</div>

<div data-wrapper="1" role="Iterator">

Iterator::next

</div>

Moves the current position to the next element.

> [!NOTE]
> This method is called *after* each ENTITY loop.

# 

ENTITY ENTITY

# 

ENTITY

Any returned value is ignored.

# rewind

Iterator::rewind

Rewind the Iterator to the first element

# 

ENTITY

<div data-wrapper="1" role="Iterator">

public

</div>

<div data-wrapper="1" role="Iterator">

void

</div>

<div data-wrapper="1" role="Iterator">

Iterator::rewind

</div>

Rewinds back to the first element of the Iterator.

> [!NOTE]
> This is the *first* method called when starting a ENTITY loop. It will *not* be executed *after* ENTITY loops.
>
> As ENTITY always calls this method before starting iteration, manually advancing the iterator position (for example via SplFileObject::seek) will be reset.
>
> To iterate without rewinding the iterator, wrap it in a `NoRewindIterator`.

# 

ENTITY ENTITY

# 

ENTITY

Any returned value is ignored.

# valid

Iterator::valid

Checks if current position is valid

# 

ENTITY

<div data-wrapper="1" role="Iterator">

public

</div>

<div data-wrapper="1" role="Iterator">

bool

</div>

<div data-wrapper="1" role="Iterator">

Iterator::valid

</div>

This method is called after Iterator::rewind and Iterator::next to check if the current position is valid.

# 

ENTITY ENTITY

# 

ENTITY

The return value will be casted to `bool` and then evaluated. ENTITY

# iteratoraggregate

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Interface to create an external Iterator.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

IteratorAggregate

</div>

<div data-wrapper="1" role="class">

extends

</div>

<div data-wrapper="1" role="class">

Traversable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div id="iteratoraggregate.example.basic" class="example" role="class">

<div class="title">

Basic usage

</div>

```
<?php

class myData implements IteratorAggregate
{
    public function getIterator(): Traversable
    {
        return new ArrayIterator([
            "key one" => "item one",
            "key two" => "item two",
            "key three" => "item three"
        ]);
    }
}

$obj = new myData();

foreach ($obj as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}

    
```

ENTITY

    string(7) "key one"
    string(8) "item one"

    string(7) "key two"
    string(8) "item two"

    string(9) "key three"
    string(10) "item three"


        

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# getiterator

IteratorAggregate::getIterator

Retrieve an external iterator or traversable

# 

ENTITY

<div data-wrapper="1" role="IteratorAggregate">

public

</div>

<div data-wrapper="1" role="IteratorAggregate">

Traversable

</div>

<div data-wrapper="1" role="IteratorAggregate">

IteratorAggregate::getIterator

</div>

Returns an external iterator or traversable.

# 

ENTITY ENTITY

# 

ENTITY

An instance of an object implementing `Iterator` or `Traversable`

# 

ENTITY

Throws an `Exception` on failure.

# parseerror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

`ParseError` is thrown when an error occurs while parsing PHP code, such as when `eval` is called.

</div>

> [!NOTE]
> `ParseError` extends `CompileError` as of PHP 7.3.0. Formerly, it extended `Error`.

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

ParseError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

CompileError

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# php-incomplete-class

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Created by `unserialize` when trying to unserialize an undefined class or a class that is not listed in the `allowed_classes` of `unserialize`'s `options` array.

</div>

<div data-wrapper="1" role="class">

Prior to PHP 7.2.0, using `is_object` on the `__PHP_Incomplete_Class` class would return ENTITY. As of PHP 7.2.0, ENTITY will be returned.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\AllowDynamicProperties\]

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

\_\_PHP_Incomplete_Class

</div>

<div data-wrapper="1" role="class">

This class has no default properties or methods. When created by `unserialize`, in addition to all unserialized properties and values the object will have a `__PHP_Incomplete_Class_Name` property which will contain the name of the unserialized class.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY                     |
|--------|----------------------------|
| 8.0.0  | This class is now `final`. |

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div id="php-incomplete-class.basic-example" class="example" role="class">

<div class="title">

Created by `unserialize`

</div>

```
<?php

class MyClass
{
    public string $property = "myValue";
}

$myObject = new MyClass;

$foo = serialize($myObject);

// unserializes all objects into __PHP_Incomplete_Class objects
$disallowed = unserialize($foo, ["allowed_classes" => false]);

var_dump($disallowed);

// unserializes all objects into __PHP_Incomplete_Class objects except those of MyClass2 and MyClass3
$disallowed2 = unserialize($foo, ["allowed_classes" => ["MyClass2", "MyClass3"]]);

var_dump($disallowed2);

// unserializes undefined class into __PHP_Incomplete_Class object
$undefinedClass = unserialize('O:16:"MyUndefinedClass":0:{}');

var_dump($undefinedClass);

    
```

ENTITY

    object(__PHP_Incomplete_Class)#2 (2) {
      ["__PHP_Incomplete_Class_Name"]=>
      string(7) "MyClass"
      ["property"]=>
      string(7) "myValue"
    }
    object(__PHP_Incomplete_Class)#3 (2) {
      ["__PHP_Incomplete_Class_Name"]=>
      string(7) "MyClass"
      ["property"]=>
      string(7) "myValue"
    }
    object(__PHP_Incomplete_Class)#4 (1) {
      ["__PHP_Incomplete_Class_Name"]=>
      string(16) "MyUndefinedClass"
    }


        

</div>

# requestparsebodyexception

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

A RequestParseBodyException is thrown in `request_parse_body` when the request body is invalid, according to the `Content-Type` header.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

RequestParseBodyException

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Exception

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# construct

ReturnTypeWillChange::\_\_construct

Construct a new ReturnTypeWillChange attribute instance

# 

ENTITY

<div data-wrapper="1" role="ReturnTypeWillChange">

public

</div>

<div data-wrapper="1" role="ReturnTypeWillChange">

ReturnTypeWillChange::\_\_construct

</div>

Constructs a new `ReturnTypeWillChange` instance.

# 

ENTITY ENTITY

# construct

SensitiveParameter::\_\_construct

Construct a new SensitiveParameter attribute instance

# 

ENTITY

<div data-wrapper="1" role="SensitiveParameter">

public

</div>

<div data-wrapper="1" role="SensitiveParameter">

SensitiveParameter::\_\_construct

</div>

Constructs a new `SensitiveParameter` instance.

# 

ENTITY ENTITY

# sensitiveparametervalue

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

The `SensitiveParameterValue` class allows wrapping sensitive values to protect them against accidental exposure.

</div>

<div data-wrapper="1" role="class">

Values of parameters having the `SensitiveParameter` attribute will automatically be wrapped inside of a `SensitiveParameterValue` object within stack traces.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

SensitiveParameterValue

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

private

</div>

<div data-wrapper="1" role="class">

readonly

</div>

<div data-wrapper="1" role="class">

mixed

</div>

<div data-wrapper="1" role="class">

value

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

`value`  
The sensitive value to be protected against accidental exposure.

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY

</div>

# construct

SensitiveParameterValue::\_\_construct

Constructs a new SensitiveParameterValue object

# 

ENTITY

<div data-wrapper="1" role="SensitiveParameterValue">

public

</div>

<div data-wrapper="1" role="SensitiveParameterValue">

SensitiveParameterValue::\_\_construct

</div>

<div data-wrapper="1" role="SensitiveParameterValue">

mixed

</div>

<div data-wrapper="1" role="SensitiveParameterValue">

value

</div>

Construct a `SensitiveParameterValue` holding a sensitive value.

# 

ENTITY

`value`  
An arbitrary value that should be stored inside the `SensitiveParameterValue` object.

# debuginfo

SensitiveParameterValue::\_\_debugInfo

Protects the sensitive value against accidental exposure

# 

ENTITY

<div data-wrapper="1" role="SensitiveParameterValue">

public

</div>

<div data-wrapper="1" role="SensitiveParameterValue">

array

</div>

<div data-wrapper="1" role="SensitiveParameterValue">

SensitiveParameterValue::\_\_debugInfo

</div>

Returns an empty ENTITY to protect the sensitive value against accidental exposure when using `var_dump`.

# 

ENTITY ENTITY

# 

ENTITY

An empty ENTITY.

# 

ENTITY

<div class="example">

<div class="title">

Passing a `SensitiveParameterValue` object to `var_dump`

</div>

```
<?php
$s = new \SensitiveParameterValue('secret');

var_dump($s);
?>

    
```

ENTITY

    object(SensitiveParameterValue)#1 (0) {
    }

        

</div>

# getvalue

SensitiveParameterValue::getValue

Returns the sensitive value

# 

ENTITY

<div data-wrapper="1" role="SensitiveParameterValue">

public

</div>

<div data-wrapper="1" role="SensitiveParameterValue">

mixed

</div>

<div data-wrapper="1" role="SensitiveParameterValue">

SensitiveParameterValue::getValue

</div>

Get the sensitive value.

# 

ENTITY ENTITY

# 

ENTITY

The sensitive value.

# 

ENTITY

<div class="example">

<div class="title">

`SensitiveParameterValue::getValue` example

</div>

```
<?php
$s = new \SensitiveParameterValue('secret');

echo "The protected value is: ", $s->getValue(), "\n";
?>

    
```

ENTITY

    The protected value is: secret

        

</div>

# serializable

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Interface for customized serializing.

</div>

<div data-wrapper="1" role="class">

Classes that implement this interface no longer support [\_\_sleep()](#object.sleep) and [\_\_wakeup()](#object.wakeup). The serialize method is called whenever an instance needs to be serialized. This does not invoke \_\_destruct or have any other side effect unless programmed inside the method. When the data is unserialized the class is known and the appropriate unserialize method is called as a constructor instead of calling \_\_construct. The constructor can be called from within the unserialize method if desired.

</div>

> [!WARNING]
> As of PHP 8.1.0, a class which implements Serializable without also implementing [\_\_serialize()](#object.serialize) and [\_\_unserialize()](#object.unserialize) will generate a deprecation warning.

<div data-wrapper="1" role="class">

New code should use the [\_\_serialize()](#object.serialize) and [\_\_unserialize()](#object.unserialize) magic methods instead, available as of PHP 7.4.0. When a class declares both them and this interface, `serialize` always uses [\_\_serialize()](#object.serialize) and never reaches Serializable::serialize. Unserializing is decided by the format of the data instead: a payload written by PHP 7.4.0 or later is read by [\_\_unserialize()](#object.unserialize), one written before it is still read by Serializable::unserialize. Implementing Serializable therefore remains of use for reading such older payloads, and for satisfying a Serializable type declaration; declaring all four methods covers every case, and avoids the deprecation notice.

</div>

> [!NOTE]
> The magic methods have no interface of their own, so a class which declares them without implementing Serializable is not an instance of it. `method_exists` is the way to detect them.

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Serializable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div id="serializable.example.basic" class="example" role="class">

<div class="title">

Supporting PHP 7.1.0 through 7.3.0

</div>

The magic methods carry the serialized form, and the interface methods delegate to them, so that a single representation serves both.

```
<?php
class Task implements Serializable
{
    private $label;

    public function __construct($label)
    {
        $this->label = $label;
    }

    public function __serialize(): array
    {
        return ['label' => $this->label];
    }

    public function __unserialize(array $data): void
    {
        $this->label = $data['label'];
    }

    // Never called as of PHP 7.4.0
    public function serialize()
    {
        return serialize($this->__serialize());
    }

    // Still called as of PHP 7.4.0, for data written before it
    public function unserialize($data)
    {
        $this->__unserialize(unserialize($data));
    }
}

var_dump(serialize(new Task('deploy')));
?>

    
```

ENTITY

    string(40) "O:4:"Task":1:{s:5:"label";s:6:"deploy";}"

        

Prior to PHP 7.4.0, the same code serializes through the interface instead, and outputs `string(47) "C:4:"Task":31:{a:1:{s:5:"label";s:6:"deploy";}}"`.

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY

</div>

# serialize

Serializable::serialize

String representation of object

# 

ENTITY

<div data-wrapper="1" role="Serializable">

public

</div>

<div data-wrapper="1" role="Serializable">

string

</div>

<div data-wrapper="1" role="Serializable">

null

</div>

<div data-wrapper="1" role="Serializable">

Serializable::serialize

</div>

Should return the string representation of the object.

# 

ENTITY ENTITY

# 

ENTITY

Returns the string representation of the object or ENTITY

# 

ENTITY

Throws `Exception` when returning other types than strings and ENTITY.

# 

ENTITY

[\_\_sleep()](#object.sleep), [\_\_serialize()](#object.serialize)

# unserialize

Serializable::unserialize

Constructs the object

# 

ENTITY

<div data-wrapper="1" role="Serializable">

public

</div>

<div data-wrapper="1" role="Serializable">

void

</div>

<div data-wrapper="1" role="Serializable">

Serializable::unserialize

</div>

<div data-wrapper="1" role="Serializable">

string

</div>

<div data-wrapper="1" role="Serializable">

data

</div>

Called during unserialization of the object.

> [!NOTE]
> This method acts as the [constructor](#language.oop5.decon.constructor) of the object. The [\_\_construct()](#object.construct) method will *not* be called after this method.

# 

ENTITY

`data`  
The string representation of the object.

# 

ENTITY

The return value from this method is ignored.

# 

ENTITY

[\_\_wakeup()](#object.wakeup), [\_\_unserialize()](#object.unserialize)

# stdclass

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

A generic empty class with dynamic properties.

</div>

<div data-wrapper="1" role="class">

Objects of this class can be instantiated with the [new](#language.oop5.basic.new) operator or created by [typecasting to object](#language.types.object.casting). Several PHP functions also create instances of this class, e.g. `json_decode`, `mysqli_fetch_object` or PDOStatement::fetchObject.

</div>

<div data-wrapper="1" role="class">

Despite not implementing [\_\_get()](#object.get)/[\_\_set()](#object.set) magic methods, this class allows dynamic properties and does not require the `#[\AllowDynamicProperties]` attribute.

</div>

<div data-wrapper="1" role="class">

This is not a base class as PHP does not have a concept of a universal base class. However, it is possible to create a custom class that extends `stdClass` and as a result inherits the functionality of dynamic properties.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="attribute">

\#\[\AllowDynamicProperties\]

</div>

<div data-wrapper="1" role="class">

stdClass

</div>

<div data-wrapper="1" role="class">

This class has no methods or default properties.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div id="stdclass.basic-example" class="example" role="class">

<div class="title">

Created as a result of typecasting to object

</div>

```
<?php
$obj = (object) array('foo' => 'bar');
var_dump($obj);

    
```

ENTITY

    object(stdClass)#1 (1) {
      ["foo"]=>
      string(3) "bar"
    }

        

</div>

<div id="stdclass.json-example" class="example" role="class">

<div class="title">

Created as a result of `json_decode`

</div>

```
<?php
$json = '{"foo":"bar"}';
var_dump(json_decode($json));

    
```

ENTITY

    object(stdClass)#1 (1) {
      ["foo"]=>
      string(3) "bar"
    }

        

</div>

<div id="stdclass.properties-example" class="example" role="class">

<div class="title">

Declaring dynamic properties

</div>

```
<?php
$obj = new stdClass();
$obj->foo = 42;
$obj->{1} = 42;
var_dump($obj);

    
```

ENTITY

    object(stdClass)#1 (2) {
      ["foo"]=>
      int(42)
      ["1"]=>
      int(42)
    }

        

</div>

# stringable

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

The Stringable interface denotes a class as having a [\_\_toString()](#object.tostring) method. Unlike most interfaces, Stringable is implicitly present on any class that has the magic [\_\_toString()](#object.tostring) method defined, although it can and should be declared explicitly.

</div>

<div data-wrapper="1" role="class">

Its primary value is to allow functions to type check against the union type `string|Stringable` to accept either a string primitive or an object that can be cast to a string.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Stringable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# Stringable Examples

<div id="stringable.basic-example" class="example" role="class">

<div class="title">

Basic Stringable Usage

</div>

This uses [constructor property promotion](#language.oop5.decon.constructor.promotion).

```
<?php
class IPv4Address implements Stringable {
    public function __construct(
        private string $oct1,
        private string $oct2,
        private string $oct3,
        private string $oct4,
    ) {}

    public function __toString(): string {
        return "$this->oct1.$this->oct2.$this->oct3.$this->oct4";
    }
}

function showStuff(string|Stringable $value) {
    // For a Stringable, this will implicitly call __toString().
    print $value;
}

$ip = new IPv4Address('123', '234', '42', '9');

showStuff($ip);
?>

     
```

ENTITY

    123.234.42.9

         

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# tostring

Stringable::\_\_toString

Gets a string representation of the object

# 

ENTITY

<div data-wrapper="1" role="Stringable">

public

</div>

<div data-wrapper="1" role="Stringable">

string

</div>

<div data-wrapper="1" role="Stringable">

Stringable::\_\_toString

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns the ENTITY representation of the object.

# 

ENTITY

[\_\_toString()](#object.tostring)

# throwable

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Throwable is the base interface for any object that can be thrown via a ENTITY statement, including Error and Exception.

</div>

> [!NOTE]
> PHP classes cannot implement the Throwable interface directly, and must instead extend Exception.

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Throwable

</div>

<div data-wrapper="1" role="class">

extends

</div>

<div data-wrapper="1" role="class">

Stringable

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY                               |
|--------|--------------------------------------|
| 8.0.0  | Throwable implements Stringable now. |

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# getcode

Throwable::getCode

Gets the exception code

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

int

</div>

<div data-wrapper="1" role="Throwable">

Throwable::getCode

</div>

Returns the error code associated with the thrown object.

# 

ENTITY ENTITY

# 

ENTITY

Returns the exception code as `int` in `Exception` but possibly as other type in `Exception` descendants (for example as `string` in `PDOException`).

# 

ENTITY

Exception::getCode

# getfile

Throwable::getFile

Gets the file in which the object was created

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

string

</div>

<div data-wrapper="1" role="Throwable">

Throwable::getFile

</div>

Get the name of the file in which the thrown object was created.

# 

ENTITY ENTITY

# 

ENTITY

Returns the filename in which the thrown object was created.

# 

ENTITY

Exception::getFile

# getline

Throwable::getLine

Gets the line on which the object was instantiated

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

int

</div>

<div data-wrapper="1" role="Throwable">

Throwable::getLine

</div>

Returns the line number where the thrown object was instantiated.

# 

ENTITY ENTITY

# 

ENTITY

Returns the line number where the thrown object was instantiated.

# 

ENTITY

Exception::getLine

# getmessage

Throwable::getMessage

Gets the message

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

string

</div>

<div data-wrapper="1" role="Throwable">

Throwable::getMessage

</div>

Returns the message associated with the thrown object.

# 

ENTITY ENTITY

# 

ENTITY

Returns the message associated with the thrown object.

# 

ENTITY

Exception::getMessage

# getprevious

Throwable::getPrevious

Returns the previous Throwable

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

Throwable

</div>

<div data-wrapper="1" role="Throwable">

null

</div>

<div data-wrapper="1" role="Throwable">

Throwable::getPrevious

</div>

Returns any previous Throwable (for example, one provided as the third parameter to Exception::\_\_construct).

# 

ENTITY ENTITY

# 

ENTITY

Returns the previous `Throwable` if available, or ENTITY otherwise.

# 

ENTITY

Exception::getPrevious

# gettrace

Throwable::getTrace

Gets the stack trace

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

array

</div>

<div data-wrapper="1" role="Throwable">

Throwable::getTrace

</div>

Returns the stack trace as an `array`.

# 

ENTITY ENTITY

# 

ENTITY

Returns the stack trace as an `array` in the same format as `debug_backtrace`.

# 

ENTITY

Exception::getTrace

# gettraceasstring

Throwable::getTraceAsString

Gets the stack trace as a string

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

string

</div>

<div data-wrapper="1" role="Throwable">

Throwable::getTraceAsString

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns the stack trace as a string.

# 

ENTITY

Exception::getTraceAsString

# tostring

Throwable::\_\_toString

Gets a string representation of the thrown object

# 

ENTITY

<div data-wrapper="1" role="Throwable">

public

</div>

<div data-wrapper="1" role="Throwable">

string

</div>

<div data-wrapper="1" role="Throwable">

Throwable::\_\_toString

</div>

# 

ENTITY ENTITY

# 

ENTITY

Returns the `string` representation of the thrown object.

# 

ENTITY

Exception::\_\_toString

# traversable

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Interface to detect if a class is traversable using ENTITY.

</div>

<div data-wrapper="1" role="class">

Abstract base interface that cannot be implemented alone. Instead, it must be implemented by either IteratorAggregate or Iterator.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Traversable

</div>

<div data-wrapper="1" role="class">

This interface has no methods; its only purpose is to be the base interface for all traversable classes.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 8.0.0 | The Traversable interface can now be implemented by abstract classes. Extending classes must implement Iterator or IteratorAggregate. |

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

> [!NOTE]
> Internal (built-in) classes that implement this interface can be used in a ENTITY construct and do not need to implement IteratorAggregate or Iterator.

> [!NOTE]
> Prior to PHP 8.0.0, this internal engine interface couldn't be directly implemented in PHP scripts — not even by abstract classes. Either IteratorAggregate or Iterator must be used instead.

# typeerror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

A TypeError may be thrown when: The value being set for a class property does not match the property's corresponding declared type., The argument type being passed to a function does not match its corresponding declared parameter type., A value being returned from a function does not match the declared function return type.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

TypeError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Error

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 7.1.0 | In strict mode, passing an incorrect number of arguments to a built-in PHP function no longer results in a generic TypeError. Instead, a more specific ArgumentCountError, which extends TypeError, is thrown. |

# unhandledmatcherror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

An `UnhandledMatchError` is thrown when the subject passed to a ENTITY expression is not handled by any arm of the ENTITY expression.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

UnhandledMatchError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Error

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# unitenum

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

The `UnitEnum` interface is automatically applied to all enumerations by the engine. It may not be implemented by user-defined classes. Enumerations may not override its methods, as default implementations are provided by the engine. It is available only for type checks.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

UnitEnum

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="class">

ENTITY

</div>

# cases

UnitEnum::cases

Generates a list of cases on an enum

# 

ENTITY

<div data-wrapper="1" role="UnitEnum">

public

</div>

<div data-wrapper="1" role="UnitEnum">

static

</div>

<div data-wrapper="1" role="UnitEnum">

array

</div>

<div data-wrapper="1" role="UnitEnum">

UnitEnum::cases

</div>

This method will return a packed array of all cases in an enumeration, in order of declaration.

# 

ENTITY ENTITY

# 

ENTITY

An array of all defined cases of this enumeration, in order of declaration.

# 

ENTITY

<div class="example">

<div class="title">

Basic usage

</div>

The following example illustrates how enum cases are returned.

```
<?php
enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

var_dump(Suit::cases());

   
```

ENTITY

    array(4) {
      [0]=>
      enum(Suit::Hearts)
      [1]=>
      enum(Suit::Diamonds)
      [2]=>
      enum(Suit::Clubs)
      [3]=>
      enum(Suit::Spades)
    }

       

</div>

# valueerror

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

A `ValueError` is thrown when the type of an argument is correct but its value is incorrect. For example, passing a negative integer when the function expects a positive one, or passing an empty string/array when the function expects it to not be empty.

</div>

# 

<div data-wrapper="1" role="exception">

ENTITY

</div>

<div data-wrapper="1" role="exception">

ValueError

</div>

<div data-wrapper="1" role="exception">

extends

</div>

<div data-wrapper="1" role="exception">

Error

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# variables

PHP provides predefined variables that represent [external variables](#language.variables.external), built-in environment variables, and other information about the execution environment, such as the number and values of the arguments passed to the script in the CLI environment.

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# argc

<div data-wrapper="1" role="variable">

\$argc

</div>

<div data-wrapper="1" role="variable">

The number of arguments passed to script

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

Contains the number of arguments passed to the current script when running from the [command line](#features.commandline).

</div>

> [!NOTE]
> The script's filename is always passed as an argument to the script, therefore the minimum value of `$argc` is `1`.

> [!NOTE]
> This variable is not available when [register_argc_argv](#ini.register-argc-argv) is disabled.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.argc.basic" class="example" role="variable">

<div class="title">

`$argc` example

</div>

```
<?php
var_dump($argc);
?>

    
```

When executing the example with: php script.php arg1 arg2 arg3

ENTITY

    int(4)

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

> [!NOTE]
> This is also available as `$_SERVER['argc']`.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`getopt`, [`$argv`](#reserved.variables.argv)

</div>

# argv

<div data-wrapper="1" role="variable">

\$argv

</div>

<div data-wrapper="1" role="variable">

Array of arguments passed to script

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

Contains an `array` of all the arguments passed to the script when running from the [command line](#features.commandline).

</div>

> [!NOTE]
> The first argument `$argv[0]` is always the name that was used to run the script.

> [!NOTE]
> This variable is not available when [register_argc_argv](#ini.register-argc-argv) is disabled.

> [!WARNING]
> To test if a script is being run from the command line, `php_sapi_name` should be used instead of checking whether `$argv` or `$_SERVER['argv']` is set.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.argv.basic" class="example" role="variable">

<div class="title">

`$argv` example

</div>

```
<?php
var_dump($argv);
?>

    
```

When executing the example with: php script.php arg1 arg2 arg3

ENTITY

    array(4) {
      [0]=>
      string(10) "script.php"
      [1]=>
      string(4) "arg1"
      [2]=>
      string(4) "arg2"
      [3]=>
      string(4) "arg3"
    }

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

> [!NOTE]
> This is also available as `$_SERVER['argv']`.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`getopt`, [`$argc`](#reserved.variables.argc)

</div>

# cookie

<div data-wrapper="1" role="variable">

\$\_COOKIE

</div>

<div data-wrapper="1" role="variable">

HTTP Cookies

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative `array` of variables passed to the current script via HTTP Cookies.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.cookie.basic" class="example" role="variable">

<div class="title">

`$_COOKIE` example

</div>

```
<?php
echo 'Hello ' . htmlspecialchars($_COOKIE["name"]) . '!';
?>

    
```

Assuming the "name" cookie has been set earlier

ENTITY

    Hello Hannes!

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`setcookie`, [Handling external variables](#language.variables.external), [The filter extension](#book.filter)

</div>

# env

<div data-wrapper="1" role="variable">

\$\_ENV

</div>

<div data-wrapper="1" role="variable">

Environment variables

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative `array` of variables passed to the current script via the environment method.

</div>

<div data-wrapper="1" role="variable">

These variables are imported into PHP's global namespace from the environment under which the PHP parser is running. Many are provided by the shell under which PHP is running and different systems are likely running different kinds of shells, a definitive list is impossible. Please see your shell's documentation for a list of defined environment variables.

</div>

<div data-wrapper="1" role="variable">

Other environment variables include the CGI variables, placed there regardless of whether PHP is running as a server module or CGI processor.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.env.basic" class="example" role="variable">

<div class="title">

`$_ENV` example

</div>

```
<?php
echo 'My username is ' .$_ENV["USER"] . '!';
?>

    
```

Assuming "bjori" executes this script

ENTITY

    My username is bjori!

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`getenv`, [The filter extension](#book.filter)

</div>

# files

<div data-wrapper="1" role="variable">

\$\_FILES

</div>

<div data-wrapper="1" role="variable">

HTTP File Upload variables

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative `array` of items uploaded to the current script via the HTTP POST method. The structure of this array is outlined in the [POST method uploads](#features.file-upload.post-method) section.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`move_uploaded_file`, [Handling File Uploads](#features.file-upload)

</div>

# get

<div data-wrapper="1" role="variable">

\$\_GET

</div>

<div data-wrapper="1" role="variable">

Query string variables

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative array of variables passed to the current script via the URL parameters (also known as the query string). Note that this array is populated whenever a query string is present, regardless of the HTTP request method.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.get.basic" class="example" role="variable">

<div class="title">

`$_GET` example

</div>

```
<?php
echo 'Hello ' . htmlspecialchars($_GET["name"]) . '!';
?>

    
```

Assuming the user entered `http://example.com/?name=Hannes`.

ENTITY

    Hello Hannes!

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

> [!NOTE]
> The values in `$_GET` are automatically passed through `urldecode`.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

[Handling external variables](#language.variables.external), [The filter extension](#book.filter)

</div>

# globals

<div data-wrapper="1" role="variable">

\$GLOBALS

</div>

<div data-wrapper="1" role="variable">

References all variables available in global scope

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative `array` containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.globals.basic" class="example" role="variable">

<div class="title">

`$GLOBALS` example

</div>

```
<?php

function test()
{
    $foo = "local variable";

    echo '$foo in global scope: ' . $GLOBALS["foo"] . "\n";
    echo '$foo in current scope: ' . $foo . "\n";
}

$foo = "Example content";
test();

?>

    
```

ENTITY

    $foo in global scope: Example content
    $foo in current scope: local variable

        

</div>

> [!WARNING]
> As of PHP 8.1.0, write access to the entire `$GLOBALS` array is no longer supported:
>
> <div id="variable.globals.entire_write_error" class="example">
>
> <div class="title">
>
> writing entire `$GLOBALS` will result in error.
>
> </div>
>
> ```
> <?php
>
> // Generates compile-time error:
> $GLOBALS = [];
> $GLOBALS += [];
> $GLOBALS =& $x;
> $x =& $GLOBALS;
> unset($GLOBALS);
> array_pop($GLOBALS);
> // ...and any other write/read-write operation on $GLOBALS
>
> ?>
>  
>      
> ```
>
> </div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

> [!NOTE]
> Unlike all of the other [superglobals](#language.variables.superglobals), `$GLOBALS` has essentially always been available in PHP.

> [!NOTE]
> As of PHP 8.1.0, `$GLOBALS` is now a read-only copy of the global [symbol table](#features.gc.refcounting-basics). That is, global variables cannot be modified via its copy. Previously, `$GLOBALS` array is excluded from the usual by-value behavior of PHP arrays and global variables can be modified via its copy.
>
> <div class="informalexample">
>
> ```
> <?php
>
> // Before PHP 8.1.0
> $a = 1;
>
> $globals = $GLOBALS; // Ostensibly by-value copy
> $globals['a'] = 2;
> var_dump($a); // int(2)
>
> // As of PHP 8.1.0
> // this no longer modifies $a. The previous behavior violated by-value semantics.
> $globals = $GLOBALS;
> $globals['a'] = 1;
>
> // To restore the previous behavior, iterate its copy and assign each property back to $GLOBALS.
> foreach ($globals as $key => $value) {
>     $GLOBALS[$key] = $value;
> }
>
> ?>
>
>      
> ```
>
> </div>

# httpresponseheader

<div data-wrapper="1" role="variable">

\$http_response_header

</div>

<div data-wrapper="1" role="variable">

HTTP response headers

</div>

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

Use `http_get_last_response_headers` instead.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

The `$http_response_header` `array` is similar to the `get_headers` function. When using the [HTTP wrapper](#wrappers.http), `$http_response_header` will be populated with the HTTP response headers. `$http_response_header` will be created in the [local scope](#language.variables.scope).

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.httpresponseheader.basic" class="example" role="variable">

<div class="title">

`$http_response_header` example

</div>

```
<?php
function get_contents() {
  file_get_contents("http://example.com");
  var_dump($http_response_header); // variable is populated in the local scope
}
get_contents();
var_dump($http_response_header); // a call to get_contents() does not populate the variable outside the function scope
?>

    
```

ENTITY

    array(9) {
      [0]=>
      string(15) "HTTP/1.1 200 OK"
      [1]=>
      string(35) "Date: Sat, 12 Apr 2008 17:30:38 GMT"
      [2]=>
      string(29) "Server: Apache/2.2.3 (CentOS)"
      [3]=>
      string(44) "Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT"
      [4]=>
      string(27) "ETag: "280100-1b6-80bfd280""
      [5]=>
      string(20) "Accept-Ranges: bytes"
      [6]=>
      string(19) "Content-Length: 438"
      [7]=>
      string(17) "Connection: close"
      [8]=>
      string(38) "Content-Type: text/html; charset=UTF-8"
    }

    Warning: Undefined variable $http_response_header
    NULL

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

http_get_last_response_headers

</div>

<div data-wrapper="1" role="variable">

http_clear_last_response_headers

</div>

# phperrormsg

<div data-wrapper="1" role="variable">

\$php_errormsg

</div>

<div data-wrapper="1" role="variable">

The previous error message

</div>

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

Use `error_get_last` instead.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`$php_errormsg` is a variable containing the text of the last error message generated by PHP. This variable will only be available within the scope in which the error occurred, and only if the [track_errors](#ini.track-errors) configuration option is turned on (it defaults to off).

</div>

> [!WARNING]
> If a user defined error handler (`set_error_handler`) is set `$php_errormsg` is only set if the error handler returns ENTITY.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 8.0.0 | Directive [track_errors](#ini.track-errors) which caused `$php_errormsg` to be available has been removed. |
| 7.2.0 | Directive [track_errors](#ini.track-errors) which caused `$php_errormsg` to be available has been deprecated. |

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.phperrormsg.basic" class="example" role="variable">

<div class="title">

`$php_errormsg` example

</div>

```
<?php
@strpos();
echo $php_errormsg;
?>

    
```

ENTITY

    Wrong parameter count for strpos()

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`error_get_last`

</div>

# post

<div data-wrapper="1" role="variable">

\$\_POST

</div>

<div data-wrapper="1" role="variable">

Form data from HTTP POST requests

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative array of variables passed to the current script via the HTTP POST method when using `application/x-www-form-urlencoded` or `multipart/form-data` as the HTTP Content-Type in the request.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.post.basic" class="example" role="variable">

<div class="title">

`$_POST` example

</div>

```
<?php
echo 'Hello ' . htmlspecialchars($_POST["name"]) . '!';
?>

    
```

Assuming the user sent a POST request with `name=Hannes` in the body.

ENTITY

    Hello Hannes!

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

> [!NOTE]
> To read POST data sent with other content types (e.g. `application/json` or `application/xml`) [`php://input`](#wrappers.php.input) must be used. Unlike `$_POST`, which only works with `application/x-www-form-urlencoded` and `multipart/form-data`, `php://input` provides direct access to the raw data from the body of the request.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

[Handling external variables](#language.variables.external), [The filter extension](#book.filter)

</div>

# request

<div data-wrapper="1" role="variable">

\$\_REQUEST

</div>

<div data-wrapper="1" role="variable">

HTTP Request variables

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative `array` that by default contains the contents of `$_GET`, `$_POST`ENTITY `$_COOKIE`.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

> [!NOTE]
> When running on the [command line ](#features.commandline), this will *not* include the [argv](#reserved.variables.argv) and [argc](#reserved.variables.argc) entries; these are present in the `$_SERVER` `array`.

> [!NOTE]
> The variables in `$_REQUEST` are provided to the script via the GET, POST, and COOKIE input mechanisms and therefore could be modified by the remote user and cannot be trusted. The presence and order of variables listed in this array is defined according to the PHP [request_order](#ini.request-order), and [variables_order](#ini.variables-order) configuration directives.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

Handling external variables

</div>

<div data-wrapper="1" role="variable">

The filter extension

</div>

# server

<div data-wrapper="1" role="variable">

\$\_SERVER

</div>

<div data-wrapper="1" role="variable">

Server and execution environment information

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`$_SERVER` is an ENTITY containing information such as headers, paths, and script locations. The entries in this array are created by the web server, therefore there is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here. However, most of these variables are accounted for in the [CGI/1.1 specification](ENTITY3875), and are likely to be defined.

</div>

> [!NOTE]
> When running PHP on the [command line](#features.commandline) most of these entries will not be available or have any meaning.

<div data-wrapper="1" role="variable">

In addition to the elements listed below, PHP will create additional elements with values from request headers. These entries will be named `HTTP_` followed by the header name, capitalized and with underscores instead of hyphens. For example, the `Accept-Language` header would be available as `$_SERVER['HTTP_ACCEPT_LANGUAGE']`.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

'`PHP_SELF`'  
The filename of the currently executing script, relative to the document root. For instance, `$_SERVER['PHP_SELF']` in a script at the address `http://example.com/foo/bar.php` would be `/foo/bar.php`. The [\_\_FILE\_\_](#language.constants.magic) constant contains the full path and filename of the current (i.e. included) file.

If PHP is running as a command-line processor this variable contains the script name.

'[argv](#reserved.variables.argv)'  
Array of arguments passed to the script. When the script is run on the command line, this gives C-style access to the command line parameters. When called via the GET method, this will contain the query string.

'[argc](#reserved.variables.argc)'  
Contains the number of command line parameters passed to the script (if run on the command line).

'`GATEWAY_INTERFACE`'  
What revision of the CGI specification the server is using; e.g. `'CGI/1.1'`.

'`SERVER_ADDR`'  
The IP address of the server under which the current script is executing.

'`SERVER_NAME`'  
The name of the server host under which the current script is executing. If the script is running on a virtual host, this will be the value defined for that virtual host.

> [!NOTE]
> Under Apache 2, `UseCanonicalName = On` and `ServerName` must be set. Otherwise, this value reflects the hostname supplied by the client, which can be spoofed. It is not safe to rely on this value in security-dependent contexts.

'`SERVER_SOFTWARE`'  
Server identification string, given in the headers when responding to requests.

'`SERVER_PROTOCOL`'  
Name and revision of the information protocol via which the page was requested; e.g. `'HTTP/1.0'`;

'`REQUEST_METHOD`'  
Which request method was used to access the page; e.g. `'GET'`, `'HEAD'`, `'POST'`, `'PUT'`.

> [!NOTE]
> PHP script is terminated after sending headers (it means after producing any output without output buffering) if the request method was `HEAD`.

'`REQUEST_TIME`'  
The timestamp when PHP started processing the request.

'`REQUEST_TIME_FLOAT`'  
The timestamp when PHP started processing the request, with microsecond precision.

'`QUERY_STRING`'  
The query string, if any, via which the page was accessed.

'`DOCUMENT_ROOT`'  
The document root directory under which the current script is executing, as defined in the server's configuration file.

'`HTTPS`'  
Set to a non-empty value if the script was queried through the HTTPS protocol.

'`REMOTE_ADDR`'  
The IP address from which the user is viewing the current page.

'`REMOTE_HOST`'  
The Host name from which the user is viewing the current page. The reverse dns lookup is based on the `REMOTE_ADDR` of the user.

> [!NOTE]
> The web server must be configured to create this variable. For example in Apache `HostnameLookups On` must be set inside ENTITY for it to exist. See also `gethostbyaddr`.

'`REMOTE_PORT`'  
The port being used on the user's machine to communicate with the web server.

'`REMOTE_USER`'  
The authenticated user.

'`REDIRECT_REMOTE_USER`'  
The authenticated user if the request is internally redirected.

'`SCRIPT_FILENAME`'  
The absolute pathname of the currently executing script.

> [!NOTE]
> If a script is executed with the CLI, as a relative path, such as `file.php` or `../file.php`, `$_SERVER['SCRIPT_FILENAME']` will contain the relative path specified by the user.

'`SERVER_ADMIN`'  
The value given to the SERVER_ADMIN (for Apache) directive in the web server configuration file. If the script is running on a virtual host, this will be the value defined for that virtual host.

'`SERVER_PORT`'  
The port on the server machine being used by the web server for communication. For default setups, this will be `'80'`; using SSL, for instance, will change this to whatever your defined secure HTTP port is.

> [!NOTE]
> Under Apache 2, `UseCanonicalName = On`, as well as `UseCanonicalPhysicalPort = On` must be set in order to get the physical (real) port, otherwise, this value can be spoofed, and it may or may not return the physical port value. It is not safe to rely on this value in security-dependent contexts.

'`SERVER_SIGNATURE`'  
String containing the server version and virtual host name which are added to server-generated pages, if enabled.

'`PATH_TRANSLATED`'  
Filesystem- (not document root-) based path to the current script, after the server has done any virtual-to-real mapping.

> [!NOTE]
> Apache 2 users may use `AcceptPathInfo = On` inside `httpd.conf` to define `PATH_INFO`.

'`SCRIPT_NAME`'  
Contains the current script's path. This is useful for pages which need to point to themselves. The [\_\_FILE\_\_](#language.constants.magic) constant contains the full path and filename of the current (i.e. included) file.

'`REQUEST_URI`'  
The URI which was given in order to access this page; for instance, '`/index.html`'.

'`PHP_AUTH_DIGEST`'  
When doing Digest HTTP authentication this variable is set to the 'Authorization' header sent by the client (which you should then use to make the appropriate validation).

'`PHP_AUTH_USER`'  
When doing HTTP authentication this variable is set to the username provided by the user.

'`PHP_AUTH_PW`'  
When doing HTTP authentication this variable is set to the password provided by the user.

'`AUTH_TYPE`'  
When doing HTTP authentication this variable is set to the authentication type.

'`PATH_INFO`'  
Contains any client-provided pathname information trailing the actual script filename but preceding the query string, if available. For instance, if the current script was accessed via the URI `http://www.example.com/php/path_info.php/some/stuff?foo=bar`, then `$_SERVER['PATH_INFO']` would contain `/some/stuff`.

'`ORIG_PATH_INFO`'  
Original version of '`PATH_INFO`' before processed by PHP.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div id="variable.server.basic" class="example" role="variable">

<div class="title">

`$_SERVER` example

</div>

```
<?php
echo $_SERVER['SERVER_NAME'];
?>

    
```

ENTITY

    www.example.com

        

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

[The filter extension](#book.filter)

</div>

# session

<div data-wrapper="1" role="variable">

\$\_SESSION

</div>

<div data-wrapper="1" role="variable">

Session variables

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

An associative array containing session variables available to the current script. See the [Session functions](#ref.session) documentation for more information on how this is used.

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY ENTITY

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

`session_start`

</div>

# superglobals

<div data-wrapper="1" role="variable">

Superglobals

</div>

<div data-wrapper="1" role="variable">

Built-in variables that are always available in all scopes

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

Several predefined variables in PHP are "superglobals", which means they are available in all scopes throughout a script. There is no need to do `global $variable;` to access them within functions or methods.

</div>

<div data-wrapper="1" role="variable">

These superglobal variables are: `$GLOBALS`, `$_SERVER`, `$_GET`, `$_POST`, `$_FILES`, `$_COOKIE`, `$_SESSION`, `$_REQUEST`, `$_ENV`

</div>

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

> [!NOTE]
> By default, all of the superglobals are available but there are directives that affect this availability. For further information, refer to the documentation for [variables_order](#ini.variables-order).

> [!NOTE]
> Superglobals cannot be used as [variable variables](#language.variables.variable) inside functions or class methods.

# 

<div data-wrapper="1" role="variable">

ENTITY

</div>

<div data-wrapper="1" role="variable">

[variable scope](#language.variables.scope), The [variables_order](#ini.variables-order) directive, [The filter extension](#book.filter)

</div>

# weakmap

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

A `WeakMap` is a map (or dictionary) that accepts objects as keys. However, unlike the otherwise similar `SplObjectStorage`, an object in a key of a `WeakMap` does not contribute toward the object's reference count. That is, if at any point the only remaining reference to an object is the key of a `WeakMap`, the object will be garbage collected and removed from the `WeakMap`. Its primary use case is for building caches of data derived from an object that do not need to live longer than the object.

</div>

<div data-wrapper="1" role="class">

`WeakMap` implements ArrayAccess, Traversable (via IteratorAggregate), and Countable, so in most cases it can be used in the same fashion as an associative array.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

WeakMap

</div>

<div data-wrapper="1" role="class">

implements

</div>

<div data-wrapper="1" role="class">

ArrayAccess

</div>

<div data-wrapper="1" role="class">

Countable

</div>

<div data-wrapper="1" role="class">

IteratorAggregate

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div class="example" role="class">

<div class="title">

`WeakMap` usage example

</div>

```
      
<?php
$wm = new WeakMap();

$o = new stdClass;

class A {
    public function __destruct() {
        echo "Dead!\n";
    }
}

$wm[$o] = new A;

var_dump(count($wm));
echo "Unsetting...\n";
unset($o);
echo "Done\n";
var_dump(count($wm));

     
```

ENTITY

          
    int(1)
    Unsetting...
    Dead!
    Done
    int(0)

         

</div>

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

</div>

# count

WeakMap::count

Counts the number of live entries in the map

# 

ENTITY

<div data-wrapper="1" role="WeakMap">

public

</div>

<div data-wrapper="1" role="WeakMap">

int

</div>

<div data-wrapper="1" role="WeakMap">

WeakMap::count

</div>

Counts the number of live entries in the map.

# 

ENTITY ENTITY

# 

ENTITY

Returns the number of live entries in the map.

# getiterator

WeakMap::getIterator

Retrieve an external iterator

# 

ENTITY

<div data-wrapper="1" role="WeakMap">

public

</div>

<div data-wrapper="1" role="WeakMap">

Iterator

</div>

<div data-wrapper="1" role="WeakMap">

WeakMap::getIterator

</div>

Returns an external iterator.

# 

ENTITY ENTITY

# 

ENTITY

An instance of an object implementing `Iterator` or `Traversable`

# 

ENTITY

Throws an `Exception` on failure.

# offsetexists

WeakMap::offsetExists

Checks whether a certain object is in the map

# 

ENTITY

<div data-wrapper="1" role="WeakMap">

public

</div>

<div data-wrapper="1" role="WeakMap">

bool

</div>

<div data-wrapper="1" role="WeakMap">

WeakMap::offsetExists

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

Checks whether the passed object is referenced in the map.

# 

ENTITY

`object`  
Object to check for.

# 

ENTITY

Returns ENTITY if the object is contained in the map, ENTITY otherwise.

# 

ENTITY

> [!NOTE]
> Like `isset`, this method returns ENTITY if the value associated with `object` is ENTITY, even though the object is still contained in the map.

# offsetget

WeakMap::offsetGet

Returns the value pointed to by a certain object

# 

ENTITY

<div data-wrapper="1" role="WeakMap">

public

</div>

<div data-wrapper="1" role="WeakMap">

mixed

</div>

<div data-wrapper="1" role="WeakMap">

WeakMap::offsetGet

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

Returns the value pointed to by a certain object.

# 

ENTITY

`object`  
Some object contained as key in the map.

# 

ENTITY

Returns the value associated to the object passed as argument.

# 

ENTITY

Throws an `Error` on failure.

# offsetset

WeakMap::offsetSet

Updates the map with a new key-value pair

# 

ENTITY

<div data-wrapper="1" role="WeakMap">

public

</div>

<div data-wrapper="1" role="WeakMap">

void

</div>

<div data-wrapper="1" role="WeakMap">

WeakMap::offsetSet

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

<div data-wrapper="1" role="WeakMap">

mixed

</div>

<div data-wrapper="1" role="WeakMap">

value

</div>

Updates the map with a new key-value pair. If the key already existed in the map, the old value is replaced with the new.

# 

ENTITY

`object`  
The object serving as key of the key-value pair.

`value`  
The arbitrary data serving as value of the key-value pair.

# 

ENTITY

ENTITY

# offsetunset

WeakMap::offsetUnset

Removes an entry from the map

# 

ENTITY

<div data-wrapper="1" role="WeakMap">

public

</div>

<div data-wrapper="1" role="WeakMap">

void

</div>

<div data-wrapper="1" role="WeakMap">

WeakMap::offsetUnset

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

<div data-wrapper="1" role="WeakMap">

object

</div>

Removes an entry from the map.

# 

ENTITY

`object`  
The key object to remove from the map.

# 

ENTITY

ENTITY

# weakreference

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

Weak references allow the programmer to retain a reference to an object without preventing the object from being destroyed. They are useful for implementing cache-like structures. If the original object has been destroyed, ENTITY will be returned when calling the WeakReference::get method. The original object will be destroyed when the [refcount](#features.gc.refcounting-basics) for it drops to zero; creating weak references does not increase the `refcount` of the object being referenced.

</div>

<div data-wrapper="1" role="class">

`WeakReference`s cannot be serialized.

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

<div data-wrapper="1" role="class">

final

</div>

<div data-wrapper="1" role="class">

WeakReference

</div>

<div data-wrapper="1" role="comment">

ENTITY

</div>

# WeakReference Examples

<div id="weakreference.basic-example" class="example" role="class">

<div class="title">

Basic WeakReference Usage

</div>

```
<?php

$obj = new stdClass();
$weakref = WeakReference::create($obj);

var_dump($weakref->get());

unset($obj);

var_dump($weakref->get());

?>

     
```

ENTITY

    object(stdClass)#1 (0) {
    }
    NULL

         

</div>

# 

<div data-wrapper="1" role="class">

ENTITY

</div>

| ENTITY | ENTITY |
|----|----|
| 8.4.0 | The output of WeakReference::\_\_debugInfo now includes the referenced object, or ENTITY if the reference is no longer valid. |

<div data-wrapper="1" role="class">

ENTITY ENTITY ENTITY

</div>

# construct

WeakReference::\_\_construct

Constructor that disallows instantiation

# 

ENTITY

<div data-wrapper="1" role="WeakReference">

public

</div>

<div data-wrapper="1" role="WeakReference">

WeakReference::\_\_construct

</div>

This method exists only to disallow instantiation of the `WeakReference` class. Weak references are to be instantiated with the factory method WeakReference::create.

# 

ENTITY ENTITY

# 

ENTITY

WeakReference::create

# create

WeakReference::create

Create a new weak reference

# 

ENTITY

<div data-wrapper="1" role="WeakReference">

public

</div>

<div data-wrapper="1" role="WeakReference">

static

</div>

<div data-wrapper="1" role="WeakReference">

WeakReference

</div>

<div data-wrapper="1" role="WeakReference">

WeakReference::create

</div>

<div data-wrapper="1" role="WeakReference">

object

</div>

<div data-wrapper="1" role="WeakReference">

object

</div>

Creates a new `WeakReference`.

# 

ENTITY

`object`  
The object to be weakly referenced.

# 

ENTITY

Returns a new `WeakReference`, or the existing instance if there was already a `WeakReference` to the same object.

# get

WeakReference::get

Get a weakly referenced Object

# 

ENTITY

<div data-wrapper="1" role="WeakReference">

public

</div>

<div data-wrapper="1" role="WeakReference">

object

</div>

<div data-wrapper="1" role="WeakReference">

null

</div>

<div data-wrapper="1" role="WeakReference">

WeakReference::get

</div>

Gets a weakly referenced object. If the object has already been destroyed, ENTITY is returned.

# 

ENTITY ENTITY

# 

ENTITY

Returns the referenced ENTITY, or ENTITY if the object has been destroyed.

# References Explained

## What References Are

References in PHP are a means to access the same variable content by different names. They are not like C pointers; for instance, you cannot perform pointer arithmetic using them, they are not actual memory addresses, and so on. See [What References Are Not](#language.references.arent) for more information. Instead, they are [symbol table](#features.gc.refcounting-basics) aliases. Note that in PHP, variable name and variable content are different, so the same content can have different names. The closest analogy is with Unix filenames and files - variable names are directory entries, while variable content is the file itself. References can be likened to hardlinking in Unix filesystem.

## What References Do

There are three basic operations performed using references: [assigning by reference](#language.references.whatdo.assign), [passing by reference](#language.references.whatdo.pass), and [returning by reference](#language.references.whatdo.return). This section will give an introduction to these operations, with links for further reading.

### Assign By Reference

In the first of these, PHP references allow you to make two variables refer to the same content. Meaning, when you do:

<div class="informalexample">

```
<?php
$a =& $b;

      
```

</div>

it means that `$a` and `$b` point to the same content.

> [!NOTE]
> `$a` and `$b` are completely equal here. `$a` is not pointing to `$b` or vice versa. `$a` and `$b` are pointing to the same place.

> [!NOTE]
> If you assign, pass, or return an undefined variable by reference, it will get created.
>
> <div class="example">
>
> <div class="title">
>
> Using references with undefined variables
>
> </div>
>
> ```
> <?php
>
> function foo(&$var) {}
>
> foo($a); // $a is "created" and assigned to null
>
> $b = array();
> foo($b['b']);
> var_dump(array_key_exists('b', $b)); // bool(true)
>
> $c = new stdClass();
> foo($c->d);
> var_dump(property_exists($c, 'd')); // bool(true)
>
>        
> ```
>
> </div>

The same syntax can be used with functions that return references:

<div class="informalexample">

```
<?php
$foo =& find_var($bar);

      
```

</div>

Using the same syntax with a function that does *not* return by reference will give an error, as will using it with the result of the [new](#language.oop5.basic.new) operator. Although objects are passed around as pointers, these are not the same as references, as explained under [Objects and references](#language.oop5.references).

> [!WARNING]
> If you assign a reference to a variable declared `global` inside a function, the reference will be visible only inside the function. You can avoid this by using the `$GLOBALS` array.
>
> <div class="example">
>
> <div class="title">
>
> Referencing global variables inside functions
>
> </div>
>
> ```
> <?php
> $var1 = "Example variable";
> $var2 = "";
>
> function global_references($use_globals)
> {
>     global $var1, $var2;
>
>     if (!$use_globals) {
>         $var2 =& $var1; // visible only inside the function
>     } else {
>         $GLOBALS["var2"] =& $var1; // visible also in global context
>     }
> }
>
> global_references(false);
> echo "var2 is set to '$var2'\n"; // var2 is set to ''
>
> global_references(true);
> echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable'
>
>        
> ```
>
> </div>
>
> Think about `global $var;` as a shortcut to `$var =ENTITY $GLOBALS['var'];`. Thus assigning another reference to `$var` only changes the local variable's reference.

> [!NOTE]
> If you assign a value to a variable with references in a ENTITY statement, the references are modified too.
>
> <div class="example">
>
> <div class="title">
>
> References and foreach statement
>
> </div>
>
> ```
> <?php
> $ref = 0;
> $row =& $ref;
>
> foreach (array(1, 2, 3) as $row) {
>     // Do something
> }
>
> echo $ref; // 3 - last element of the iterated array
>
>        
> ```
>
> </div>

While not being strictly an assignment by reference, expressions created with the language construct [`array()`](#function.array) can also behave as such by prefixing `ENTITY` to the array element to add. Example:

<div class="informalexample">

```
<?php
$a = 1;
$b = array(2, 3);

$arr = array(&$a, &$b[0], &$b[1]);
$arr[0]++;
$arr[1]++;
$arr[2]++;
/* $a == 2, $b == array(3, 4); */
var_dump($a);
var_dump($b);

      
```

</div>

Note, however, that references inside arrays are potentially dangerous. Doing a normal (not by reference) assignment with a reference on the right side does not turn the left side into a reference, but references inside arrays are preserved in these normal assignments. This also applies to function calls where the array is passed by value. Example:

<div class="informalexample">

```
<?php

/* Assignment of scalar variables */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; // $c is not a reference; no change to $a or $b
print "a = {$a}; b = {$b}; c = {$c}\n\n";

/* Assignment of array variables */
$arr = array(1);
$a =& $arr[0]; // $a and $arr[0] are in the same reference set
$arr2 = $arr; // Not an assignment-by-reference!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* The contents of $arr are changed even though it's not a reference! */
print "a = {$a}\n";
var_dump($arr);
var_dump($arr2);

      
```

</div>

In other words, the reference behavior of arrays is defined in an element-by-element basis; the reference behavior of individual elements is dissociated from the reference status of the array container.

### Pass By Reference

The second thing references do is to pass variables by reference. This is done by making a local variable in a function and a variable in the calling scope referencing the same content. Example:

<div class="informalexample">

```
<?php
function foo(&$var)
{
    $var++;
}

$a = 5;
foo($a);
print $a;

      
```

</div>

will make `$a` to be 6. This happens because in the function `foo` the variable `$var` refers to the same content as `$a`. For more information on this, read the [passing by reference](#language.references.pass) section.

### Return By Reference

The third thing references can do is [return by reference](#language.references.return).

## What References Are Not

As said before, references are not pointers. That means, the following construct won't do what you expect:

<div class="informalexample">

```
<?php
function foo(&$var)
{
    $var =& $GLOBALS["baz"];
}

foo($bar);

     
```

</div>

What happens is that `$var` in `foo` will be bound with `$bar` in the caller, but then re-bound with `$GLOBALS["baz"]`. There's no way to bind `$bar` in the calling scope to something else using the reference mechanism, since `$bar` is not available in the function `foo` (it is represented by `$var`, but `$var` has only variable contents and not name-to-value binding in the calling [symbol table](#features.gc.refcounting-basics)). You can use [returning references](#language.references.return) to reference variables selected by the function.

## Passing by Reference

You can pass a variable by reference to a function so the function can modify the variable. The syntax is as follows:

<div class="informalexample">

```
<?php
function foo(&$var)
{
    $var++;
}

$a = 5;
foo($a);
print $a; // $a is 6 here

     
```

</div>

> [!NOTE]
> There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference.

The following things can be passed by reference:

- Variables, i.e. `foo($a)`

- References returned from functions, i.e.:

  <div class="informalexample">

  ```
  <?php

  function foo(&$var)
  {
      $var++;
      print $var;
  }

  function &bar()
  {
      $a = 5;
      return $a;
  }

  foo(bar());

       
  ```

  </div>

  See more about [returning by reference](#language.references.return).

No other expressions should be passed by reference, as the result is undefined. For example, the following examples of passing by reference are invalid:

<div class="informalexample">

```
<?php

function foo(&$var)
{
    $var++;
}

function bar() // Note the missing &
{
    $a = 5;
    return $a;
}

foo(bar()); // Produces a notice

foo($a = 5); // Expression, not variable
foo(5); // Produces fatal error

class Foobar {}

foo(new Foobar()) // Produces a notice as of PHP 7.0.7
                  // Notice: Only variables should be passed by reference

     
```

</div>

## Returning References

Returning by reference is useful when you want to use a function to find to which variable a reference should be bound. Do *not* use return-by-reference to increase performance. The engine will automatically optimize this on its own. Only return references when you have a valid technical reason to do so. To return references, use this syntax:

<div class="informalexample">

```
<?php

class Foo
{
    public $value = 42;

    public function &getValue()
    {
        return $this->value;
    }
}

$obj = new Foo();
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42
$obj->value = 2;
echo $myValue;                // Prints the new value of $obj->value, i.e. 2

     
```

</div>

In this example, the property of the object returned by the `getValue` function would be set, not the copy, as it would be without using reference syntax.

> [!NOTE]
> Unlike parameter passing, here you have to use `ENTITY` in both places - to indicate that you want to return by reference, not a copy, and to indicate that reference binding, rather than usual assignment, should be done for `$myValue`.

> [!NOTE]
> If you try to return a reference from a function with the syntax: `return ($this->value);` this will *not* work as you are attempting to return the result of an *expression*, and not a variable, by reference. You can only return variables by reference from a function - nothing else.

To use the returned reference, you must use reference assignment:

<div class="informalexample">

```
<?php

function &collector()
{
    static $collection = array();
    return $collection;
}

$collection = &collector();
// Now the $collection is a referenced variable that references the static array inside the function

$collection[] = 'foo';

print_r(collector());

     
```

ENTITY

    Array
    (
        [0] => foo
    )

         

</div>

> [!NOTE]
> If the assignment is done without the `ENTITY` symbol, e.g. `$collection = collector();`, the `$collection` variable will receive a copy of the value, not the reference returned by the function.

To pass the returned reference to another function expecting a reference you can use this syntax:

<div class="informalexample">

```
<?php

function &collector()
{
    static $collection = array();
    return $collection;
}

array_push(collector(), 'foo');

     
```

</div>

> [!NOTE]
> Note that `array_push(ENTITYcollector(), 'foo');` will *not* work, it results in a fatal error.

## Unsetting References

When you unset the reference, you just break the binding between variable name and variable content. This does not mean that variable content will be destroyed. For example:

<div class="informalexample">

```
<?php

$a = 1;
$b =& $a;
unset($a); 
var_dump($a);
var_dump($b);

     
```

</div>

won't unset `$b`, just `$a`.

Again, it might be useful to think about this as analogous to the Unix `unlink` call.

## Spotting References

Many syntax constructs in PHP are implemented via referencing mechanisms, so everything mentioned herein about reference binding also applies to these constructs. Some constructs, like passing and returning by reference, are mentioned above. Other constructs that use references are:

### global References

When you declare a variable as `global $var` you are in fact creating reference to a global variable. That means, this is the same as:

<div class="informalexample">

```
<?php
$var =& $GLOBALS["var"];

      
```

</div>

This also means that unsetting `$var` won't unset the global variable.

# Types

## Introduction

Every single expression in PHP has one of the following built-in types depending on its value:

- `null`

- `bool`

- `int`

- `float` (floating-point number)

- `string`

- `array`

- `object`

- `callable`

- `resource`

PHP is a dynamically typed language, which means that by default there is no need to specify the type of a variable, as this will be determined at runtime. However, it is possible to statically type some aspect of the language via the use of [type declarations](#language.types.declarations). Different types that are supported by PHP's type system can be found at the [type system](#language.types.type-system) page.

Types restrict the kind of operations that can be performed on them. However, if an expression/variable is used in an operation which its type does not support, PHP will attempt to [type juggle](#language.types.type-juggling) the value into a type that supports the operation. This process depends on the context in which the value is used. For more information, see the section on [Type Juggling](#language.types.type-juggling).

> [!TIP]
> [The type comparison tables](#types.comparisons) may also be useful, as various examples of comparison between values of different types are present.

> [!NOTE]
> It is possible to force an expression to be evaluated to a certain type by using a [type cast](#language.types.typecasting). A variable can also be type cast in-place by using the `settype` function on it.

To check the value and type of an [expression](#language.expressions), use the `var_dump` function. To retrieve the type of an [expression](#language.expressions), use the `get_debug_type` function. However, to check if an expression is of a certain type use the `is_type` functions instead.

<div class="example">

<div class="title">

Different Types

</div>

```
<?php
$a_bool = true;   // a bool
$a_str  = "foo";  // a string
$a_str2 = 'foo';  // a string
$an_int = 12;     // an int

echo get_debug_type($a_bool), "\n";
echo get_debug_type($a_str), "\n";

// If this is an integer, increment it by four
if (is_int($an_int)) {
    $an_int += 4;
}
var_dump($an_int);

// If $a_bool is a string, print it out
if (is_string($a_bool)) {
    echo "String: $a_bool";
}
?>

    
```

ENTITY

    bool
    string
    int(16)

        

</div>

> [!NOTE]
> Prior to PHP 8.0.0, where the `get_debug_type` is not available, the `gettype` function can be used instead. However, it doesn't use the canonical type names.

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# Arrays

For a list of all array functions, see the [array functions](#ref.array) chapter in the documentation.

An `array` in PHP is actually an ordered map. A map is a type that associates *values* to *keys*. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As `array` values can be other `array`s, trees and multidimensional `array`s are also possible.

Explanation of those data structures is beyond the scope of this manual, but at least one example is provided for each of them. For more information, look towards the considerable literature that exists about this broad topic.

## Syntax

### Specifying with `array`

An `array` can be created using the `array` language construct. It takes any number of comma-separated `key =ENTITY value` pairs as arguments.

array(

key

=ENTITY

value

,

key2

=ENTITY

value2

,

key3

=ENTITY

value3

, ... )

The comma after the last array element is optional and can be omitted. This is usually done for single-line arrays, i.e. `array(1, 2)` is preferred over `array(1, 2, )`. For multi-line arrays on the other hand the trailing comma is commonly used, as it allows easier addition of new elements at the end.

> [!NOTE]
> A short array syntax exists which replaces `array()` with `[]`.

<div class="example">

<div class="title">

A simple array

</div>

```
<?php
$array1 = array(
    "foo" => "bar",
    "bar" => "foo",
);

// Using the short array syntax
$array2 = [
    "foo" => "bar",
    "bar" => "foo",
];

var_dump($array1, $array2);
?>

    
```

</div>

The \<key\> can either be an `int` or a `string`. The \<value\> can be of any type.

Additionally the following \<key\> casts will occur:

- `String`s containing valid decimal `int`s, unless the number is preceded by a `+` sign, will be cast to the `int` type. E.g. the key `"8"` will actually be stored under `8`. On the other hand `"08"` will not be cast, as it isn't a valid decimal integer.

- `Float`s are also cast to `int`s, which means that the fractional part will be truncated. E.g. the key `8.7` will actually be stored under `8`.

- `Bool`s are cast to `int`s, too, i.e. the key ENTITY will actually be stored under `1` and the key ENTITY under `0`.

- `Null` will be cast to the empty string, i.e. the key ENTITY will actually be stored under `""`.

- `Array`s and `object`s *can not* be used as keys. Doing so will result in a warning: `Illegal offset type`.

If multiple elements in the array declaration use the same key, only the last one will be used as all others are overwritten.

<div class="example">

<div class="title">

Type Casting and Overwriting example

</div>

```
<?php
$array = array(
    1    => "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",
);
var_dump($array);
?>

    
```

ENTITY

    array(1) {
      [1]=>
      string(1) "d"
    }

        

As all the keys in the above example are cast to `1`, the value will be overwritten on every new element and the last assigned value `"d"` is the only one left over.

</div>

PHP arrays can contain `int` and `string` keys at the same time as PHP does not distinguish between indexed and associative arrays.

<div class="example">

<div class="title">

Mixed `int` and `string` keys

</div>

```
<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo",
    100   => -100,
    -100  => 100,
);
var_dump($array);
?>

    
```

ENTITY

    array(4) {
      ["foo"]=>
      string(3) "bar"
      ["bar"]=>
      string(3) "foo"
      [100]=>
      int(-100)
      [-100]=>
      int(100)
    }

        

</div>

The \<key\> is optional. If it is not specified, PHP will use the increment of the largest previously used `int` key.

<div class="example">

<div class="title">

Indexed arrays without key

</div>

```
<?php
$array = array("foo", "bar", "hello", "world");
var_dump($array);
?>

    
```

ENTITY

    array(4) {
      [0]=>
      string(3) "foo"
      [1]=>
      string(3) "bar"
      [2]=>
      string(5) "hello"
      [3]=>
      string(5) "world"
    }

        

</div>

It is possible to specify the key only for some elements and leave it out for others:

<div class="example">

<div class="title">

Keys not on all elements

</div>

```
<?php
$array = array(
         "a",
         "b",
    6 => "c",
         "d",
);
var_dump($array);
?>

    
```

ENTITY

    array(4) {
      [0]=>
      string(1) "a"
      [1]=>
      string(1) "b"
      [6]=>
      string(1) "c"
      [7]=>
      string(1) "d"
    }

        

As you can see the last value `"d"` was assigned the key `7`. This is because the largest integer key before that was `6`.

</div>

<div class="example">

<div class="title">

Complex Type Casting and Overwriting example

</div>

This example includes all variations of type casting of keys and overwriting of elements.

```
<?php
$array = array(
    1    => 'a',
    '1'  => 'b', // the value "a" will be overwritten by "b"
    1.5  => 'c', // the value "b" will be overwritten by "c"
    -1 => 'd',
    '01'  => 'e', // as this is not an integer string it will NOT override the key for 1
    '1.5' => 'f', // as this is not an integer string it will NOT override the key for 1
    true => 'g', // the value "c" will be overwritten by "g"
    false => 'h',
    '' => 'i',
    null => 'j', // the value "i" will be overwritten by "j"
    'k', // value "k" is assigned the key 2. This is because the largest integer key before that was 1
    2 => 'l', // the value "k" will be overwritten by "l"
);

var_dump($array);
?>

    
```

ENTITY

    array(7) {
      [1]=>
      string(1) "g"
      [-1]=>
      string(1) "d"
      ["01"]=>
      string(1) "e"
      ["1.5"]=>
      string(1) "f"
      [0]=>
      string(1) "h"
      [""]=>
      string(1) "j"
      [2]=>
      string(1) "l"
    }

        

</div>

<div class="example">

<div class="title">

Negative index example

</div>

When assigning a negative integer key `n`, PHP will take care to assign the next key to `n+1`.

```
     
<?php
$array = [];

$array[-5] = 1;
$array[] = 2;

var_dump($array);
?>

    
```

ENTITY

         
    array(2) {
      [-5]=>
      int(1)
      [-4]=>
      int(2)
    }

        

> [!WARNING]
> Prior to PHP 8.3.0, assigning a negative integer key `n` would assign the next key to `0`, the previous example would therefore output:
>
> <div class="informalexample">
>
>     array(2) {
>       [-5]=>
>       int(1)
>       [0]=>
>       int(2)
>     }
>
>           
>
> </div>

</div>

### Accessing array elements with square bracket syntax

Array elements can be accessed using the `array[key]` syntax.

<div class="example">

<div class="title">

Accessing array elements

</div>

```
<?php
$array = array(
    "foo" => "bar",
    42    => 24,
    "multi" => array(
         "dimensional" => array(
             "array" => "foo"
         )
    )
);

var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>

    
```

ENTITY

    string(3) "bar"
    int(24)
    string(3) "foo"

        

</div>

> [!NOTE]
> Prior to PHP 8.0.0, square brackets and curly braces could be used interchangeably for accessing array elements (e.g. `$array[42]` and `$array{42}` would both do the same thing in the example above). The curly brace syntax was deprecated as of PHP 7.4.0 and no longer supported as of PHP 8.0.0.

<div class="example">

<div class="title">

Array dereferencing

</div>

```
<?php
function getArray() {
    return array(1, 2, 3);
}

$secondElement = getArray()[1];

var_dump($secondElement);
?>

    
```

</div>

> [!NOTE]
> Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an `E_WARNING`-level error message (`E_NOTICE`-level prior to PHP 8.0.0) will be issued, and the result will be ENTITY.

> [!NOTE]
> Array dereferencing a scalar value which is not a `string` yields ENTITY. Prior to PHP 7.4.0, that did not issue an error message. As of PHP 7.4.0, this issues `E_NOTICE`; as of PHP 8.0.0, this issues `E_WARNING`.

### Creating/modifying with square bracket syntax

An existing `array` can be modified by explicitly setting values in it.

This is done by assigning values to the `array`, specifying the key in brackets. The key can also be omitted, resulting in an empty pair of brackets (`[]`).

\$arr\[

key

\] =

value

; \$arr\[\] =

value

; //

key

may be an

int

or

string

//

value

may be any value of any type

If `$arr` doesn't exist yet or is set to ENTITY or ENTITY, it will be created, so this is also an alternative way to create an `array`. This practice is however discouraged because if `$arr` already contains some value (e.g. `string` from request variable) then this value will stay in place and `[]` may actually stand for [string access operator](#language.types.string.substr). It is always better to initialize a variable by a direct assignment.

> [!NOTE]
> As of PHP 7.1.0, applying the empty index operator on a string throws a fatal error. Formerly, the string was silently converted to an array.

> [!NOTE]
> As of PHP 8.1.0, creating a new array from ENTITY value is deprecated. Creating a new array from ENTITY and undefined values is still allowed.

To change a certain value, assign a new value to that element using its key. To remove a key/value pair, call the `unset` function on it.

<div class="example">

<div class="title">

Using Square Brackets with Arrays

</div>

```
<?php
$arr = array(5 => 1, 12 => 2);

$arr[] = 56;    // This is the same as $arr[13] = 56;
                // at this point of the script

$arr["x"] = 42; // This adds a new element to
                // the array with key "x"

unset($arr[5]); // This removes the element from the array

var_dump($arr);

unset($arr);    // This deletes the whole array

var_dump($arr);
?>

    
```

</div>

> [!NOTE]
> If no key is specified, the key will be the maximum existing integer index + `1`. If the array has no positive integer indices, the key will be `0`. As of PHP 8.3.0, it can also be a negative integer.
>
> Note that the maximum integer key used for this *need not currently exist in the `array`*. It need only have existed in the `array` at some time since the last time the `array` was re-indexed. The following example illustrates:
>
> <div class="informalexample">
>
> ```
> <?php
> // Create a simple array.
> $array = array(1, 2, 3, 4, 5);
> print_r($array);
>
> // Now delete every item, but leave the array itself intact:
> foreach ($array as $i => $value) {
>     unset($array[$i]);
> }
> print_r($array);
>
> // Append an item (note that the new key is 5, instead of 0).
> $array[] = 6;
> print_r($array);
>
> // Re-index:
> $array = array_values($array);
> $array[] = 7;
> print_r($array);
> ?>
>
>      
> ```
>
> ENTITY
>
>     Array
>     (
>         [0] => 1
>         [1] => 2
>         [2] => 3
>         [3] => 4
>         [4] => 5
>     )
>     Array
>     (
>     )
>     Array
>     (
>         [5] => 6
>     )
>     Array
>     (
>         [0] => 6
>         [1] => 7
>     )
>
>          
>
> </div>

### Array destructuring

Arrays can be destructured using the `[]` (as of PHP 7.1.0) or `list` language constructs. These constructs can be used to destructure an array into distinct variables.

<div class="example">

<div class="title">

Array Destructuring

</div>

```
<?php
$source_array = ['foo', 'bar', 'baz'];

[$foo, $bar, $baz] = $source_array;

echo $foo, PHP_EOL;    // prints "foo"
echo $bar, PHP_EOL;    // prints "bar"
echo $baz, PHP_EOL;    // prints "baz"
?>

    
```

</div>

Array destructuring can be used in ENTITY to destructure a multi-dimensional array while iterating over it.

<div class="example">

<div class="title">

Array Destructuring in Foreach

</div>

```
<?php
$source_array = [
    [1, 'John'],
    [2, 'Jane'],
];

foreach ($source_array as [$id, $name]) {
    echo "{$id}: '{$name}'\n";
}
?>

    
```

</div>

Array elements will be ignored if the variable is not provided. Array destructuring always starts at index `0`.

<div class="example">

<div class="title">

Ignoring Elements

</div>

```
<?php
$source_array = ['foo', 'bar', 'baz'];

// Assign the element at index 2 to the variable $baz
[, , $baz] = $source_array;

echo $baz;    // prints "baz"
?>

    
```

</div>

As of PHP 7.1.0, associative arrays can be destructured too. This also allows for easier selection of the right element in numerically indexed arrays as the index can be explicitly specified.

<div class="example">

<div class="title">

Destructuring Associative Arrays

</div>

```
<?php
$source_array = ['foo' => 1, 'bar' => 2, 'baz' => 3];

// Assign the element at index 'baz' to the variable $three
['baz' => $three] = $source_array;

echo $three, PHP_EOL;  // prints 3

$source_array = ['foo', 'bar', 'baz'];

// Assign the element at index 2 to the variable $baz
[2 => $baz] = $source_array;

echo $baz, PHP_EOL;    // prints "baz"
?>

    
```

</div>

Array destructuring can be used for easy swapping of two variables.

<div class="example">

<div class="title">

Swapping Two Variable

</div>

```
<?php
$a = 1;
$b = 2;

[$b, $a] = [$a, $b];

echo $a, PHP_EOL;    // prints 2
echo $b, PHP_EOL;    // prints 1
?>

    
```

</div>

> [!NOTE]
> The spread operator (`...`) is not supported in assignments.

> [!NOTE]
> Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an `E_WARNING`-level error message (`E_NOTICE`-level prior to PHP 8.0.0) will be issued, and the result will be ENTITY.

> [!NOTE]
> Destructuring a scalar value assigns ENTITY to all variables.

## Useful functions

There are quite a few useful functions for working with arrays. See the [array functions](#ref.array) section.

> [!NOTE]
> The `unset` function allows removing keys from an `array`. Be aware that the array will *not* be reindexed. If a true "remove and shift" behavior is desired, the `array` can be reindexed using the `array_values` function.
>
> <div class="example">
>
> <div class="title">
>
> Unsetting Intermediate Elements
>
> </div>
>
> ```
> <?php
> $a = array(1 => 'one', 2 => 'two', 3 => 'three');
>
> /* will produce an array that would have been defined as
>    $a = array(1 => 'one', 3 => 'three');
>    and NOT
>    $a = array(1 => 'one', 2 =>'three');
> */
> unset($a[2]);
> var_dump($a);
>
> $b = array_values($a);
> // Now $b is array(0 => 'one', 1 =>'three')
> var_dump($b);
> ?>
>
>     
> ```
>
> </div>

The ENTITY control structure exists specifically for `array`s. It provides an easy way to traverse an `array`.

## Array do's and don'ts

### Why is `$foo[bar]` wrong?

Always use quotes around a string literal array index. For example, `$foo['bar']` is correct, while `$foo[bar]` is not. But why? It is common to encounter this kind of syntax in old scripts:

<div class="informalexample">

```
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>

    
```

</div>

This is wrong, but it works. The reason is that this code has an undefined constant (`bar`) rather than a `string` (`'bar'` - notice the quotes). It works because PHP automatically converts a *bare string* (an unquoted `string` which does not correspond to any known symbol) into a `string` which contains the bare `string`. For instance, if there is no defined constant named `bar`, then PHP will substitute in the `string` `'bar'` and use that.

> [!WARNING]
> The fallback to treat an undefined constant as bare string issues an error of level `E_NOTICE`. This has been deprecated as of PHP 7.2.0, and issues an error of level `E_WARNING`. As of PHP 8.0.0, it has been removed and throws an `Error` exception.

This does not mean to *always* quote the key. Do not quote keys which are [constants](#language.constants) or [variables](#language.variables), as this will prevent PHP from interpreting them.

<div class="example">

<div class="title">

Key Quoting

</div>

```
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);

// Simple array:
$array = array(1, 2);
$count = count($array);

for ($i = 0; $i < $count; $i++) {
    echo "\nChecking $i: \n";
    echo "Bad: " . $array['$i'] . "\n";
    echo "Good: " . $array[$i] . "\n";
    echo "Bad: {$array['$i']}\n";
    echo "Good: {$array[$i]}\n";
}
?>

     
```

</div>

ENTITY

    Checking 0:
    Notice: Undefined index:  $i in /path/to/script.html on line 9
    Bad:
    Good: 1
    Notice: Undefined index:  $i in /path/to/script.html on line 11
    Bad:
    Good: 1

    Checking 1:
    Notice: Undefined index:  $i in /path/to/script.html on line 9
    Bad:
    Good: 2
    Notice: Undefined index:  $i in /path/to/script.html on line 11
    Bad:
    Good: 2

       

More examples to demonstrate this behaviour:

<div class="example">

<div class="title">

More Examples

</div>

```
<?php
// Show all errors
error_reporting(E_ALL);

$arr = array('fruit' => 'apple', 'veggie' => 'carrot');

// Correct
echo $arr['fruit'], PHP_EOL;  // apple
echo $arr['veggie'], PHP_EOL; // carrot

// Incorrect. This does not work and throws a PHP Error because
// of an undefined constant named fruit
//
// Error: Undefined constant "fruit"
try {
    echo $arr[fruit];
} catch (Error $e) {
    echo get_class($e), ': ', $e->getMessage(), PHP_EOL;
}

// This defines a constant to demonstrate what's going on.  The value 'veggie'
// is assigned to a constant named fruit.
define('fruit', 'veggie');

// Notice the difference now
echo $arr['fruit'], PHP_EOL;  // apple
echo $arr[fruit], PHP_EOL;    // carrot

// The following is okay, as it's inside a string. Constants are not looked for
// within strings, so no error occurs here
echo "Hello $arr[fruit]", PHP_EOL;      // Hello apple

// With one exception: braces surrounding arrays within strings allows constants
// to be interpreted
echo "Hello {$arr[fruit]}", PHP_EOL;    // Hello carrot
echo "Hello {$arr['fruit']}", PHP_EOL;  // Hello apple

// Concatenation is another option
echo "Hello " . $arr['fruit'], PHP_EOL; // Hello apple
?>

    
```

</div>

<div class="informalexample">

```
<?php
// This will not work, and will result in a parse error, such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using superglobals in strings as well
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";
?>

    
```

</div>

As stated in the [syntax](#language.types.array.syntax) section, what's inside the square brackets ('`[`' and '`]`') must be an expression. This means that code like this works:

<div class="informalexample">

```
<?php
echo $arr[somefunc($bar)];
?>

    
```

</div>

This is an example of using a function return value as the array index. PHP also knows about constants:

<div class="informalexample">

```
<?php
$error_descriptions[E_ERROR]   = "A fatal error has occurred";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE]  = "This is just an informal notice";
?>

    
```

</div>

Note that `E_ERROR` is also a valid identifier, just like `bar` in the first example. But the last example is in fact the same as writing:

<div class="informalexample">

```
<?php
$error_descriptions[1] = "A fatal error has occurred";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
?>

    
```

</div>

because `E_ERROR` equals `1`, etc.

#### So why is it bad then?

At some point in the future, the PHP team might want to add another constant or keyword, or a constant in other code may interfere. For example, it is already wrong to use the words `empty` and `default` this way, since they are [reserved keywords](#reserved).

> [!NOTE]
> To reiterate, inside a double-quoted `string`, it's valid to not surround array indexes with quotes so `"$foo[bar]"` is valid. See the above examples for details on why as well as the section on [variable parsing in strings](#language.types.string.parsing).

## Converting to array

For any of the types `int`, `float`, `string`, `bool` and `resource`, converting a value to an `array` results in an array with a single element with index zero and the value of the scalar which was converted. In other words, `(array) $scalarValue` is exactly the same as `array($scalarValue)`.

If an `object` is converted to an `array`, the result is an `array` whose elements are the `object`'s properties. The keys are the member variable names, with a few notable exceptions: integer properties are inaccessible; private variables have the class name prepended to the variable name; protected variables have a '\*' prepended to the variable name. These prepended values have `NUL` bytes on either side. Uninitialized [typed properties](#language.oop5.properties.typed-properties) are silently discarded.

<div class="example">

<div class="title">

Converting to an Array

</div>

```
    
<?php

class A {
    private $B;
    protected $C;
    public $D;
    function __construct()
    {
        $this->{1} = null;
    }
}

var_export((array) new A());
?>

   
```

ENTITY

        
    array (
      '' . "\0" . 'A' . "\0" . 'B' => NULL,
      '' . "\0" . '*' . "\0" . 'C' => NULL,
      'D' => NULL,
      1 => NULL,
    )

       

</div>

These `NUL` can result in some unexpected behaviour:

<div class="example">

<div class="title">

Casting an Object to an Array

</div>

```
<?php

class A {
    private $A; // This will become '\0A\0A'
}

class B extends A {
    private $A; // This will become '\0B\0A'
    public $AA; // This will become 'AA'
}

var_dump((array) new B());
?>

   
```

ENTITY

        
    array(3) {
      ["BA"]=>
      NULL
      ["AA"]=>
      NULL
      ["AA"]=>
      NULL
    }

       

ENTITY

        
    array(3) {
      ["AA"]=>
      NULL
      ["BA"]=>
      NULL
      ["AA"]=>
      NULL
    }

       

</div>

The above will appear to have two keys named 'AA', although one of them is actually named '\0A\0A'.

Converting ENTITY to an `array` results in an empty `array`.

## Comparing

It is possible to compare arrays with the `array_diff` function and with [array operators](#language.operators.array).

## Array unpacking

An array prefixed by `...` will be expanded in place during array definition. Only arrays and objects which implement Traversable can be expanded. Array unpacking with `...` is available as of PHP 7.4.0. This is also called the spread operator.

It's possible to expand multiple times, and add normal elements before or after the `...` operator:

<div class="example">

<div class="title">

Simple array unpacking

</div>

```
<?php
// Using short array syntax.
// Also, works with array() syntax.
$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; // [1, 2, 3]
$arr3 = [0, ...$arr1]; // [0, 1, 2, 3]
$arr4 = [...$arr1, ...$arr2, 111]; // [1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]

function getArr() {
  return ['a', 'b'];
}
$arr6 = [...getArr(), 'c' => 'd']; // ['a', 'b', 'c' => 'd']

var_dump($arr1, $arr2, $arr3, $arr4, $arr5, $arr6);
?>

    
```

</div>

Unpacking an array with the `...` operator follows the semantics of the `array_merge` function. That is, later string keys overwrite earlier ones and integer keys are renumbered:

<div class="example">

<div class="title">

Array unpacking with duplicate key

</div>

```
<?php
// string key
$arr1 = ["a" => 1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]

// integer key
$arr4 = [1, 2, 3];
$arr5 = [4, 5, 6];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Which is [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// where the original integer keys have not been retained.
?>

    
```

</div>

> [!NOTE]
> Keys that are neither integers nor strings throw a `TypeError`. Such keys can only be generated by a Traversable object.

> [!NOTE]
> Prior to PHP 8.1, unpacking an array which has a string key is not supported:
>
> <div class="informalexample">
>
> ```
> <?php
>
> $arr1 = [1, 2, 3];
> $arr2 = ['a' => 4];
> $arr3 = [...$arr1, ...$arr2];
> // Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5
>
> $arr4 = [1, 2, 3];
> $arr5 = [4, 5];
> $arr6 = [...$arr4, ...$arr5]; // works. [1, 2, 3, 4, 5]
> ?>
>
>     
> ```
>
> </div>

## Examples

The array type in PHP is very versatile. Here are some examples:

<div class="example">

<div class="title">

Array Versatility

</div>

```
<?php
// This:
$a = array( 'color' => 'red',
            'taste' => 'sweet',
            'shape' => 'round',
            'name'  => 'apple',
            4        // key will be 0
          );

$b = array('a', 'b', 'c');

var_dump($a, $b);

// . . .is completely equivalent with this:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // key will be 0

$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';

// After the above code is executed, $a will be the array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), and $b will be the array
// array(0 => 'a', 1 => 'b', 2 => 'c'), or simply array('a', 'b', 'c').

var_dump($a, $b);
?>

   
```

</div>

<div class="example">

<div class="title">

Using array()

</div>

```
<?php
// Array as (property-)map
$map = array( 'version'    => 4,
              'OS'         => 'Linux',
              'lang'       => 'english',
              'short_tags' => true
            );
var_dump($map);

// strictly numerical keys
// this is the same as array(0 => 7, 1 => 8, ...)
$array = array( 7,
                8,
                0,
                156,
                -10
              );
var_dump($array);

$switching = array(         10, // key = 0
                    5    =>  6,
                    3    =>  7,
                    'a'  =>  4,
                            11, // key = 6 (maximum of integer-indices was 5)
                    '8'  =>  2, // key = 8 (integer!)
                    '02' => 77, // key = '02'
                    0    => 12  // the value 10 will be overwritten by 12
                  );
var_dump($switching);

// empty array
$empty = array();
var_dump($empty);
?>


   
```

</div>

<div id="language.types.array.examples.loop" class="example">

<div class="title">

Collection

</div>

```
<?php
$colors = array('red', 'blue', 'green', 'yellow');

foreach ($colors as $color) {
    echo "Do you like $color?\n";
}

?>

   
```

ENTITY

    Do you like red?
    Do you like blue?
    Do you like green?
    Do you like yellow?

       

</div>

Changing the values of the `array` directly is possible by passing them by reference.

<div id="language.types.array.examples.changeloop" class="example">

<div class="title">

Changing element in the loop

</div>

```
<?php
$colors = array('red', 'blue', 'green', 'yellow');

foreach ($colors as &$color) {
    $color = mb_strtoupper($color);
}
unset($color); /* ensure that following writes to
$color will not modify the last array element */

print_r($colors);
?>

   
```

ENTITY

    Array
    (
        [0] => RED
        [1] => BLUE
        [2] => GREEN
        [3] => YELLOW
    )

       

</div>

This example creates a one-based array.

<div class="example">

<div class="title">

One-based index

</div>

```
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>

   
```

ENTITY

    Array
    (
        [1] => January
        [2] => February
        [3] => March
    )

       

</div>

<div class="example">

<div class="title">

Filling an array

</div>

```
<?php
// fill an array with all items from a directory
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
    $files[] = $file;
}
closedir($handle);

var_dump($files);
?>

   
```

</div>

`Array`s are ordered. The order can be changed using various sorting functions. See the [array functions](#ref.array) section for more information. The `count` function can be used to count the number of items in an `array`.

<div class="example">

<div class="title">

Sorting an array

</div>

```
<?php
sort($files);
print_r($files);
?>

   
```

</div>

Because the value of an `array` can be anything, it can also be another `array`. This enables the creation of recursive and multi-dimensional `array`s.

<div class="example">

<div class="title">

Recursive and multi-dimensional arrays

</div>

```
<?php
$fruits = array ( "fruits"  => array ( "a" => "orange",
                                       "b" => "banana",
                                       "c" => "apple"
                                     ),
                  "numbers" => array ( 1,
                                       2,
                                       3,
                                       4,
                                       5,
                                       6
                                     ),
                  "holes"   => array (      "first",
                                       5 => "second",
                                            "third"
                                     )
                );
var_dump($fruits);

// Some examples to address values in the array above
echo $fruits["holes"][5];    // prints "second"
echo $fruits["fruits"]["a"]; // prints "orange"
unset($fruits["holes"][0]);  // remove "first"

// Create a new multi-dimensional array
$juices["apple"]["green"] = "good";
var_dump($juices);
?>

   
```

</div>

`Array` assignment always involves value copying. Use the [reference operator](#language.operators) to copy an `array` by reference.

<div class="example">

<div class="title">

Array Copying

</div>

```
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same

var_dump($arr1, $arr2, $arr3);
?>

   
```

</div>

# Booleans

The `bool` type only has two values, and is used to express a truth value. It can be either ENTITY or ENTITY.

## Syntax

To specify a `bool` literal, use the constants ENTITY or ENTITY. Both are case-insensitive.

<div class="informalexample">

```
<?php

$foo = True; // assign the value TRUE to $foo

var_dump($foo); // bool(true)
?>

   
```

</div>

Typically, the result of an [operator](#language.operators) which returns a `bool` value is passed on to a [control structure](#language.control-structures).

<div class="informalexample">

```
<?php

$action = "show_version";
$show_separators = true;

// == is an operator which tests
// equality and returns a boolean
if ($action == "show_version") {
    echo "The version is 1.23";
}

// this is not necessary...
if ($show_separators == TRUE) {
    echo "<hr>\n";
}

// ...because this can be used with exactly the same meaning:
if ($show_separators) {
    echo "<hr>\n";
}
?>

   
```

</div>

## Converting to boolean

To explicitly convert a value to `bool`, use the `(bool)` cast. Generally this is not necessary because when a value is used in a logical context it will be automatically interpreted as a value of type `bool`. For more information see the [Type Juggling](#language.types.type-juggling) page.

When converting to `bool`, the following values are considered ENTITY:

- the [boolean](#language.types.boolean) ENTITY itself

- the [integer](#language.types.integer) `0` (zero)

- the [float](#language.types.float)s `0.0` and `-0.0` (zero)

- the empty [string](#language.types.string) `""`, and the [string](#language.types.string) `"0"`

- an [array](#language.types.array) with zero elements

- the unit type [NULL](#language.types.null) (including unset variables)

- Internal objects that overload their casting behaviour to bool. For example, `GMP` objects representing the value `0`.

Every other value is considered ENTITY (including [resource](#language.types.resource) and `NAN`).

> [!WARNING]
> `-1` is considered ENTITY, like any other non-zero (whether negative or positive) number!

<div class="example">

<div class="title">

Casting to Boolean

</div>

```
<?php
var_dump((bool) "");        // bool(false)
var_dump((bool) "0");       // bool(false)
var_dump((bool) 1);         // bool(true)
var_dump((bool) -2);        // bool(true)
var_dump((bool) "foo");     // bool(true)
var_dump((bool) 2.3e5);     // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array());   // bool(false)
var_dump((bool) "false");   // bool(true)
?>

   
```

</div>

# Callables

A callable is a reference to a function or method that is passed to another function as an argument. They are represented with the `callable` type declaration.

<div class="informalexample">

```
<?php
function foo(callable $callback) {
    $callback();
}
?>

  
```

</div>

Some functions accept callback functions as a parameter, e.g. `array_map`, `usort`, or `preg_replace_callback`.

## Creation of callables

A callable is a type that represents something that can be invoked. Callables can be passed as arguments to functions or methods which expect a callback parameter or they can be invoked directly. The `callable` type cannot be used as a type declaration for class properties. Instead, use a `Closure` type declaration.

Callables can be created in several different ways:

- `Closure` object

- ENTITY containing the name of a function or a method

- ENTITY containing a class name or an `object` in index 0 and the method name in index 1

- ENTITY implementing the [\_\_invoke()](#object.invoke) magic method

A `Closure` object can be created using [anonymous function](#functions.anonymous) syntax, [arrow function](#functions.arrow) syntax, [first-class callable syntax](#functions.first_class_callable_syntax), or the Closure::fromCallable method.

> [!NOTE]
> The [first-class callable syntax](#functions.first_class_callable_syntax) is only available as of PHP 8.1.0.

<div class="example">

<div class="title">

Callback example using a `Closure`

</div>

```
<?php
// Using anonymous function syntax
$double1 = function ($a) {
    return $a * 2;
};

// Using first-class callable syntax
function double_function($a) {
    return $a * 2;
}
$double2 = double_function(...);

// Using arrow function syntax
$double3 = fn($a) => $a * 2;

// Using Closure::fromCallable
$double4 = Closure::fromCallable('double_function');

// Use the closure as a callback here to
// double the size of each element in our range
$new_numbers = array_map($double1, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;

$new_numbers = array_map($double2, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;

$new_numbers = array_map($double3, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;

$new_numbers = array_map($double4, range(1, 5));
print implode(' ', $new_numbers);

?>

   
```

ENTITY

    2 4 6 8 10
    2 4 6 8 10
    2 4 6 8 10
    2 4 6 8 10

       

</div>

A callable can also be a string containing the name of a function or a static method. Any built-in or user-defined function can be used, except language constructs such as: `array`, `echo`, `empty`, `eval`, `isset`, `list`, `print` or `unset`.

Static class methods can be used without instantiating an `object` of that class by either creating an array with the class name at index 0 and the method name at index 1, or by using the special syntax with the scope resolution operator `::`, as in `'ClassName::methodName'`.

A method of an instantiated `object` can be a callable when provided as an array with the `object` at index 0 and the method name at index 1.

The main difference between a `Closure` object and the `callable` type is that a `Closure` object is scope-independent and can always be invoked, whereas a callable type may be scope-dependent and may not be directly invoked. `Closure` is the preferred way to create callables. As of PHP 8.5.0, `Closure` is a proper subtype of `callable`.

> [!NOTE]
> While `Closure` objects are bound to the scope where they are created, callables referencing class methods as strings or arrays are resolved in the scope where they are called. To create a callable from a private or protected method, which can then be invoked from outside the class scope, use Closure::fromCallable or the [first-class callable syntax](#functions.first_class_callable_syntax).

PHP allows the creation of callables which can be used as a callback argument but cannot be called directly. These are context-dependent callables which reference a class method in the inheritance hierarchy of a class, e.g. `'parent::method'` or `["static", "method"]`.

> [!NOTE]
> As of PHP 8.2.0, context-dependent callables are deprecated. Remove the context dependency by replacing `'parent::method'` with `parent::class . '::method'` or use the [first-class callable syntax](#functions.first_class_callable_syntax).

<div class="example">

<div class="title">

Calling various types of callables with `call_user_func`

</div>

```
<?php

// An example callback function
function my_callback_function() {
    echo 'hello world!', PHP_EOL;
}

// An example callback method
class MyClass {
    static function myCallbackMethod() {
        echo 'Hello World!', PHP_EOL;
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function');

// Type 2: Static class method call
call_user_func(['MyClass', 'myCallbackMethod']);

// Type 3: Object method call
$obj = new MyClass();
call_user_func([$obj, 'myCallbackMethod']);

// Type 4: Static class method call
call_user_func('MyClass::myCallbackMethod');

// Type 5: Static class method call using ::class keyword
call_user_func([MyClass::class, 'myCallbackMethod']);

// Type 6: Relative static class method call
class A {
    public static function who() {
        echo 'A', PHP_EOL;
    }
}

class B extends A {
    public static function who() {
        echo 'B', PHP_EOL;
    }
}

call_user_func(['B', 'parent::who']); // deprecated as of PHP 8.2.0

// Type 7: Objects implementing __invoke can be used as callables
class C {
    public function __invoke($name) {
        echo 'Hello ', $name;
    }
}

$c = new C();
call_user_func($c, 'PHP!');
?>

   
```

ENTITY

    hello world!
    Hello World!
    Hello World!
    Hello World!
    Hello World!

    Deprecated: Callables of the form ["B", "parent::who"] are deprecated in script on line 44
    A
    Hello PHP!

       

</div>

ENTITY

# Type declarations

Type declarations can be added to function arguments, return values, as of PHP 7.4.0, class properties, and as of PHP 8.3.0, class constants. They ensure that the value is of the specified type at call time, otherwise a `TypeError` is thrown.

Every single type that PHP supports, with the exception of `resource`, can be used within a user-land type declaration. This page contains a changelog of availability of the different types and documentation about usage of them in type declarations.

> [!NOTE]
> When a class implements an interface method or reimplements a method which has already been defined by a parent class, it has to be compatible with the aforementioned definition. A method is compatible if it follows the [variance](#language.oop5.variance) rules.

## 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 8.3.0 | Support for class, interface, trait, and enum constant typing has been added. |
| 8.2.0 | Support for DNF types has been added. |
| 8.2.0 | Support for the literal type `true` has been added. |
| 8.2.0 | The types `null` and `false` can now be used standalone. |
| 8.1.0 | Support for intersection types has been added. |
| 8.1.0 | Returning by reference from a `void` function is now deprecated. |
| 8.1.0 | Support for the return only type `never` has been added. |
| 8.0.0 | Support for `mixed` has been added. |
| 8.0.0 | Support for the return only type `static` has been added. |
| 8.0.0 | Support for union types has been added. |
| 7.4.0 | Support for class properties typing has been added. |
| 7.2.0 | Support for `object` has been added. |
| 7.1.0 | Support for `iterable` has been added. |
| 7.1.0 | Support for `void` has been added. |
| 7.1.0 | Support for nullable types has been added. |

## Atomic Types Usage Notes

Atomic types have straightforward behaviour with some minor caveats which are described in this section.

### Scalar types

> [!WARNING]
> Name aliases for scalar types (`bool`, `int`, `float`, `string`) are not supported. Instead, they are treated as class or interface names. For example, using `boolean` as a type declaration will require the value to be an ENTITY the class or interface `boolean`, rather than of type `bool`:
>
> <div class="informalexample">
>
> ```
> <?php
>     function test(boolean $param) {}
>     test(true);
> ?>
>
>      
> ```
>
> ENTITY
>
>     Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /in/9YrUX on line 2
>
>     Fatal error: Uncaught TypeError: test(): Argument #1 ($param) must be of type boolean, bool given, called in - on line 3 and defined in -:2
>     Stack trace:
>     #0 -(3): test(true)
>     #1 {main}
>       thrown in - on line 2
>
>          
>
> </div>

### void

> [!NOTE]
> Returning by reference from a `void` function is deprecated as of PHP 8.1.0, because such a function is contradictory. Previously, it already emitted the following `E_NOTICE` when called: `Only variable references should be returned by reference`.
>
> <div class="informalexample">
>
> ```
> <?php
> function &test(): void {}
> ?>
>
>       
> ```
>
> </div>

### Callable types

This type cannot be used as a class property type declaration.

> [!NOTE]
> It is not possible to specify the signature of the function.

### Type declarations on pass-by-reference Parameters

If a pass-by-reference parameter has a type declaration, the type of the variable is *only* checked on function entry, at the beginning of the call, but not when the function returns. This means that a function can change the type of the variable passed by reference.

<div class="example">

<div class="title">

Typed pass-by-reference Parameters

</div>

```
<?php
function array_baz(array &$param)
{
    $param = 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>

    
```

ENTITY

    int(1)

    Fatal error: Uncaught TypeError: array_baz(): Argument #1 ($param) must be of type array, int given, called in - on line 9 and defined in -:2
    Stack trace:
    #0 -(9): array_baz(1)
    #1 {main}
      thrown in - on line 2

        

</div>

## Composite Types Usage Notes

Composite type declarations are subject to a couple of restrictions and will perform a redundancy check at compile time to prevent simple bugs.

> [!CAUTION]
> Prior to PHP 8.2.0, and the introduction of DNF types, it was not possible to combine intersection types with union types.

### Union types

> [!WARNING]
> It is not possible to combine the two singleton types `false` and `true` together in a union type. Use `bool` instead.

> [!CAUTION]
> Prior to PHP 8.2.0, as `false` and `null` could not be used as standalone types, a union type comprised of only these types was not permitted. This comprises the following types: `false`, `false|null`, and `?false`.

#### Nullable type syntactic sugar

A single base type declaration can be marked nullable by prefixing the type with a question mark (`?`). Thus `?T` and `T|null` are identical.

> [!NOTE]
> This syntax is supported as of PHP 7.1.0, and predates generalized union types support.

> [!NOTE]
> It is also possible to achieve nullable arguments by making ENTITY the default value. This is not recommended because if the default value is changed in a child class a type compatibility violation will be raised as the `null` type will need to be added to the type declaration. This behavior is also deprecated since PHP 8.4.
>
> <div class="example">
>
> <div class="title">
>
> Old way to make arguments nullable
>
> </div>
>
> ```
> <?php
> class C {}
>
> function f(C $c = null) {
>     var_dump($c);
> }
>
> f(new C);
> f(null);
> ?>
>
>       
> ```
>
> ENTITY
>
>     object(C)#1 (0) {
>     }
>     NULL
>
>           
>
> </div>

### Duplicate and redundant types

To catch simple bugs in composite type declarations, redundant types that can be detected without performing class loading will result in a compile-time error. This includes:

- Each name-resolved type may only occur once. Types such as `int|string|INT` or `CountableENTITYTraversableENTITYCOUNTABLE` result in an error.

- Using `mixed` or `never` results in an error.

- For union types:

  - If `bool` is used, `false` or `true` cannot be used additionally.

  - If `object` is used, class types cannot be used additionally.

  - If `iterable` is used, `array` and `Traversable` cannot be used additionally.

- For intersection types:

  - Using a type which is not a class-type results in an error.

  - Using either `self`, `parent`, or `static` results in an error.

- For DNF types:

  - If a more generic type is used, the more restrictive one is redundant.

  - Using two identical intersection types.

> [!NOTE]
> This does not guarantee that the type is “minimal”, because doing so would require loading all used class types.

For example, if `A` and `B` are class aliases, then `A|B` remains a legal union type, even though it could be reduced to either `A` or `B`. Similarly, if class `B extends A {}`, then `A|B` is also a legal union type, even though it could be reduced to just `A`.

<div class="informalexample">

```
<?php
function foo(): int|INT {} // Disallowed
function foo(): bool|false {} // Disallowed
function foo(): int&Traversable {} // Disallowed
function foo(): self&Traversable {} // Disallowed

use A as B;
function foo(): A|B {} // Disallowed ("use" is part of name resolution)
function foo(): A&B {} // Disallowed ("use" is part of name resolution)

class_alias('X', 'Y');
function foo(): X|Y {} // Allowed (redundancy is only known at runtime)
function foo(): X&Y {} // Allowed (redundancy is only known at runtime)
?>

     
```

</div>

## 

ENTITY

<div class="example">

<div class="title">

Basic class type declaration

</div>

```
<?php
class C {}
class D extends C {}

// This doesn't extend C.
class E {}

function f(C $c) {
    echo get_class($c)."\n";
}

f(new C);
f(new D);
f(new E);
?>

   
```

ENTITY

    C
    D

    Fatal error: Uncaught TypeError: f(): Argument #1 ($c) must be of type C, E given, called in /in/gLonb on line 14 and defined in /in/gLonb:8
    Stack trace:
    #0 -(14): f(Object(E))
    #1 {main}
      thrown in - on line 8

       

</div>

<div class="example">

<div class="title">

Basic interface type declaration

</div>

```
<?php
interface I { public function f(); }
class C implements I { public function f() {} }

// This doesn't implement I.
class E {}

function f(I $i) {
    echo get_class($i)."\n";
}

f(new C);
f(new E);
?>

   
```

ENTITY

    C

    Fatal error: Uncaught TypeError: f(): Argument #1 ($i) must be of type I, E given, called in - on line 13 and defined in -:8
    Stack trace:
    #0 -(13): f(Object(E))
    #1 {main}
      thrown in - on line 8

       

</div>

<div class="example">

<div class="title">

Basic return type declaration

</div>

```
<?php
function sum($a, $b): float {
    return $a + $b;
}

// Note that a float will be returned.
var_dump(sum(1, 2));
?>

   
```

ENTITY

    float(3)

       

</div>

<div class="example">

<div class="title">

Returning an object

</div>

```
<?php
class C {}

function getC(): C {
    return new C;
}

var_dump(getC());
?>

   
```

ENTITY

    object(C)#1 (0) {
    }

       

</div>

<div class="example">

<div class="title">

Nullable argument type declaration

</div>

```
    
<?php
class C {}

function f(?C $c) {
    var_dump($c);
}

f(new C);
f(null);
?>

   
```

ENTITY

        
    object(C)#1 (0) {
    }
    NULL

       

</div>

<div class="example">

<div class="title">

Nullable return type declaration

</div>

```
    
<?php
function get_item(): ?string {
    if (isset($_GET['item'])) {
        return $_GET['item'];
    } else {
        return null;
    }
}
?>

   
```

</div>

<div class="example">

<div class="title">

Class property type declaration

</div>

```
<?php
class User {
    public static string $foo = 'foo';

    public int $id;
    public string $username;

    public function __construct(int $id, string $username) {
        $this->id = $id;
        $this->username = $username;
    }
}
?>

   
```

</div>

## Strict typing

By default, PHP will coerce values of the wrong type into the expected scalar type declaration if possible. For example, a function that is given an `int` for a parameter that expects a `string` will get a variable of type `string`.

It is possible to enable strict mode on a per-file basis. In strict mode, only a value corresponding exactly to the type declaration will be accepted, otherwise a `TypeError` will be thrown. The only exception to this rule is that an `int` value will pass a `float` type declaration.

> [!WARNING]
> Function calls from within internal functions will not be affected by the `strict_types` declaration.

To enable strict mode, the ENTITY statement is used with the `strict_types` declaration:

> [!NOTE]
> Strict typing applies to function calls made from *within* the file with strict typing enabled, not to the functions declared within that file. If a file without strict typing enabled makes a call to a function that was defined in a file with strict typing, the caller's preference (coercive typing) will be respected, and the value will be coerced.

> [!NOTE]
> Strict typing is only defined for scalar type declarations.

<div class="example">

<div class="title">

Strict typing for arguments values

</div>

```
<?php
declare(strict_types=1);

function sum(int $a, int $b) {
    return $a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));
?>

   
```

ENTITY

    int(3)

    Fatal error: Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 9 and defined in -:4
    Stack trace:
    #0 -(9): sum(1.5, 2.5)
    #1 {main}
      thrown in - on line 4

       

</div>

<div class="example">

<div class="title">

Coercive typing for argument values

</div>

```
<?php
function sum(int $a, int $b) {
    return $a + $b;
}

var_dump(sum(1, 2));

// These will be coerced to integers: note the output below!
var_dump(sum(1.5, 2.5));
?>

   
```

ENTITY

    int(3)
    int(3)

       

</div>

<div class="example">

<div class="title">

Strict typing for return values

</div>

```
<?php
declare(strict_types=1);

function sum($a, $b): int {
    return $a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1, 2.5));
?>

   
```

ENTITY

    int(3)

    Fatal error: Uncaught TypeError: sum(): Return value must be of type int, float returned in -:5
    Stack trace:
    #0 -(9): sum(1, 2.5)
    #1 {main}
      thrown in - on line 5

       

</div>

# Enumerations

## Basic Enumerations

Enumerations are a restricting layer on top of classes and class constants, intended to provide a way to define a closed set of possible values for a type.

<div class="informalexample">

```
<?php
enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

function do_stuff(Suit $s)
{
    // ...
}

do_stuff(Suit::Spades);
?>

   
```

</div>

For a full discussion, see the [Enumerations](#language.enumerations) chapter.

## Casting

If an `enum` is converted to an `object`, it is not modified. If an `enum` is converted to an `array`, an array with a single `name` key (for Pure enums) or an array with both `name` and `value` keys (for Backed enums) is created. All other cast types will result in an error.

# Floating-point numbers

Floating-point numbers (also known as "floats", "doubles", or "real numbers") can be specified using any of the following syntaxes:

<div class="informalexample">

```
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // as of PHP 7.4.0
?>

  
```

</div>

Formally as of PHP 7.4.0 (previously, underscores have not been allowed):

<div class="informalexample">

    LNUM          [0-9]+(_[0-9]+)*
    DNUM          ({LNUM}?"."{LNUM}) | ({LNUM}"."{LNUM}?)
    EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})

      

</div>

The size of a float is platform-dependent, although a maximum of approximately 1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format).

> [!WARNING]
> Floating-point numbers have limited precision. Although it depends on the system, PHP typically uses the IEEE 754 double precision format, which will give a maximum relative error due to rounding in the order of 1.11e-16. Non-elementary arithmetic operations may give larger errors, and, of course, error propagation must be considered when several operations are compounded.
>
> Additionally, rational numbers that are exactly representable as floating-point numbers in base 10, like `0.1` or `0.7`, do not have an exact representation as floating-point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, `floor((0.1+0.7)*10)` will usually return `7` instead of the expected `8`, since the internal representation will be something like `7.9999999999999991118...`.
>
> So never trust floating-point number results to the last digit, and do not compare floating-point numbers directly for equality. If higher precision is necessary, the [arbitrary precision math functions](#ref.bc) and [gmp](#ref.gmp) functions are available.
>
> For a "simple" explanation, see the [floating point guide](ENTITY) that's also titled "Why don’t my numbers add up?"

## Converting to float

### From strings

If the string is [numeric](#language.types.numeric-strings) or leading numeric then it will resolve to the corresponding float value, otherwise it is converted to zero (`0`).

### From other types

For values of other types, the conversion is performed by converting the value to `int` first and then to `float`. See [Converting to integer](#language.types.integer.casting) for more information.

> [!NOTE]
> As certain types have undefined behavior when converting to `int`, this is also the case when converting to `float`.

## Comparing floats

As noted in the warning above, testing floating-point values for equality is problematic, due to the way that they are represented internally. However, there are ways to make comparisons of floating-point values that work around these limitations.

To test floating-point values for equality, an upper bound on the relative error due to rounding is used. This value is known as the machine epsilon, or unit roundoff, and is the smallest acceptable difference in calculations.

`$a` and `$b` are equal to 5 digits of precision.

<div class="example">

<div class="title">

Comparing Floats

</div>

```
<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if (abs($a - $b) < $epsilon) {
    echo "true";
}
?>

   
```

</div>

## NaN

Some numeric operations can result in a value represented by the constant `NAN`. This result represents an undefined or unrepresentable value in floating-point calculations. Any loose or strict comparisons of this value against any other value, including itself, but except ENTITY, will have a result of ENTITY.

Because `NAN` represents any number of different values, `NAN` should not be compared to other values, including itself, and instead should be checked for using `is_nan`.

# Integers

An `int` is a number of the set ℤ = {..., -2, -1, 0, 1, 2, ...}.

## 

ENTITY

[Floating-point numbers](#language.types.float), [Arbitrary precision / BCMath](#book.bc), [Arbitrary length integer / GMP](#book.gmp)

## Syntax

`Int`s can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) or binary (base 2) notation. The [negation operator](#language.operators.arithmetic) can be used to denote a negative `int`.

To use octal notation, precede the number with a `0` (zero). As of PHP 8.1.0, octal notation can also be preceded with `0o` or `0O`. To use hexadecimal notation, precede the number with `0x`. To use binary notation, precede the number with `0b`.

As of PHP 7.4.0, integer literals may contain underscores (`_`) between digits, for better readability of literals. These underscores are removed by PHP's scanner.

<div class="example">

<div class="title">

Integer literals

</div>

```
<?php
$a = 1234; // decimal number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0o123; // octal number (as of PHP 8.1.0)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
$a = 0b11111111; // binary number (equivalent to 255 decimal)
$a = 1_234_567; // decimal number (as of PHP 7.4.0)
?>

   
```

</div>

Formally, the structure for `int` literals is as of PHP 8.1.0 (previously, the `0o` or `0O` octal prefixes were not allowed, and prior to PHP 7.4.0 the underscores were not allowed):

<div class="informalexample">

    decimal     : [1-9][0-9]*(_[0-9]+)*
                | 0

    hexadecimal : 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)*

    octal       : 0[oO]?[0-7]+(_[0-7]+)*

    binary      : 0[bB][01]+(_[01]+)*

    integer     : decimal
                | hexadecimal
                | octal
                | binary

       

</div>

The size of an `int` is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned `int`s. `int` size can be determined using the constant `PHP_INT_SIZE`, maximum value using the constant `PHP_INT_MAX`, and minimum value using the constant `PHP_INT_MIN`.

## Integer overflow

If PHP encounters a number beyond the bounds of the `int` type, it will be interpreted as a `float` instead. Also, an operation which results in a number beyond the bounds of the `int` type will return a `float` instead.

<div class="example">

<div class="title">

Integer overflow

</div>

```
<?php
$large_number = 50000000000000000000;
var_dump($large_number);         // float(5.0E+19)

var_dump(PHP_INT_MAX + 1);       // 32-bit system: float(2147483648)
                                 // 64-bit system: float(9.2233720368548E+18)
?>

   
```

</div>

## Integer division

There is no `int` division operator in PHP. To achieve this, use the `intdiv` function. `1/2` yields the `float` `0.5`. The value can be cast to an `int` to round it towards zero, or the `round` function provides finer control over rounding.

<div class="example">

<div class="title">

Divisions

</div>

```
<?php
var_dump(25/7);         // float(3.5714285714286)
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7));  // float(4)
?>

   
```

</div>

## Converting to integer

To explicitly convert a value to `int`, use the `(int)` cast. However, in most cases the cast is not needed, since a value will be automatically converted if an operator, function or control structure requires an `int` argument. A value can also be converted to `int` with the `intval` function.

If a `resource` is converted to an `int`, then the result will be the unique resource number assigned to the `resource` by PHP at runtime.

See also [Type Juggling](#language.types.type-juggling).

### From [booleans](#language.types.boolean)

ENTITY will yield `0` (zero), and ENTITY will yield `1` (one).

### From [floating point numbers](#language.types.float)

When converting from `float` to `int`, the number will be rounded *towards zero*. As of PHP 8.1.0, a deprecation notice is emitted when implicitly converting a non-integral ENTITY to an ENTITY which loses precision.

<div class="example">

<div class="title">

Casting from Float

</div>

```
<?php

function foo($value): int {
  return $value;
}

var_dump(foo(8.1)); // "Deprecated: Implicit conversion from float 8.1 to int loses precision" as of PHP 8.1.0
var_dump(foo(8.1)); // 8 prior to PHP 8.1.0
var_dump(foo(8.0)); // 8 in both cases

var_dump((int) 8.1); // 8 in both cases
var_dump(intval(8.1)); // 8 in both cases
?>

    
```

</div>

If the float is beyond the boundaries of `int` (usually `+/- 2.15e+9 = 2^31` on 32-bit platforms and `+/- 9.22e+18 = 2^63` on 64-bit platforms), the result is undefined, since the `float` doesn't have enough precision to give an exact `int` result. As of PHP 8.5.0, an `E_WARNING` is emitted when a `float` that is not representable as an `int` is cast to one. Prior to PHP 8.5.0, no diagnostic at all was issued.

> [!NOTE]
> `NaN`, `Inf` and `-Inf` will always be zero when cast to `int`. As of PHP 8.5.0, casting them to `int` emits an `E_WARNING`, as does casting `NAN` to any other type.

> [!WARNING]
> Never cast an unknown fraction to `int`, as this can sometimes lead to unexpected results.
>
> <div class="informalexample">
>
> ```
> <?php
> echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
> ?>
>
>      
> ```
>
> </div>
>
> See also the [warning about float precision](#warn.float-precision).

### From strings

If the string is [numeric](#language.types.numeric-strings) or leading numeric then it will resolve to the corresponding integer value, otherwise it is converted to zero (`0`).

### From `NULL`

ENTITY is always converted to zero (`0`).

### From other types

> [!CAUTION]
> The behaviour of converting to `int` is undefined for other types. Do *not* rely on any observed behaviour, as it can change without notice.

# Iterables

`Iterable` is a built-in compile-time type alias for `array|Traversable`. From its introduction in PHP 7.1.0 and prior to PHP 8.2.0, `iterable` was a built-in pseudo-type that acted as the aforementioned type alias and could be used as a type declaration. An iterable type can be used in ENTITY and with `yield from` within a [generator](#language.generators).

> [!NOTE]
> Functions declaring iterable as a return type may also be [generators](#language.generators).
>
> <div class="example">
>
> <div class="title">
>
> Iterable generator return type example
>
> </div>
>
> ```
>      
> <?php
>
> function gen(): iterable {
>     yield 1;
>     yield 2;
>     yield 3;
> }
>
> foreach(gen() as $value) {
>     echo $value, "\n";
> }
> ?>
>
>     
> ```
>
> </div>

# Mixed

The `mixed` type accepts every value. It is equivalent to the [union type](#language.types.type-system.composite.union) `object|resource|array|string|float|int|bool|null`. Available as of PHP 8.0.0.

`mixed` is, in type theory parlance, the top type, meaning every other type is a subtype of it.

# Never

`never` is a return-only type indicating the function does not terminate. This means that it either calls `exit`, throws an exception, or is an infinite loop. Therefore, it cannot be part of a [union type](#language.types.type-system.composite.union) declaration. Available as of PHP 8.1.0.

A `return` statement in a `never` function is a compile-time error, even if the `return` would not be reached during execution. If control flow reaches the end of a `never` function without exiting, throwing an exception, or entering an infinite loop, a TypeError is thrown.

`never` is, in type theory parlance, the bottom type, meaning it is the subtype of every other type and can replace any other return type during inheritance.

# NULL

The `null` type is PHP's unit type, i.e. it has only one value: ENTITY.

Undefined and `unset` variables resolve to the value ENTITY.

## Syntax

There is only one value of type `null`, and that is the case-insensitive constant ENTITY.

<div class="informalexample">

```
<?php
$var = NULL;       
?>

   
```

</div>

## Casting to ENTITY

ENTITY

Casting a variable to `null` using `(unset) $var` will *not* remove the variable or unset its value. It will only return a ENTITY value.

## 

ENTITY

`is_null`, `unset`

# Numeric strings

A PHP `string` is considered numeric if it can be interpreted as an `int` or a `float`.

Formally as of PHP 8.0.0:

<div class="informalexample">

       
    WHITESPACES      \s*
    LNUM             [0-9]+
    DNUM             ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
    EXPONENT_DNUM    (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
    INT_NUM_STRING   {WHITESPACES} [+-]? {LNUM} {WHITESPACES}
    FLOAT_NUM_STRING {WHITESPACES} [+-]? ({DNUM} | {EXPONENT_DNUM}) {WHITESPACES}
    NUM_STRING       ({INT_NUM_STRING} | {FLOAT_NUM_STRING})

      

</div>

PHP also has a concept of *leading* numeric strings. This is simply a string which starts like a numeric string followed by any characters.

> [!NOTE]
> Any string that contains the letter `E` (case insensitive) bounded by numbers will be seen as a number expressed in scientific notation. This can produce unexpected results.
>
> <div class="example">
>
> <div class="title">
>
> Scientific Notation Comparisons
>
> </div>
>
> ```
> <?php
> var_dump("0D1" == "000"); // false, "0D1" is not scientific notation
> var_dump("0E1" == "000"); // true, "0E1" is 0 * (10 ^ 1), or 0
> var_dump("2E1" == "020"); // true, "2E1" is 2 * (10 ^ 1), or 20
> ?>
>
>    
> ```
>
> </div>

## Strings used in numeric contexts

When a `string` needs to be evaluated as a number (e.g. arithmetic operations, `int` type declaration, etc.) the following steps are taken to determine the outcome:

1.  If the `string` is numeric, resolve to an `int` if the `string` is an integer numeric string and fits into the limits of the `int` type limits (as defined by `PHP_INT_MIN` and `PHP_INT_MAX`), otherwise resolve to a `float`.

2.  If the context allows leading numeric strings and the `string` is one, resolve to an `int` if the leading part of the `string` is an integer numeric string and fits into the limits of the `int` type limits (as defined by `PHP_INT_MIN` and `PHP_INT_MAX`), otherwise resolve to a `float`. Additionally an error of level `E_WARNING` is raised.

3.  If the `string` is not numeric, throw a `TypeError`.

## Behavior prior to PHP 8.0.0

Prior to PHP 8.0.0, a `string` was considered numeric if it only had *leading* whitespaces. If it had *trailing* whitespaces then the string was considered to be leading numeric.

Prior to PHP 8.0.0, when a string was used in a numeric context it would perform the same steps as above with the following differences:

- The usage of a leading numeric string would raise an `E_NOTICE` instead of an `E_WARNING`.

- If the string was not numeric, an `E_WARNING` was raised and the value `0` would be returned.

Prior to PHP 7.1.0, neither `E_NOTICE` nor `E_WARNING` was raised.

<div class="informalexample">

```
<?php
$foo = 1 + "10.5";                // $foo is float (11.5)
$foo = 1 + "-1.3e3";              // $foo is float (-1299)
$foo = 1 + "bob-1.3e3";           // TypeError as of PHP 8.0.0, $foo is integer (1) previously
$foo = 1 + "bob3";                // TypeError as of PHP 8.0.0, $foo is integer (1) previously
$foo = 1 + "10 Small Pigs";       // $foo is integer (11) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
$foo = "10.0 pigs " + 1;          // $foo is float (11) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
$foo = "10.0 pigs " + 1.0;        // $foo is float (11) and an E_WARNING is raised in PHP 8.0.0, E_NOTICE previously
?>

   
```

</div>

# Objects

## Object Initialization

To create a new `object`, use the `new` statement to instantiate a class:

<div class="example">

<div class="title">

Object Construction

</div>

```
<?php
class foo
{
    function do_foo()
    {
        echo "Doing foo.";
    }
}

$bar = new foo;
$bar->do_foo();
?>

   
```

</div>

For a full discussion, see the [Classes and Objects](#language.oop5) chapter.

## Converting to object

If an `object` is converted to an `object`, it is not modified. If a value of any other type is converted to an `object`, a new instance of the `stdClass` built-in class is created. If the value was ENTITY, the new instance will be empty. An `array` converts to an `object` with properties named by keys and with their corresponding values. Prior to PHP 7.2.0, numeric keys would have been inaccessible unless iterated.

<div class="example">

<div class="title">

Casting to an Object

</div>

```
<?php
$obj = (object) array('1' => 'foo');
var_dump(isset($obj->{'1'})); // outputs 'bool(true)'

// Deprecated as of PHP 8.1
var_dump(key($obj)); // outputs 'string(1) "1"'
?>

   
```

</div>

For any other value, a member variable named `scalar` will contain the value.

<div class="example">

<div class="title">

`(object)` cast

</div>

```
<?php
$obj = (object) 'ciao';
echo $obj->scalar;  // outputs 'ciao'
?>

   
```

</div>

# Relative class types

These type declarations can only be used within classes.

## `self`

The value must be an ENTITY the same class as the one in which the type declaration is used.

## `parent`

The value must be an ENTITY a parent of the class in which the type declaration is used.

## static

`static` is a return-only type which requires that the value returned must be an ENTITY the same class as the one the method is called in. Available as of PHP 8.0.0.

# Resources

A `resource` is a special variable, holding a reference to an external resource. Resources are created and used by special functions. See the [appendix](#resource) for a listing of all these functions and the corresponding `resource` types.

See also the `get_resource_type` function.

## Converting to resource

As `resource` variables hold special handles to opened files, database connections, image canvas areas and the like, converting to a `resource` makes no sense.

## Freeing resources

Thanks to the reference-counting system being part of the Zend Engine, a `resource` with no more references to it is detected automatically, and it is freed by the garbage collector. For this reason, it is rarely necessary to free the memory manually.

> [!NOTE]
> Persistent database links are an exception to this rule. They are *not* destroyed by the garbage collector. See the [persistent connections](#features.persistent-connections) section for more information.

# Singleton types

Singleton types are those which allow only one value. PHP has support for two singleton types: `false` as of PHP 8.0.0 and `true` as of PHP 8.2.0.

> [!WARNING]
> Prior to PHP 8.2.0, the `false` type could only be used as part of a [union type](#language.types.type-system.composite.union).

> [!NOTE]
> It is not possible to define custom singleton types. Consider using [enumerations](#language.types.enumerations) instead.

# Strings

A `string` is a series of characters, where a character is the same as a byte. This means that PHP only supports a 256-character set, and hence does not offer native Unicode support. See [details of the string type](#language.types.string.details).

> [!NOTE]
> On 32-bit builds, a `string` can be up to 2GB (2147483647 bytes) in length.

## Syntax

A `string` literal can be specified in four different ways:

- [single quoted](#language.types.string.syntax.single)

- [double quoted](#language.types.string.syntax.double)

- [heredoc syntax](#language.types.string.syntax.heredoc)

- [nowdoc syntax](#language.types.string.syntax.nowdoc)

### Single quoted

The simplest way to specify a `string` is to enclose it in single quotes (the character `'`).

To specify a literal single quote, escape it with a backslash (`\`). To specify a literal backslash, double it (`\\`). All other instances of backslash will be treated as a literal backslash: this means that the other escape sequences you might be used to, such as `\r` or `\n`, will be output literally as specified rather than having any special meaning.

> [!NOTE]
> Unlike the [double-quoted](#language.types.string.syntax.double) and [heredoc](#language.types.string.syntax.heredoc) syntaxes, [variables](#language.variables) and escape sequences for special characters will *not* be expanded when they occur in single quoted `string`s.

<div class="example">

<div class="title">

Syntax Variants

</div>

```
<?php
echo 'this is a simple string', PHP_EOL;

echo 'You can also have embedded newlines in
strings this way as it is
okay to do', PHP_EOL;

// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"', PHP_EOL;

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?', PHP_EOL;

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?', PHP_EOL;

// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline', PHP_EOL;

// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either', PHP_EOL;
?>

    
```

</div>

### Double quoted

If the `string` is enclosed in double-quotes (`"`), PHP will interpret the following escape sequences for special characters:

| Sequence | Meaning |
|----|----|
| `\n` | linefeed (LF or 0x0A (10) in ASCII) |
| `\r` | carriage return (CR or 0x0D (13) in ASCII) |
| `\t` | horizontal tab (HT or 0x09 (9) in ASCII) |
| `\v` | vertical tab (VT or 0x0B (11) in ASCII) |
| `\e` | escape (ESC or 0x1B (27) in ASCII) |
| `\f` | form feed (FF or 0x0C (12) in ASCII) |
| `\\` | backslash |
| `\$` | dollar sign |
| `\"` | double-quote |
| `\[0-7]{1,3}` | Octal: the sequence of characters matching the regular expression `[0-7]{1,3}` is a character in octal notation (e.g. `"\101" === "A"`), which silently overflows to fit in a byte (e.g. `"\400" === "\000"`) |
| `\x[0-9A-Fa-f]{1,2}` | Hexadecimal: the sequence of characters matching the regular expression `[0-9A-Fa-f]{1,2}` is a character in hexadecimal notation (e.g. `"\x41" === "A"`) |
| `\u{[0-9A-Fa-f]+}` | Unicode: the sequence of characters matching the regular expression `[0-9A-Fa-f]+` is a Unicode codepoint, which will be output to the string as that codepoint's UTF-8 representation. The braces are required in the sequence. E.g. `"\u{41}" === "A"` |

Escaped characters

As in single quoted `string`s, escaping any other character will result in the backslash being printed too.

The most important feature of double-quoted `string`s is the fact that variable names will be expanded. See [string interpolation](#language.types.string.parsing) for details.

### Heredoc

A third way to delimit `string`s is the heredoc syntax: `ENTITYENTITYENTITY`. After this operator, an identifier is provided, then a newline. The `string` itself follows, and then the same identifier again to close the quotation.

The closing identifier may be indented with spaces or tabs. Whitespace equal to the closing identifier's indentation is then removed from the beginning of every line in the heredoc string. Prior to PHP 7.3.0, the closing identifier *must* begin in the first column of the line.

Also, the closing identifier must follow the same naming rules as any other label in PHP: it must contain only alphanumeric characters and underscores, and must start with a non-digit character or underscore.

<div class="example">

<div class="title">

Basic Heredoc example as of PHP 7.3.0

</div>

```
<?php
// closing identifier not indented
echo <<<END
      a
     b
    c
\n
END;

// closing identifier indented with 3 spaces; 3 spaces stripped from each line
echo <<<END
      a
     b
    c
   END;

    
```

ENTITY

          a
         b
        c

       a
      b
     c

        

</div>

If the closing identifier is indented further than any lines of the body, then a ParseError will be thrown:

<div class="example">

<div class="title">

Closing identifier must not be indented further than any lines of the body

</div>

```
<?php
echo <<<END
  a
 b
c
   END;

    
```

ENTITY

    Parse error: Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4

        

</div>

If the closing identifier is indented, tabs can be used as well. However, tabs and spaces *must not* be intermixed. The indentation of the body and the closing identifier must use one or the other consistently. If tabs and spaces are mixed, then a ParseError will be thrown. These whitespace constraints have been included because mixing tabs and spaces for indentation is harmful to legibility.

<div class="example">

<div class="title">

Different indentation for body and closing identifier

</div>

```
<?php
// All of the following code does not work.

// different indentation for body (spaces) and ending marker (tabs)
{
    echo <<<END
     a
        END;
}

// mixing spaces and tabs in body
{
    echo <<<END
        a
     END;
}

// mixing spaces and tabs in ending marker
{
    echo <<<END
          a
         END;
}

    
```

ENTITY

    Parse error: Invalid indentation - tabs and spaces cannot be mixed in example.php line 8

        

</div>

The closing identifier for the body string is not required to be followed by a semicolon or newline. For example, the following code is allowed as of PHP 7.3.0:

<div class="example">

<div class="title">

Continuing an expression after a closing identifier

</div>

```
<?php
$values = [<<<END
a
  b
    c
END, 'd e f'];
var_dump($values);

    
```

ENTITY

    array(2) {
      [0] =>
      string(11) "a
      b
        c"
      [1] =>
      string(5) "d e f"
    }

        

</div>

> [!WARNING]
> If the closing identifier is found at the start of a line, then regardless of whether it is a part of another word, it is considered as the closing identifier and causes a ParseError.
>
> <div class="example">
>
> <div class="title">
>
> Closing identifier in body of the string tends to cause ParseError
>
> </div>
>
> ```
> <?php
> $values = [<<<END
> a
> b
> END ING
> END, 'd e f'];
>
>      
> ```
>
> ENTITY
>
>     Parse error: syntax error, unexpected identifier "ING", expecting "]" in example.php on line 5
>
>          
>
> </div>
>
> To avoid this problem, it is safe to follow the simple rule: *do not choose a word that appears in the body of the text as a closing identifier*.

> [!WARNING]
> Prior to PHP 7.3.0, it is very important to note that the line with the closing identifier must contain no other characters, except a semicolon (`;`). That means especially that the identifier *may not be indented*, and there may not be any spaces or tabs before or after the semicolon. It's also important to realize that the first character before the closing identifier must be a newline as defined by the local operating system. This is `\n` on UNIX systems, including macOS. The closing delimiter must also be followed by a newline.
>
> If this rule is broken and the closing identifier is not "clean", it will not be considered a closing identifier, and PHP will continue looking for one. If a proper closing identifier is not found before the end of the current file, a parse error will result at the last line.
>
> <div class="example">
>
> <div class="title">
>
> Invalid example, prior to PHP 7.3.0
>
> </div>
>
> ```
>       
>
> <?php
> class foo {
>     public $bar = <<<EOT
> bar
>     EOT;
> }
> // Identifier must not be indented
> ?>
>
>      
> ```
>
> </div>
>
> <div class="example">
>
> <div class="title">
>
> Valid example, even prior to PHP 7.3.0
>
> </div>
>
> ```
>       
>
> <?php
> class foo {
>     public $bar = <<<EOT
> bar
> EOT;
> }
> ?>
>
>      
> ```
>
> </div>
>
> Heredocs containing variables can not be used for initializing class properties.

Heredoc text behaves just like a double-quoted `string`, without the double quotes. This means that quotes in a heredoc do not need to be escaped, but the escape codes listed above can still be used. Variables are expanded, but the same care must be taken when expressing complex variables inside a heredoc as with `string`s.

<div class="example">

<div class="title">

Heredoc string quoting example

</div>

```
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* More complex example, with variables. */
class foo
{
    var $foo;
    var $bar;

    function __construct()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>

    
```

ENTITY

    My name is "MyName". I am printing some Foo.
    Now, I am printing some Bar2.
    This should print a capital 'A': A
        

</div>

It is also possible to use the Heredoc syntax to pass data to function arguments:

<div class="example">

<div class="title">

Heredoc in arguments example

</div>

```
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>

    
```

</div>

It's possible to initialize static variables and class properties/constants using the Heredoc syntax:

<div class="example">

<div class="title">

Using Heredoc to initialize static values

</div>

```
<?php
// Static variables
function foo()
{
    static $bar = <<<LABEL
Nothing in here...
LABEL;
}

// Class properties/constants
class foo
{
    const BAR = <<<FOOBAR
Constant example
FOOBAR;

    public $baz = <<<FOOBAR
Property example
FOOBAR;
}
?>

    
```

</div>

The opening Heredoc identifier may optionally be enclosed in double quotes:

<div class="example">

<div class="title">

Using double quotes in Heredoc

</div>

```
<?php
echo <<<"FOOBAR"
Hello World!
FOOBAR;
?>

    
```

</div>

### Nowdoc

Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. A nowdoc is specified similarly to a heredoc, but *no string interpolation is done* inside a nowdoc. The construct is ideal for embedding PHP code or other large blocks of text without the need for escaping. It shares some features in common with the SGML `ENTITY![CDATA[ ]]ENTITY` construct, in that it declares a block of text which is not for parsing.

A nowdoc is identified with the same `ENTITYENTITYENTITY` sequence used for heredocs, but the identifier which follows is enclosed in single quotes, e.g. `ENTITYENTITYENTITY'EOT'`. All the rules for heredoc identifiers also apply to nowdoc identifiers, especially those regarding the appearance of the closing identifier.

<div class="example">

<div class="title">

Nowdoc string quoting example

</div>

```
<?php
echo <<<'EOD'
Example of string spanning multiple lines
using nowdoc syntax. Backslashes are always treated literally,
e.g. \\ and \'.
EOD;

    
```

ENTITY

    Example of string spanning multiple lines
    using nowdoc syntax. Backslashes are always treated literally,
    e.g. \\ and \'.

        

</div>

<div class="example">

<div class="title">

Nowdoc string quoting example with variables

</div>

```
<?php
class foo
{
    public $foo;
    public $bar;

    function __construct()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;
?>

    
```

ENTITY

    My name is "$name". I am printing some $foo->foo.
    Now, I am printing some {$foo->bar[1]}.
    This should not print a capital 'A': \x41
        

</div>

<div class="example">

<div class="title">

Static data example

</div>

```
<?php
class foo {
    public $bar = <<<'EOT'
bar
EOT;
}
?>

    
```

</div>

### String interpolation

When a `string` is specified in double quotes or with heredoc, [variables](#language.variables) can be substituted within it.

There are two types of syntax: a [basic](#language.types.string.parsing.basic) one and an [advanced](#language.types.string.parsing.advanced) one. The basic syntax is the most common and convenient. It provides a way to embed a variable, an `array` value, or an `object` property in a `string` with a minimum of effort.

#### Basic syntax

If a dollar sign (`$`) is encountered, the characters that follow it which can be used in a variable name will be interpreted as such and substituted.

<div class="example">

<div class="title">

String Interpolation

</div>

```
<?php
$juice = "apple";

echo "He drank some $juice juice." . PHP_EOL;

?>

     
```

ENTITY

    He drank some apple juice.

         

</div>

Formally, the structure for the basic variable substitution syntax is as follows:

<div class="informalexample">

    string-variable::
         variable-name   (offset-or-property)?
       | ${   expression   }

    offset-or-property::
         offset-in-string
       | property-in-string

    offset-in-string::
         [   name   ]
       | [   variable-name   ]
       | [   integer-literal   ]

    property-in-string::
         ->  name

    variable-name::
         $   name

    name::
         [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*


         

</div>

> [!WARNING]
> The `${ expression }` syntax is deprecated as of PHP 8.2.0, as it can be interpreted as [variable variables](#language.variables.variable):
>
> <div class="informalexample">
>
> ```
> <?php
> const foo = 'bar';
> $foo = 'foo';
> $bar = 'bar';
> var_dump("${foo}");
> var_dump("${(foo)}");
> ?>
>
>        
> ```
>
> ENTITY
>
>     Deprecated: Using ${var} in strings is deprecated, use {$var} instead in file on line 6
>
>     Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in file on line 9
>     string(3) "foo"
>     string(3) "bar"
>
>            
>
> ENTITY
>
>     string(3) "foo"
>     string(3) "bar"
>
>            
>
> </div>
>
> The [advanced](#language.types.string.parsing.advanced) string interpolation syntax should be used instead.

> [!NOTE]
> If it is not possible to form a valid name the dollar sign remains verbatim in the string:
>
> <div class="informalexample">
>
> ```
> <?php
> echo "No interpolation $  has happened\n";
> echo "No interpolation $\n has happened\n";
> echo "No interpolation $2 has happened\n";
> ?>
>
>       
> ```
>
> ENTITY
>
>     No interpolation $  has happened
>     No interpolation $
>      has happened
>     No interpolation $2 has happened
>
>           
>
> </div>

<div class="example">

<div class="title">

Interpolating the value of the first dimension of an array or property

</div>

```
<?php
$juices = array("apple", "orange", "string_key" => "purple");

echo "He drank some $juices[0] juice.";
echo PHP_EOL;
echo "He drank some $juices[1] juice.";
echo PHP_EOL;
echo "He drank some $juices[string_key] juice.";
echo PHP_EOL;

class A {
    public $s = "string";
}

$o = new A();

echo "Object value: $o->s.";
?>

     
```

ENTITY

    He drank some apple juice.
    He drank some orange juice.
    He drank some purple juice.
    Object value: string.

         

</div>

> [!NOTE]
> The array key must be unquoted, and it is therefore not possible to refer to a constant as a key with the basic syntax. Use the [advanced](#language.types.string.parsing.advanced) syntax instead.

As of PHP 7.1.0, *negative* numeric indices are supported too.

<div class="example">

<div class="title">

Negative numeric indices

</div>

```
<?php
$string = 'string';
echo "The character at index -2 is $string[-2].", PHP_EOL;
$string[-3] = 'o';
echo "Changing the character at index -3 to o gives $string.", PHP_EOL;
?>

     
```

ENTITY

    The character at index -2 is n.
    Changing the character at index -3 to o gives strong.

         

</div>

For anything more complex, the [advanced](#language.types.string.parsing.advanced) syntax must be used.

#### Advanced (curly) syntax

The advanced syntax permits the interpolation of *variables* with arbitrary accessors.

Any scalar variable, array element or object property (static or not) with a `string` representation can be included via this syntax. The expression is written the same way as it would appear outside the `string`, and then wrapped in `{` and `}`. Since `{` can not be escaped, this syntax will only be recognised when the `$` immediately follows the `{`. Use `{\$` to get a literal `{$`. Some examples to make it clear:

<div class="example">

<div class="title">

Curly Syntax

</div>

```
<?php
const DATA_KEY = 'const-key';
$great = 'fantastic';
$arr = [
    '1',
    '2',
    '3',
    [41, 42, 43],
    'key' => 'Indexed value',
    'const-key' => 'Key with minus sign',
    'foo' => ['foo1', 'foo2', 'foo3']
];

// Won't work, outputs: This is { fantastic}
echo "This is { $great}" . PHP_EOL;

// Works, outputs: This is fantastic
echo "This is {$great}" . PHP_EOL;

// To show curly braces in the output:
echo "This is {{$great}}" . PHP_EOL;

class Square {
    public $width;

    public function __construct(int $width) { $this->width = $width; }
}

$square = new Square(5);

// Works
echo "This square is {$square->width}00 centimeters wide." . PHP_EOL;


// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}" . PHP_EOL;


// Works
echo "This works: {$arr[3][2]}" . PHP_EOL;

echo "This works: {$arr[DATA_KEY]}" . PHP_EOL;

// When using multidimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][2]}" . PHP_EOL;

echo "This works: {$obj->values[3]->name}" . PHP_EOL;

echo "This works: {$obj->$staticProp}" . PHP_EOL;

// Won't work, outputs: C:\directory\{fantastic}.txt
echo "C:\directory\{$great}.txt" . PHP_EOL;

// Works, outputs: C:\directory\fantastic.txt
echo "C:\\directory\\{$great}.txt" . PHP_EOL;
?>

     
```

</div>

> [!NOTE]
> As this syntax allows arbitrary expressions, it is possible to use [variable variables](#language.variables.variable) within the advanced syntax.

### String access and modification by character

Characters within `string`s may be accessed and modified by specifying the zero-based offset of the desired character after the `string` using square `array` brackets, as in `$str[42]`. Think of a `string` as an `array` of characters for this purpose. The functions `substr` and `substr_replace` can be used when you want to extract or replace more than 1 character.

> [!NOTE]
> As of PHP 7.1.0, negative string offsets are also supported. These specify the offset from the end of the string. Formerly, negative offsets emitted `E_NOTICE` for reading (yielding an empty string) and `E_WARNING` for writing (leaving the string untouched).

> [!NOTE]
> Prior to PHP 8.0.0, `string`s could also be accessed using braces, as in `$str{42}`, for the same purpose. This curly brace syntax was deprecated as of PHP 7.4.0 and no longer supported as of PHP 8.0.0.

> [!WARNING]
> Writing to an out-of-range offset pads the string with spaces. Non-integer types are converted to an integer. An illegal offset type emits `E_WARNING`. Only the first character of an assigned string is used. As of PHP 7.1.0, assigning an empty string throws a fatal error. Formerly, it assigned a NULL byte.

> [!WARNING]
> Internally, PHP strings are byte arrays. As a result, accessing or modifying a string using array brackets is not multi-byte safe, and should only be done with strings that are in a single-byte encoding such as ISO-8859-1.

> [!NOTE]
> As of PHP 7.1.0, applying the empty index operator on an empty string throws a fatal error. Formerly, the empty string was silently converted to an array.

<div class="example">

<div class="title">

Some string examples

</div>

```
<?php
// Get the first character of a string
$str = 'This is a test.';
$first = $str[0];
var_dump($first);

// Get the third character of a string
$third = $str[2];
var_dump($third);

// Get the last character of a string.
$str = 'This is still a test.';
$last = $str[strlen($str)-1];
var_dump($last);

// Modify the last character of a string
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';
var_dump($str);
?>

    
```

</div>

String offsets must be either integers or integer-like strings. As of PHP 8.0.0, any other string throws a TypeError, except for a string starting with an integer followed by other characters, which emits `E_WARNING` and is interpreted as that leading integer. Prior to PHP 8.0.0, no TypeError was thrown: an illegal offset emitted `E_WARNING` instead.

<div class="example">

<div class="title">

Example of Illegal String Offsets

</div>

```
<?php
$str = 'abc';

$keys = [ '1', '1.0', 'x', '1x' ];

foreach ($keys as $keyToTry) {
    var_dump(isset($str[$keyToTry]));

    try {
        var_dump($str[$keyToTry]);
    } catch (TypeError $e) {
        echo $e->getMessage(), PHP_EOL;
    }

    echo PHP_EOL;
}
?>

    
```

ENTITY

    bool(true)
    string(1) "b"

    bool(false)
    Cannot access offset of type string on string

    bool(false)
    Cannot access offset of type string on string

    bool(false)

    Warning: Illegal string offset "1x" in example.php on line 10
    string(1) "b"

        

ENTITY

    bool(true)
    string(1) "b"

    bool(false)

    Warning: Illegal string offset '1.0' in example.php on line 10
    string(1) "b"

    bool(false)

    Warning: Illegal string offset 'x' in example.php on line 10
    string(1) "a"

    bool(false)

    Notice: A non well formed numeric value encountered in example.php on line 10
    string(1) "b"

        

</div>

> [!NOTE]
> Accessing variables of other types (not including arrays or objects implementing the appropriate interfaces) using `[]` or `{}` silently returns ENTITY.

> [!NOTE]
> Characters within string literals can be accessed using `[]` or `{}`.

> [!NOTE]
> Accessing characters within string literals using the `{}` syntax has been deprecated in PHP 7.4. This has been removed in PHP 8.0.

## Useful functions and operators

`String`s may be concatenated using the '.' (dot) operator. Note that the '+' (addition) operator will *not* work for this. See [String operators](#language.operators.string) for more information.

There are a number of useful functions for `string` manipulation.

See the [string functions section](#ref.strings) for general functions, and the [Perl-compatible regular expression functions](#ref.pcre) for advanced find ENTITY replace functionality.

There are also [functions for URL strings](#ref.url), and functions to encrypt/decrypt strings ([Sodium](#ref.sodium) and [Hash](#ref.hash)).

Finally, see also the [character type functions](#ref.ctype).

## Converting to string

A value can be converted to a `string` using the `(string)` cast or the `strval` function. `String` conversion is automatically done in the scope of an expression where a `string` is needed. This happens when using the `echo` or `print` functions, or when a variable is compared to a `string`. The sections on [Types](#language.types) and [Type Juggling](#language.types.type-juggling) will make the following clearer. See also the `settype` function.

A `bool` ENTITY value is converted to the `string` `"1"`. `bool` ENTITY is converted to `""` (the empty string). This allows conversion back and forth between `bool` and `string` values.

An `int` or `float` is converted to a `string` representing the number textually (including the exponent part for `float`s). Floating-point numbers can be converted using exponential notation (`4.1E+6`).

> [!NOTE]
> As of PHP 8.0.0, the decimal point character is always a period ("`.`"). Prior to PHP 8.0.0, the decimal point character is defined in the script's locale (category LC_NUMERIC). See the `setlocale` function.

`Array`s are always converted to the `string` `"Array"`; because of this, `echo` and `print` can not by themselves show the contents of an `array`. To view a single element, use a construction such as `echo $arr['foo']`. See below for tips on viewing the entire contents.

In order to convert `object`s to `string`, the magic method [\_\_toString](#language.oop5.magic) must be used.

`Resource`s are always converted to `string`s with the structure `"Resource id #1"`, where `1` is the resource number assigned to the `resource` by PHP at runtime. While the exact structure of this string should not be relied on and is subject to change, it will always be unique for a given resource within the lifetime of a script being executed (ie a Web request or CLI process) and won't be reused. To get a `resource`'s type, use the `get_resource_type` function.

ENTITY is always converted to an empty string.

As stated above, directly converting an `array`, `object`, or `resource` to a `string` does not provide any useful information about the value beyond its type. See the functions `print_r` and `var_dump` for more effective means of inspecting the contents of these types.

Most PHP values can also be converted to `string`s for permanent storage. This method is called serialization, and is performed by the `serialize` function.

## Details of the String Type

The `string` in PHP is implemented as an array of bytes and an integer indicating the length of the buffer. It has no information about how those bytes translate to characters, leaving that task to the programmer. There are no limitations on the values the string can be composed of; in particular, bytes with value `0` (“NUL bytes”) are allowed anywhere in the string. However, a few functions, said in this manual not to be “binary safe”, may hand off the strings to libraries that ignore data after a NUL byte.

This nature of the string type explains why there is no separate “byte” type in PHP – strings take this role. Functions that return no textual data – for instance, arbitrary data read from a network socket – will still return strings.

Given that PHP does not dictate a specific encoding for strings, one might wonder how string literals are encoded. For instance, is the string `"á"` equivalent to `"\xE1"` (ISO-8859-1), `"\xC3\xA1"` (UTF-8, C form), `"\x61\xCC\x81"` (UTF-8, D form) or any other possible representation? The answer is that the string will be encoded in whatever fashion it is encoded in the script file. Thus, if the script is written in ISO-8859-1, the string will be encoded in ISO-8859-1 and so on. However, this does not apply if Zend Multibyte is enabled; in that case, the script may be written in an arbitrary encoding (which is explicitly declared or is detected) and then converted to a certain internal encoding, which is then the encoding that will be used for the string literals. Note that there are some constraints on the encoding of the script (or on the internal encoding, should Zend Multibyte be enabled) – this almost always means that this encoding should be a compatible superset of ASCII, such as UTF-8 or ISO-8859-1. Note, however, that state-dependent encodings where the same byte values can be used in initial and non-initial shift states may be problematic.

Of course, in order to be useful, functions that operate on text may have to make some assumptions about how the string is encoded. Unfortunately, there is much variation on this matter throughout PHP’s functions:

- Some functions assume that the string is encoded in some (any) single-byte encoding, but they do not need to interpret those bytes as specific characters. This is the case of, for instance, `substr`, `strpos`, `strlen` or `strcmp`. Another way to think of these functions is that they operate on memory buffers, i.e., they work with bytes and byte offsets.

- Other functions receive the encoding of the string as a parameter or assume a default when it's not provided. This is the case of `htmlentities` and the majority of the functions in the [mbstring](#book.mbstring) extension.

- Others use the current locale (see `setlocale`), but operate byte-by-byte.

- Finally, they may just assume the string is using a specific encoding, usually UTF-8. This is the case of most functions in the [intl](#book.intl) extension and in the [PCRE](#book.pcre) extension (in the last case, only when the `u` modifier is used).

Ultimately, this means writing correct programs using Unicode depends on carefully avoiding functions that will not work and that most likely will corrupt the data and using instead the functions that do behave correctly, generally from the [intl](#book.intl) and [mbstring](#book.mbstring) extensions. However, using functions that can handle Unicode encodings is just the beginning. No matter the functions the language provides, it is essential to know the Unicode specification. For instance, a program that assumes there is only uppercase and lowercase is making a wrong assumption.

# Type Juggling

PHP does not require explicit type definition in variable declaration. In this case, the type of a variable is determined by the value it stores. That is to say, if a `string` is assigned to variable `$var`, then `$var` is of type `string`. If afterwards an `int` value is assigned to `$var`, it will be of type `int`.

PHP may attempt to convert the type of a value to another automatically in certain contexts. The different contexts which exist are:

- Numeric

- String

- Logical

- Integral and string

- Comparative

- Function

> [!NOTE]
> When a value needs to be interpreted as a different type, the value itself does *not* change types.

To force a variable to be evaluated as a certain type, see the section on [Type casting](#language.types.typecasting). To change the type of a variable, see the `settype` function.

## Numeric contexts

This is the context when using an [arithmetical operator](#language.operators.arithmetic).

In this context, if either operand is a `float` (or not interpretable as an `int`), both operands are interpreted as `float`s, and the result will be a `float`. Otherwise, the operands will be interpreted as `int`s, and the result will also be an `int`. As of PHP 8.0.0, if one of the operands cannot be interpreted, a TypeError is thrown.

## String contexts

This is the context when using `echo`, `print`, [string interpolation](#language.types.string.parsing), or the string [concatenation operator](#language.operators.string).

In this context, the value will be interpreted as `string`. If the value cannot be interpreted, a TypeError is thrown. Prior to PHP 7.4.0, an `E_RECOVERABLE_ERROR` was raised.

## Logical contexts

This is the context when using conditional statements, the [ternary operator](#language.operators.comparison.ternary), or a [logical operator](#language.operators.logical).

In this context, the value will be interpreted as `bool`.

## Integral and string contexts

This is the context when using [bitwise operators](#language.operators.bitwise).

In this context, if all operands are of type `string`, the result will also be a `string`. Otherwise, the operands will be interpreted as `int`s, and the result will also be an `int`. As of PHP 8.0.0, if one of the operands cannot be interpreted, a TypeError is thrown.

## Comparative contexts

This is the context when using a [comparison operator](#language.operators.comparison).

The type conversions which occur in this context are explained in the Comparison with Various Types [table](#language.operators.comparison.types).

## Function contexts

This is the context when a value is passed to a typed parameter, property, or returned from a function which declares a return type.

In this context, the value must be a value of the type. Two exceptions exist. The first one is: if the value is of type `int` and the declared type is `float`, then the integer is converted to a floating point number. The second one is: if the declared type is a *scalar* type, the value is convertible to a scalar type, and the coercive typing mode is active (the default), the value may be converted to an accepted scalar value. See below for a description of this behaviour.

> [!WARNING]
> [Internal functions](#functions.internal) automatically coerce ENTITY to scalar types. This behaviour is *DEPRECATED* as of PHP 8.1.0.

### Coercive typing with simple type declarations

- `bool` type declaration: value is interpreted as `bool`.

- `int` type declaration: value is interpreted as `int` if the conversion is well-defined. For example, the string is [numeric](#language.types.numeric-strings).

- `float` type declaration: value is interpreted as `float` if the conversion is well-defined. For example, the string is [numeric](#language.types.numeric-strings).

- `string` type declaration: value is interpreted as `string`.

### Coercive typing with union types

When `strict_types` is not enabled, scalar type declarations are subject to limited implicit type coercions. If the exact type of the value is not part of the union, then the target type is chosen in the following order of preference:

1.  `int`

2.  `float`

3.  `string`

4.  `bool`

If the type exists in the union and the value can be coerced to the type under PHP's existing type-checking semantics, then the type is chosen. Otherwise, the next type is tried.

> [!CAUTION]
> As an exception, if the value is a string and both int and float are part of the union, the preferred type is determined by the existing [numeric string](#language.types.numeric-strings) semantics. For example, for `"42"` `int` is chosen, while for `"42.0"` `float` is chosen.

> [!NOTE]
> Types that are not part of the above preference list are not eligible targets for implicit coercion. In particular, no implicit coercions to the `null`, `false`, and `true` types occur.

<div class="example">

<div class="title">

Example of types being coerced into a type part of the union

</div>

```
<?php
// int|string
42    --> 42          // exact type
"42"  --> "42"        // exact type
new ObjectWithToString --> "Result of __toString()"
                      // object never compatible with int, fall back to string
42.0  --> 42          // float compatible with int
42.1  --> 42          // float compatible with int
1e100 --> "1.0E+100"  // float too large for int type, fall back to string
INF   --> "INF"       // float too large for int type, fall back to string
true  --> 1           // bool compatible with int
[]    --> TypeError   // array not compatible with int or string

// int|float|bool
"45"    --> 45        // int numeric string
"45.0"  --> 45.0      // float numeric string

"45X"   --> true      // not numeric string, fall back to bool
""      --> false     // not numeric string, fall back to bool
"X"     --> true      // not numeric string, fall back to bool
[]      --> TypeError // array not compatible with int, float or bool
?>

    
```

</div>

## Type Casting

Type casting converts the value to a chosen type by writing the type within parentheses before the value to convert.

<div class="example">

<div class="title">

Type Casting

</div>

```
<?php
$foo = 10;          // $foo is an integer
$bar = (bool) $foo; // $bar is a boolean

var_dump($bar);
?>

   
```

</div>

The casts allowed are:

(int)

\- cast to

int

(bool)

\- cast to

bool

(float)

\- cast to

float

(string)

\- cast to

string

(array)

\- cast to

array

(object)

\- cast to

object

(unset)

\- cast to

NULL

The [`(void)`](#language.types.void.casting) cast is also available as of PHP 8.5.0, but it is not a value conversion. It is used as a statement to explicitly discard the result of an expression.

> [!WARNING]
> `(integer)` is an alias of the `(int)` cast. `(boolean)` is an alias of the `(bool)` cast. `(binary)` is an alias of the `(string)` cast. `(double)` and `(real)` are aliases of the `(float)` cast. These casts do not use the canonical type name and are deprecated as of PHP 8.5.0.

> [!WARNING]
> The `(real)` cast alias has been deprecated as of PHP 7.4.0 and removed as of PHP 8.0.0.

> [!WARNING]
> The `(unset)` cast has been deprecated as of PHP 7.2.0. Note that the `(unset)` cast is the same as assigning the value `NULL` to the variable or call. The `(unset)` cast is removed as of PHP 8.0.0.

> [!CAUTION]
> The `(binary)` cast and `b` prefix exist for forward support. Currently `(binary)` and `(string)` are identical, however this may change and should not be relied upon.

> [!NOTE]
> Whitespaces are ignored within the parentheses of a cast. Therefore, the following two casts are equivalent:
>
> <div class="informalexample">
>
> ```
> <?php
> $foo = (int) $bar;
> $foo = ( int ) $bar;
> ?>
>
>      
> ```
>
> </div>

<div class="informalexample">

Casting literal `string`s and variables to binary `string`s:

```
<?php
$binary = (binary) $string;
$binary = b"binary string";
?>

   
```

</div>

Instead of casting a variable to a `string`, it is also possible to enclose the variable in double quotes.

<div class="example">

<div class="title">

Different Casting Mechanisms

</div>

```
<?php
$foo = 10;            // $foo is an integer
$str = "$foo";        // $str is a string
$fst = (string) $foo; // $fst is also a string

// This prints out that "they are the same"
if ($fst === $str) {
    echo "they are the same", PHP_EOL;
}
?>

   
```

</div>

It may not be obvious exactly what will happen when casting between certain types. For more information, see these sections: [Converting to boolean](#language.types.boolean.casting), [Converting to integer](#language.types.integer.casting), [Converting to float](#language.types.float.casting), [Converting to string](#language.types.string.casting), [Converting to array](#language.types.array.casting), [Converting to object](#language.types.object.casting), [Converting to resource](#language.types.resource.casting), [Converting to NULL](#language.types.null.casting), [Discarding a value with `(void)`](#language.types.void.casting), [The type comparison tables](#types.comparisons)

> [!NOTE]
> Because PHP supports indexing into `string`s via offsets using the same syntax as `array` indexing, the following example holds true for all PHP versions:
>
> <div class="example">
>
> <div class="title">
>
> Using Array Offset with a String
>
> </div>
>
> ```
> <?php
> $a    = 'car'; // $a is a string
> $a[0] = 'b';   // $a is still a string
> echo $a;       // bar
> ?>
>
>     
> ```
>
> </div>
>
> See the section titled [String access by character](#language.types.string.substr) for more information.

# Type System

PHP uses a nominal type system with a strong behavioral subtyping relation. The subtyping relation is checked at compile time whereas the verification of types is dynamically checked at run time.

PHP's type system supports various atomic types that can be composed together to create more complex types. Some of these types can be written as [type declarations](#language.types.declarations).

## Atomic types

Some atomic types are built-in types which are tightly integrated with the language and cannot be reproduced with user-defined types.

The list of base types is:

- Built-in types

  - Scalar types:

    - `bool` type

    - `int` type

    - `float` type

    - `string` type

  - `array` type

  - `object` type

  - `resource` type

  - `never` type

  - `void` type

  - [Relative class types](#language.types.relative-class-types): `self`, `parent`, and `static`

  - [Singleton types](#language.types.singleton)

    - `false`

    - `true`

  - Unit types

    - `null`

- User-defined types (generally referred to as class-types)

  - [Interfaces](#language.oop5.interfaces)

  - [Classes](#language.oop5.basic.class)

  - [Enumerations](#language.types.enumerations)

- `callable` type

### Scalar types

A value is considered scalar if it is of type `int`, `float`, `string` or `bool`.

### User-defined types

It is possible to define custom types with [interfaces](#language.oop5.interfaces), [classes](#language.oop5.basic.class) and [enumerations](#language.types.enumerations). These are considered as user-defined types, or class-types. For example, a class called `Elephant` can be defined, then objects of type `Elephant` can be instantiated, and a function can request a parameter of type `Elephant`.

## Composite types

It is possible to combine multiple atomic types into composite types. PHP allows types to be combined in the following ways:

- Intersection of class-types (interfaces and class names).

- Union of types.

### Intersection types

An intersection type accepts values which satisfy multiple class-type declarations, rather than a single one. Individual types which form the intersection type are joined by the `ENTITY` symbol. Therefore, an intersection type comprised of the types `T`, `U`, and `V` will be written as `TENTITYUENTITYV`.

### Union types

A union type accepts values of multiple different types, rather than a single one. Individual types which form the union type are joined by the `|` symbol. Therefore, a union type comprised of the types `T`, `U`, and `V` will be written as `T|U|V`. If one of the types is an intersection type, it needs to be bracketed with parentheses for it to be written in DNF: `T|(XENTITYY)`.

## Type aliases

PHP supports two type aliases: `mixed` and `iterable` which correspond to the [union type](#language.types.type-system.composite.union) of `object|resource|array|string|float|int|bool|null` and `Traversable|array` respectively.

> [!NOTE]
> PHP does not support user-defined type aliases.

# Void

`void` is a return-only type declaration indicating the function does not return a value, but the function may still terminate. Therefore, it cannot be part of a [union type](#language.types.type-system.composite.union) declaration. Available as of PHP 7.1.0.

A `return` statement with an expression in a `void` function is a compile-time error, even if the `return` would not be reached during execution. This includes `return null;`; use a bare `return;` to exit the function early. The `null` mentioned below is only the implicit value of the call.

> [!NOTE]
> Even if a function has a return type of `void`, it will still return a value. This value is always ENTITY.

## Discarding a value with `(void)`

The `(void)` syntax may be used to explicitly discard the result of an expression. This is useful to indicate that ignoring a return value is intentional, especially when calling a function or method marked with the `NoDiscard` attribute.

Unlike other casts, `(void)` does not convert the value to another type and does not produce a value. It is a statement and cannot be used as part of an expression.

<div class="example">

<div class="title">

Discarding a return value

</div>

```
    
<?php
#[\NoDiscard]
function process(): bool {
    return true;
}

(void) process(); // Explicitly discard the return value
?>

   
```

</div>

# Variables

## Basics

Variables in PHP are represented by a dollar sign followed by the name of the variable. The variable name is case-sensitive.

A valid variable name starts with a letter (`A-Z`, `a-z`, or the bytes from 128 through 255) or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: `^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$`

> [!NOTE]
> Variable names are compared as bytes, not as characters. PHP does not interpret or validate the encoding of the bytes from 128 through 255, and two names refer to the same variable only when their bytes are identical.
>
> One consequence is that names written in UTF-8 work, because every byte of a UTF-8 multi-byte sequence falls inside the accepted range. The same holds for any encoding whose non-ASCII bytes all fall in that range, and for byte sequences that are not valid text in any encoding. Encodings that use bytes below 128 within a multi-byte sequence, such as Shift-JIS or UTF-16, do not.
>
> Another is that two names which display identically may be distinct. `ä` encoded as U+00E4 and as `a` followed by the combining diaeresis U+0308 are different variables, as are a name with and without a trailing U+00A0 NO-BREAK SPACE.

> [!NOTE]
> `$this` is a special variable that can't be assigned. Prior to PHP 7.1.0, indirect assignment (e.g. by using [variable variables](#language.variables.variable)) was possible.

ENTITY

<div class="example">

<div class="title">

Valid variable names

</div>

```
<?php
$var = 'Bob';
$Var = 'Joe';
echo "$var, $Var";      // outputs "Bob, Joe"

$_4site = 'not yet';    // valid; starts with an underscore
$täyte = 'mansikka';    // valid; 'ä' is (Extended) ASCII 228.

    
```

</div>

<div class="example">

<div class="title">

Invalid variable names

</div>

```
<?php
$4site = 'not yet';     // invalid; starts with a number

    
```

</div>

PHP accepts a sequence of any bytes as a variable name. Variable names that do not follow the above-mentioned naming rules can only be accessed dynamically at runtime. See [variable variables](#language.variables.variable) for information on how to access them.

<div class="example">

<div class="title">

Accessing obscure variable names

</div>

```
<?php
${'invalid-name'} = 'bar';
$name = 'invalid-name';
echo ${'invalid-name'}, " ", $$name;

    
```

ENTITY

    bar bar

        

</div>

By default, variables are always assigned by value. That is to say, when an expression is assigned to a variable, the entire value of the original expression is copied into the destination variable. This means, for instance, that after assigning one variable's value to another, changing one of those variables will have no effect on the other. For more information on this kind of assignment, see the chapter on [Expressions](#language.expressions).

PHP also offers another way to assign values to variables: [assign by reference](#language.references). This means that the new variable simply references (in other words, "becomes an alias for" or "points to") the original variable. Changes to the new variable affect the original, and vice versa.

To assign by reference, simply prepend an ampersand (ENTITY) to the beginning of the variable which is being assigned (the source variable). For instance, the following code snippet outputs '`My name is Bob`' twice:

<div class="informalexample">

```
<?php
$foo = 'Bob';              // Assign the value 'Bob' to $foo
$bar = &$foo;              // Reference $foo via $bar.
$bar = "My name is $bar";  // Alter $bar...
echo $bar . PHP_EOL;
echo $foo . PHP_EOL;       // $foo is altered too.

     
```

</div>

One important thing to note is that only variables may be assigned by reference.

<div class="informalexample">

```
<?php
$original = 25;
$ref1 = &$original;        // This is a valid assignment.
$ref2 = &(24 * 7);         // Invalid; references an unnamed expression.

     
```

</div>

<div class="informalexample">

```
<?php
// Note the lack of & indicating a returned reference in the function declaration.
// i.e. the function does not return a reference, so the result cannot be assigned by reference
function test()
{
   $original = 25;
   return $original;
}

// Note: A notice is issued, but the non-reference value is assigned
$result1 = &test();        // Invalid because test() doesn't return a variable by reference.
var_dump($result1);

// This function is defined as returning a reference, but does not return a variable
function &test2()
{
    return 26;             // Invalid because the returned value isn't a variable reference.
}

// Note: The non-reference value is assigned
$result2 = &test2();
var_dump($result2);

     
```

</div>

It is not necessary to declare variables in PHP, however, it is a very good practice. Accessing an undefined variable will result in an `E_WARNING` (prior to PHP 8.0.0, `E_NOTICE`). An undefined variable has a default value of ENTITY. The `isset` language construct can be used to detect if a variable has already been initialized.

<div class="example">

<div class="title">

Default value of an uninitialized variable

</div>

```
<?php
// Unset AND unreferenced (no use context) variable.
var_dump($unset_var);

     
```

ENTITY

    Warning: Undefined variable $unset_var in ...
    NULL

         

</div>

PHP allows array autovivification (automatic creation of new arrays) from an undefined variable. Appending an element to an undefined variable will create a new array and will not generate a warning.

<div class="example">

<div class="title">

Autovivification of an array from an undefined variable

</div>

```
<?php
$unset_array[] = 'value'; // Does not generate a warning.
var_dump($unset_array);

    
```

</div>

> [!WARNING]
> Relying on the default value of an uninitialized variable is problematic when including one file in another which uses the same variable name.

A variable can be destroyed by using the `unset` language construct.

For information on variable-related functions, see the [Variable Functions Reference](#ref.var).

## Predefined Variables

PHP provides a number of [predefined variables](#reserved.variables). PHP also provides an additional set of predefined arrays containing variables from the web server (if applicable), the environment, and user input. These arrays are automatically available in every scope. For this reason, they are often known as "superglobals". (There is no mechanism in PHP for user-defined superglobals.) Refer to the [list of superglobals](#language.variables.superglobals) for details.

> [!NOTE]
> Superglobals cannot be used as [variable variables](#language.variables.variable) inside functions or class methods.

If certain variables in [variables_order](#ini.variables-order) are not set, their appropriate PHP predefined arrays are also left empty.

## Variable scope

The scope of a variable is the context within which it is defined. PHP has a function scope and a global scope. Any variable defined outside a function is limited to the global scope. When a file is included, the code it contains inherits the variable scope of the line on which the include occurs.

<div class="example">

<div class="title">

Example of global variable scope

</div>

```
<?php
$a = 1;
include 'b.inc'; // Variable $a will be available within b.inc

    
```

</div>

Any variable created inside a named function or an [anonymous](#functions.anonymous) function is limited to the scope of the function body. However, [arrow functions](#functions.arrow) bind variables from the parent scope to make them available inside the body. If a file include occurs inside a function within the calling file, the variables contained in the called file will be available as if they had been defined inside the calling function.

<div class="example">

<div class="title">

Example of local variable scope

</div>

```
 

<?php
$a = 1; // global scope

function test()
{ 
    var_dump($a); // Variable $a is undefined as it refers to a local version of $a
}

test();

    
```

</div>

The example above will generate an undefined variable `E_WARNING` (or an `E_NOTICE` prior to PHP 8.0.0). This is because the echo statement refers to a local version of the `$a` variable, and it has not been assigned a value within this scope. Note that this is a little bit different from the C language in that global variables in C are automatically available to functions unless specifically overridden by a local definition. This can cause some problems in that people may inadvertently change a global variable. In PHP global variables must be declared global inside a function if they are going to be used in that function.

### The `global` keyword

The `global` keyword is used to bind a variable from a global scope into a local scope. The keyword can be used with a list of variables or a single variable. A local variable will be created referencing the global variable of the same name. If the global variable does not exist, the variable will be created in global scope and assigned ENTITY.

<div class="example">

<div class="title">

Using `global`

</div>

```
<?php
$a = 1;
$b = 2;

function Sum()
{
    global $a, $b;

    $b = $a + $b;
} 

Sum();
echo $b;

      
```

ENTITY

    3

          

</div>

By declaring `$a` and `$b` global within the function, all references to either variable will refer to the global version. There is no limit to the number of global variables that can be manipulated by a function.

A second way to access variables from the global scope is to use the special PHP-defined `$GLOBALS` array. The previous example can be rewritten as:

<div class="example">

<div class="title">

Using `$GLOBALS` instead of global

</div>

```
<?php
$a = 1;
$b = 2;

function Sum()
{
    $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
} 

Sum();
echo $b;

     
```

</div>

The `$GLOBALS` array is an associative array with the name of the global variable being the key and the contents of that variable being the value of the array element. Notice how `$GLOBALS` exists in any scope, this is because `$GLOBALS` is a [superglobal](#language.variables.superglobals). Here's an example demonstrating the power of superglobals:

<div class="example">

<div class="title">

Example demonstrating superglobals and scope

</div>

```
<?php
function test_superglobal()
{
    echo $_POST['name'];
}

     
```

</div>

> [!NOTE]
> Using `global` keyword outside a function is not an error. It can be used if the file is included from inside a function.

### Using `static` variables

Another important feature of variable scoping is the *static* variable. A static variable exists only in a local function scope, but it does not lose its value when program execution leaves this scope. Consider the following example:

<div class="example">

<div class="title">

Example demonstrating need for static variables

</div>

```
<?php
function test()
{
    $a = 0;
    echo $a . PHP_EOL;
    $a++;
}

test();
test();
test();

     
```

</div>

This function is quite useless since every time it is called it sets `$a` to `0` and prints `0`. The `$a`++ which increments the variable serves no purpose since as soon as the function exits the `$a` variable disappears. To make a useful counting function which will not lose track of the current count, the `$a` variable is declared static:

<div class="example">

<div class="title">

Example use of static variables

</div>

```
<?php
function test()
{
    static $a = 0;
    echo $a . PHP_EOL;
    $a++;
}

test();
test();
test();

     
```

</div>

Now, `$a` is initialized only in first call of function and every time the `test()` function is called it will print the value of `$a` and increment it.

Static variables also provide one way to deal with recursive functions. The following simple function recursively counts to 10, using the static variable `$count` to know when to stop:

<div class="example">

<div class="title">

Static variables with recursive functions

</div>

```
<?php
function test()
{
    static $count = 0;

    $count++;
    echo $count . PHP_EOL;
    if ($count < 10) {
        test();
    }
    // Undo the increment, so $count is back to 0 once test() has finished
    // and a later call to test() counts from 1 again
    $count--;
}

test();

     
```

ENTITY

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

         

</div>

Prior to PHP 8.3.0, static variables could only be initialized using a constant expression. As of PHP 8.3.0, dynamic expressions (e.g. function calls) are also allowed:

<div class="example">

<div class="title">

Declaring static variables

</div>

```
<?php
function foo(){
    static $int = 0;          // correct 
    static $int = 1+2;        // correct
    static $int = sqrt(121);  // correct as of PHP 8.3.0

    $int++;
    echo $int;
}

     
```

</div>

Static variables inside anonymous functions persist only within that specific function instance. If the anonymous function is recreated on each call, the static variable will be reinitialized.

<div class="example">

<div class="title">

Static variables in anonymous functions

</div>

```
<?php
function exampleFunction($input) {
    $result = (static function () use ($input) {
        static $counter = 0;
        $counter++;
        return "Input: $input, Counter: $counter\n";
    });

    return $result();
}

// Calls to exampleFunction will recreate the anonymous function, so the static
// variable does not retain its value.
echo exampleFunction('A'); // Outputs: Input: A, Counter: 1
echo exampleFunction('B'); // Outputs: Input: B, Counter: 1

    
```

</div>

As of PHP 8.1.0, when a method using static variables is inherited (but not overridden), the inherited method will now share static variables with the parent method. This means that static variables in methods now behave the same way as static properties.

As of PHP 8.3.0, static variables can be initialized with arbitrary expressions. This means that method calls, for example, can be used to initialize static variables.

<div class="example">

<div class="title">

Usage of static Variables in Inherited Methods

</div>

```
<?php
class Foo {
    public static function counter() {
        static $counter = 0;
        $counter++;
        return $counter;
    }
}
class Bar extends Foo {}
var_dump(Foo::counter()); // int(1)
var_dump(Foo::counter()); // int(2)
var_dump(Bar::counter()); // int(3), prior to PHP 8.1.0 int(1)
var_dump(Bar::counter()); // int(4), prior to PHP 8.1.0 int(2)

    
```

</div>

### References with `global` and `static` variables

PHP implements the [static](#language.variables.scope.static) and [global](#language.variables.scope.global) modifier for variables in terms of [ references](#language.references). For example, a true global variable imported inside a function scope with the `global` statement actually creates a reference to the global variable. This can lead to unexpected behaviour which the following example addresses:

<div class="informalexample">

```
<?php
function test_global_ref() {
    global $obj;
    $new = new stdClass;
    $obj = &$new;
}

function test_global_noref() {
    global $obj;
    $new = new stdClass;
    $obj = $new;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);

    
```

ENTITY

    NULL
    object(stdClass)#1 (0) {
    }

        

</div>

A similar behaviour applies to the `static` statement. References are not stored statically:

<div class="informalexample">

```
<?php
function &get_instance_ref() {
    static $obj;

    echo 'Static object: ';
    var_dump($obj);
    if (!isset($obj)) {
        $new = new stdClass;
        // Assign a reference to the static variable
        $obj = &$new;
    }
    if (!isset($obj->property)) {
        $obj->property = 1;
    } else {
        $obj->property++;
    }
    return $obj;
}

function &get_instance_noref() {
    static $obj;

    echo 'Static object: ';
    var_dump($obj);
    if (!isset($obj)) {
        $new = new stdClass;
        // Assign the object to the static variable
        $obj = $new;
    }
    if (!isset($obj->property)) {
        $obj->property = 1;
    } else {
        $obj->property++;
    }
    return $obj;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();

    
```

ENTITY

    Static object: NULL
    Static object: NULL

    Static object: NULL
    Static object: object(stdClass)#3 (1) {
      ["property"]=>
      int(1)
    }

        

</div>

This example demonstrates that when assigning a reference to a static variable, it is not *remembered* when the `ENTITYget_instance_ref()` function is called a second time.

## Variable variables

Sometimes it is convenient to be able to have variable variable names. That is, a variable name which can be set and used dynamically. A normal variable is set with a statement such as:

<div class="informalexample">

```
<?php
$a = 'hello';
var_dump($a);

    
```

</div>

A variable variable takes the value of a variable and treats that as the name of a variable. In the above example, *hello*, can be used as the name of a variable by using two dollar signs. i.e.

<div class="informalexample">

```
<?php
$a = 'hello';
$$a = 'world';
var_dump($hello);

    
```

</div>

At this point two variables have been defined and stored in the PHP symbol tree: `$a` with contents "hello" and `$hello` with contents "world". Therefore, this statement:

<div class="informalexample">

```
<?php
$a = 'hello';
$$a = 'world';
echo "$a {$$a}";

    
```

</div>

produces the exact same output as:

<div class="informalexample">

```
<?php
$a = 'hello';
$$a = 'world';
echo "$a $hello";

    
```

</div>

i.e. they both produce: `hello world`.

In order to use variable variables with arrays, an ambiguity problem has to be resolved. That is, if the parser sees `$$a[1]` then it needs to know if `$a[1]` was meant to be used as a variable, or if `$$a` was wanted as the variable and then the `[1]` index from that variable. The syntax for resolving this ambiguity is: `${$a[1]}` for the first case and `${$a}[1]` for the second.

Class properties may also be accessed using variable property names. The variable property name will be resolved within the scope from which the call is made. For instance, if there is an expression such as `$foo->$bar`, then the local scope will be examined for `$bar` and its value will be used as the name of the property of `$foo`. This is also true if `$bar` is an array access.

Curly braces may also be used to clearly delimit the property name. They are most useful when accessing values within a property that contains an array, when the property name is made of multiple parts, or when the property name contains characters that are not otherwise valid (e.g. from `json_decode` or [SimpleXML](#book.simplexml)).

<div class="example">

<div class="title">

Variable property example

</div>

```
<?php
class Foo {
    public $bar = 'I am bar.';
    public $arr = ['I am A.', 'I am B.', 'I am C.'];
    public $r   = 'I am r.';
}

$foo = new Foo();
$bar = 'bar';
$baz = ['foo', 'bar', 'baz', 'quux'];
echo $foo->$bar . "\n";
echo $foo->{$baz[1]} . "\n";

$start = 'b';
$end   = 'ar';
echo $foo->{$start . $end} . "\n";

$arr = 'arr';
echo $foo->{$arr[1]} . "\n";
echo $foo->{$arr}[1] . "\n";

     
```

ENTITY

    I am bar.
    I am bar.
    I am bar.
    I am r.
    I am B.

         

</div>

> [!WARNING]
> Please note that variable variables cannot be used with PHP's [Superglobal arrays](#language.variables.superglobals) within functions or class methods. The variable `$this` is also a special variable that cannot be referenced dynamically.

## Variables From External Sources

### HTML Forms (GET and POST)

When a form is submitted to a PHP script, the information from that form is automatically made available to the script. There are few ways to access this information, for example:

<div class="example">

<div class="title">

A simple HTML form

</div>

```
<form action="foo.php" method="post">
    Name:  <input type="text" name="username" /><br />
    Email: <input type="text" name="email" /><br />
    <input type="submit" name="submit" value="Submit me!" />
</form>

      
```

</div>

There are only two ways to access data from HTML forms. Currently available methods are listed below:

<div class="example">

<div class="title">

Accessing data from a simple POST HTML form

</div>

```
<?php
echo $_POST['username'];
echo $_REQUEST['username'];

      
```

</div>

Using a GET form is similar except the appropriate GET predefined variable can be used instead. GET also applies to the `QUERY_STRING` (the information after the '?' in a URL). So, for example, `http://www.example.com/test.php?id=3` contains GET data which is accessible with `$_GET['id']`. See also `$_REQUEST`.

> [!NOTE]
> Dots and spaces in variable names are converted to underscores. For example `ENTITYinput name="a.b" /ENTITY` becomes `$_REQUEST["a_b"]`.

PHP also understands arrays in the context of form variables (see the [related faq](#faq.html)). For example, related variables may be grouped together, or this feature may be used to retrieve values from a multiple select input. For example, let's post a form to itself and upon submission display the data:

<div class="example">

<div class="title">

More complex form variables

</div>

```
<?php
if ($_POST) {
    echo '<pre>';
    echo htmlspecialchars(print_r($_POST, true));
    echo '</pre>';
}
?>
<form action="" method="post">
    Name:  <input type="text" name="personal[name]" /><br />
    Email: <input type="text" name="personal[email]" /><br />
    Beer: <br />
    <select multiple name="beer[]">
        <option value="warthog">Warthog</option>
        <option value="guinness">Guinness</option>
        <option value="stuttgarter">Stuttgarter Schwabenbräu</option>
    </select><br />
    <input type="submit" value="submit me!" />
</form>

      
```

</div>

> [!NOTE]
> If an external variable name begins with a valid array syntax, trailing characters are silently ignored. For example, `ENTITYinput name="foo[bar]baz"ENTITY` becomes `$_REQUEST['foo']['bar']`.

#### IMAGE SUBMIT variable names

When submitting a form, it is possible to use an image instead of the standard submit button with a tag like:

<div class="informalexample">

```
<input type="image" src="image.gif" name="sub" />

      
```

</div>

When the user clicks somewhere on the image, the accompanying form will be transmitted to the server with two additional variables, `sub_x` and `sub_y`. These contain the coordinates of the user click within the image. The experienced may note that the actual variable names sent by the browser contains a period rather than an underscore, but PHP converts the period to an underscore automatically.

### HTTP Cookies

PHP transparently supports HTTP cookies as defined by [RFC 6265](ENTITY6265). Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. It is possible to set cookies using the `setcookie` function. Cookies are part of the HTTP header, so the SetCookie function must be called before any output is sent to the browser. This is the same restriction as for the `header` function. Cookie data is then available in the appropriate cookie data arrays, such as `$_COOKIE` as well as in `$_REQUEST`. See the `setcookie` manual page for more details and examples.

> [!NOTE]
> As of PHP 7.2.34, 7.3.23 and 7.4.11, respectively, the *names* of incoming cookies are no longer url-decoded for security reasons.

If multiple values should be assigned to a single cookie variable, they can be assigned as an array. For example:

<div class="informalexample">

```
<?php
setcookie("MyCookie[foo]", 'Testing 1', time()+3600);
setcookie("MyCookie[bar]", 'Testing 2', time()+3600);

     
```

</div>

That will create two separate cookies although `MyCookie` will now be a single array in the script. If just one cookie should be set with multiple values, consider using `serialize` or `explode` on the value first.

Note that a cookie will replace a previous cookie by the same name in the browser unless the path or domain is different. So, for a shopping cart application a counter may be kept, and passed along. I.e.

<div class="example">

<div class="title">

A `setcookie` example

</div>

```
<?php
if (isset($_COOKIE['count'])) {
    $count = $_COOKIE['count'] + 1;
} else {
    $count = 1;
}
setcookie('count', $count, time()+3600);
setcookie("Cart[$count]", $item, time()+3600);

     
```

</div>

### Dots in incoming variable names

Typically, PHP does not alter the names of variables when they are passed into a script. However, it should be noted that the dot (period, full stop) is not a valid character in a PHP variable name. For the reason, look at it:

```
<?php
$varname.ext;  /* invalid variable name */

     
```

Now, what the parser sees is a variable named `$varname`, followed by the string concatenation operator, followed by the barestring (i.e. unquoted string which doesn't match any known key or reserved words) 'ext'. Obviously, this doesn't have the intended result.

For this reason, it is important to note that PHP will automatically replace any dots in incoming variable names with underscores.

### Determining variable types

Because PHP determines the types of variables and converts them (generally) as needed, it is not always obvious what type a given variable is at any one time. PHP includes several functions which find out what type a variable is, such as: `gettype`, `is_array`, `is_float`, `is_int`, `is_object`, and `is_string`. See also the chapter on [Types](#language.types).

HTTP being a text protocol, most, if not all, content that comes in [Superglobal arrays](#language.variables.superglobals), like `$_POST` and `$_GET` will remain as strings. PHP will not try to convert values to a specific type. In the example below, `$_GET["var1"]` will contain the string "null" and `$_GET["var2"]`, the string "123".

    /index.php?var1=null&var2=123

          

### 

ENTITY

| ENTITY | ENTITY |
|----|----|
| 7.2.34, 7.3.23, 7.4.11 | The *names* of incoming cookies are no longer url-decoded for security reasons. |

# wrappers

PHP comes with many built-in wrappers for various URL-style protocols for use with the filesystem functions such as `fopen`, `copy`, `file_exists` and `filesize`. In addition to these wrappers, it is possible to register custom wrappers using the `stream_wrapper_register` function.

> [!NOTE]
> The URL syntax used to describe a wrapper only supports the `scheme://...` syntax. The `scheme:/` and `scheme:` syntaxes are not supported.

ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY ENTITY

# audio

<div data-wrapper="1" role="stream_wrapper">

ogg://

</div>

<div data-wrapper="1" role="stream_wrapper">

Audio streams

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

Files opened for reading via the `ogg://` wrapper are treated as compressed audio encoded using the `OGG/Vorbis` codec. Similarly, files opened for writing or appending via the `ogg://` wrapper are written as compressed audio data. `stream_get_meta_data`, when used on an `OGG/Vorbis` file opened for reading will return various details about the stream including the `vendor` tag, any included `comments`, the number of `channels`, the sampling `rate`, and the encoding rate range described by: `bitrate_lower`, `bitrate_upper`, `bitrate_nominal`, and `bitrate_window`.

</div>

<div data-wrapper="1" role="stream_wrapper">

`ogg://` (PECL)

</div>

> [!NOTE]
> In order to use the `ogg://` wrapper, the [OGG/Vorbis](ENTITYoggvorbis) extension available from ENTITY must be installed.

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `ogg://soundfile.ogg`

- `ogg:///path/to/soundfile.ogg`

- `ogg://http://www.example.com/path/to/soundstream.ogg`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                             | Supported |
|-------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | No        |
| Allows Reading                                        | Yes       |
| Allows Writing                                        | Yes       |
| Allows Appending                                      | Yes       |
| Allows Simultaneous Reading and Writing               | No        |
| Supports `stat`                                       | No        |
| Supports `unlink`                                     | No        |
| Supports `rename`                                     | No        |
| Supports `mkdir`                                      | No        |
| Supports `rmdir`                                      | No        |

Wrapper Summary {role="stream_wrapper"}

| Name | Usage | Default | Mode |
|----|----|----|----|
| `pcm_mode` | PCM encoding to apply while reading, one of: `OGGVORBIS_PCM_U8`, `OGGVORBIS_PCM_S8`, `OGGVORBIS_PCM_U16_BE`, `OGGVORBIS_PCM_S16_BE`, `OGGVORBIS_PCM_U16_LE`, and `OGGVORBIS_PCM_S16_LE`. (8 vs 16 bit, signed or unsigned, big or little `endian`) | OGGVORBIS_PCM_S16_LE | Read |
| `rate` | Sampling rate of input data, expressed in Hz | 44100 | Write/Append |
| `bitrate` | When given as an integer, the fixed bitrate at which to encode. (16000 to 131072) When given as a float, the variable bitrate quality to use. (-1.0 to 1.0) | 128000 | Write/Append |
| `channels` | The number of audio channels to encode, typically 1 (Mono), or 2 (Stereo). May range as high as 16. | 2 | Write/Append |
| `comments` | An array of string values to encode into the track header. |  | Write/Append |

Context options {role="stream_wrapper"}

# compression

<div data-wrapper="1" role="stream_wrapper">

zlib://

</div>

<div data-wrapper="1" role="stream_wrapper">

bzip2://

</div>

<div data-wrapper="1" role="stream_wrapper">

zip://

</div>

<div data-wrapper="1" role="stream_wrapper">

Compression Streams

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

`compress.zlib://` and `compress.bzip2://`

</div>

<div data-wrapper="1" role="stream_wrapper">

`zlib:` works like `gzopen`, except that the stream can be used with `fread` and the other filesystem functions. This is deprecated due to ambiguities with filenames containing ':' characters; use `compress.zlib://` instead.

</div>

<div data-wrapper="1" role="stream_wrapper">

`compress.zlib://` and `compress.bzip2://` are equivalent to `gzopen` and `bzopen` respectively, and operate even on systems that do not support fopencookie.

</div>

<div data-wrapper="1" role="stream_wrapper">

[ZIP extension](#book.zip) registers `zip:` wrapper. As of PHP 7.2.0 and libzip 1.2.0+, support for the passwords for encrypted archives were added, allowing passwords to be supplied by stream contexts. Passwords can be set using the `'password'` stream context option.

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `compress.zlib://file.gz`

- `compress.bzip2://file.bz2`

- `zip://archive.zip#dir/file.txt`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute | Supported |
|----|----|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | No |
| Allows Reading | Yes |
| Allows Writing | Yes (except `zip://`) |
| Allows Appending | Yes (except `zip://`) |
| Allows Simultaneous Reading and Writing | No |
| Supports `stat` | No, use the normal `file://` wrapper to stat compressed files. |
| Supports `unlink` | No, use the normal `file://` wrapper to unlink compressed files. |
| Supports `rename` | No |
| Supports `mkdir` | No |
| Supports `rmdir` | No |

Wrapper Summary {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

# data

<div data-wrapper="1" role="stream_wrapper">

data://

</div>

<div data-wrapper="1" role="stream_wrapper">

Data (RFC 2397)

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

The `data:` ([RFC 2397](ENTITY2397)) stream wrapper.

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `data://text/plain;base64,`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                                 | Supported |
|-----------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen)     | Yes       |
| Restricted by [allow_url_include](#ini.allow-url-include) | Yes       |
| Allows Reading                                            | Yes       |
| Allows Writing                                            | No        |
| Allows Appending                                          | No        |
| Allows Simultaneous Reading and Writing                   | No        |
| Supports `stat`                                           | No        |
| Supports `unlink`                                         | No        |
| Supports `rename`                                         | No        |
| Supports `mkdir`                                          | No        |
| Supports `rmdir`                                          | No        |

Wrapper Summary {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div class="example" role="stream_wrapper">

<div class="title">

Print data:// contents

</div>

```
<?php
// prints "I love PHP"
echo file_get_contents('data://text/plain;base64,SSBsb3ZlIFBIUAo=');
?>

   
```

</div>

<div class="example" role="stream_wrapper">

<div class="title">

Fetch the media type

</div>

```
<?php
$fp   = fopen('data://text/plain;base64,', 'r');
$meta = stream_get_meta_data($fp);

// prints "text/plain"
echo $meta['mediatype'];
?>

   
```

</div>

# expect

<div data-wrapper="1" role="stream_wrapper">

expect://

</div>

<div data-wrapper="1" role="stream_wrapper">

Process Interaction Streams

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

Streams opened via the `expect://` wrapper provide access to process's stdin, stdout and stderr via PTY.

</div>

> [!NOTE]
> In order to use the `expect://` wrapper, the [Expect](ENTITYexpect) extension available from ENTITY must be installed.

<div data-wrapper="1" role="stream_wrapper">

`expect://` (PECL)

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `expect://command`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                             | Supported |
|-------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | No        |
| Allows Reading                                        | Yes       |
| Allows Writing                                        | Yes       |
| Allows Appending                                      | Yes       |
| Allows Simultaneous Reading and Writing               | No        |
| Supports `stat`                                       | No        |
| Supports `unlink`                                     | No        |
| Supports `rename`                                     | No        |
| Supports `mkdir`                                      | No        |
| Supports `rmdir`                                      | No        |

Wrapper Summary {role="stream_wrapper"}

# file

<div data-wrapper="1" role="stream_wrapper">

file://

</div>

<div data-wrapper="1" role="stream_wrapper">

Accessing local filesystem

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

`file://` is the default wrapper used with PHP and represents the local filesystem. When a relative path is specified (a path which does not begin with `/`, `\`, `\\`, or a Windows drive letter) the path provided will be applied against the current working directory. In many cases this is the directory in which the script resides unless it has been changed. Using the CLI SAPI, this defaults to the directory from which the script was called.

</div>

<div data-wrapper="1" role="stream_wrapper">

With some functions, such as `fopen` and `file_get_contents`, `include_path` may be optionally searched for relative paths as well.

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `/path/to/file.ext`

- `relative/path/to/file.ext`

- `fileInCwd.ext`

- `C:/path/to/winfile.ext`

- `C:\path\to\winfile.ext`

- `\\smbserver\share\path\to\winfile.ext`

- `file:///path/to/file.ext`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                             | Supported |
|-------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | No        |
| Allows Reading                                        | Yes       |
| Allows Writing                                        | Yes       |
| Allows Appending                                      | Yes       |
| Allows Simultaneous Reading and Writing               | Yes       |
| Supports `stat`                                       | Yes       |
| Supports `unlink`                                     | Yes       |
| Supports `rename`                                     | Yes       |
| Supports `mkdir`                                      | Yes       |
| Supports `rmdir`                                      | Yes       |

Wrapper Summary {role="stream_wrapper"}

# ftp

<div data-wrapper="1" role="stream_wrapper">

ftp://

</div>

<div data-wrapper="1" role="stream_wrapper">

ftps://

</div>

<div data-wrapper="1" role="stream_wrapper">

Accessing FTP(s) URLs

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

Allows read access to existing files and creation of new files via FTP. If the server does not support passive mode ftp, the connection will fail.

</div>

<div data-wrapper="1" role="stream_wrapper">

You can open files for either reading or writing, but not both simultaneously. If the remote file already exists on the ftp server and you attempt to open it for writing but have not specified the context option `overwrite`, the connection will fail. If you need to overwrite existing files over ftp, specify the `overwrite` option in the context and open the file for writing. Alternatively, you can use the [FTP extension](#ref.ftp).

</div>

<div data-wrapper="1" role="stream_wrapper">

If you have set the [from](#ini.from) directive in ENTITY, then this value will be sent as the anonymous FTP password.

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `ftp://example.com/pub/file.txt`

- `ftp://user:password@example.com/pub/file.txt`

- `ftps://example.com/pub/file.txt`

- `ftps://user:password@example.com/pub/file.txt`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute | Supported |
|----|----|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | Yes |
| Allows Reading | Yes |
| Allows Writing | Yes (new files/existing files with `overwrite`) |
| Allows Appending | Yes |
| Allows Simultaneous Reading and Writing | No |
| Supports `stat` | `filesize`, `filemtime`, `filetype`, `file_exists`, `is_file`, and `is_dir` elements only. |
| Supports `unlink` | Yes |
| Supports `rename` | Yes |
| Supports `mkdir` | Yes |
| Supports `rmdir` | Yes |

Wrapper Summary {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

> [!NOTE]
> FTPS is only supported when the [openssl](#book.openssl) extension is enabled.
>
> If the server does not support SSL, then the connection falls back to regular unencrypted ftp.

> [!NOTE]
> Files may be appended via the `ftp://` URL wrapper.

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

# glob

<div data-wrapper="1" role="stream_wrapper">

glob://

</div>

<div data-wrapper="1" role="stream_wrapper">

Find pathnames matching pattern

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

The `glob:` stream wrapper.

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `glob://`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                                 | Supported |
|-----------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen)     | No        |
| Restricted by [allow_url_include](#ini.allow-url-include) | No        |
| Allows Reading                                            | No        |
| Allows Writing                                            | No        |
| Allows Appending                                          | No        |
| Allows Simultaneous Reading and Writing                   | No        |
| Supports `stat`                                           | No        |
| Supports `unlink`                                         | No        |
| Supports `rename`                                         | No        |
| Supports `mkdir`                                          | No        |
| Supports `rmdir`                                          | No        |

Wrapper Summary {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div class="example" role="stream_wrapper">

<div class="title">

Basic usage

</div>

```
<?php
// Loop over all *.php files in ext/spl/examples/ directory
// and print the filename and its size
$it = new DirectoryIterator("glob://ext/spl/examples/*.php");
foreach($it as $f) {
    printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024);
}
?>

   
```

    tree.php: 1.0K
    findregex.php: 0.6K
    findfile.php: 0.7K
    dba_dump.php: 0.9K
    nocvsdir.php: 1.1K
    phar_from_dir.php: 1.0K
    ini_groups.php: 0.9K
    directorytree.php: 0.9K
    dba_array.php: 1.1K
    class_tree.php: 1.8K

       

</div>

# http

<div data-wrapper="1" role="stream_wrapper">

http://

</div>

<div data-wrapper="1" role="stream_wrapper">

https://

</div>

<div data-wrapper="1" role="stream_wrapper">

Accessing HTTP(s) URLs

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

Allows read-only access to files/resources via HTTP. By default, a HTTP 1.0 GET is used. A `Host:` header is sent with the request to handle name-based virtual hosts. If you have configured a [user_agent](#ini.user-agent) string using your ENTITY file or the stream context, it will also be included in the request.

</div>

<div data-wrapper="1" role="stream_wrapper">

The stream allows access to the *body* of the resource; the headers are stored in the `$http_response_header` variable.

</div>

<div data-wrapper="1" role="stream_wrapper">

If it's important to know the URL of the resource where your document came from (after all redirects have been processed), you'll need to process the series of response headers returned by the stream.

</div>

<div data-wrapper="1" role="stream_wrapper">

The [from](#ini.from) directive will be used for the `From:` header if set and not overwritten by the [???](#context).

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `http://example.com`

- `http://example.com/file.php?var1=val1ENTITYvar2=val2`

- `http://user:password@example.com`

- `https://example.com`

- `https://example.com/file.php?var1=val1ENTITYvar2=val2`

- `https://user:password@example.com`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                             | Supported |
|-------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | Yes       |
| Allows Reading                                        | Yes       |
| Allows Writing                                        | No        |
| Allows Appending                                      | No        |
| Allows Simultaneous Reading and Writing               | N/A       |
| Supports `stat`                                       | No        |
| Supports `unlink`                                     | No        |
| Supports `rename`                                     | No        |
| Supports `mkdir`                                      | No        |
| Supports `rmdir`                                      | No        |

Wrapper Summary {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div id="wrappers.http.example.basic" class="example" role="stream_wrapper">

<div class="title">

Detecting which URL we ended up on after redirects

</div>

```
<?php
$url = 'http://www.example.com/redirecting_page.php';

$fp = fopen($url, 'r');

$meta_data = stream_get_meta_data($fp);
foreach ($meta_data['wrapper_data'] as $response) {

    /* Were we redirected? */
    if (strtolower(substr($response, 0, 10)) == 'location: ') {

        /* update $url with where we were redirected to */
        $url = substr($response, 10);
    }

}

?>

   
```

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

> [!NOTE]
> HTTPS is only supported when the [openssl](#book.openssl) extension is enabled.

<div data-wrapper="1" role="stream_wrapper">

HTTP connections are read-only; writing data or copying files to an HTTP resource is not supported.

</div>

<div data-wrapper="1" role="stream_wrapper">

Sending *POST* and *PUT* requests, for example, can be done with the help of [HTTP Contexts](#context.http).

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

\$http_response_header

</div>

<div data-wrapper="1" role="stream_wrapper">

stream_get_meta_data

</div>

# phar

<div data-wrapper="1" role="stream_wrapper">

phar://

</div>

<div data-wrapper="1" role="stream_wrapper">

PHP Archive

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

The `phar://` stream wrapper. See [Phar stream wrapper](#phar.using.stream) for a detailed description.

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `phar://`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                                 | Supported |
|-----------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen)     | No        |
| Restricted by [allow_url_include](#ini.allow-url-include) | No        |
| Allows Reading                                            | Yes       |
| Allows Writing                                            | Yes       |
| Allows Appending                                          | No        |
| Allows Simultaneous Reading and Writing                   | Yes       |
| Supports `stat`                                           | Yes       |
| Supports `unlink`                                         | Yes       |
| Supports `rename`                                         | Yes       |
| Supports `mkdir`                                          | Yes       |
| Supports `rmdir`                                          | Yes       |

Wrapper Summary {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

# php

<div data-wrapper="1" role="stream_wrapper">

php://

</div>

<div data-wrapper="1" role="stream_wrapper">

Accessing various I/O streams

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

PHP provides a number of miscellaneous I/O streams that allow access to PHP's own input and output streams, the standard input, output and error file descriptors, in-memory and disk-backed temporary file streams, and filters that can manipulate other file resources as they are read from and written to.

</div>

## php://stdin, php://stdout and php://stderr

<div data-wrapper="1" role="stream_wrapper">

`php://stdin`, `php://stdout` and `php://stderr` allow direct access to the corresponding input or output stream of the PHP process. The stream references a duplicate file descriptor, so if you open `php://stdin` and later close it, you close only your copy of the descriptor-the actual stream referenced by `STDIN` is unaffected. It is recommended that you simply use the constants `STDIN`, `STDOUT` and `STDERR` instead of manually opening streams using these wrappers.

</div>

<div data-wrapper="1" role="stream_wrapper">

`php://stdin` is read-only, whereas `php://stdout` and `php://stderr` are write-only.

</div>

## php://input

<div data-wrapper="1" role="stream_wrapper">

`php://input` is a read-only stream that allows you to read raw data from the request body. It can be opened and read as many times as needed. `php://input` is not available in POST requests with `enctype="multipart/form-data"` if [enable_post_data_reading](#ini.enable-post-data-reading) option is enabled.

</div>

## php://output

<div data-wrapper="1" role="stream_wrapper">

`php://output` is a write-only stream that allows you to write to the output buffer mechanism in the same way as `print` and `echo`.

</div>

## php://fd

<div data-wrapper="1" role="stream_wrapper">

`php://fd` allows direct access to the given file descriptor. For example, `php://fd/3` refers to file descriptor 3.

</div>

## php://memory and php://temp

<div data-wrapper="1" role="stream_wrapper">

`php://memory` and `php://temp` are read-write streams that allow temporary data to be stored in a file-like wrapper. One difference between the two is that `php://memory` will always store its data in memory, whereas `php://temp` will use a temporary file once the amount of data stored hits a predefined limit (the default is 2 MB). The location of this temporary file is determined in the same way as the `sys_get_temp_dir` function.

</div>

<div data-wrapper="1" role="stream_wrapper">

The memory limit of `php://temp` can be controlled by appending `/maxmemory:NN`, where `NN` is the maximum amount of data to keep in memory before using a temporary file, in bytes.

</div>

> [!CAUTION]
> Some PHP extensions may require a standard IO stream, and may attempt to cast a given stream to a standard IO stream. This cast can fail for memory streams as it requires the C `fopencookie` function to be available. This C function is *not* available on Windows.

## php://filter

<div data-wrapper="1" role="stream_wrapper">

`php://filter` is a kind of meta-wrapper designed to permit the application of [filters](#filters) to a stream at the time of opening. This is useful with all-in-one file functions such as `readfile`, `file`, and `file_get_contents` where there is otherwise no opportunity to apply a filter to the stream prior the contents being read.

</div>

<div data-wrapper="1" role="stream_wrapper">

The `php://filter` target takes the following parameters as part of its path. Multiple filter chains can be specified on one path. Please refer to the examples for specifics on using these parameters.

</div>

| Name | Description |
|----|----|
| `resource=ENTITYstream to be filteredENTITY` | This parameter is required. It specifies the stream that you would like to filter. |
| `read=ENTITYfilter list to apply to read chainENTITY` | This parameter is optional. One or more filter names can be provided here, separated by the pipe character (`|`). |
| `write=ENTITYfilter list to apply to write chainENTITY` | This parameter is optional. One or more filter names can be provided here, separated by the pipe character (`|`). |
| `ENTITYfilter list to apply to both chainsENTITY` | Any filter lists which are not prefixed by `read=` or `write=` will be applied to both the read and write chains as appropriate. |

php://filter parameters {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute | Supported |
|----|----|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | No |
| Restricted by [allow_url_include](#ini.allow-url-include) | `php://input`, `php://stdin`, `php://memory` and `php://temp` only. |
| Allows Reading | `php://stdin`, `php://input`, `php://fd`, `php://memory` and `php://temp` only. |
| Allows Writing | `php://stdout`, `php://stderr`, `php://output`, `php://fd`, `php://memory` and `php://temp` only. |
| Allows Appending | `php://stdout`, `php://stderr`, `php://output`, `php://fd`, `php://memory` and `php://temp` only. (Equivalent to writing) |
| Allows Simultaneous Reading and Writing | `php://fd`, `php://memory` and `php://temp` only. |
| Supports `stat` | No. However, `php://memory` and `php://temp` support `fstat`. |
| Supports `unlink` | No |
| Supports `rename` | No |
| Supports `mkdir` | No |
| Supports `rmdir` | No |
| Supports `stream_select` | `php://stdin`, `php://stdout`, `php://stderr`, `php://fd` and `php://temp` only. |

Wrapper Summary (for `php://filter`, refer to the summary of the wrapper being filtered) {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div class="example" role="stream_wrapper">

<div class="title">

php://temp/maxmemory

</div>

This optional parameter allows setting the memory limit before `php://temp` starts using a temporary file.

```
<?php
// Set the limit to 5 MB.
$fiveMBs = 5 * 1024 * 1024;
$fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+');

fputs($fp, "hello\n");

// Read what we have written.
rewind($fp);
echo stream_get_contents($fp);
?>

   
```

</div>

<div class="example" role="stream_wrapper">

<div class="title">

php://filter/resource=ENTITYstream to be filteredENTITY

</div>

This parameter must be located at the end of your `php://filter` specification and should point to the stream which you want filtered.

```
<?php
/* This is equivalent to simply:
  readfile("http://www.example.com");
  since no filters are actually specified */

readfile("php://filter/resource=http://www.example.com");
?>

   
```

</div>

<div class="example" role="stream_wrapper">

<div class="title">

php://filter/read=ENTITYfilter list to apply to read chainENTITY

</div>

This parameter takes one or more filternames separated by the pipe character `|`.

```
<?php
/* This will output the contents of
  www.example.com entirely in uppercase */
readfile("php://filter/read=string.toupper/resource=http://www.example.com");

/* This will do the same as above
  but will also ROT13 encode it */
readfile("php://filter/read=string.toupper|string.rot13/resource=http://www.example.com");
?>

   
```

</div>

<div class="example" role="stream_wrapper">

<div class="title">

php://filter/write=ENTITYfilter list to apply to write chainENTITY

</div>

This parameter takes one or more filternames separated by the pipe character `|`.

```
<?php
/* This will filter the string "Hello World"
  through the rot13 filter, then write to
  example.txt in the current directory */
file_put_contents("php://filter/write=string.rot13/resource=example.txt","Hello World");
?>

   
```

</div>

<div class="example" role="stream_wrapper">

<div class="title">

php://memory and php://temp are not reusable

</div>

`php://memory` and `php://temp` are not reusable, i.e. after the streams have been closed there is no way to refer to them again.

```
<?php
file_put_contents('php://memory', 'PHP');
echo file_get_contents('php://memory'); // prints nothing

   
```

</div>

<div class="example" role="stream_wrapper">

<div class="title">

php://input to read JSON data from the request body

</div>

This example demonstrates how to read raw JSON data from POST, PUT and PATCH requests using `php://input`.

```
<?php
$input = file_get_contents("php://input");
$json_array = json_decode(
  json: $input,
  associative: true,
  flags: JSON_THROW_ON_ERROR
);

echo "Received JSON data: ";
print_r($json_array);
?>

   
```

</div>

# rar

<div data-wrapper="1" role="stream_wrapper">

rar://

</div>

<div data-wrapper="1" role="stream_wrapper">

RAR

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

The wrapper takes the url encoded path to the RAR archive (relative or absolute), an optional asterisk (`*`), an optional number sign (`#`) and an optional url encoded entry name, as stored in the archive. Specifying an entry name requires the number sign; a leading forward slash in the entry name is optional.

</div>

<div data-wrapper="1" role="stream_wrapper">

This wrapper can open both files and directories. When opening directories, the asterisk sign forces the directory entries names to be returned unencoded. If it's not specified, they will be returned url encoded – the reason for this is to allow the wrapper to be correctly used with built-in functionality like the `RecursiveDirectoryIterator` in the presence of file names that seem like url encoded data.

</div>

<div data-wrapper="1" role="stream_wrapper">

If the pound sign and the entry name part are not included, the root of the archive will be displayed. This differs from regular directories in that the resulting stream will not contain information such as the modification time, as the root directory is not stored in an individual entry in the archive. The usage of the wrapper with `RecursiveDirectoryIterator` requires the number sign to be included in the URL when accessing the root, so that the URLs of the children may be constructed correctly.

</div>

> [!NOTE]
> In order to use the `rar://` wrapper, the [rar](ENTITYrar) extension available from ENTITY must be installed.

<div data-wrapper="1" role="stream_wrapper">

`rar://` Available since PECL rar 3.0.0

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `rar://ENTITYurl encoded archive nameENTITY[*][#[ENTITYurl encoded entry nameENTITY]]`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute                                                 | Supported |
|-----------------------------------------------------------|-----------|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen)     | No        |
| Restricted by [allow_url_include](#ini.allow-url-include) | No        |
| Allows Reading                                            | Yes       |
| Allows Writing                                            | No        |
| Allows Appending                                          | No        |
| Allows Simultaneous Reading and Writing                   | No        |
| Supports `stat`                                           | Yes       |
| Supports `unlink`                                         | No        |
| Supports `rename`                                         | No        |
| Supports `mkdir`                                          | No        |
| Supports `rmdir`                                          | No        |

Wrapper Summary {role="stream_wrapper"}

| Name | Usage | Default |
|----|----|----|
| `open_password` | The password used to encrypt the headers of the archive, if any. WinRAR will encrypt all the files with the same password as the headers password when the later is present, so for archives with encrypted headers, `file_password` will be ignored. |  |
| `file_password` | The password used to encrypt a file, if any. If the headers are also encrypted, this option will be ignored in favor of `open_password`. The reason there are two options is to cover the possibility of supporting archives with different headers and file passwords, should those archives arise. Note that if the archive does not have its headers encrypted, `open_password` will be ignored and this option must be used instead. |  |
| `volume_callback` | A callback to determine the path of missing volumes. See RarArchive::open for more information. |  |

Context options {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div class="example" role="stream_wrapper">

<div class="title">

Traversing a RAR archive

</div>

```
<?php

class MyRecDirIt extends RecursiveDirectoryIterator {
    function current() {
        return rawurldecode($this->getSubPathName()) .
            (is_dir(parent::current())?" [DIR]":"");
    }
}

$f = "rar://" . rawurlencode(dirname(__FILE__)) .
    DIRECTORY_SEPARATOR . 'dirs_and_extra_headers.rar#';

$it = new RecursiveTreeIterator(new MyRecDirIt($f));

foreach ($it as $s) {
    echo $s, "\n";
}
?>

   
```

ENTITY

    |-allow_everyone_ni [DIR]
    |-file1.txt
    |-file2_אּ.txt
    |-with_streams.txt
    \-אּ [DIR]
      |-אּ\%2Fempty%2E [DIR]
      | \-אּ\%2Fempty%2E\file7.txt
      |-אּ\empty [DIR]
      |-אּ\file3.txt
      |-אּ\file4_אּ.txt
      \-אּ\אּ_2 [DIR]
        |-אּ\אּ_2\file5.txt
        \-אּ\אּ_2\file6_אּ.txt

       

</div>

<div class="example" role="stream_wrapper">

<div class="title">

Opening an encrypted file (header encryption)

</div>

```
<?php
$stream = fopen("rar://" .
    rawurlencode(dirname(__FILE__)) . DIRECTORY_SEPARATOR .
    'encrypted_headers.rar' . '#encfile1.txt', "r", false,
    stream_context_create(
        array(
            'rar' =>
                array(
                    'open_password' => 'samplepassword'
                )
            )
        )
    );
var_dump(stream_get_contents($stream));
/* creation and last access date is opt-in in WinRAR, hence most
 * files don't have them */
var_dump(fstat($stream));
?>

   
```

ENTITY

    string(26) "Encrypted file 1 contents."
    Array
    (
        [0] => 0
        [1] => 0
        [2] => 33206
        [3] => 1
        [4] => 0
        [5] => 0
        [6] => 0
        [7] => 26
        [8] => 0
        [9] => 1259550052
        [10] => 0
        [11] => -1
        [12] => -1
        [dev] => 0
        [ino] => 0
        [mode] => 33206
        [nlink] => 1
        [uid] => 0
        [gid] => 0
        [rdev] => 0
        [size] => 26
        [atime] => 0
        [mtime] => 1259550052
        [ctime] => 0
        [blksize] => -1
        [blocks] => -1
    )

       

</div>

# ssh2

<div data-wrapper="1" role="stream_wrapper">

ssh2://

</div>

<div data-wrapper="1" role="stream_wrapper">

Secure Shell 2

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

`ssh2.shell://` `ssh2.exec://` `ssh2.tunnel://` `ssh2.sftp://` `ssh2.scp://` (PECL)

</div>

> [!NOTE]
> In order to use the `ssh2.*://` wrappers, the [SSH2](ENTITYssh2) extension available from ENTITY must be installed.

<div data-wrapper="1" role="stream_wrapper">

In addition to accepting traditional URI login details, the ssh2 wrappers will also reuse open connections by passing the connection resource in the host portion of the URL.

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div data-wrapper="1" role="stream_wrapper">

- `ssh2.shell://user:pass@example.com:22/xterm`

- `ssh2.exec://user:pass@example.com:22/usr/local/bin/somecmd`

- `ssh2.tunnel://user:pass@example.com:22/192.168.0.1:14`

- `ssh2.sftp://user:pass@example.com:22/path/to/filename`

</div>

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

| Attribute | ssh2.shell | ssh2.exec | ssh2.tunnel | ssh2.sftp | ssh2.scp |
|----|----|----|----|----|----|
| Restricted by [allow_url_fopen](#ini.allow-url-fopen) | Yes | Yes | Yes | Yes | Yes |
| Allows Reading | Yes | Yes | Yes | Yes | Yes |
| Allows Writing | Yes | Yes | Yes | Yes | No |
| Allows Appending | No | No | No | Yes (When supported by server) | No |
| Allows Simultaneous Reading and Writing | Yes | Yes | Yes | Yes | No |
| Supports `stat` | No | No | No | Yes | No |
| Supports `unlink` | No | No | No | Yes | No |
| Supports `rename` | No | No | No | Yes | No |
| Supports `mkdir` | No | No | No | Yes | No |
| Supports `rmdir` | No | No | No | Yes | No |

Wrapper Summary {role="stream_wrapper"}

| Name | Usage | Default |
|----|----|----|
| `session` | Preconnected ssh2 resource to be reused |  |
| `sftp` | Preallocated sftp resource to be reused |  |
| `methods` | Key exchange, hostkey, cipher, compression, and MAC methods to use |  |
| `callbacks` |  |  |
| `username` | Username to connect as |  |
| `password` | Password to use with password authentication |  |
| `pubkey_file` | Name of public key file to use for authentication |  |
| `privkey_file` | Name of private key file to use for authentication |  |
| `env` | Associate array of environment variables to set |  |
| `term` | Terminal emulation type to request when allocating a pty |  |
| `term_width` | Width of terminal requested when allocating a pty |  |
| `term_height` | Height of terminal requested when allocating a pty |  |
| `term_units` | Units to use with term_width and term_height | `SSH2_TERM_UNIT_CHARS` |

Context options {role="stream_wrapper"}

# 

<div data-wrapper="1" role="stream_wrapper">

ENTITY

</div>

<div class="example" role="stream_wrapper">

<div class="title">

Opening a stream from an active connection

</div>

```
<?php
$session = ssh2_connect('example.com', 22);
ssh2_auth_pubkey_file($session, 'username', '/home/username/.ssh/id_rsa.pub',
                                            '/home/username/.ssh/id_rsa', 'secret');
$stream = fopen("ssh2.tunnel://$session/remote.example.com:1234", 'r');
?>

   
```

</div>

<div class="example" role="stream_wrapper">

<div class="title">

This `$session` variable must be kept available!

</div>

In order to use the `ssh2.*://$session` wrappers, the `$session` resource variable must be kept. The code below will not have the desired effect:

```
<?php
$session = ssh2_connect('example.com', 22);
ssh2_auth_pubkey_file($session, 'username', '/home/username/.ssh/id_rsa.pub',
                                            '/home/username/.ssh/id_rsa', 'secret');
$connection_string = "ssh2.sftp://$session/";
unset($session);
$stream = fopen($connection_string . "path/to/file", 'r');
?>

   
```

unset() closes the session, because `$connection_string` does not hold a reference to the `$session` variable, just a string cast derived from it. This also happens when the `unset` is implicit because of leaving scope (like in a function).

</div>