A variable is written as $ followed by a name, and exists from its first
assignment. It has no declared type of its own and can hold any value (see
Types).
Basics
- Names follow the identifier
pattern and are case-sensitive:
$aand$Aare different variables. - Reading a variable that was never assigned gives
nulland raises a warning (a notice before PHP 8.0).isset()checks for it without a warning, and??supplies a fallback. - Appending to an undefined variable,
$list[] = 1;, creates an array without a warning. unset($a)destroys a variable. After it, reading$ais the same as reading an undefined variable.$thisis special. It is the current object in a method and cannot be assigned to.
Assignment copies the value. Arrays are copied too, but the copy is made only when one
of them is modified (copy on write). An object variable holds a handle to the object,
so assigning it does not copy the object. Use
clone for that.
Scope
A variable belongs to the scope where it was created.
- Global scope is everything outside functions. A file included at that level shares it.
- Function scope. Each function has its own variables, and global
variables are not visible inside unless asked for. Blocks such as
ifandfordo not create a scope, so a variable set inside one remains set afterwards. - Closures have function scope too and import outer variables with
use. Arrow functions capture them automatically by value.
The global keyword
global $a; binds a local name to the global variable of that name, by
reference. If the global does not exist it is created as null. It may
be used outside a function, which helps in files included from inside one.
$count = 1;
function bump(): void {
global $count;
$count++;
}
bump();
echo $count; // 2
Because global is a reference, assigning a new reference to the local
name re-points only the local name.
Static variables
static $n = 0; makes a local variable that keeps its value between
calls of the function. The initialiser runs once.
function counter(): int {
static $n = 0;
return ++$n;
}
counter(); // 1
counter(); // 2
- Before PHP 8.3 the initialiser had to be a constant expression. Since 8.3 any expression is allowed, including a function call.
- In a method inherited without overriding, the static variables are shared with the parent since PHP 8.1. Before that each child had its own copy.
- A closure object has its own static variables. A new closure made from the same code starts afresh.
- Static variables are built on references, and a reference assigned to one is not kept between calls. Assign a value instead.
Variable variables
A variable name can come from a variable.
$name = 'greeting';
$$name = 'hello'; // sets $greeting
${'a' . 'b'} = 1; // sets $ab
echo ${$name}; // hello
$obj = new stdClass;
$obj->$name = 2; // sets $obj->greeting
$obj->{'a-b'} = 3; // a property name that is not an identifier
$func = 'strlen';
echo $func('abc'); // 3
$$a[1]is ambiguous. Since PHP 7.0, with uniform variable syntax, indirect expressions are read strictly from left to right, so it means${$a}[1]. Use braces to mean${$a[1]}.- Superglobals and
$thiscannot be used as variable variables inside functions and methods. - Any byte sequence can name a variable when written this way, including names that
could not be typed directly:
${'invalid-name'} = 1;.
References
A reference makes two names refer to the same value. It is not a pointer. There is no address and no arithmetic. Internally both names point at a shared slot.
| Form | Meaning |
|---|---|
$a = &$b; | Make $a a reference to $b |
function f(&$x) | Take the argument by reference: see Functions |
function &f() | Return a reference, used as $a = &f(); |
foreach ($arr as &$v) | Iterate by reference, so $v changes elements |
[&$x] = $arr; | Destructure by reference (PHP 7.3) |
function () use (&$x) | Import into a closure by reference |
unset($a)breaks only the binding of the name$a. Other names sharing the value keep it.- After a
foreachby reference, the loop variable still refers to the last element. Writing to it later changes that element. Callunset($v)after the loop. - A value that is not a variable, such as a function result or a literal, cannot be passed to a by-reference parameter.
- A reference in an array element is copied as a reference. Assigning such an array shares that element, which is a common source of surprises.
- Objects are not references. An object variable is a handle, passed by value: reassigning it inside a function does not change the caller’s variable, but changing the object’s properties does.
- A reference to a typed property keeps the property’s type, so a write of the wrong type through the reference fails.
Superglobals
Superglobals are arrays available in every scope with no global
declaration. Programs cannot define their own. Whether the request-based ones are filled
depends on the
variables_order
setting.
| Variable | Contents |
|---|---|
$GLOBALS | Every variable in the global scope, by name |
$_SERVER | Server and execution environment: headers, paths, script locations. Exact entries depend on the server |
$_GET | Query string parameters |
$_POST | Form fields from an HTTP POST with a form content type |
$_FILES | Files uploaded by HTTP POST |
$_COOKIE | Cookies sent with the request |
$_SESSION | Session data for the current session |
$_REQUEST | By default a merge of $_GET, $_POST and $_COOKIE |
$_ENV | Environment variables. Empty unless variables_order includes E |
Since PHP 8.1 $GLOBALS is restricted. Reading it or writing individual
elements works as before, but writing to it as a whole
($GLOBALS = [], unset($GLOBALS)) is a compile error, and a copy
of it is an ordinary array whose changes do not reach the globals.
Other predefined variables
| Variable | Contents |
|---|---|
$argc, $argv | Command-line argument count and list, on the CLI. Global scope only; inside a function use $_SERVER['argv'] |
$http_response_header | Response headers from the last HTTP wrapper call, in the local scope |
$php_errormsg | Last error message. Deprecated in 7.2 and removed in 8.0. Use error_get_last() |
$HTTP_RAW_POST_DATA | Raw POST body. Removed in 7.0. Read php://input |
$HTTP_GET_VARS and the like | Old long names for the superglobals. Removed in 5.4 |
Constants
A constant holds a value that cannot change once set. Its name has no
$ and is case-sensitive, and it is available everywhere, unless it is in a
namespace. There are two ways to define one
(manual).
const | define() | |
|---|---|---|
| When | At compile time | At run time, as a function call |
| Where | At the top level of a file only, not inside functions or blocks | Anywhere, including conditions |
| Value | A constant expression | Any expression |
| In a class | Yes, a class constant | No |
| Namespace | Belongs to the current namespace | The name is taken as given; write the full name |
const LIMIT = 100;
const DOUBLE = LIMIT * 2;
define('STARTED_AT', time());
echo LIMIT; // 100
echo constant('LIMIT'); // the name as a string
var_dump(defined('LIMIT')); // true
Using an undefined constant throws Error since PHP 8.0. Older versions
treated it as a string of its own name, with a notice.
Constant expressions
Some places require a value that the compiler can work out: a const,
a property default, a parameter default and an attribute argument, for example. Such
an expression may use literals, other constants, class constants,
__CLASS__ and other magic constants, and most operators, including
array literals (5.6). Since 8.1 new is allowed in parameter defaults,
attribute arguments, static variable initialisers and global constants, but not in
class constants or property defaults
(RFC). Since 8.5 casts,
static closures and first-class callables are allowed.
Predefined constants
The core defines many. Common ones are PHP_VERSION,
PHP_MAJOR_VERSION, PHP_MINOR_VERSION,
PHP_RELEASE_VERSION, PHP_VERSION_ID, PHP_OS,
PHP_OS_FAMILY, PHP_EOL, DIRECTORY_SEPARATOR,
PATH_SEPARATOR, PHP_INT_MAX, PHP_FLOAT_EPSILON,
the E_* error levels and STDIN, STDOUT and
STDERR on the CLI.
Magic constants
These are keywords replaced at compile time, based on where they appear. They are
not true constants, so defined() and constant() do not
find them. They are case-insensitive, and are empty outside the context that gives
them a value.
| Name | Value |
|---|---|
__LINE__ | The current line number |
__FILE__ | The full path of the file, with symbolic links resolved |
__DIR__ | The directory of the file, the same as dirname(__FILE__). No trailing slash unless it is the root |
__FUNCTION__ | The function name, with its namespace. In a method, just the method name. In a closure, an engine-generated name ({closure} before 8.4) |
__CLASS__ | The class name, with its namespace. In a trait, the class using the trait |
__TRAIT__ | The trait name, with its namespace |
__METHOD__ | The class and method, Foo\Bar::baz. Outside a method, the same as __FUNCTION__ |
__PROPERTY__ | The property name, inside a property hook (PHP 8.4) |
__NAMESPACE__ | The current namespace, empty in the global namespace |
ClassName::class | The fully qualified name of a class, as a compile-time string (5.5) |