Skip to content

Instantly share code, notes, and snippets.

@onlyforbopi
Last active October 7, 2021 11:56
Show Gist options
  • Save onlyforbopi/51d521a6bc04e58c9230aaa52a353bb8 to your computer and use it in GitHub Desktop.
Save onlyforbopi/51d521a6bc04e58c9230aaa52a353bb8 to your computer and use it in GitHub Desktop.
#php
// #Example #1 PHP Opening and Closing Tags
<?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' ?>.
<? echo 'this code is within short tags, but will only work '.
'if short_open_tag is enabled'; ?>
<?php
echo "Hello world";
// ... more code
echo "Last statement";
// the script ends here with no PHP closing tag
// 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.
<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>;
// //////////////////////////////////////////////////////
// Example #1 Advanced escaping using conditions
<?php if ($expression == true): ?>
This will show if the expression is true.
<?php else: ?>
Otherwise this will show.
<?php endif; ?>
//////////////////////////////////////////
//Example #1 Example showing the closing tag encompassing the trailing newline
<?php echo "Some text"; ?>
No newline
<?= "But newline now" ?>
//The above example will output:
//Some textNo newline
//But newline now
//Examples of entering and exiting the PHP parser:
<?php
echo 'This is a test';
?>
<?php echo 'This is a test' ?>
<?php echo 'We omitted the last closing tag';
////////////////////////////////////////////////////////////////
// COMMENTS
Comments
PHP supports 'C', 'C++' and Unix shell-style (Perl style) comments. For example:
<?php
echo 'This is a test'; // 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';
echo 'One Final Test'; # This is a one-line shell-style comment
?>
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 // ... ?> or # ... ?> WILL be printed: ?> breaks out of PHP mode and returns to HTML mode, and // or # cannot influence that.
<h1>This is an <?php # echo 'simple';?> example</h1>
<p>The header above will say 'This is an example'.</p>
'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.
<?php
/*
echo 'This is a test'; /* This comment will cause a problem */
*/
?>
/////////////////////////////////////////////////////////////////////
// Check type
Note: To check the type and value of an expression, use the var_dump() function.
To get a human-readable representation of a type for debugging, use the gettype() function. To check for a certain type, do not use gettype(), but rather the is_type functions. Some examples:
<?php
$a_bool = TRUE; // a boolean
$a_str = "foo"; // a string
$a_str2 = 'foo'; // a string
$an_int = 12; // an integer
echo gettype($a_bool); // prints out: boolean
echo gettype($a_str); // prints out: string
// If this is an integer, increment it by four
if (is_int($an_int)) {
$an_int += 4;
}
// If $a_bool is a string, print it out
// (does not print out anything)
if (is_string($a_bool)) {
echo "String: $a_bool";
}
?>
/////////////////////////////////////////////////////////////
// TYPE CASTING
ype Casting ¶
Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast.
<?php
$foo = 10; // $foo is an integer
$bar = (boolean) $foo; // $bar is a boolean
?>
The casts allowed are:
(int), (integer) - cast to int
(bool), (boolean) - cast to bool
(float), (double), (real) - cast to float
(string) - cast to string
(array) - cast to array
(object) - cast to object
(unset) - cast to NULL
(binary) casting and b prefix exists for forward support. Note that the (binary) cast is essential the same as (string), but it should not be relied upon.
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.
Note that tabs and spaces are allowed inside the parentheses, so the following are functionally equivalent:
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
Casting literal strings and variables to binary strings:
<?php
$binary = (binary) $string;
$binary = b"binary string";
?>
Note:
Instead of casting a variable to a string, it is also possible to enclose the variable in double quotes.
<?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";
}
?>
////////////////////////////////////////////////////
// GETTYPE
gettype
(PHP 4, PHP 5, PHP 7, PHP 8)
gettype — Get the type of a variable
Description ¶
gettype(mixed $value): string
////////////////////////////////////////////////////
// BOOLEANS
Booleans ¶
This is the simplest type. A bool expresses a truth value. It can be either true or false.
Syntax ¶
To specify a bool literal, use the constants true or false. Both are case-insensitive.
<?php
$foo = True; // assign the value TRUE to $foo
?>
Typically, the result of an operator which returns a bool value is passed on to a control structure.
<?php
// == 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";
}
?>
Converting to boolean ¶
To explicitly convert a value to bool, use the (bool) or (boolean) casts. However, in most cases the cast is unnecessary, since a value will be automatically converted if an operator, function or control structure requires a bool argument.
See also Type Juggling.
When converting to bool, the following values are considered false:
the boolean false itself
the integer 0 (zero)
the floats 0.0 and -0.0 (zero)
the empty string, and the string "0"
an array with zero elements
the special type NULL (including unset variables)
SimpleXML objects created from attributeless empty elements, i.e. elements which have neither children nor attributes.
Every other value is considered true (including any resource and NAN).
<?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)
?>
////////////////////////////////////////////////////////
// INTEGERS
Syntax ¶
ints can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) or binary (base 2) notation. The negation operator can be used to denote a negative int.
To use octal notation, precede the number with a 0 (zero). 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.
Example #1 Integer literals
<?php
$a = 1234; // decimal number
$a = 0123; // octal number (equivalent to 83 decimal)
$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)
?>
Formally, the structure for int literals is as of PHP 7.4.0 (previously, underscores have not been allowed):
decimal : [1-9][0-9]*(_[0-9]+)*
| 0
hexadecimal : 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)*
octal : 0[0-7]+(_[0-7]+)*
binary : 0[bB][01]+(_[01]+)*
integer : decimal
| hexadecimal
| octal
| binary
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 ints. 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.
Example #2 Integer overflow on a 32-bit system
<?php
$large_number = 2147483647;
var_dump($large_number); // int(2147483647)
$large_number = 2147483648;
var_dump($large_number); // float(2147483648)
$million = 1000000;
$large_number = 50000 * $million;
var_dump($large_number); // float(50000000000)
?>
Example #3 Integer overflow on a 64-bit system
<?php
$large_number = 9223372036854775807;
var_dump($large_number); // int(9223372036854775807)
$large_number = 9223372036854775808;
var_dump($large_number); // float(9.2233720368548E+18)
$million = 1000000;
$large_number = 50000000000000 * $million;
var_dump($large_number); // float(5.0E+19)
?>
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.
<?php
var_dump(25/7); // float(3.5714285714286)
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7)); // float(4)
?>
Converting to integer ¶
To explicitly convert a value to int, use either the (int) or (integer) casts. 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.
From booleans ¶
false will yield 0 (zero), and true will yield 1 (one).
From floating point numbers ¶
When converting from float to int, the number will be rounded towards zero.
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. No warning, not even a notice will be issued when this happens!
Note:
NaN and Infinity will always be zero when cast to int.
Warning
Never cast an unknown fraction to int, as this can sometimes lead to unexpected results.
<?php
echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
?>
See also the warning about float precision.
From strings ¶
If the string is numeric or leading numeric then it will resolve to the corresponding integer value, otherwise it is converted to zero (0).
From NULL ¶
null is always converted to zero (0).
/////////////////////////////////////////////////////////
// FLOATING POINT
Floating point numbers ¶
Floating point numbers (also known as "floats", "doubles", or "real numbers") can be specified using any of the following syntaxes:
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // as of PHP 7.4.0
?>
Formally as of PHP 7.4.0 (previously, underscores have not been allowed):
LNUM [0-9]+(_[0-9]+)*
DNUM ([0-9]*(_[0-9]+)*[\.]{LNUM}) | ({LNUM}[\.][0-9]*(_[0-9]+)*)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
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 precision
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 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 and gmp functions are available.
For a "simple" explanation, see the » floating point guide that's also titled "Why don’t my numbers add up?"
Converting to float ¶
From strings ¶
If the string is numeric 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 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.
<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;
if(abs($a-$b) < $epsilon) {
echo "true";
}
?>
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 true, will have a result of false.
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().
/////////////////////////////////////////////////////
// STRINGS
Strings ¶
A string is 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.
Note: On 32-bit builds, a string can be as large as up to 2GB (2147483647 bytes maximum)
Syntax ¶
A string literal can be specified in four different ways:
single quoted
double quoted
heredoc syntax
nowdoc syntax
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 and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.
<?php
echo 'this is a simple string';
echo 'You can also have embedded newlines in
strings this way as it is
okay to do';
// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';
// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';
// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?';
// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline';
// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either';
?>
Double quoted ¶
If the string is enclosed in double-quotes ("), PHP will interpret the following escape sequences for special characters:
Escaped 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} the sequence of characters matching the regular expression is a character in octal notation, which silently overflows to fit in a byte (e.g. "\400" === "\000")
\x[0-9A-Fa-f]{1,2} the sequence of characters matching the regular expression is a character in hexadecimal notation
\u{[0-9A-Fa-f]+} the sequence of characters matching the regular expression is a Unicode codepoint, which will be output to the string as that codepoint's UTF-8 representation
As in single quoted strings, escaping any other character will result in the backslash being printed too.
The most important feature of double-quoted strings is the fact that variable names will be expanded. See string parsing for details.
Heredoc ¶
A third way to delimit strings is the heredoc syntax: <<<. 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 by space or tab, in which case the indentation will be stripped from all lines in the doc 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.
Example #1 Basic Heredoc example as of PHP 7.3.0
<?php
// no indentation
echo <<<END
a
b
c
\n
END;
// 4 spaces of indentation
echo <<<END
a
b
c
END;
Output of the above example in PHP 7.3:
a
b
c
a
b
c
If the closing identifier is indented further than any lines of the body, then a ParseError will be thrown:
Example #2 Closing identifier must not be indented further than any lines of the body
<?php
echo <<<END
a
b
c
END;
Output of the above example in PHP 7.3:
PHP Parse error: Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4
If the closing identifier is indented, tabs can be used as well, however, tabs and spaces must not be intermixed regarding the indentation of the closing identifier and the indentation of the body (up to the closing identifier). In any of these cases, a ParseError will be thrown. These whitespace constraints have been included because mixing tabs and spaces for indentation is harmful to legibility.
Example #3 Different indentation for body (spaces) closing identifier
<?php
// All the following code do not work.
// different indentation for body (spaces) 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;
}
Output of the above example in PHP 7.3:
PHP Parse error: Invalid indentation - tabs and spaces cannot be mixed in example.php line 8
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:
Example #4 Continuing an expression after a closing identifier
<?php
$values = [<<<END
a
b
c
END, 'd e f'];
var_dump($values);
Output of the above example in PHP 7.3:
array(2) {
[0] =>
string(11) "a
b
c"
[1] =>
string(5) "d e f"
}
Warning
If the closing identifier was found at the start of a line, then regardless of whether it was a part of another word, it may be considered as the closing identifier and causes a ParseError.
Example #5 Closing identifier in body of the string tends to cause ParseError
<?php
$values = [<<<END
a
b
END ING
END, 'd e f'];
Output of the above example in PHP 7.3:
PHP Parse error: syntax error, unexpected identifier "ING", expecting "]" in example.php on line 6
To avoid this problem, it is safe for you to follow the simple rule: do not choose the closing identifier that appears in the body of the text.
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.
Example #6 Invalid example, prior to PHP 7.3.0
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
// Identifier must not be indented
?>
Example #7 Valid example, even if prior to PHP 7.3.0
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
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 strings.
Example #8 Heredoc string quoting example
<?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;
?>
The above example will output:
My name is "MyName". I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital 'A': A
It is also possible to use the Heredoc syntax to pass data to function arguments:
Example #9 Heredoc in arguments example
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
It's possible to initialize static variables and class properties/constants using the Heredoc syntax:
Example #10 Using Heredoc to initialize static values
<?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;
}
?>
The opening Heredoc identifier may optionally be enclosed in double quotes:
Example #11 Using double quotes in Heredoc
<?php
echo <<<"FOOBAR"
Hello World!
FOOBAR;
?>
Nowdoc ¶
Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. A nowdoc is specified similarly to a heredoc, but no parsing 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 <![CDATA[ ]]> construct, in that it declares a block of text which is not for parsing.
A nowdoc is identified with the same <<< sequence used for heredocs, but the identifier which follows is enclosed in single quotes, e.g. <<<'EOT'. All the rules for heredoc identifiers also apply to nowdoc identifiers, especially those regarding the appearance of the closing identifier.
Example #12 Nowdoc string quoting example
<?php
echo <<<'EOD'
Example of string spanning multiple lines
using nowdoc syntax. Backslashes are always treated literally,
e.g. \\ and \'.
EOD;
The above example will output:
Example of string spanning multiple lines
using nowdoc syntax. Backslashes are always treated literally,
e.g. \\ and \'.
Example #13 Nowdoc string quoting example with variables
<?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;
?>
The above example will output:
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
Example #14 Static data example
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
Variable parsing ¶
When a string is specified in double quotes or with heredoc, variables are parsed within it.
There are two types of syntax: a simple one and a complex one. The simple 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.
The complex syntax can be recognised by the curly braces surrounding the expression.
Simple syntax
If a dollar sign ($) is encountered, the parser will greedily take as many tokens as possible to form a valid variable name. Enclose the variable name in curly braces to explicitly specify the end of the name.
<?php
$juice = "apple";
echo "He drank some $juice juice.".PHP_EOL;
// Invalid. "s" is a valid character for a variable name, but the variable is $juice.
echo "He drank some juice made of $juices.";
// Valid. Explicitly specify the end of the variable name by enclosing it in braces:
echo "He drank some juice made of ${juice}s.";
?>
The above example will output:
He drank some apple juice.
He drank some juice made of .
He drank some juice made of apples.
Similarly, an array index or an object property can be parsed. With array indices, the closing square bracket (]) marks the end of the index. The same rules apply to object properties as to simple variables.
Example #15 Simple syntax example
<?php
$juices = array("apple", "orange", "koolaid1" => "purple");
echo "He drank some $juices[0] juice.".PHP_EOL;
echo "He drank some $juices[1] juice.".PHP_EOL;
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;
class people {
public $john = "John Smith";
public $jane = "Jane Smith";
public $robert = "Robert Paulsen";
public $smith = "Smith";
}
$people = new people();
echo "$people->john drank some $juices[0] juice.".PHP_EOL;
echo "$people->john then said hello to $people->jane.".PHP_EOL;
echo "$people->john's wife greeted $people->robert.".PHP_EOL;
echo "$people->robert greeted the two $people->smiths."; // Won't work
?>
The above example will output:
He drank some apple juice.
He drank some orange juice.
He drank some purple juice.
John Smith drank some apple juice.
John Smith then said hello to Jane Smith.
John Smith's wife greeted Robert Paulsen.
Robert Paulsen greeted the two .
As of PHP 7.1.0 also negative numeric indices are supported.
Example #16 Negative numeric indices
<?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;
?>
The above example will output:
The character at index -2 is n.
Changing the character at index -3 to o gives strong.
For anything more complex, you should use the complex syntax.
Complex (curly) syntax
This isn't called complex because the syntax is complex, but because it allows for the use of complex expressions.
Any scalar variable, array element or object property with a string representation can be included via this syntax. Simply write the expression the same way as it would appear outside the string, and then wrap it 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:
<?php
// Show all errors
error_reporting(E_ALL);
$great = 'fantastic';
// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
// Works
echo "This square is {$square->width}00 centimeters broad.";
// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";
// Works
echo "This works: {$arr[4][3]}";
// This is wrong for the same reason as $foo[bar] is wrong outside a string.
// In other words, it will still work, but only because PHP first looks for a
// constant named foo; an error of level E_NOTICE (undefined constant) will be
// thrown.
echo "This is wrong: {$arr[foo][3]}";
// Works. When using multi-dimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][3]}";
// Works.
echo "This works: " . $arr['foo'][3];
echo "This works too: {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
// Won't work, outputs: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>
It is also possible to access class properties using variables within strings using this syntax.
<?php
class foo {
var $bar = 'I am bar.';
}
$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo "{$foo->$bar}\n";
echo "{$foo->{$baz[1]}}\n";
?>
The above example will output:
I am bar.
I am bar.
Note:
The value accessed from functions, method calls, static class variables, and class constants inside {$} will be interpreted as the name of a variable in the scope in which the string is defined. Using single curly braces ({}) will not work for accessing the return values of functions or methods or the values of class constants or static class variables.
<?php
// Show all errors.
error_reporting(E_ALL);
class beers {
const softdrink = 'rootbeer';
public static $ale = 'ipa';
}
$rootbeer = 'A & W';
$ipa = 'Alexander Keith\'s';
// This works; outputs: I'd like an A & W
echo "I'd like an {${beers::softdrink}}\n";
// This works too; outputs: I'd like an Alexander Keith's
echo "I'd like an {${beers::$ale}}\n";
?>
String access and modification by character ¶
Characters within strings 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, strings 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 integer. 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.
Example #17 Some string examples
<?php
// Get the first character of a string
$str = 'This is a test.';
$first = $str[0];
// Get the third character of a string
$third = $str[2];
// Get the last character of a string.
$str = 'This is still a test.';
$last = $str[strlen($str)-1];
// Modify the last character of a string
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';
?>
String offsets have to either be integers or integer-like strings, otherwise a warning will be thrown.
Example #18 Example of Illegal String Offsets
<?php
$str = 'abc';
var_dump($str['1']);
var_dump(isset($str['1']));
var_dump($str['1.0']);
var_dump(isset($str['1.0']));
var_dump($str['x']);
var_dump(isset($str['x']));
var_dump($str['1x']);
var_dump(isset($str['1x']));
?>
The above example will output:
string(1) "b"
bool(true)
Warning: Illegal string offset '1.0' in /tmp/t.php on line 7
string(1) "b"
bool(false)
Warning: Illegal string offset 'x' in /tmp/t.php on line 9
string(1) "a"
bool(false)
string(1) "b"
bool(false)
Note:
Accessing variables of other types (not including arrays or objects implementing the appropriate interfaces) using [] or {} silently returns null.
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 ¶
Strings may be concatenated using the '.' (dot) operator. Note that the '+' (addition) operator will not work for this. See String operators for more information.
There are a number of useful functions for string manipulation.
See the string functions section for general functions, and the Perl-compatible regular expression functions for advanced find & replace functionality.
There are also functions for URL strings, and functions to encrypt/decrypt strings (Sodium and Hash).
Finally, see also the character type functions.
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 and Type Juggling will make the following clearer. See also the settype() function.
A bool true value is converted to the string "1". bool false 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 floats). 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 .. Prior to PHP 8.0.0, the decimal point character is defined in the script's locale (category LC_NUMERIC). See the setlocale() function.
Arrays 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 objects to string magic method __toString must be used.
Resources are always converted to strings 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.
null 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 strings 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 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 case of, for instance, substr(), strpos(), strlen() or strcmp(). Another way to think of these functions is that operate on memory buffers, i.e., they work with bytes and byte offsets.
Other functions are passed the encoding of the string, possibly they also assume a default if no such information is given. This is the case of htmlentities() and the majority of the functions in the mbstring extension.
Others use the current locale (see setlocale()), but operate byte-by-byte. This is the case of strcasecmp(), strtoupper() and ucfirst(). This means they can be used only with single-byte encodings, as long as the encoding is matched by the locale. For instance strtoupper("á") may return "Á" if the locale is correctly set and á is encoded with a single byte. If it is encoded in UTF-8, the correct result will not be returned and the resulting string may or may not be returned corrupted, depending on the current locale.
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 extension and in the PCRE extension (in the last case, only when the u modifier is used). Although this is due to their special purpose, the function utf8_decode() assumes a UTF-8 encoding and the function utf8_encode() assumes an ISO-8859-1 encoding.
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 and 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.
///////////////////////////////////////////////////////////////
// NUMERIC STRINGS
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:
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})
PHP also has a concept of leading numeric strings. This is simply a string which starts like a numeric string followed by any characters.
Strings used in numeric contexts ¶
When a string needs to be evaluated as number (e.g. arithmetic operations, int type declaration, etc.) the following steps are taken to determine the outcome:
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_MAX), otherwise resolve to a float.
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_MAX), otherwise resolve to a float. Additionally an error of level E_WARNING is raised.
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 only if it 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 is 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.
<?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
?>
////////////////////////////////////////////////////////////////////////////
// ARRAYS
Arrays ¶
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 arrays, trees and multidimensional arrays 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 => value pairs as arguments.
array(
key => value,
key2 => value2,
key3 => 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 [].
Example #1 A simple array
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// Using the short array syntax
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>
The key can either be an int or a string. The value can be of any type.
Additionally the following key casts will occur:
Strings containing valid decimal ints, 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.
Floats are also cast to ints, which means that the fractional part will be truncated. E.g. the key 8.7 will actually be stored under 8.
Bools are cast to ints, too, i.e. the key true will actually be stored under 1 and the key false under 0.
Null will be cast to the empty string, i.e. the key null will actually be stored under "".
Arrays and objects 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.
Example #2 Type Casting and Overwriting example
<?php
$array = array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>
The above example will output:
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.
PHP arrays can contain int and string keys at the same time as PHP does not distinguish between indexed and associative arrays.
Example #3 Mixed int and string keys
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
The above example will output:
array(4) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
[100]=>
int(-100)
[-100]=>
int(100)
}
The key is optional. If it is not specified, PHP will use the increment of the largest previously used int key.
Example #4 Indexed arrays without key
<?php
$array = array("foo", "bar", "hello", "world");
var_dump($array);
?>
The above example will output:
array(4) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(5) "hello"
[3]=>
string(5) "world"
}
It is possible to specify the key only for some elements and leave it out for others:
Example #5 Keys not on all elements
<?php
$array = array(
"a",
"b",
6 => "c",
"d",
);
var_dump($array);
?>
The above example will output:
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.
Example #6 Complex Type Casting and Overwriting example
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);
?>
The above example will output:
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"
}
Accessing array elements with square bracket syntax ¶
Array elements can be accessed using the array[key] syntax.
Example #7 Accessing array elements
<?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"]);
?>
The above example will output:
string(3) "bar"
int(24)
string(3) "foo"
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.
Example #8 Array dereferencing
<?php
function getArray() {
return array(1, 2, 3);
}
$secondElement = getArray()[1];
// or
list(, $secondElement) = getArray();
?>
Note:
Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an E_NOTICE-level error message will be issued, and the result will be null.
Note:
Array dereferencing a scalar value which is not a string yields null. 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, 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 the place and [] may actually stand for string access operator. 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.
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.
<?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
unset($arr); // This deletes the whole array
?>
Note:
As mentioned above, if no key is specified, the maximum of the existing int indices is taken, and the new key will be that maximum value plus 1 (but at least 0). If no int indices exist yet, the key will be 0 (zero).
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:
<?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);
?>
The above example will output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
)
Array
(
[5] => 6
)
Array
(
[0] => 6
[1] => 7
)
Useful functions ¶
There are quite a few useful functions for working with arrays. See the array functions 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.
<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* will produce an array that would have been defined as
$a = array(1 => 'one', 3 => 'three');
and NOT
$a = array(1 => 'one', 2 =>'three');
*/
$b = array_values($a);
// Now $b is array(0 => 'one', 1 =>'three')
?>
The foreach control structure exists specifically for arrays. 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:
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
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.
Note: This does not mean to always quote the key. Do not quote keys which are constants or variables, as this will prevent PHP from interpreting them.
<?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";
}
?>
The above example will output:
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:
<?php
// Show all errors
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Correct
print $arr['fruit']; // apple
print $arr['veggie']; // carrot
// Incorrect. This works but also throws a PHP error of level E_NOTICE because
// of an undefined constant named fruit
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit]; // apple
// 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
print $arr['fruit']; // apple
print $arr[fruit]; // carrot
// The following is okay, as it's inside a string. Constants are not looked for
// within strings, so no E_NOTICE occurs here
print "Hello $arr[fruit]"; // Hello apple
// With one exception: braces surrounding arrays within strings allows constants
// to be interpreted
print "Hello {$arr[fruit]}"; // Hello carrot
print "Hello {$arr['fruit']}"; // Hello apple
// 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']";
// Concatenation is another option
print "Hello " . $arr['fruit']; // Hello apple
?>
When error_reporting is set to show E_NOTICE level errors (by setting it to E_ALL, for example), such uses will become immediately visible. By default, error_reporting is set not to show notices.
As stated in the syntax section, what's inside the square brackets ('[' and ']') must be an expression. This means that code like this works:
<?php
echo $arr[somefunc($bar)];
?>
This is an example of using a function return value as the array index. PHP also knows about constants:
<?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";
?>
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:
<?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";
?>
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.
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.
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 unaccessible; 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.
<?php
class A {
private $B;
protected $C;
public $D;
function __construct()
{
$this->{1} = null;
}
}
var_export((array) new A());
?>
The above example will output:
array (
'' . "\0" . 'A' . "\0" . 'B' => NULL,
'' . "\0" . '*' . "\0" . 'C' => NULL,
'D' => NULL,
1 => NULL,
)
These NUL can result in some unexpected behaviour:
<?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());
?>
The above example will output:
array(3) {
["BA"]=>
NULL
["AA"]=>
NULL
["AA"]=>
NULL
}
The above will appear to have two keys named 'AA', although one of them is actually named '\0A\0A'.
Converting null to an array results in an empty array.
Comparing ¶
It is possible to compare arrays with the array_diff() function and with array operators.
Examples ¶
The array type in PHP is very versatile. Here are some examples:
<?php
// This:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // key will be 0
);
$b = array('a', 'b', 'c');
// . . .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').
?>
Example #9 Using array()
<?php
// Array as (property-)map
$map = array( 'version' => 4,
'OS' => 'Linux',
'lang' => 'english',
'short_tags' => true
);
// strictly numerical keys
$array = array( 7,
8,
0,
156,
-10
);
// this is the same as array(0 => 7, 1 => 8, ...)
$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
);
// empty array
$empty = array();
?>
Example #10 Collection
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as $color) {
echo "Do you like $color?\n";
}
?>
The above example will output:
Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?
Changing the values of the array directly is possible by passing them by reference.
Example #11 Changing element in the loop
<?php
foreach ($colors as &$color) {
$color = strtoupper($color);
}
unset($color); /* ensure that following writes to
$color will not modify the last array element */
print_r($colors);
?>
The above example will output:
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
This example creates a one-based array.
Example #12 One-based index
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>
The above example will output:
Array
(
[1] => 'January'
[2] => 'February'
[3] => 'March'
)
Example #13 Filling an array
<?php
// fill an array with all items from a directory
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>
Arrays are ordered. The order can be changed using various sorting functions. See the array functions section for more information. The count() function can be used to count the number of items in an array.
Example #14 Sorting an array
<?php
sort($files);
print_r($files);
?>
Because the value of an array can be anything, it can also be another array. This enables the creation of recursive and multi-dimensional arrays.
Example #15 Recursive and multi-dimensional arrays
<?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"
)
);
// 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";
?>
Array assignment always involves value copying. Use the reference operator to copy an array by reference.
<?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
?>
add a note add a note
User Contributed Notes 20 notes
up
down
127mlvljr ¶10 years ago
please note that when arrays are copied, the "reference status" of their members is preserved (http://www.php.net/manual/en/language.references.whatdo.php).
up
down
50thomas tulinsky ¶5 years ago
I think your first, main example is needlessly confusing, very confusing to newbies:
$array = array(
"foo" => "bar",
"bar" => "foo",
);
It should be removed.
For newbies:
An array index can be any string value, even a value that is also a value in the array.
The value of array["foo"] is "bar".
The value of array["bar"] is "foo"
The following expressions are both true:
$array["foo"] == "bar"
$array["bar"] == "foo"
///////////////////////////////////////////////////////////////////
// Iterables
Iterables ¶
Iterable is a pseudo-type introduced in PHP 7.1. It accepts any array or object implementing the Traversable interface. Both of these types are iterable using foreach and can be used with yield from within a generator.
Using Iterables ¶
Iterable can be used as a parameter type to indicate that a function requires a set of values, but does not care about the form of the value set since it will be used with foreach. If a value is not an array or instance of Traversable, a TypeError will be thrown.
Example #1 Iterable parameter type example
<?php
function foo(iterable $iterable) {
foreach ($iterable as $value) {
// ...
}
}
?>
Parameters declared as iterable may use null or an array as a default value.
Example #2 Iterable parameter default value example
<?php
function foo(iterable $iterable = []) {
// ...
}
?>
Iterable can also be used as a return type to indicate a function will return an iterable value. If the returned value is not an array or instance of Traversable, a TypeError will be thrown.
Example #3 Iterable return type example
<?php
function bar(): iterable {
return [1, 2, 3];
}
?>
Functions declaring iterable as a return type may also be generators.
Example #4 Iterable generator return type example
<?php
function gen(): iterable {
yield 1;
yield 2;
yield 3;
}
?>
add a note add a note
User Contributed Notes 1 note
up
down
-13j_jaberi at yahoo dot com ¶1 year ago
Just to note:
Though objects may (or may not) be Traversable, the can use in foreach because implicit conversion to array
<?php
class Foo {
public $a = 1;
public $b = "Helo";
};
$bar = new Foo;
foreach($bar as $elm) {
echo $elm . ' ';
}
?>
prints 1 Hello
Even
<?php
$bar = new stdClass
foreach($bar as $elm) {
echo $elm . ' ';
}
?>
is correct.
//////////////////////////////////////////////////////////
// OBJECTS
Objects ¶
Object Initialization ¶
To create a new object, use the new statement to instantiate a class:
<?php
class foo
{
function do_foo()
{
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo();
?>
For a full discussion, see the Classes and Objects 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 null, the new instance will be empty. An array converts to an object with properties named by keys and corresponding values. Note that in this case before PHP 7.2.0 numeric keys have been inaccessible unless iterated.
<?php
$obj = (object) array('1' => 'foo');
var_dump(isset($obj->{'1'})); // outputs 'bool(true)' as of PHP 7.2.0; 'bool(false)' previously
var_dump(key($obj)); // outputs 'string(1) "1"' as of PHP 7.2.0; 'int(1)' previously
?>
For any other value, a member variable named scalar will contain the value.
<?php
$obj = (object) 'ciao';
echo $obj->scalar; // outputs 'ciao'
?>
add a note add a note
User Contributed Notes 28 notes
up
down
580helpful at stranger dot com ¶9 years ago
By far the easiest and correct way to instantiate an empty generic php object that you can then modify for whatever purpose you choose:
<?php $genericObject = new stdClass(); ?>
I had the most difficult time finding this, hopefully it will help someone else!
up
down
226Anthony ¶5 years ago
In PHP 7 there are a few ways to create an empty object:
<?php
$obj1 = new \stdClass; // Instantiate stdClass object
$obj2 = new class{}; // Instantiate anonymous class
$obj3 = (object)[]; // Cast empty array to object
var_dump($obj1); // object(stdClass)#1 (0) {}
var_dump($obj2); // object(class@anonymous)#2 (0) {}
var_dump($obj3); // object(stdClass)#3 (0) {}
?>
$obj1 and $obj3 are the same type, but $obj1 !== $obj3. Also, all three will json_encode() to a simple JS object {}:
<?php
echo json_encode([
new \stdClass,
new class{},
(object)[],
]);
?>
Outputs: [{},{},{}]
////////////////////////////////////////////////////////////////////////////
// RESOURCES
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 for a listing of all these functions and the corresponding resource types.
See also the get_resource_type() function.
/////////////////////////////////////////////////////////////////////////////
// NULL
NULL ¶
The special null value represents a variable with no value. null is the only possible value of type null.
A variable is considered to be null if:
it has been assigned the constant null.
it has not been set to any value yet.
it has been unset().
Syntax ¶
There is only one value of type null, and that is the case-insensitive constant null.
<?php
$var = NULL;
?>
//////////////////////////////////////////////////////////////
// CALLABLES
Callbacks / Callables ¶
Callbacks can be denoted by the callable type declaration.
Some functions like call_user_func() or usort() accept user-defined callback functions as a parameter. Callback functions can not only be simple functions, but also object methods, including static class methods.
Passing ¶
A PHP function is passed by its name as a string. Any built-in or user-defined function can be used, except language constructs such as: array(), echo, empty(), eval(), exit(), isset(), list(), print or unset().
A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1. Accessing protected and private methods from within a class is allowed.
Static class methods can also be passed without instantiating an object of that class by either, passing the class name instead of an object at index 0, or passing 'ClassName::methodName'.
Apart from common user-defined function, anonymous functions and arrow functions can also be passed to a callback parameter.
Generally, any object implementing __invoke() can also be passed to a callback parameter.
Example #1 Callback function examples
<?php
// An example callback function
function my_callback_function() {
echo 'hello world!';
}
// An example callback method
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!';
}
}
// Type 1: Simple callback
call_user_func('my_callback_function');
// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod'));
// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
// Type 4: Static class method call
call_user_func('MyClass::myCallbackMethod');
// Type 5: Relative static class method call
class A {
public static function who() {
echo "A\n";
}
}
class B extends A {
public static function who() {
echo "B\n";
}
}
call_user_func(array('B', 'parent::who')); // A
// Type 6: Objects implementing __invoke can be used as callables
class C {
public function __invoke($name) {
echo 'Hello ', $name, "\n";
}
}
$c = new C();
call_user_func($c, 'PHP!');
?>
Example #2 Callback example using a Closure
<?php
// Our closure
$double = function($a) {
return $a * 2;
};
// This is our range of numbers
$numbers = range(1, 5);
// Use the closure as a callback here to
// double the size of each element in our
// range
$new_numbers = array_map($double, $numbers);
print implode(' ', $new_numbers);
?>
The above example will output:
2 4 6 8 10
Note:
Callbacks registered with functions such as call_user_func() and call_user_func_array() will not be called if there is an uncaught exception thrown in a previous callback.
add a note add a note
User Contributed Notes 17 notes
up
down
265andrewbessa at gmail dot com ¶9 years ago
You can also use the $this variable to specify a callback:
<?php
class MyClass {
public $property = 'Hello World!';
public function MyMethod()
{
call_user_func(array($this, 'myCallbackMethod'));
}
public function MyCallbackMethod()
{
echo $this->property;
}
}
?>
//////////////////////////////////////////////////////////
// Type declarations ¶
Type declarations can be added to function arguments, return values, and, as of PHP 7.4.0, class properties. They ensure that the value is of the specified type at call time, otherwise a TypeError is thrown.
Note:
When overriding a parent method, the child's method must match any return type declaration on the parent. If the parent doesn't define a return type, then the child method may do so.
Single types ¶
Type Description Version
Class/interface name The value must be an instanceof the given class or interface.
self The value must be an instanceof the same class as the one in which the type declaration is used. Can only be used in classes.
parent The value must be an instanceof the parent of the class in which the type declaration is used. Can only be used in classes.
array The value must be an array.
callable The value must be a valid callable. Cannot be used as a class property type declaration.
bool The value must be a boolean value.
float The value must be a floating point number.
int The value must be an integer.
string The value must be a string.
iterable The value must be either an array or an instanceof Traversable. PHP 7.1.0
object The value must be an object. PHP 7.2.0
mixed The value can be any value. PHP 8.0.0
Warning
Aliases for the above scalar types 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 instanceof the class or interface boolean, rather than of type bool:
<?php
function test(boolean $param) {}
test(true);
?>
Output of the above example in PHP 8:
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
mixed ¶
mixed is equivalent to the union type object|resource|array|string|int|float|bool|null. Available as of PHP 8.0.0.
Examples ¶
Example #1 Basic class type declaration
<?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);
?>
Output of the above example in PHP 8:
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
Example #2 Basic interface type declaration
<?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);
?>
Output of the above example in PHP 8:
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
Example #3 Basic return type declaration
<?php
function sum($a, $b): float {
return $a + $b;
}
// Note that a float will be returned.
var_dump(sum(1, 2));
?>
The above example will output:
float(3)
Example #4 Returning an object
<?php
class C {}
function getC(): C {
return new C;
}
var_dump(getC());
?>
The above example will output:
object(C)#1 (0) {
}
Nullable type ¶
As of PHP 7.1.0, type declarations can be marked nullable by prefixing the type name with a question mark (?). This signifies that the value can be of the specified type or null.
Example #5 Nullable argument type declaration
<?php
class C {}
function f(?C $c) {
var_dump($c);
}
f(new C);
f(null);
?>
The above example will output:
object(C)#1 (0) {
}
NULL
Example #6 Nullable return type declaration
<?php
function get_item(): ?string {
if (isset($_GET['item'])) {
return $_GET['item'];
} else {
return null;
}
}
?>
Note:
Prior to PHP 7.1.0, it was possible to achieve nullable arguments by making null the default value. This is not recommended as this breaks during inheritance.
Example #7 Old way to make arguments nullable
<?php
class C {}
function f(C $c = null) {
var_dump($c);
}
f(new C);
f(null);
?>
The above example will output:
object(C)#1 (0) {
}
NULL
Union types ¶
A union type declaration accepts values of multiple different types, rather than a single one. Union types are specified using the syntax T1|T2|.... Union types are available as of PHP 8.0.0.
Nullable union types ¶
The null type is supported as part of unions, such that T1|T2|null can be used to create a nullable union. The existing ?T notation is considered a shorthand for the common case of T|null.
Caution
null cannot be used as a standalone type.
false pseudo-type ¶
The false literal type is supported as part of unions, and is included as for historical reasons many internal functions return false instead of null for failures. A classic example of such a function is strpos().
Caution
false cannot be used as a standalone type (including nullable standalone type). As such, all of false, false|null and ?false are not permitted.
Caution
The true literal type does not exist.
Duplicate and redundant types ¶
To catch simple bugs in union 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 result in an error.
If bool is used, false 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.
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.
<?php
function foo(): int|INT {} // Disallowed
function foo(): bool|false {} // Disallowed
use A as B;
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)
?>
Return only types ¶
void ¶
void is a return type indicating the function does not return a value. Therefore it cannot be part of a union type declaration. Available as of PHP 7.1.0.
never ¶
never is a return type indicating the function does not return. This means that it either calls exit(), throws an exception, or is an infinite loop. Therefore it cannot be part of a union type declaration. Available as of PHP 8.1.0.
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.
static ¶
The value must be an instanceof the same class as the one the method is called in. Available as of PHP 8.0.0.
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 declare 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.
Example #8 Strict typing for arguments values
<?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));
?>
Output of the above example in PHP 8:
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
Example #9 Coercive typing for argument values
<?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));
?>
The above example will output:
int(3)
int(3)
Example #10 Strict typing for return values
<?php
declare(strict_types=1);
function sum($a, $b): int {
return $a + $b;
}
var_dump(sum(1, 2));
var_dump(sum(1, 2.5));
?>
The above example will output:
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
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:
int
float
string
bool
If the type both exists in the union, and the value can be coerced to the type under PHPs 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” 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 and false types occur.
Example #11 Example of types being coerced into a type part of the union
<?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
?>
Misc ¶
Example #12 Typed pass-by-reference Parameters
Declared types of reference parameters are checked on function entry, but not when the function returns, so after the function had returned, the argument's type may have changed.
<?php
function array_baz(array &$param)
{
$param = 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>
Output of the above example in PHP 8:
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
Example #13 Catching TypeError
<?php
declare(strict_types=1);
function sum(int $a, int $b) {
return $a + $b;
}
try {
var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));
} catch (TypeError $e) {
echo 'Error: ', $e->getMessage();
}
?>
Output of the above example in PHP 8:
int(3)
Error: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 10
////////////////////////////////////////////////////////
// Type Juggling ¶
PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which the variable is used. That is to say, if a string value is assigned to variable $var, $var becomes a string. If an int value is then assigned to $var, it becomes an int.
An example of PHP's automatic type conversion is the multiplication operator '*'. If either operand is a float, then both operands are evaluated as floats, and the result will be a float. Otherwise, the operands will be interpreted as ints, and the result will also be an int. Note that this does not change the types of the operands themselves; the only change is in how the operands are evaluated and what the type of the expression itself is.
<?php
$foo = "1"; // $foo is string (ASCII 49)
$foo *= 2; // $foo is now an integer (2)
$foo = $foo * 1.3; // $foo is now a float (2.6)
$foo = 5 * "10 Little Piggies"; // $foo is integer (50)
$foo = 5 * "10 Small Pigs"; // $foo is integer (50)
?>
If the last two examples above seem odd, see how numeric strings convert to integers.
To force a variable to be evaluated as a certain type, see the section on Type casting. To change the type of a variable, see the settype() function.
To test any of the examples in this section, use the var_dump() function.
Note:
The behaviour of an automatic conversion to array is currently undefined.
Also, because PHP supports indexing into strings via offsets using the same syntax as array indexing, the following example holds true for all PHP versions:
<?php
$a = 'car'; // $a is a string
$a[0] = 'b'; // $a is still a string
echo $a; // bar
?>
See the section titled String access by character for more information.
Type Casting ¶
Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast.
<?php
$foo = 10; // $foo is an integer
$bar = (boolean) $foo; // $bar is a boolean
?>
The casts allowed are:
(int), (integer) - cast to int
(bool), (boolean) - cast to bool
(float), (double), (real) - cast to float
(string) - cast to string
(array) - cast to array
(object) - cast to object
(unset) - cast to NULL
(binary) casting and b prefix exists for forward support. Note that the (binary) cast is essential the same as (string), but it should not be relied upon.
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.
Note that tabs and spaces are allowed inside the parentheses, so the following are functionally equivalent:
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
Casting literal strings and variables to binary strings:
<?php
$binary = (binary) $string;
$binary = b"binary string";
?>
Note:
Instead of casting a variable to a string, it is also possible to enclose the variable in double quotes.
<?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";
}
?>
It may not be obvious exactly what will happen when casting between certain types. For more information, see these sections:
Converting to boolean
Converting to integer
Converting to float
Converting to string
Converting to array
Converting to object
Converting to resource
Converting to NULL
The type comparison tables
//////////////////////////////////////////////////////
// VARIABLES BASICS
Variables in PHP are represented by a dollar sign followed by the name of the variable. The variable name is case-sensitive.
Variable names follow the same rules as other labels in PHP. A valid variable 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]*$
Note: For our purposes here, a letter is a-z, A-Z, and the bytes from 128 through 255 (0x80-0xff).
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) was possible.
Tip
See also the Userland Naming Guide.
For information on variable related functions, see the Variable Functions Reference.
<?php
$var = 'Bob';
$Var = 'Joe';
echo "$var, $Var"; // outputs "Bob, Joe"
$4site = 'not yet'; // invalid; starts with a number
$_4site = 'not yet'; // valid; starts with an underscore
$täyte = 'mansikka'; // valid; 'ä' is (Extended) ASCII 228.
?>
By default, variables are always assigned by value. That is to say, when you assign an expression 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.
PHP also offers another way to assign values to variables: assign by reference. 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 (&) 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:
<?php
$foo = 'Bob'; // Assign the value 'Bob' to $foo
$bar = &$foo; // Reference $foo via $bar.
$bar = "My name is $bar"; // Alter $bar...
echo $bar;
echo $foo; // $foo is altered too.
?>
One important thing to note is that only named variables may be assigned by reference.
<?php
$foo = 25;
$bar = &$foo; // This is a valid assignment.
$bar = &(24 * 7); // Invalid; references an unnamed expression.
function test()
{
return 25;
}
$bar = &test(); // Invalid.
?>
It is not necessary to initialize variables in PHP however it is a very good practice. Uninitialized variables have a default value of their type depending on the context in which they are used - booleans default to false, integers and floats default to zero, strings (e.g. used in echo) are set as an empty string and arrays become to an empty array.
Example #1 Default values of uninitialized variables
<?php
// Unset AND unreferenced (no use context) variable; outputs NULL
var_dump($unset_var);
// Boolean usage; outputs 'false' (See ternary operators for more on this syntax)
echo($unset_bool ? "true\n" : "false\n");
// String usage; outputs 'string(3) "abc"'
$unset_str .= 'abc';
var_dump($unset_str);
// Integer usage; outputs 'int(25)'
$unset_int += 25; // 0 + 25 => 25
var_dump($unset_int);
// Float/double usage; outputs 'float(1.25)'
$unset_float += 1.25;
var_dump($unset_float);
// Array usage; outputs array(1) { [3]=> string(3) "def" }
$unset_arr[3] = "def"; // array() + array(3 => "def") => array(3 => "def")
var_dump($unset_arr);
// Object usage; creates new stdClass object (see http://www.php.net/manual/en/reserved.classes.php)
// Outputs: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
$unset_obj->foo = 'bar';
var_dump($unset_obj);
?>
Relying on the default value of an uninitialized variable is problematic in the case of including one file into another which uses the same variable name. E_NOTICE level error is issued in case of working with uninitialized variables, however not in the case of appending elements to the uninitialized array. isset() language construct can be used to detect if a variable has been already initialized.
///////////////////////////////////////////////////
// PREDEFINED VARS
Predefined Variables ¶
PHP provides a large number of predefined variables to any script which it runs. Many of these variables, however, cannot be fully documented as they are dependent upon which server is running, the version and setup of the server, and other factors. Some of these variables will not be available when PHP is run on the command line. Refer to the list of predefined variables for details.
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 rather special in that they are automatically global - i.e., 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 for details.
Note: Variable variables
Superglobals cannot be used as variable variables inside functions or class methods.
If certain variables in variables_order are not set, their appropriate PHP predefined arrays are also left empty.
///////////////////////////////////////////////////////
// VARIABLE SCOPE
Variable scope ¶
The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well. For example:
<?php
$a = 1;
include 'b.inc';
?>
Here the $a variable will be available within the included b.inc script. However, within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope. For example:
<?php
$a = 1; /* global scope */
function test()
{
echo $a; /* reference to local scope variable */
}
test();
?>
This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope. You may notice 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 ¶
First, an example use of global:
Example #1 Using global
<?php
$a = 1;
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b;
?>
The above script will output 3. 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:
Example #2 Using $GLOBALS instead of global
<?php
$a = 1;
$b = 2;
function Sum()
{
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}
Sum();
echo $b;
?>
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. Here's an example demonstrating the power of superglobals:
Example #3 Example demonstrating superglobals and scope
<?php
function test_superglobal()
{
echo $_POST['name'];
}
?>
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:
Example #4 Example demonstrating need for static variables
<?php
function test()
{
$a = 0;
echo $a;
$a++;
}
?>
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:
Example #5 Example use of static variables
<?php
function test()
{
static $a = 0;
echo $a;
$a++;
}
?>
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. A recursive function is one which calls itself. Care must be taken when writing a recursive function because it is possible to make it recurse indefinitely. You must make sure you have an adequate way of terminating the recursion. The following simple function recursively counts to 10, using the static variable $count to know when to stop:
Example #6 Static variables with recursive functions
<?php
function test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
}
?>
Static variables can be assigned values which are the result of constant expressions, but dynamic expressions, such as function calls, will cause a parse error.
Example #7 Declaring static variables
<?php
function foo(){
static $int = 0; // correct
static $int = 1+2; // correct
static $int = sqrt(121); // wrong (as it is a function)
$int++;
echo $int;
}
?>
Note:
Static declarations are resolved in compile-time.
References with global and static variables ¶
PHP implements the static and global modifier for variables in terms of 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:
<?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);
?>
The above example will output:
NULL
object(stdClass)#1 (0) {
}
A similar behaviour applies to the static statement. References are not stored statically:
<?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();
?>
The above example will output:
Static object: NULL
Static object: NULL
Static object: NULL
Static object: object(stdClass)#3 (1) {
["property"]=>
int(1)
}
This example demonstrates that when assigning a reference to a static variable, it's not remembered when you call the &get_instance_ref() function a second time.
//////////////////////////////////////////////////////////
// VARIABLE VARIABLES
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:
<?php
$a = 'hello';
?>
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.
<?php
$$a = 'world';
?>
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:
<?php
echo "$a ${$a}";
?>
produces the exact same output as:
<?php
echo "$a $hello";
?>
i.e. they both produce: hello world.
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a 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 you have 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).
Example #1 Variable property example
<?php
class foo {
var $bar = 'I am bar.';
var $arr = array('I am A.', 'I am B.', 'I am C.');
var $r = 'I am r.';
}
$foo = new foo();
$bar = 'bar';
$baz = array('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";
?>
The above example will output:
I am bar.
I am bar.
I am bar.
I am r.
Warning
Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.
/////////////////////////////////////////////////////
// VARIABLES FROM EXTERNAL SOURCES
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:
Example #1 A simple HTML form
<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>
There are only two ways to access data from your HTML forms. Currently available methods are listed below:
Example #2 Accessing data from a simple POST HTML form
<?php
echo $_POST['username'];
echo $_REQUEST['username'];
?>
Using a GET form is similar except you'll use the appropriate GET predefined variable 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 <input name="a.b" /> becomes $_REQUEST["a_b"].
PHP also understands arrays in the context of form variables (see the related faq). You may, for example, group related variables together, or use this feature to retrieve values from a multiple select input. For example, let's post a form to itself and upon submission display the data:
Example #3 More complex form variables
<?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>
Note: If an external variable name begins with a valid array syntax, trailing characters are silently ignored. For example, <input name="foo[bar]baz"> 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:
<input type="image" src="image.gif" name="sub" />
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. Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. You can 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 you wish to assign multiple values to a single cookie variable, you may assign it as an array. For example:
<?php
setcookie("MyCookie[foo]", 'Testing 1', time()+3600);
setcookie("MyCookie[bar]", 'Testing 2', time()+3600);
?>
That will create two separate cookies although MyCookie will now be a single array in your script. If you want to set just one cookie 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 your browser unless the path or domain is different. So, for a shopping cart application you may want to keep a counter and pass this along. i.e.
Example #4 A setcookie() example
<?php
if (isset($_COOKIE['count'])) {
$count = $_COOKIE['count'] + 1;
} else {
$count = 1;
}
setcookie('count', $count, time()+3600);
setcookie("Cart[$count]", $item, time()+3600);
?>
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.
HTTP being a text protocol, most, if not all, content that comes in Superglobal arrays, 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
Changelog ¶
Version Description
7.2.34, 7.3.23, 7.4.11 The names of incoming cookies are no longer url-decoded for security reasons.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment