4252 lines
82 KiB
Plaintext
4252 lines
82 KiB
Plaintext
--- Source: boolean.xml ---
|
||
<?php
|
||
$foo = True; // assign the value TRUE to $foo
|
||
?>
|
||
|
||
--- Source: boolean.xml ---
|
||
<?php
|
||
$action = "show_version";
|
||
$show_separators = true;
|
||
|
||
// == is an operator which tests
|
||
// equality and returns a boolean
|
||
if ($action == "show_version") {
|
||
echo "The version is 1.23";
|
||
}
|
||
|
||
// this is not necessary...
|
||
if ($show_separators == TRUE) {
|
||
echo "<hr>\n";
|
||
}
|
||
|
||
// ...because this can be used with exactly the same meaning:
|
||
if ($show_separators) {
|
||
echo "<hr>\n";
|
||
}
|
||
?>
|
||
|
||
--- Source: boolean.xml ---
|
||
<?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)
|
||
?>
|
||
|
||
--- Source: integer.xml ---
|
||
<?php
|
||
$a = 1234; // decimal number
|
||
$a = 0123; // octal number (equivalent to 83 decimal)
|
||
$a = 0o123; // octal number (as of PHP 8.1.0)
|
||
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
|
||
$a = 0b11111111; // binary number (equivalent to 255 decimal)
|
||
$a = 1_234_567; // decimal number (as of PHP 7.4.0)
|
||
?>
|
||
|
||
--- Source: integer.xml ---
|
||
decimal : [1-9][0-9]*(_[0-9]+)*
|
||
| 0
|
||
|
||
hexadecimal : 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)*
|
||
|
||
octal : 0[oO]?[0-7]+(_[0-7]+)*
|
||
|
||
binary : 0[bB][01]+(_[01]+)*
|
||
|
||
integer : decimal
|
||
| hexadecimal
|
||
| octal
|
||
| binary
|
||
|
||
--- Source: integer.xml ---
|
||
<?php
|
||
$large_number = 50000000000000000000;
|
||
var_dump($large_number); // float(5.0E+19)
|
||
|
||
var_dump(PHP_INT_MAX + 1); // 32-bit system: float(2147483648)
|
||
// 64-bit system: float(9.2233720368548E+18)
|
||
?>
|
||
|
||
--- Source: integer.xml ---
|
||
<?php
|
||
var_dump(25/7); // float(3.5714285714286)
|
||
var_dump((int) (25/7)); // int(3)
|
||
var_dump(round(25/7)); // float(4)
|
||
?>
|
||
|
||
--- Source: integer.xml ---
|
||
<?php
|
||
|
||
function foo($value): int {
|
||
return $value;
|
||
}
|
||
|
||
var_dump(foo(8.1)); // "Deprecated: Implicit conversion from float 8.1 to int loses precision" as of PHP 8.1.0
|
||
var_dump(foo(8.1)); // 8 prior to PHP 8.1.0
|
||
var_dump(foo(8.0)); // 8 in both cases
|
||
|
||
var_dump((int) 8.1); // 8 in both cases
|
||
var_dump(intval(8.1)); // 8 in both cases
|
||
?>
|
||
|
||
--- Source: integer.xml ---
|
||
<?php
|
||
echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
|
||
?>
|
||
|
||
--- Source: callable.xml ---
|
||
<?php
|
||
function foo(callable $callback) {
|
||
$callback();
|
||
}
|
||
?>
|
||
|
||
--- Source: callable.xml ---
|
||
<?php
|
||
// Using anonymous function syntax
|
||
$double1 = function ($a) {
|
||
return $a * 2;
|
||
};
|
||
|
||
// Using first-class callable syntax
|
||
function double_function($a) {
|
||
return $a * 2;
|
||
}
|
||
$double2 = double_function(...);
|
||
|
||
// Using arrow function syntax
|
||
$double3 = fn($a) => $a * 2;
|
||
|
||
// Using Closure::fromCallable
|
||
$double4 = Closure::fromCallable('double_function');
|
||
|
||
// Use the closure as a callback here to
|
||
// double the size of each element in our range
|
||
$new_numbers = array_map($double1, range(1, 5));
|
||
print implode(' ', $new_numbers) . PHP_EOL;
|
||
|
||
$new_numbers = array_map($double2, range(1, 5));
|
||
print implode(' ', $new_numbers) . PHP_EOL;
|
||
|
||
$new_numbers = array_map($double3, range(1, 5));
|
||
print implode(' ', $new_numbers) . PHP_EOL;
|
||
|
||
$new_numbers = array_map($double4, range(1, 5));
|
||
print implode(' ', $new_numbers);
|
||
|
||
?>
|
||
|
||
--- Source: callable.xml ---
|
||
<?php
|
||
|
||
// An example callback function
|
||
function my_callback_function() {
|
||
echo 'hello world!', PHP_EOL;
|
||
}
|
||
|
||
// An example callback method
|
||
class MyClass {
|
||
static function myCallbackMethod() {
|
||
echo 'Hello World!', PHP_EOL;
|
||
}
|
||
}
|
||
|
||
// Type 1: Simple callback
|
||
call_user_func('my_callback_function');
|
||
|
||
// Type 2: Static class method call
|
||
call_user_func(['MyClass', 'myCallbackMethod']);
|
||
|
||
// Type 3: Object method call
|
||
$obj = new MyClass();
|
||
call_user_func([$obj, 'myCallbackMethod']);
|
||
|
||
// Type 4: Static class method call
|
||
call_user_func('MyClass::myCallbackMethod');
|
||
|
||
// Type 5: Static class method call using ::class keyword
|
||
call_user_func([MyClass::class, 'myCallbackMethod']);
|
||
|
||
// Type 6: Relative static class method call
|
||
class A {
|
||
public static function who() {
|
||
echo 'A', PHP_EOL;
|
||
}
|
||
}
|
||
|
||
class B extends A {
|
||
public static function who() {
|
||
echo 'B', PHP_EOL;
|
||
}
|
||
}
|
||
|
||
call_user_func(['B', 'parent::who']); // deprecated as of PHP 8.2.0
|
||
|
||
// Type 7: Objects implementing __invoke can be used as callables
|
||
class C {
|
||
public function __invoke($name) {
|
||
echo 'Hello ', $name;
|
||
}
|
||
}
|
||
|
||
$c = new C();
|
||
call_user_func($c, 'PHP!');
|
||
?>
|
||
|
||
--- Source: float.xml ---
|
||
<?php
|
||
$a = 1.234;
|
||
$b = 1.2e3;
|
||
$c = 7E-10;
|
||
$d = 1_234.567; // as of PHP 7.4.0
|
||
?>
|
||
|
||
--- Source: float.xml ---
|
||
LNUM [0-9]+(_[0-9]+)*
|
||
DNUM ({LNUM}?"."{LNUM}) | ({LNUM}"."{LNUM}?)
|
||
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
|
||
|
||
--- Source: float.xml ---
|
||
<?php
|
||
$a = 1.23456789;
|
||
$b = 1.23456780;
|
||
$epsilon = 0.00001;
|
||
|
||
if (abs($a - $b) < $epsilon) {
|
||
echo "true";
|
||
}
|
||
?>
|
||
|
||
--- Source: enumerations.xml ---
|
||
<?php
|
||
enum Suit
|
||
{
|
||
case Hearts;
|
||
case Diamonds;
|
||
case Clubs;
|
||
case Spades;
|
||
}
|
||
|
||
function do_stuff(Suit $s)
|
||
{
|
||
// ...
|
||
}
|
||
|
||
do_stuff(Suit::Spades);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$array1 = array(
|
||
"foo" => "bar",
|
||
"bar" => "foo",
|
||
);
|
||
|
||
// Using the short array syntax
|
||
$array2 = [
|
||
"foo" => "bar",
|
||
"bar" => "foo",
|
||
];
|
||
|
||
var_dump($array1, $array2);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$array = array(
|
||
1 => "a",
|
||
"1" => "b",
|
||
1.5 => "c",
|
||
true => "d",
|
||
);
|
||
var_dump($array);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$array = array(
|
||
"foo" => "bar",
|
||
"bar" => "foo",
|
||
100 => -100,
|
||
-100 => 100,
|
||
);
|
||
var_dump($array);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$array = array("foo", "bar", "hello", "world");
|
||
var_dump($array);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$array = array(
|
||
"a",
|
||
"b",
|
||
6 => "c",
|
||
"d",
|
||
);
|
||
var_dump($array);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?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);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$array = [];
|
||
|
||
$array[-5] = 1;
|
||
$array[] = 2;
|
||
|
||
var_dump($array);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?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"]);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
function getArray() {
|
||
return array(1, 2, 3);
|
||
}
|
||
|
||
$secondElement = getArray()[1];
|
||
|
||
var_dump($secondElement);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$arr = array(5 => 1, 12 => 2);
|
||
|
||
$arr[] = 56; // This is the same as $arr[13] = 56;
|
||
// at this point of the script
|
||
|
||
$arr["x"] = 42; // This adds a new element to
|
||
// the array with key "x"
|
||
|
||
unset($arr[5]); // This removes the element from the array
|
||
|
||
var_dump($arr);
|
||
|
||
unset($arr); // This deletes the whole array
|
||
|
||
var_dump($arr);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?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);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$source_array = ['foo', 'bar', 'baz'];
|
||
|
||
[$foo, $bar, $baz] = $source_array;
|
||
|
||
echo $foo, PHP_EOL; // prints "foo"
|
||
echo $bar, PHP_EOL; // prints "bar"
|
||
echo $baz, PHP_EOL; // prints "baz"
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$source_array = [
|
||
[1, 'John'],
|
||
[2, 'Jane'],
|
||
];
|
||
|
||
foreach ($source_array as [$id, $name]) {
|
||
echo "{$id}: '{$name}'\n";
|
||
}
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$source_array = ['foo', 'bar', 'baz'];
|
||
|
||
// Assign the element at index 2 to the variable $baz
|
||
[, , $baz] = $source_array;
|
||
|
||
echo $baz; // prints "baz"
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$source_array = ['foo' => 1, 'bar' => 2, 'baz' => 3];
|
||
|
||
// Assign the element at index 'baz' to the variable $three
|
||
['baz' => $three] = $source_array;
|
||
|
||
echo $three, PHP_EOL; // prints 3
|
||
|
||
$source_array = ['foo', 'bar', 'baz'];
|
||
|
||
// Assign the element at index 2 to the variable $baz
|
||
[2 => $baz] = $source_array;
|
||
|
||
echo $baz, PHP_EOL; // prints "baz"
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$a = 1;
|
||
$b = 2;
|
||
|
||
[$b, $a] = [$a, $b];
|
||
|
||
echo $a, PHP_EOL; // prints 2
|
||
echo $b, PHP_EOL; // prints 1
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
|
||
|
||
/* will produce an array that would have been defined as
|
||
$a = array(1 => 'one', 3 => 'three');
|
||
and NOT
|
||
$a = array(1 => 'one', 2 =>'three');
|
||
*/
|
||
unset($a[2]);
|
||
var_dump($a);
|
||
|
||
$b = array_values($a);
|
||
// Now $b is array(0 => 'one', 1 =>'three')
|
||
var_dump($b);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$foo[bar] = 'enemy';
|
||
echo $foo[bar];
|
||
// etc
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?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";
|
||
}
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
// Show all errors
|
||
error_reporting(E_ALL);
|
||
|
||
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
|
||
|
||
// Correct
|
||
echo $arr['fruit'], PHP_EOL; // apple
|
||
echo $arr['veggie'], PHP_EOL; // carrot
|
||
|
||
// Incorrect. This does not work and throws a PHP Error because
|
||
// of an undefined constant named fruit
|
||
//
|
||
// Error: Undefined constant "fruit"
|
||
try {
|
||
echo $arr[fruit];
|
||
} catch (Error $e) {
|
||
echo get_class($e), ': ', $e->getMessage(), PHP_EOL;
|
||
}
|
||
|
||
// This defines a constant to demonstrate what's going on. The value 'veggie'
|
||
// is assigned to a constant named fruit.
|
||
define('fruit', 'veggie');
|
||
|
||
// Notice the difference now
|
||
echo $arr['fruit'], PHP_EOL; // apple
|
||
echo $arr[fruit], PHP_EOL; // carrot
|
||
|
||
// The following is okay, as it's inside a string. Constants are not looked for
|
||
// within strings, so no error occurs here
|
||
echo "Hello $arr[fruit]", PHP_EOL; // Hello apple
|
||
|
||
// With one exception: braces surrounding arrays within strings allows constants
|
||
// to be interpreted
|
||
echo "Hello {$arr[fruit]}", PHP_EOL; // Hello carrot
|
||
echo "Hello {$arr['fruit']}", PHP_EOL; // Hello apple
|
||
|
||
// Concatenation is another option
|
||
echo "Hello " . $arr['fruit'], PHP_EOL; // Hello apple
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
// This will not work, and will result in a parse error, such as:
|
||
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
|
||
// This of course applies to using superglobals in strings as well
|
||
print "Hello $arr['fruit']";
|
||
print "Hello $_GET['foo']";
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
echo $arr[somefunc($bar)];
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?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";
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?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";
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
|
||
class A {
|
||
private $B;
|
||
protected $C;
|
||
public $D;
|
||
function __construct()
|
||
{
|
||
$this->{1} = null;
|
||
}
|
||
}
|
||
|
||
var_export((array) new A());
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?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());
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
// Using short array syntax.
|
||
// Also, works with array() syntax.
|
||
$arr1 = [1, 2, 3];
|
||
$arr2 = [...$arr1]; // [1, 2, 3]
|
||
$arr3 = [0, ...$arr1]; // [0, 1, 2, 3]
|
||
$arr4 = [...$arr1, ...$arr2, 111]; // [1, 2, 3, 1, 2, 3, 111]
|
||
$arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]
|
||
|
||
function getArr() {
|
||
return ['a', 'b'];
|
||
}
|
||
$arr6 = [...getArr(), 'c' => 'd']; // ['a', 'b', 'c' => 'd']
|
||
|
||
var_dump($arr1, $arr2, $arr3, $arr4, $arr5, $arr6);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
// string key
|
||
$arr1 = ["a" => 1];
|
||
$arr2 = ["a" => 2];
|
||
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
|
||
var_dump($arr3); // ["a" => 2]
|
||
|
||
// integer key
|
||
$arr4 = [1, 2, 3];
|
||
$arr5 = [4, 5, 6];
|
||
$arr6 = [...$arr4, ...$arr5];
|
||
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
|
||
// Which is [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
|
||
// where the original integer keys have not been retained.
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
|
||
$arr1 = [1, 2, 3];
|
||
$arr2 = ['a' => 4];
|
||
$arr3 = [...$arr1, ...$arr2];
|
||
// Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5
|
||
|
||
$arr4 = [1, 2, 3];
|
||
$arr5 = [4, 5];
|
||
$arr6 = [...$arr4, ...$arr5]; // works. [1, 2, 3, 4, 5]
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
// This:
|
||
$a = array( 'color' => 'red',
|
||
'taste' => 'sweet',
|
||
'shape' => 'round',
|
||
'name' => 'apple',
|
||
4 // key will be 0
|
||
);
|
||
|
||
$b = array('a', 'b', 'c');
|
||
|
||
var_dump($a, $b);
|
||
|
||
// . . .is completely equivalent with this:
|
||
$a = array();
|
||
$a['color'] = 'red';
|
||
$a['taste'] = 'sweet';
|
||
$a['shape'] = 'round';
|
||
$a['name'] = 'apple';
|
||
$a[] = 4; // key will be 0
|
||
|
||
$b = array();
|
||
$b[] = 'a';
|
||
$b[] = 'b';
|
||
$b[] = 'c';
|
||
|
||
// After the above code is executed, $a will be the array
|
||
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
|
||
// 'name' => 'apple', 0 => 4), and $b will be the array
|
||
// array(0 => 'a', 1 => 'b', 2 => 'c'), or simply array('a', 'b', 'c').
|
||
|
||
var_dump($a, $b);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
// Array as (property-)map
|
||
$map = array( 'version' => 4,
|
||
'OS' => 'Linux',
|
||
'lang' => 'english',
|
||
'short_tags' => true
|
||
);
|
||
var_dump($map);
|
||
|
||
// strictly numerical keys
|
||
// this is the same as array(0 => 7, 1 => 8, ...)
|
||
$array = array( 7,
|
||
8,
|
||
0,
|
||
156,
|
||
-10
|
||
);
|
||
var_dump($array);
|
||
|
||
$switching = array( 10, // key = 0
|
||
5 => 6,
|
||
3 => 7,
|
||
'a' => 4,
|
||
11, // key = 6 (maximum of integer-indices was 5)
|
||
'8' => 2, // key = 8 (integer!)
|
||
'02' => 77, // key = '02'
|
||
0 => 12 // the value 10 will be overwritten by 12
|
||
);
|
||
var_dump($switching);
|
||
|
||
// empty array
|
||
$empty = array();
|
||
var_dump($empty);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$colors = array('red', 'blue', 'green', 'yellow');
|
||
|
||
foreach ($colors as $color) {
|
||
echo "Do you like $color?\n";
|
||
}
|
||
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$colors = array('red', 'blue', 'green', 'yellow');
|
||
|
||
foreach ($colors as &$color) {
|
||
$color = mb_strtoupper($color);
|
||
}
|
||
unset($color); /* ensure that following writes to
|
||
$color will not modify the last array element */
|
||
|
||
print_r($colors);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$firstquarter = array(1 => 'January', 'February', 'March');
|
||
print_r($firstquarter);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
// fill an array with all items from a directory
|
||
$handle = opendir('.');
|
||
while (false !== ($file = readdir($handle))) {
|
||
$files[] = $file;
|
||
}
|
||
closedir($handle);
|
||
|
||
var_dump($files);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
sort($files);
|
||
print_r($files);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$fruits = array ( "fruits" => array ( "a" => "orange",
|
||
"b" => "banana",
|
||
"c" => "apple"
|
||
),
|
||
"numbers" => array ( 1,
|
||
2,
|
||
3,
|
||
4,
|
||
5,
|
||
6
|
||
),
|
||
"holes" => array ( "first",
|
||
5 => "second",
|
||
"third"
|
||
)
|
||
);
|
||
var_dump($fruits);
|
||
|
||
// Some examples to address values in the array above
|
||
echo $fruits["holes"][5]; // prints "second"
|
||
echo $fruits["fruits"]["a"]; // prints "orange"
|
||
unset($fruits["holes"][0]); // remove "first"
|
||
|
||
// Create a new multi-dimensional array
|
||
$juices["apple"]["green"] = "good";
|
||
var_dump($juices);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$arr1 = array(2, 3);
|
||
$arr2 = $arr1;
|
||
$arr2[] = 4; // $arr2 is changed,
|
||
// $arr1 is still array(2, 3)
|
||
|
||
$arr3 = &$arr1;
|
||
$arr3[] = 4; // now $arr1 and $arr3 are the same
|
||
|
||
var_dump($arr1, $arr2, $arr3);
|
||
?>
|
||
|
||
--- Source: type-juggling.xml ---
|
||
<?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
|
||
?>
|
||
|
||
--- Source: type-juggling.xml ---
|
||
<?php
|
||
$foo = 10; // $foo is an integer
|
||
$bar = (bool) $foo; // $bar is a boolean
|
||
|
||
var_dump($bar);
|
||
?>
|
||
|
||
--- Source: type-juggling.xml ---
|
||
<?php
|
||
$foo = (int) $bar;
|
||
$foo = ( int ) $bar;
|
||
?>
|
||
|
||
--- Source: type-juggling.xml ---
|
||
<?php
|
||
$binary = (binary) $string;
|
||
$binary = b"binary string";
|
||
?>
|
||
|
||
--- Source: type-juggling.xml ---
|
||
<?php
|
||
$foo = 10; // $foo is an integer
|
||
$str = "$foo"; // $str is a string
|
||
$fst = (string) $foo; // $fst is also a string
|
||
|
||
// This prints out that "they are the same"
|
||
if ($fst === $str) {
|
||
echo "they are the same", PHP_EOL;
|
||
}
|
||
?>
|
||
|
||
--- Source: type-juggling.xml ---
|
||
<?php
|
||
$a = 'car'; // $a is a string
|
||
$a[0] = 'b'; // $a is still a string
|
||
echo $a; // bar
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
function test(boolean $param) {}
|
||
test(true);
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
function &test(): void {}
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
function array_baz(array &$param)
|
||
{
|
||
$param = 1;
|
||
}
|
||
$var = [];
|
||
array_baz($var);
|
||
var_dump($var);
|
||
array_baz($var);
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
class C {}
|
||
|
||
function f(C $c = null) {
|
||
var_dump($c);
|
||
}
|
||
|
||
f(new C);
|
||
f(null);
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
function foo(): int|INT {} // Disallowed
|
||
function foo(): bool|false {} // Disallowed
|
||
function foo(): int&Traversable {} // Disallowed
|
||
function foo(): self&Traversable {} // Disallowed
|
||
|
||
use A as B;
|
||
function foo(): A|B {} // Disallowed ("use" is part of name resolution)
|
||
function foo(): A&B {} // Disallowed ("use" is part of name resolution)
|
||
|
||
class_alias('X', 'Y');
|
||
function foo(): X|Y {} // Allowed (redundancy is only known at runtime)
|
||
function foo(): X&Y {} // Allowed (redundancy is only known at runtime)
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?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);
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?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);
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
function sum($a, $b): float {
|
||
return $a + $b;
|
||
}
|
||
|
||
// Note that a float will be returned.
|
||
var_dump(sum(1, 2));
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
class C {}
|
||
|
||
function getC(): C {
|
||
return new C;
|
||
}
|
||
|
||
var_dump(getC());
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
class C {}
|
||
|
||
function f(?C $c) {
|
||
var_dump($c);
|
||
}
|
||
|
||
f(new C);
|
||
f(null);
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
function get_item(): ?string {
|
||
if (isset($_GET['item'])) {
|
||
return $_GET['item'];
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
class User {
|
||
public static string $foo = 'foo';
|
||
|
||
public int $id;
|
||
public string $username;
|
||
|
||
public function __construct(int $id, string $username) {
|
||
$this->id = $id;
|
||
$this->username = $username;
|
||
}
|
||
}
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?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));
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?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));
|
||
?>
|
||
|
||
--- Source: declarations.xml ---
|
||
<?php
|
||
declare(strict_types=1);
|
||
|
||
function sum($a, $b): int {
|
||
return $a + $b;
|
||
}
|
||
|
||
var_dump(sum(1, 2));
|
||
var_dump(sum(1, 2.5));
|
||
?>
|
||
|
||
--- Source: object.xml ---
|
||
<?php
|
||
class foo
|
||
{
|
||
function do_foo()
|
||
{
|
||
echo "Doing foo.";
|
||
}
|
||
}
|
||
|
||
$bar = new foo;
|
||
$bar->do_foo();
|
||
?>
|
||
|
||
--- Source: object.xml ---
|
||
<?php
|
||
$obj = (object) array('1' => 'foo');
|
||
var_dump(isset($obj->{'1'})); // outputs 'bool(true)'
|
||
|
||
// Deprecated as of PHP 8.1
|
||
var_dump(key($obj)); // outputs 'string(1) "1"'
|
||
?>
|
||
|
||
--- Source: object.xml ---
|
||
<?php
|
||
$obj = (object) 'ciao';
|
||
echo $obj->scalar; // outputs 'ciao'
|
||
?>
|
||
|
||
--- Source: null.xml ---
|
||
<?php
|
||
$var = NULL;
|
||
?>
|
||
|
||
--- Source: iterable.xml ---
|
||
<?php
|
||
|
||
function gen(): iterable {
|
||
yield 1;
|
||
yield 2;
|
||
yield 3;
|
||
}
|
||
|
||
foreach(gen() as $value) {
|
||
echo $value, "\n";
|
||
}
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
echo 'this is a simple string', PHP_EOL;
|
||
|
||
echo 'You can also have embedded newlines in
|
||
strings this way as it is
|
||
okay to do', PHP_EOL;
|
||
|
||
// Outputs: Arnold once said: "I'll be back"
|
||
echo 'Arnold once said: "I\'ll be back"', PHP_EOL;
|
||
|
||
// Outputs: You deleted C:\*.*?
|
||
echo 'You deleted C:\\*.*?', PHP_EOL;
|
||
|
||
// Outputs: You deleted C:\*.*?
|
||
echo 'You deleted C:\*.*?', PHP_EOL;
|
||
|
||
// Outputs: This will not expand: \n a newline
|
||
echo 'This will not expand: \n a newline', PHP_EOL;
|
||
|
||
// Outputs: Variables do not $expand $either
|
||
echo 'Variables do not $expand $either', PHP_EOL;
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
// no indentation
|
||
echo <<<END
|
||
a
|
||
b
|
||
c
|
||
\n
|
||
END;
|
||
|
||
// 4 spaces of indentation
|
||
echo <<<END
|
||
a
|
||
b
|
||
c
|
||
END;
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
echo <<<END
|
||
a
|
||
b
|
||
c
|
||
END;
|
||
|
||
--- Source: string.xml ---
|
||
<?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;
|
||
}
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
$values = [<<<END
|
||
a
|
||
b
|
||
c
|
||
END, 'd e f'];
|
||
var_dump($values);
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
$values = [<<<END
|
||
a
|
||
b
|
||
END ING
|
||
END, 'd e f'];
|
||
|
||
--- Source: string.xml ---
|
||
|
||
|
||
--- Source: string.xml ---
|
||
|
||
|
||
--- Source: string.xml ---
|
||
<?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;
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
var_dump(array(<<<EOD
|
||
foobar!
|
||
EOD
|
||
));
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?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;
|
||
}
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
echo <<<"FOOBAR"
|
||
Hello World!
|
||
FOOBAR;
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
echo <<<'EOD'
|
||
Example of string spanning multiple lines
|
||
using nowdoc syntax. Backslashes are always treated literally,
|
||
e.g. \\ and \'.
|
||
EOD;
|
||
|
||
--- Source: string.xml ---
|
||
<?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;
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
class foo {
|
||
public $bar = <<<'EOT'
|
||
bar
|
||
EOT;
|
||
}
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
$juice = "apple";
|
||
|
||
echo "He drank some $juice juice." . PHP_EOL;
|
||
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
string-variable::
|
||
variable-name (offset-or-property)?
|
||
| ${ expression }
|
||
|
||
offset-or-property::
|
||
offset-in-string
|
||
| property-in-string
|
||
|
||
offset-in-string::
|
||
[ name ]
|
||
| [ variable-name ]
|
||
| [ integer-literal ]
|
||
|
||
property-in-string::
|
||
-> name
|
||
|
||
variable-name::
|
||
$ name
|
||
|
||
name::
|
||
[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
const foo = 'bar';
|
||
$foo = 'foo';
|
||
$bar = 'bar';
|
||
var_dump("${foo}");
|
||
var_dump("${(foo)}");
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
echo "No interpolation $ has happened\n";
|
||
echo "No interpolation $\n has happened\n";
|
||
echo "No interpolation $2 has happened\n";
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
$juices = array("apple", "orange", "string_key" => "purple");
|
||
|
||
echo "He drank some $juices[0] juice.";
|
||
echo PHP_EOL;
|
||
echo "He drank some $juices[1] juice.";
|
||
echo PHP_EOL;
|
||
echo "He drank some $juices[string_key] juice.";
|
||
echo PHP_EOL;
|
||
|
||
class A {
|
||
public $s = "string";
|
||
}
|
||
|
||
$o = new A();
|
||
|
||
echo "Object value: $o->s.";
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?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;
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
const DATA_KEY = 'const-key';
|
||
$great = 'fantastic';
|
||
$arr = [
|
||
'1',
|
||
'2',
|
||
'3',
|
||
[41, 42, 43],
|
||
'key' => 'Indexed value',
|
||
'const-key' => 'Key with minus sign',
|
||
'foo' => ['foo1', 'foo2', 'foo3']
|
||
];
|
||
|
||
// Won't work, outputs: This is { fantastic}
|
||
echo "This is { $great}";
|
||
|
||
// Works, outputs: This is fantastic
|
||
echo "This is {$great}";
|
||
|
||
class Square {
|
||
public $width;
|
||
|
||
public function __construct(int $width) { $this->width = $width; }
|
||
}
|
||
|
||
$square = new Square(5);
|
||
|
||
// Works
|
||
echo "This square is {$square->width}00 centimeters wide.";
|
||
|
||
|
||
// Works, quoted keys only work using the curly brace syntax
|
||
echo "This works: {$arr['key']}";
|
||
|
||
|
||
// Works
|
||
echo "This works: {$arr[3][2]}";
|
||
|
||
echo "This works: {$arr[DATA_KEY]}";
|
||
|
||
// When using multidimensional arrays, always use braces around arrays
|
||
// when inside of strings
|
||
echo "This works: {$arr['foo'][2]}";
|
||
|
||
echo "This works: {$obj->values[3]->name}";
|
||
|
||
echo "This works: {$obj->$staticProp}";
|
||
|
||
// Won't work, outputs: C:\directory\{fantastic}.txt
|
||
echo "C:\directory\{$great}.txt";
|
||
|
||
// Works, outputs: C:\directory\fantastic.txt
|
||
echo "C:\\directory\\{$great}.txt";
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
// Get the first character of a string
|
||
$str = 'This is a test.';
|
||
$first = $str[0];
|
||
var_dump($first);
|
||
|
||
// Get the third character of a string
|
||
$third = $str[2];
|
||
var_dump($third);
|
||
|
||
// Get the last character of a string.
|
||
$str = 'This is still a test.';
|
||
$last = $str[strlen($str)-1];
|
||
var_dump($last);
|
||
|
||
// Modify the last character of a string
|
||
$str = 'Look at the sea';
|
||
$str[strlen($str)-1] = 'e';
|
||
var_dump($str);
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
$str = 'abc';
|
||
|
||
$keys = [ '1', '1.0', 'x', '1x' ];
|
||
|
||
foreach ($keys as $keyToTry) {
|
||
var_dump(isset($str[$keyToTry]));
|
||
|
||
try {
|
||
var_dump($str[$keyToTry]);
|
||
} catch (TypeError $e) {
|
||
echo $e->getMessage(), PHP_EOL;
|
||
}
|
||
|
||
echo PHP_EOL;
|
||
}
|
||
?>
|
||
|
||
--- Source: bitwise.xml ---
|
||
<?php
|
||
/*
|
||
* Ignore the top section,
|
||
* it is just formatting to make output clearer.
|
||
*/
|
||
|
||
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
|
||
. ' %3$s (%4$2d = %4$04b)' . "\n";
|
||
|
||
echo <<<EOH
|
||
--------- --------- -- ---------
|
||
result value op test
|
||
--------- --------- -- ---------
|
||
EOH;
|
||
|
||
|
||
/*
|
||
* Here are the examples.
|
||
*/
|
||
|
||
$values = array(0, 1, 2, 4, 8);
|
||
$test = 1 + 4;
|
||
|
||
echo "\n Bitwise AND \n";
|
||
foreach ($values as $value) {
|
||
$result = $value & $test;
|
||
printf($format, $result, $value, '&', $test);
|
||
}
|
||
|
||
echo "\n Bitwise Inclusive OR \n";
|
||
foreach ($values as $value) {
|
||
$result = $value | $test;
|
||
printf($format, $result, $value, '|', $test);
|
||
}
|
||
|
||
echo "\n Bitwise Exclusive OR (XOR) \n";
|
||
foreach ($values as $value) {
|
||
$result = $value ^ $test;
|
||
printf($format, $result, $value, '^', $test);
|
||
}
|
||
?>
|
||
|
||
--- Source: bitwise.xml ---
|
||
<?php
|
||
echo 12 ^ 9, PHP_EOL; // Outputs '5'
|
||
|
||
echo "12" ^ "9", PHP_EOL; // Outputs the Backspace character (ascii 8)
|
||
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
|
||
|
||
echo "hallo" ^ "hello", PHP_EOL; // Outputs the ascii values #0 #4 #0 #0 #0
|
||
// 'a' ^ 'e' = #4
|
||
|
||
echo 2 ^ "3", PHP_EOL; // Outputs 1
|
||
// 2 ^ ((int) "3") == 1
|
||
|
||
echo "2" ^ 3, PHP_EOL; // Outputs 1
|
||
// ((int) "2") ^ 3 == 1
|
||
?>
|
||
|
||
--- Source: bitwise.xml ---
|
||
<?php
|
||
/*
|
||
* Here are the examples.
|
||
*/
|
||
|
||
echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";
|
||
|
||
$val = 4;
|
||
$places = 1;
|
||
$res = $val >> $places;
|
||
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
|
||
|
||
$val = 4;
|
||
$places = 2;
|
||
$res = $val >> $places;
|
||
p($res, $val, '>>', $places);
|
||
|
||
$val = 4;
|
||
$places = 3;
|
||
$res = $val >> $places;
|
||
p($res, $val, '>>', $places, 'bits shift out right side');
|
||
|
||
$val = 4;
|
||
$places = 4;
|
||
$res = $val >> $places;
|
||
p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0');
|
||
|
||
|
||
echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";
|
||
|
||
$val = -4;
|
||
$places = 1;
|
||
$res = $val >> $places;
|
||
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
|
||
|
||
$val = -4;
|
||
$places = 2;
|
||
$res = $val >> $places;
|
||
p($res, $val, '>>', $places, 'bits shift out right side');
|
||
|
||
$val = -4;
|
||
$places = 3;
|
||
$res = $val >> $places;
|
||
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');
|
||
|
||
|
||
echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";
|
||
|
||
$val = 4;
|
||
$places = 1;
|
||
$res = $val << $places;
|
||
p($res, $val, '<<', $places, 'zeros fill in right side');
|
||
|
||
$val = 4;
|
||
$places = (PHP_INT_SIZE * 8) - 4;
|
||
$res = $val << $places;
|
||
p($res, $val, '<<', $places);
|
||
|
||
$val = 4;
|
||
$places = (PHP_INT_SIZE * 8) - 3;
|
||
$res = $val << $places;
|
||
p($res, $val, '<<', $places, 'sign bits get shifted out');
|
||
|
||
$val = 4;
|
||
$places = (PHP_INT_SIZE * 8) - 2;
|
||
$res = $val << $places;
|
||
p($res, $val, '<<', $places, 'bits shift out left side');
|
||
|
||
|
||
echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";
|
||
|
||
$val = -4;
|
||
$places = 1;
|
||
$res = $val << $places;
|
||
p($res, $val, '<<', $places, 'zeros fill in right side');
|
||
|
||
$val = -4;
|
||
$places = (PHP_INT_SIZE * 8) - 3;
|
||
$res = $val << $places;
|
||
p($res, $val, '<<', $places);
|
||
|
||
$val = -4;
|
||
$places = (PHP_INT_SIZE * 8) - 2;
|
||
$res = $val << $places;
|
||
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');
|
||
|
||
|
||
/*
|
||
* Ignore this bottom section,
|
||
* it is just formatting to make output clearer.
|
||
*/
|
||
|
||
function p($res, $val, $op, $places, $note = '') {
|
||
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";
|
||
|
||
printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);
|
||
|
||
echo " Decimal:\n";
|
||
printf(" val=%d\n", $val);
|
||
printf(" res=%d\n", $res);
|
||
|
||
echo " Binary:\n";
|
||
printf(' val=' . $format, $val);
|
||
printf(' res=' . $format, $res);
|
||
|
||
if ($note) {
|
||
echo " NOTE: $note\n";
|
||
}
|
||
|
||
echo "\n\n";
|
||
}
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
class MyClass
|
||
{
|
||
}
|
||
|
||
class NotMyClass
|
||
{
|
||
}
|
||
$a = new MyClass;
|
||
|
||
var_dump($a instanceof MyClass);
|
||
var_dump($a instanceof NotMyClass);
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
class ParentClass
|
||
{
|
||
}
|
||
|
||
class MyClass extends ParentClass
|
||
{
|
||
}
|
||
|
||
$a = new MyClass;
|
||
|
||
var_dump($a instanceof MyClass);
|
||
var_dump($a instanceof ParentClass);
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
class MyClass
|
||
{
|
||
}
|
||
|
||
$a = new MyClass;
|
||
var_dump(!($a instanceof stdClass));
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
interface MyInterface
|
||
{
|
||
}
|
||
|
||
class MyClass implements MyInterface
|
||
{
|
||
}
|
||
|
||
$a = new MyClass;
|
||
|
||
var_dump($a instanceof MyClass);
|
||
var_dump($a instanceof MyInterface);
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
interface MyInterface
|
||
{
|
||
}
|
||
|
||
class MyClass implements MyInterface
|
||
{
|
||
}
|
||
|
||
$a = new MyClass;
|
||
$b = new MyClass;
|
||
$c = 'MyClass';
|
||
$d = 'NotMyClass';
|
||
|
||
var_dump($a instanceof $b); // $b is an object of class MyClass
|
||
var_dump($a instanceof $c); // $c is a string 'MyClass'
|
||
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
$a = 1;
|
||
$b = NULL;
|
||
$c = fopen('/tmp/', 'r');
|
||
var_dump($a instanceof stdClass); // $a is an integer
|
||
var_dump($b instanceof stdClass); // $b is NULL
|
||
var_dump($c instanceof stdClass); // $c is a resource
|
||
var_dump(FALSE instanceof stdClass);
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
var_dump(FALSE instanceof stdClass);
|
||
?>
|
||
|
||
--- Source: type.xml ---
|
||
<?php
|
||
|
||
class ClassA extends \stdClass {}
|
||
class ClassB extends \stdClass {}
|
||
class ClassC extends ClassB {}
|
||
class ClassD extends ClassA {}
|
||
|
||
function getSomeClass(): string
|
||
{
|
||
return ClassA::class;
|
||
}
|
||
|
||
var_dump(new ClassA instanceof ('std' . 'Class'));
|
||
var_dump(new ClassB instanceof ('Class' . 'B'));
|
||
var_dump(new ClassC instanceof ('Class' . 'A'));
|
||
var_dump(new ClassD instanceof (getSomeClass()));
|
||
?>
|
||
|
||
--- Source: logical.xml ---
|
||
<?php
|
||
|
||
// --------------------
|
||
// foo() will never get called as those operators are short-circuit
|
||
|
||
$a = (false && foo());
|
||
$b = (true || foo());
|
||
$c = (false and foo());
|
||
$d = (true or foo());
|
||
|
||
// --------------------
|
||
// "||" has a greater precedence than "or"
|
||
|
||
// The result of the expression (false || true) is assigned to $e
|
||
// Acts like: ($e = (false || true))
|
||
$e = false || true;
|
||
|
||
// The constant false is assigned to $f before the "or" operation occurs
|
||
// Acts like: (($f = false) or true)
|
||
$f = false or true;
|
||
|
||
var_dump($e, $f);
|
||
|
||
// --------------------
|
||
// "&&" has a greater precedence than "and"
|
||
|
||
// The result of the expression (true && false) is assigned to $g
|
||
// Acts like: ($g = (true && false))
|
||
$g = true && false;
|
||
|
||
// The constant true is assigned to $h before the "and" operation occurs
|
||
// Acts like: (($h = true) and false)
|
||
$h = true and false;
|
||
|
||
var_dump($g, $h);
|
||
?>
|
||
|
||
--- Source: arithmetic.xml ---
|
||
<?php
|
||
var_dump(5 % 3);
|
||
var_dump(5 % -3);
|
||
var_dump(-5 % 3);
|
||
var_dump(-5 % -3);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$a = array("a" => "apple", "b" => "banana");
|
||
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
|
||
|
||
$c = $a + $b; // Union of $a and $b
|
||
echo "Union of \$a and \$b: \n";
|
||
var_dump($c);
|
||
|
||
$c = $b + $a; // Union of $b and $a
|
||
echo "Union of \$b and \$a: \n";
|
||
var_dump($c);
|
||
|
||
$a += $b; // Union of $a += $b is $a and $b
|
||
echo "Union of \$a += \$b: \n";
|
||
var_dump($a);
|
||
?>
|
||
|
||
--- Source: array.xml ---
|
||
<?php
|
||
$a = array("apple", "banana");
|
||
$b = array(1 => "banana", "0" => "apple");
|
||
|
||
var_dump($a == $b); // bool(true)
|
||
var_dump($a === $b); // bool(false)
|
||
?>
|
||
|
||
--- Source: execution.xml ---
|
||
<?php
|
||
$output = `ls -al`;
|
||
echo "<pre>$output</pre>";
|
||
?>
|
||
|
||
--- Source: functional.xml ---
|
||
<?php
|
||
$result = "Hello World" |> strlen(...);
|
||
echo $result, PHP_EOL;
|
||
|
||
$result = strlen("Hello World");
|
||
echo $result, PHP_EOL;
|
||
?>
|
||
|
||
--- Source: functional.xml ---
|
||
<?php
|
||
$result = "PHP Rocks"
|
||
|> htmlentities(...)
|
||
|> str_split(...)
|
||
|> (fn($x) => array_map(strtoupper(...), $x))
|
||
|> (fn($x) => array_filter($x, fn($v) => $v != 'O'))
|
||
;
|
||
print_r($result);
|
||
|
||
$temp = "PHP Rocks";
|
||
$temp = htmlentities($temp);
|
||
$temp = str_split($temp);
|
||
$temp = array_map(strtoupper(...), $temp);
|
||
$temp = array_filter($temp, fn($v) => $v != 'O');
|
||
$result = $temp;
|
||
print_r($result);
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
var_dump(0 == "a");
|
||
var_dump("1" == "01");
|
||
var_dump("10" == "1e1");
|
||
var_dump(100 == "1e2");
|
||
|
||
switch ("a") {
|
||
case 0:
|
||
echo "0";
|
||
break;
|
||
case "a":
|
||
echo "a";
|
||
break;
|
||
}
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
// Integers
|
||
echo 1 <=> 1, ' '; // 0
|
||
echo 1 <=> 2, ' '; // -1
|
||
echo 2 <=> 1, ' '; // 1
|
||
|
||
// Floats
|
||
echo 1.5 <=> 1.5, ' '; // 0
|
||
echo 1.5 <=> 2.5, ' '; // -1
|
||
echo 2.5 <=> 1.5, ' '; // 1
|
||
|
||
// Strings
|
||
echo "a" <=> "a", ' '; // 0
|
||
echo "a" <=> "b", ' '; // -1
|
||
echo "b" <=> "a", ' '; // 1
|
||
|
||
echo "a" <=> "aa", ' '; // -1
|
||
echo "zz" <=> "aa", ' '; // 1
|
||
|
||
// Arrays
|
||
echo [] <=> [], ' '; // 0
|
||
echo [1, 2, 3] <=> [1, 2, 3], ' '; // 0
|
||
echo [1, 2, 3] <=> [], ' '; // 1
|
||
echo [1, 2, 3] <=> [1, 2, 1], ' '; // 1
|
||
echo [1, 2, 3] <=> [1, 2, 4], ' '; // -1
|
||
|
||
// Objects
|
||
$a = (object) ["a" => "b"];
|
||
$b = (object) ["a" => "b"];
|
||
echo $a <=> $b, ' '; // 0
|
||
|
||
$a = (object) ["a" => "b"];
|
||
$b = (object) ["a" => "c"];
|
||
echo $a <=> $b, ' '; // -1
|
||
|
||
$a = (object) ["a" => "c"];
|
||
$b = (object) ["a" => "b"];
|
||
echo $a <=> $b, ' '; // 1
|
||
|
||
// not only values are compared; keys must match
|
||
$a = (object) ["a" => "b"];
|
||
$b = (object) ["b" => "b"];
|
||
echo $a <=> $b, ' '; // 1
|
||
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
// Bool and null are compared as bool always
|
||
var_dump(1 == TRUE); // TRUE - same as (bool) 1 == TRUE
|
||
var_dump(0 == FALSE); // TRUE - same as (bool) 0 == FALSE
|
||
var_dump(100 < TRUE); // FALSE - same as (bool) 100 < TRUE
|
||
var_dump(-10 < FALSE);// FALSE - same as (bool) -10 < FALSE
|
||
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool) NULL < (bool) -100 is FALSE < TRUE
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
// Arrays are compared like this with standard comparison operators as well as the spaceship operator.
|
||
function standard_array_compare($op1, $op2)
|
||
{
|
||
if (count($op1) < count($op2)) {
|
||
return -1; // $op1 < $op2
|
||
} elseif (count($op1) > count($op2)) {
|
||
return 1; // $op1 > $op2
|
||
}
|
||
foreach ($op1 as $key => $val) {
|
||
if (!array_key_exists($key, $op2)) {
|
||
return 1;
|
||
} elseif ($val < $op2[$key]) {
|
||
return -1;
|
||
} elseif ($val > $op2[$key]) {
|
||
return 1;
|
||
}
|
||
}
|
||
return 0; // $op1 == $op2
|
||
}
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
// Example usage for: Ternary Operator
|
||
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
|
||
|
||
// The above is identical to this if/else statement
|
||
if (empty($_POST['action'])) {
|
||
$action = 'default';
|
||
} else {
|
||
$action = $_POST['action'];
|
||
}
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
// on first glance, the following appears to output 'true'
|
||
echo (true ? 'true' : false ? 't' : 'f');
|
||
|
||
// however, the actual output of the above is 't' prior to PHP 8.0.0
|
||
// this is because ternary expressions are left-associative
|
||
|
||
// the following is a more obvious version of the same code as above
|
||
echo ((true ? 'true' : false) ? 't' : 'f');
|
||
|
||
// here, one can see that the first expression is evaluated to 'true', which
|
||
// in turn evaluates to (bool) true, thus returning the true branch of the
|
||
// second ternary expression.
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
|
||
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2
|
||
echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
// Example usage for: Null Coalesce Operator
|
||
$action = $_POST['action'] ?? 'default';
|
||
|
||
// The above is identical to this if/else statement
|
||
if (isset($_POST['action'])) {
|
||
$action = $_POST['action'];
|
||
} else {
|
||
$action = 'default';
|
||
}
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
// Raises a warning that $name is undefined.
|
||
print 'Mr. ' . $name ?? 'Anonymous';
|
||
|
||
// Prints "Mr. Anonymous"
|
||
print 'Mr. ' . ($name ?? 'Anonymous');
|
||
?>
|
||
|
||
--- Source: comparison.xml ---
|
||
<?php
|
||
|
||
$foo = null;
|
||
$bar = null;
|
||
$baz = 1;
|
||
$qux = 2;
|
||
|
||
echo $foo ?? $bar ?? $baz ?? $qux; // outputs 1
|
||
|
||
?>
|
||
|
||
--- Source: precedence.xml ---
|
||
<?php
|
||
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
|
||
var_dump($a);
|
||
|
||
$a = 1;
|
||
$b = 2;
|
||
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
|
||
var_dump($a, $b);
|
||
?>
|
||
|
||
--- Source: precedence.xml ---
|
||
<?php
|
||
$a = true ? 0 : (true ? 1 : 2);
|
||
var_dump($a);
|
||
|
||
// this is not allowed since PHP 8
|
||
// $a = true ? 0 : true ? 1 : 2;
|
||
?>
|
||
|
||
--- Source: precedence.xml ---
|
||
<?php
|
||
$a = 1;
|
||
echo $a + $a++; // may print either 2 or 3
|
||
|
||
$i = 1;
|
||
$array[$i] = $i++; // may set either index 1 or 2
|
||
?>
|
||
|
||
--- Source: precedence.xml ---
|
||
<?php
|
||
$x = 4;
|
||
// this line might result in unexpected output:
|
||
echo "x minus one equals " . $x-1 . ", or so I hope\n";
|
||
|
||
// the desired precedence can be enforced by using parentheses:
|
||
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
|
||
|
||
// this is not allowed, and throws a TypeError:
|
||
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
|
||
?>
|
||
|
||
--- Source: precedence.xml ---
|
||
<?php
|
||
$x = 4;
|
||
// this line might result in unexpected output:
|
||
echo "x minus one equals " . $x-1 . ", or so I hope\n";
|
||
|
||
// because it is evaluated like this line (prior to PHP 8.0.0):
|
||
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
|
||
|
||
// the desired precedence can be enforced by using parentheses:
|
||
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
|
||
?>
|
||
|
||
--- Source: errorcontrol.xml ---
|
||
<?php
|
||
$my_file = @file ('non_existent_file') or
|
||
die ("Failed opening file: error was '" . error_get_last()['message'] . "'");
|
||
?>
|
||
|
||
--- Source: errorcontrol.xml ---
|
||
<?php
|
||
// this works for any expression, not just functions:
|
||
$value = @$cache[$key];
|
||
// will not issue a notice if the index $key doesn't exist.
|
||
?>
|
||
|
||
--- Source: string.xml ---
|
||
<?php
|
||
$a = "Hello ";
|
||
$b = $a . "World!"; // now $b contains "Hello World!"
|
||
var_dump($b);
|
||
|
||
$a = "Hello ";
|
||
$a .= "World!"; // now $a contains "Hello World!"
|
||
var_dump($a);
|
||
?>
|
||
|
||
--- Source: increment.xml ---
|
||
<?php
|
||
echo 'Post-increment:', PHP_EOL;
|
||
$a = 5;
|
||
var_dump($a++);
|
||
var_dump($a);
|
||
|
||
echo 'Pre-increment:', PHP_EOL;
|
||
$a = 5;
|
||
var_dump(++$a);
|
||
var_dump($a);
|
||
|
||
echo 'Post-decrement:', PHP_EOL;
|
||
$a = 5;
|
||
var_dump($a--);
|
||
var_dump($a);
|
||
|
||
echo 'Pre-decrement:', PHP_EOL;
|
||
$a = 5;
|
||
var_dump(--$a);
|
||
var_dump($a);
|
||
?>
|
||
|
||
--- Source: increment.xml ---
|
||
<?php
|
||
echo '== Alphabetic strings ==' . PHP_EOL;
|
||
$s = 'W';
|
||
for ($n=0; $n<6; $n++) {
|
||
echo ++$s . PHP_EOL;
|
||
}
|
||
// Alphanumeric strings behave differently
|
||
echo '== Alphanumeric strings ==' . PHP_EOL;
|
||
$d = 'A8';
|
||
for ($n=0; $n<6; $n++) {
|
||
echo ++$d . PHP_EOL;
|
||
}
|
||
$d = 'A08';
|
||
for ($n=0; $n<6; $n++) {
|
||
echo ++$d . PHP_EOL;
|
||
}
|
||
?>
|
||
|
||
--- Source: increment.xml ---
|
||
<?php
|
||
$s = "5d9";
|
||
var_dump(++$s);
|
||
var_dump(++$s);
|
||
?>
|
||
|
||
--- Source: assignment.xml ---
|
||
<?php
|
||
$a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.
|
||
var_dump($a);
|
||
?>
|
||
|
||
--- Source: assignment.xml ---
|
||
<?php
|
||
$a = 3;
|
||
$a += 5; // sets $a to 8, as if we had said: $a = $a + 5;
|
||
$b = "Hello ";
|
||
$b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!";
|
||
|
||
var_dump($a, $b);
|
||
?>
|
||
|
||
--- Source: assignment.xml ---
|
||
<?php
|
||
$a = 3;
|
||
$b = &$a; // $b is a reference to $a
|
||
|
||
print "$a\n"; // prints 3
|
||
print "$b\n"; // prints 3
|
||
|
||
$a = 4; // change $a
|
||
|
||
print "$a\n"; // prints 4
|
||
print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has
|
||
// been changed
|
||
?>
|
||
|
||
--- Source: assignment.xml ---
|
||
<?php
|
||
class C {}
|
||
|
||
$o = &new C;
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
class A {
|
||
public static function counter() {
|
||
static $counter = 0;
|
||
$counter++;
|
||
return $counter;
|
||
}
|
||
}
|
||
class B extends A {}
|
||
var_dump(A::counter()); // int(1)
|
||
var_dump(A::counter()); // int(2)
|
||
var_dump(B::counter()); // int(3), previously int(1)
|
||
var_dump(B::counter()); // int(4), previously int(2)
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
function makeyogurt($container = "bowl", $flavour)
|
||
{
|
||
return "Making a $container of $flavour yogurt.\n";
|
||
}
|
||
try
|
||
{
|
||
echo makeyogurt(flavour: "raspberry");
|
||
}
|
||
catch (Error $e)
|
||
{
|
||
echo get_class($e), ' - ', $e->getMessage(), "\n";
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
014; // Non-prefix octal literal
|
||
0o14; // Prefixed octal literal
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$arr1 = [1, 'a' => 'b'];
|
||
$arr2 = [...$arr1, 'c' => 'd']; //[1, 'a' => 'b', 'c' => 'd']
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$file = new CURLStringFile($data, 'filename.txt', 'text/plain');
|
||
curl_setopt($curl, CURLOPT_POSTFIELDS, ['file' => $file]);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$h = hash("murmur3f", $data, options: ["seed" => 42]);
|
||
echo $h, "\n";
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$h = hash("xxh3", $data, options: ["seed" => 42]);
|
||
echo $h, "\n";
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$h = hash("xxh3", $data, options: ["secret" => "at least 136 bytes long secret here"]);
|
||
echo $h, "\n";
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)');
|
||
$stmt->execute([1, $username]);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$result = $mysqli->query('SELECT username FROM users WHERE id = 123');
|
||
echo $result->fetch_column();
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
new PDO('sqlite:file:path/to/sqlite.db?mode=ro')
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
var_dump(str_contains("foobar", null));
|
||
// Deprecated: Passing null to parameter #2 ($needle) of type string
|
||
// is deprecated
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
$a = [];
|
||
$a[15.5]; // deprecated, as key value loses the 0.5 component
|
||
$a[15.0]; // ok, as 15.0 == 15
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function &test(): void {}
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
$arr = false;
|
||
$arr[] = 2; // deprecated
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
// From undefined
|
||
$arr[] = 'some value';
|
||
$arr['doesNotExist'][] = 2;
|
||
// From null
|
||
$arr = null;
|
||
$arr[] = 2;
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
|
||
var_dump(number_format(-0.01)); // now outputs string(1) "0" instead of string(2) "-0"
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
|
||
// array to object
|
||
$arr = [0 => 1];
|
||
$obj = (object) $arr;
|
||
var_dump(
|
||
$obj,
|
||
$obj->{'0'}, // now accessible
|
||
$obj->{0} // now accessible
|
||
);
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
|
||
// object to array
|
||
$obj = new class {
|
||
public function __construct()
|
||
{
|
||
$this->{0} = 1;
|
||
}
|
||
};
|
||
$arr = (array) $obj;
|
||
var_dump(
|
||
$arr,
|
||
$arr[0], // now accessible
|
||
$arr['0'] // now accessible
|
||
);
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
|
||
var_dump(
|
||
count(null), // NULL is not countable
|
||
count(1), // integers are not countable
|
||
count('abc'), // strings are not countable
|
||
count(new stdClass), // objects not implementing the Countable interface are not countable
|
||
count([1,2]) // arrays are countable
|
||
);
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
function test(object $obj) : object
|
||
{
|
||
return new SplQueue();
|
||
}
|
||
|
||
test(new stdClass());
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
abstract class A
|
||
{
|
||
abstract function test(string $s);
|
||
}
|
||
abstract class B extends A
|
||
{
|
||
// overridden - still maintaining contravariance for parameters and covariance for return
|
||
abstract function test($s) : int;
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
$db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL);
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
interface A
|
||
{
|
||
public function Test(array $input);
|
||
}
|
||
|
||
class B implements A
|
||
{
|
||
public function Test($input){} // type omitted for $input
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
use Foo\Bar\{
|
||
Foo,
|
||
Bar,
|
||
Baz,
|
||
};
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
|
||
var_dump(NONEXISTENT);
|
||
|
||
/* Output:
|
||
Warning: Use of undefined constant NONEXISTENT - assumed 'NONEXISTENT' (this will throw an Error in a future version of PHP) in %s on line %d
|
||
string(11) "NONEXISTENT"
|
||
*/
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
$str = <<<FOO
|
||
abcdefg
|
||
FOO
|
||
FOO;
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
while ($foo) {
|
||
switch ($bar) {
|
||
case "baz":
|
||
continue;
|
||
// Warning: "continue" targeting switch is equivalent to
|
||
// "break". Did you mean to use "continue 2"?
|
||
}
|
||
}
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
class Test {
|
||
public static $x = 0;
|
||
}
|
||
class Test2 extends Test { }
|
||
|
||
Test2::$x = &$x;
|
||
$x = 1;
|
||
|
||
var_dump(Test::$x, Test2::$x);
|
||
// Previously: int(0), int(1)
|
||
// Now: int(1), int(1)
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
$arr = [1];
|
||
$ref =& $arr[0];
|
||
var_dump($arr[0] + ($arr[0] = 2));
|
||
// Previously: int(4), Now: int(3)
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
function foo(...$args) {
|
||
var_dump($args);
|
||
}
|
||
function gen() {
|
||
yield 1.23 => 123;
|
||
}
|
||
foo(...gen());
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
mb_strtoupper("Straße");
|
||
// Produces STRAßE on PHP 7.2
|
||
// Produces STRASSE on PHP 7.3
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
mb_ereg('(?<word>\w+)', '国', $matches);
|
||
// => [0 => "国", 1 => "国", "word" => "国"];
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
|
||
// => "_foo_foo_"
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class User {
|
||
public int $id;
|
||
public string $name;
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$factor = 10;
|
||
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
|
||
// $nums = array(10, 20, 30, 40);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class A {}
|
||
class B extends A {}
|
||
|
||
class Producer {
|
||
public function method(): A {}
|
||
}
|
||
class ChildProducer extends Producer {
|
||
public function method(): B {}
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
/**
|
||
* These classes satisfy the LSP requirements, because C is a subtype of A.
|
||
* However, at the time class B is declared, class C is not yet available
|
||
*/
|
||
class A
|
||
{
|
||
public function method(): A {}
|
||
}
|
||
|
||
class B extends A
|
||
{
|
||
// Fatal error: Could not check compatibility between B::method():C and
|
||
// A::method(): A, because class С is not available
|
||
public function method(): С {}
|
||
}
|
||
|
||
class C extends B {}
|
||
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$array['key'] ??= computeDefault();
|
||
// is roughly equivalent to
|
||
if (!isset($array['key'])) {
|
||
$array['key'] = computeDefault();
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$parts = ['apple', 'pear'];
|
||
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
|
||
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
6.674_083e-11; // float
|
||
299_792_458; // decimal
|
||
0xCAFE_F00D; // hexadecimal
|
||
0b0101_1111; // binary
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
// Returns array containing all the necessary state of the object.
|
||
public function __serialize(): array
|
||
{
|
||
}
|
||
|
||
// Restores the object state from the given data array.
|
||
public function __unserialize(array $data): void
|
||
{
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
proc_open(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
// Like 2>&1 on the shell
|
||
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
|
||
// Like 2>/dev/null or 2>nul on the shell
|
||
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
1 ? 2 : 3 ? 4 : 5; // deprecated
|
||
(1 ? 2 : 3) ? 4 : 5; // ok
|
||
1 ? 2 : (3 ? 4 : 5); // ok
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
1 ? 2 ? 3 : 4 : 5 // ok
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
// ReflectionClass::export(Foo::class, false) is:
|
||
echo new ReflectionClass(Foo::class), "\n";
|
||
|
||
// $str = ReflectionClass::export(Foo::class, true) is:
|
||
$str = (string) new ReflectionClass(Foo::class);
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
// Replace
|
||
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
|
||
if (error_reporting() == 0) {
|
||
return false;
|
||
}
|
||
// ...
|
||
}
|
||
|
||
// With
|
||
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
|
||
if (!(error_reporting() & $err_no)) {
|
||
return false;
|
||
}
|
||
// ...
|
||
}
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
echo "Sum: " . $a + $b;
|
||
// was previously interpreted as:
|
||
echo ("Sum: " . $a) + $b;
|
||
// is now interpreted as:
|
||
echo "Sum:" . ($a + $b);
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
// Replace
|
||
function test(int $arg = CONST_RESOLVING_TO_NULL) {}
|
||
// With
|
||
function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
|
||
// Or
|
||
function test(int $arg = null) {}
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
new class extends ParentClass {};
|
||
// -> ParentClass@anonymous
|
||
new class implements FirstInterface, SecondInterface {};
|
||
// -> FirstInterface@anonymous
|
||
new class {};
|
||
// -> class@anonymous
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
class X {
|
||
use T1, T2 {
|
||
func as otherFunc;
|
||
}
|
||
function func() {}
|
||
}
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
trait MyTrait {
|
||
abstract private function neededByTrait(): string;
|
||
}
|
||
|
||
class MyClass {
|
||
use MyTrait;
|
||
|
||
// Error, because of return type mismatch.
|
||
private function neededByTrait(): int { return 42; }
|
||
}
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
setlocale(LC_ALL, "de_DE");
|
||
$f = 3.14;
|
||
echo $f, "\n";
|
||
// Previously: 3,14
|
||
// Now: 3.14
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
// Instead of:
|
||
$array{0};
|
||
$array{"key"};
|
||
// Write:
|
||
$array[0];
|
||
$array["key"];
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
$ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]);
|
||
echo file_get_contents('http://example.org', false, $ctx);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class A {
|
||
public function method(int $many, string $parameters, $here) {}
|
||
}
|
||
class B extends A {
|
||
public function method(...$everything) {}
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class Test {
|
||
public function create(): static {
|
||
return new static();
|
||
}
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$fn = fn() => throw new Exception('Exception in arrow function');
|
||
$user = $session->user ?? throw new Exception('Must have user');
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
function functionWithLongSignature(
|
||
Type1 $parameter1,
|
||
Type2 $parameter2, // <-- This comma is now allowed.
|
||
) {
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class ParentClass {
|
||
private function method1() {}
|
||
private function method2() {}
|
||
private static function method3() {}
|
||
// Throws a warning, as "final" no longer has an effect:
|
||
private final function method4() {}
|
||
}
|
||
class ChildClass extends ParentClass {
|
||
// All of the following are now allowed, even though the modifiers aren't
|
||
// the same as for the private methods in the parent class.
|
||
public abstract function method1() {}
|
||
public static function method2() {}
|
||
public function method3() {}
|
||
public function method4() {}
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
printf("%.*H", (int) ini_get("precision"), $float);
|
||
printf("%.*H", (int) ini_get("serialize_precision"), $float);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$proc = proc_open($command, [['pty'], ['pty'], ['pty']], $pipes);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$proc = proc_open($command, [['socket'], ['socket'], ['socket']], $pipes);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
// OK even if $excludes is empty:
|
||
array_diff($array, ...$excludes);
|
||
// OK even if $arrays only contains a single array:
|
||
array_intersect(...$arrays);
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function test($a = [], $b) {} // Before
|
||
function test($a, $b) {} // After
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function test(A $a = null, $b) {} // Still allowed
|
||
function test(?A $a, $b) {} // Recommended
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
// Replace
|
||
usort($array, fn($a, $b) => $a > $b);
|
||
// With
|
||
usort($array, fn($a, $b) => $a <=> $b);
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
// iterate using the procedural API
|
||
assert(is_resource($zip));
|
||
while ($entry = zip_read($zip)) {
|
||
echo zip_entry_name($entry);
|
||
}
|
||
|
||
// iterate using the object-oriented API
|
||
assert($zip instanceof ZipArchive);
|
||
for ($i = 0; $entry = $zip->statIndex($i); $i++) {
|
||
echo $entry['name'];
|
||
}
|
||
?>
|
||
|
||
--- Source: openssl.xml ---
|
||
<?php
|
||
$ctx = stream_context_create(['ssl' => [
|
||
'capture_session_meta' => TRUE
|
||
]]);
|
||
|
||
$html = file_get_contents('https://google.com/', FALSE, $ctx);
|
||
$meta = stream_context_get_options($ctx)['ssl']['session_meta'];
|
||
var_dump($meta);
|
||
?>
|
||
|
||
--- Source: openssl.xml ---
|
||
openssl dhparam -out /path/to/my/certs/dh-2048.pem 2048
|
||
|
||
--- Source: openssl.xml ---
|
||
<?php
|
||
|
||
// Requiring TLS 1.0 or better when using file_get_contents():
|
||
$ctx = stream_context_create([
|
||
'ssl' => [
|
||
'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT,
|
||
],
|
||
]);
|
||
$html = file_get_contents('https://google.com/', false, $ctx);
|
||
|
||
// Requiring TLS 1.1 or 1.2:
|
||
$ctx = stream_context_create([
|
||
'ssl' => [
|
||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT |
|
||
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
|
||
],
|
||
]);
|
||
$html = file_get_contents('https://google.com/', false, $ctx);
|
||
|
||
// Connecting using the tlsv1.2:// stream socket transport.
|
||
$sock = stream_socket_client('tlsv1.2://google.com:443/');
|
||
|
||
?>
|
||
|
||
--- Source: openssl.xml ---
|
||
<?php
|
||
var_dump(openssl_get_cert_locations());
|
||
?>
|
||
|
||
--- Source: openssl.xml ---
|
||
<?php
|
||
$pkey = openssl_pkey_new();
|
||
openssl_pkey_export($pkey, 'secret passphrase');
|
||
|
||
$spkac = openssl_spki_new($pkey, 'challenge string');
|
||
?>
|
||
|
||
--- Source: openssl.xml ---
|
||
<?php
|
||
$pkey = openssl_pkey_new();
|
||
openssl_pkey_export($pkey, 'secret passphrase');
|
||
|
||
$spkac = openssl_spki_new($pkey, 'challenge string');
|
||
var_dump(openssl_spki_verify($spkac));
|
||
?>
|
||
|
||
--- Source: openssl.xml ---
|
||
<?php
|
||
$pkey = openssl_pkey_new();
|
||
openssl_pkey_export($pkey, 'secret passphrase');
|
||
|
||
$spkac = openssl_spki_new($pkey, 'challenge string');
|
||
$challenge = openssl_spki_export_challenge($spkac);
|
||
echo $challenge;
|
||
?>
|
||
|
||
--- Source: openssl.xml ---
|
||
<?php
|
||
$pkey = openssl_pkey_new();
|
||
openssl_pkey_export($pkey, 'secret passphrase');
|
||
|
||
$spkac = openssl_spki_new($pkey, 'challenge string');
|
||
echo openssl_spki_export($spkac);
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
class C {
|
||
const ONE = 1;
|
||
public $array = [
|
||
self::ONE => 'foo',
|
||
'bar',
|
||
'quux',
|
||
];
|
||
}
|
||
|
||
var_dump((new C)->array);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
const ONE = 1;
|
||
const TWO = ONE * 2;
|
||
|
||
class C {
|
||
const THREE = TWO + 1;
|
||
const ONE_THIRD = ONE / self::THREE;
|
||
const SENTENCE = 'The value of THREE is '.self::THREE;
|
||
|
||
public function f($a = ONE + self::THREE) {
|
||
return $a;
|
||
}
|
||
}
|
||
|
||
echo (new C)->f()."\n";
|
||
echo C::SENTENCE;
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
const ARR = ['a', 'b'];
|
||
|
||
echo ARR[0];
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
function f($req, $opt = null, ...$params) {
|
||
// $params is an array containing the remaining arguments.
|
||
printf('$req: %d; $opt: %d; number of params: %d'."\n",
|
||
$req, $opt, count($params));
|
||
}
|
||
|
||
f(1);
|
||
f(1, 2);
|
||
f(1, 2, 3);
|
||
f(1, 2, 3, 4);
|
||
f(1, 2, 3, 4, 5);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
function add($a, $b, $c) {
|
||
return $a + $b + $c;
|
||
}
|
||
|
||
$operators = [2, 3];
|
||
echo add(1, ...$operators);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
printf("2 ** 3 == %d\n", 2 ** 3);
|
||
printf("2 ** 3 ** 2 == %d\n", 2 ** 3 ** 2);
|
||
|
||
$a = 2;
|
||
$a **= 3;
|
||
printf("a == %d\n", $a);
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
namespace Name\Space {
|
||
const FOO = 42;
|
||
function f() { echo __FUNCTION__."\n"; }
|
||
}
|
||
|
||
namespace {
|
||
use const Name\Space\FOO;
|
||
use function Name\Space\f;
|
||
|
||
echo FOO."\n";
|
||
f();
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$a = gmp_init(42);
|
||
$b = gmp_init(17);
|
||
|
||
if (version_compare(PHP_VERSION, '5.6', '<')) {
|
||
echo gmp_intval(gmp_add($a, $b)), PHP_EOL;
|
||
echo gmp_intval(gmp_add($a, 17)), PHP_EOL;
|
||
echo gmp_intval(gmp_add(42, $b)), PHP_EOL;
|
||
} else {
|
||
echo $a + $b, PHP_EOL;
|
||
echo $a + 17, PHP_EOL;
|
||
echo 42 + $b, PHP_EOL;
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$expected = crypt('12345', '$2a$07$usesomesillystringforsalt$');
|
||
$correct = crypt('12345', '$2a$07$usesomesillystringforsalt$');
|
||
$incorrect = crypt('1234', '$2a$07$usesomesillystringforsalt$');
|
||
|
||
var_dump(hash_equals($expected, $correct));
|
||
var_dump(hash_equals($expected, $incorrect));
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class C {
|
||
private $prop;
|
||
|
||
public function __construct($val) {
|
||
$this->prop = $val;
|
||
}
|
||
|
||
public function __debugInfo() {
|
||
return [
|
||
'propSquared' => $this->prop ** 2,
|
||
];
|
||
}
|
||
}
|
||
|
||
var_dump(new C(42));
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
class A {
|
||
function f() { echo get_class($this); }
|
||
}
|
||
|
||
class B {
|
||
function f() { A::f(); }
|
||
}
|
||
|
||
(new B)->f();
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
function test($param){}
|
||
test();
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
(function () {
|
||
$func = 'func_num_args';
|
||
$func();
|
||
})();
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
$a = '';
|
||
$a[10] = 'foo';
|
||
var_dump($a);
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
$array = [];
|
||
$array["a"] =& $array["b"];
|
||
$array["b"] = 1;
|
||
var_dump($array);
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
new DateTime() == new DateTime();
|
||
?>
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
$f = function () use ($_SERVER) {};
|
||
$f = function () use ($this) {};
|
||
$f = function ($param) use ($param) {};
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
var_dump(json_decode(json_encode(['' => 1])));
|
||
|
||
--- Source: other-changes.xml ---
|
||
<?php
|
||
'1b' + 'something';
|
||
|
||
--- Source: other-changes.xml ---
|
||
<?php
|
||
var_dump("\500");
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
function testReturnA(): ?string
|
||
{
|
||
return 'elePHPant';
|
||
}
|
||
|
||
var_dump(testReturnA());
|
||
|
||
function testReturnB(): ?string
|
||
{
|
||
return null;
|
||
}
|
||
|
||
var_dump(testReturnB());
|
||
|
||
function test(?string $name)
|
||
{
|
||
var_dump($name);
|
||
}
|
||
|
||
test('elePHPant');
|
||
test(null);
|
||
test();
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
function swap(&$left, &$right): void
|
||
{
|
||
if ($left === $right) {
|
||
return;
|
||
}
|
||
|
||
$tmp = $left;
|
||
$left = $right;
|
||
$right = $tmp;
|
||
}
|
||
|
||
$a = 1;
|
||
$b = 2;
|
||
var_dump(swap($a, $b), $a, $b);
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$data = [
|
||
[1, 'Tom'],
|
||
[2, 'Fred'],
|
||
];
|
||
|
||
// list() style
|
||
list($id1, $name1) = $data[0];
|
||
|
||
// [] style
|
||
[$id1, $name1] = $data[0];
|
||
|
||
// list() style
|
||
foreach ($data as list($id, $name)) {
|
||
// logic here with $id and $name
|
||
}
|
||
|
||
// [] style
|
||
foreach ($data as [$id, $name]) {
|
||
// logic here with $id and $name
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class ConstDemo
|
||
{
|
||
const PUBLIC_CONST_A = 1;
|
||
public const PUBLIC_CONST_B = 2;
|
||
protected const PROTECTED_CONST = 3;
|
||
private const PRIVATE_CONST = 4;
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
function iterator(iterable $iter)
|
||
{
|
||
foreach ($iter as $val) {
|
||
//
|
||
}
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
try {
|
||
// some code
|
||
} catch (FirstException | SecondException $e) {
|
||
// handle first and second exceptions
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$data = [
|
||
["id" => 1, "name" => 'Tom'],
|
||
["id" => 2, "name" => 'Fred'],
|
||
];
|
||
|
||
// list() style
|
||
list("id" => $id1, "name" => $name1) = $data[0];
|
||
|
||
// [] style
|
||
["id" => $id1, "name" => $name1] = $data[0];
|
||
|
||
// list() style
|
||
foreach ($data as list("id" => $id, "name" => $name)) {
|
||
// logic here with $id and $name
|
||
}
|
||
|
||
// [] style
|
||
foreach ($data as ["id" => $id, "name" => $name]) {
|
||
// logic here with $id and $name
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
var_dump("abcdef"[-2]);
|
||
var_dump(strpos("aabbcc", "b", -3));
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$string = 'bar';
|
||
echo "The last character of '$string' is '$string[-1]'.\n";
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class Test
|
||
{
|
||
public function exposeFunction()
|
||
{
|
||
return Closure::fromCallable([$this, 'privateFunction']);
|
||
}
|
||
|
||
private function privateFunction($param)
|
||
{
|
||
var_dump($param);
|
||
}
|
||
}
|
||
|
||
$privFunc = (new Test)->exposeFunction();
|
||
$privFunc('some value');
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
pcntl_async_signals(true); // turn on async signals
|
||
|
||
pcntl_signal(SIGHUP, function($sig) {
|
||
echo "SIGHUP\n";
|
||
});
|
||
|
||
posix_kill(posix_getpid(), SIGHUP);
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
$result = "Hello World" |> strlen(...);
|
||
print $result . PHP_EOL; // Prints "11"
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
#[\NoDiscard]
|
||
function concat(string $a, string $b): string {
|
||
return $a . $b;
|
||
}
|
||
|
||
// Warning: The return value of function concat() should either be used or
|
||
// intentionally ignored by casting it as (void) in xxx.php
|
||
concat("a", "b");
|
||
|
||
// No warning, because the return value is consumed by the assignment.
|
||
$results = concat("a", "b");
|
||
|
||
// No warning, because the (void) cast is used.
|
||
(void)concat("a", "b");
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
const T1 = (int) 0.3; // Previously: "Fatal error: Constant expression contains invalid operations"
|
||
print T1 . PHP_EOL; // Prints "0"
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
range('9', 'A'); // ["9", ":", ";", "<", "=", ">", "?", "@", "A"], as of PHP 8.3.0
|
||
range('9', 'A'); // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], prior to PHP 8.3.0
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
/*
|
||
On /path/to/user.ini contains the following settings:
|
||
|
||
listen = localhost:${DRUPAL_FPM_PORT:-9000}
|
||
*/
|
||
|
||
$user_ini = parse_ini_file('/path/to/user.ini');
|
||
echo $user_ini['listen']; // localhost:9000
|
||
|
||
--- Source: incompatible.xml ---
|
||
<?php
|
||
|
||
$xmlString = "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
|
||
$xml = simplexml_load_string($xmlString);
|
||
|
||
$nodes = $xml->a->b;
|
||
foreach ($nodes as $nodeData) {
|
||
echo "nodeData: " . $nodeData . "\n";
|
||
|
||
$xml = $nodes->asXml();
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class Person
|
||
{
|
||
// A "virtual" property. It may not be set explicitly.
|
||
public string $fullName {
|
||
get => $this->firstName . ' ' . $this->lastName;
|
||
}
|
||
|
||
// All write operations go through this hook, and the result is what is written.
|
||
// Read access happens normally.
|
||
public string $firstName {
|
||
set => ucfirst(strtolower($value));
|
||
}
|
||
|
||
// All write operations go through this hook, which has to write to the backing value itself.
|
||
// Read access happens normally.
|
||
public string $lastName {
|
||
set {
|
||
if (strlen($value) < 2) {
|
||
throw new \InvalidArgumentException('Too short');
|
||
}
|
||
$this->lastName = $value;
|
||
}
|
||
}
|
||
}
|
||
|
||
$p = new Person();
|
||
|
||
$p->firstName = 'peter';
|
||
print $p->firstName; // Prints "Peter"
|
||
$p->lastName = 'Peterson';
|
||
print $p->fullName; // Prints "Peter Peterson"
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class Example
|
||
{
|
||
// The first visibility modifier controls the get-visibility, and the second modifier
|
||
// controls the set-visibility. The get-visibility must not be narrower than set-visibility.
|
||
public protected(set) string $name;
|
||
|
||
public function __construct(string $name)
|
||
{
|
||
$this->name = $name;
|
||
}
|
||
}
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class Example
|
||
{
|
||
public function __construct(private int $data)
|
||
{
|
||
}
|
||
|
||
// ...
|
||
}
|
||
|
||
$initializer = static function (Example $ghost): void {
|
||
// Fetch data or dependencies
|
||
$data = getData();
|
||
// Initialize
|
||
$ghost->__construct($data);
|
||
};
|
||
|
||
$reflector = new ReflectionClass(Example::class);
|
||
$object = $reflector->newLazyGhost($initializer);
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function foo(T1 $a = null) {}
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function foo(T1|null $a = null) {}
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function foo(?T1 $a = null) {}
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function foo(T1 $a, T2 $b = null, T3 $c) {}
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function foo(T1 $a, T2|null $b, T3 $c) {}
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
function foo(T1 $a, ?T2 $b, T3 $c) {}
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
class _ {}
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
class _MyClass {}
|
||
|
||
--- Source: other-changes.xml ---
|
||
<?php
|
||
// 'new', 'private', and 'for' were previously unusable
|
||
Project::new('Project Name')->private()->for('purpose here')->with('username here');
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
// Coercive mode
|
||
function sumOfInts(int ...$ints)
|
||
{
|
||
return array_sum($ints);
|
||
}
|
||
|
||
var_dump(sumOfInts(2, '3', 4.1));
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
function arraysSum(array ...$arrays): array
|
||
{
|
||
return array_map(function(array $array): int {
|
||
return array_sum($array);
|
||
}, $arrays);
|
||
}
|
||
|
||
print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
// Fetches the value of $_GET['user'] and returns 'nobody'
|
||
// if it does not exist.
|
||
$username = $_GET['user'] ?? 'nobody';
|
||
// This is equivalent to:
|
||
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
|
||
|
||
// Coalescing can be chained: this will return the first
|
||
// defined value out of $_GET['user'], $_POST['user'], and
|
||
// 'nobody'.
|
||
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
// Integers
|
||
echo 1 <=> 1; // 0
|
||
echo 1 <=> 2; // -1
|
||
echo 2 <=> 1; // 1
|
||
|
||
// Floats
|
||
echo 1.5 <=> 1.5; // 0
|
||
echo 1.5 <=> 2.5; // -1
|
||
echo 2.5 <=> 1.5; // 1
|
||
|
||
// Strings
|
||
echo "a" <=> "a"; // 0
|
||
echo "a" <=> "b"; // -1
|
||
echo "b" <=> "a"; // 1
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
define('ANIMALS', [
|
||
'dog',
|
||
'cat',
|
||
'bird'
|
||
]);
|
||
|
||
echo ANIMALS[1]; // outputs "cat"
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
interface Logger {
|
||
public function log(string $msg);
|
||
}
|
||
|
||
class Application {
|
||
private $logger;
|
||
|
||
public function getLogger(): Logger {
|
||
return $this->logger;
|
||
}
|
||
|
||
public function setLogger(Logger $logger) {
|
||
$this->logger = $logger;
|
||
}
|
||
}
|
||
|
||
$app = new Application;
|
||
$app->setLogger(new class implements Logger {
|
||
public function log(string $msg) {
|
||
echo $msg;
|
||
}
|
||
});
|
||
|
||
var_dump($app->getLogger());
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
echo "\u{aa}", PHP_EOL;
|
||
echo "\u{0000aa}", PHP_EOL;
|
||
|
||
echo "\u{9999}", PHP_EOL;
|
||
|
||
echo <<<EOT
|
||
\u{01f418}
|
||
EOT;
|
||
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
class A {private $x = 1;}
|
||
|
||
// Pre PHP 7 code
|
||
$getX = function() {return $this->x;};
|
||
$getXCB = $getX->bindTo(new A, 'A'); // intermediate closure
|
||
echo $getXCB();
|
||
|
||
// PHP 7+ code
|
||
$getX = function() {return $this->x;};
|
||
echo $getX->call(new A);
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
// converts all objects into __PHP_Incomplete_Class object
|
||
$data = unserialize($foo, ["allowed_classes" => false]);
|
||
|
||
// converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
|
||
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);
|
||
|
||
// default behaviour (same as omitting the second argument) that accepts all classes
|
||
$data = unserialize($foo, ["allowed_classes" => true]);
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
printf('%x', IntlChar::CODEPOINT_MAX);
|
||
echo IntlChar::charName('@');
|
||
var_dump(IntlChar::ispunct('!'));
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
ini_set('assert.exception', 1);
|
||
|
||
class CustomError extends AssertionError {}
|
||
|
||
assert(false, new CustomError('Some error message'));
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
// Pre PHP 7 code
|
||
use some\namespace\ClassA;
|
||
use some\namespace\ClassB;
|
||
use some\namespace\ClassC as C;
|
||
|
||
use function some\namespace\fn_a;
|
||
use function some\namespace\fn_b;
|
||
use function some\namespace\fn_c;
|
||
|
||
use const some\namespace\ConstA;
|
||
use const some\namespace\ConstB;
|
||
use const some\namespace\ConstC;
|
||
|
||
// PHP 7+ code
|
||
use some\namespace\{ClassA, ClassB, ClassC as C};
|
||
use function some\namespace\{fn_a, fn_b, fn_c};
|
||
use const some\namespace\{ConstA, ConstB, ConstC};
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
|
||
$gen = (function() {
|
||
yield 1;
|
||
yield 2;
|
||
|
||
return 3;
|
||
})();
|
||
|
||
foreach ($gen as $val) {
|
||
echo $val, PHP_EOL;
|
||
}
|
||
|
||
echo $gen->getReturn(), PHP_EOL;
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
function gen()
|
||
{
|
||
yield 1;
|
||
yield 2;
|
||
yield from gen2();
|
||
}
|
||
|
||
function gen2()
|
||
{
|
||
yield 3;
|
||
yield 4;
|
||
}
|
||
|
||
foreach (gen() as $val)
|
||
{
|
||
echo $val, PHP_EOL;
|
||
}
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
var_dump(intdiv(10, 3));
|
||
?>
|
||
|
||
--- Source: new-features.xml ---
|
||
<?php
|
||
session_start([
|
||
'cache_limiter' => 'private',
|
||
'read_and_close' => true,
|
||
]);
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
class foo {
|
||
function foo() {
|
||
echo 'I am the constructor';
|
||
}
|
||
}
|
||
?>
|
||
|
||
--- Source: deprecated.xml ---
|
||
<?php
|
||
class foo {
|
||
function bar() {
|
||
echo 'I am not static!';
|
||
}
|
||
}
|
||
|
||
foo::bar();
|
||
?>
|
||
|
||
--- Source: other.xml ---
|
||
<?php
|
||
class C {}
|
||
$c =& new C;
|
||
?>
|
||
|
||
--- Source: other.xml ---
|
||
<?php
|
||
class A {
|
||
public function test() { var_dump($this); }
|
||
}
|
||
|
||
// Note: Does NOT extend A
|
||
class B {
|
||
public function callNonStaticMethodOfA() { A::test(); }
|
||
}
|
||
|
||
(new B)->callNonStaticMethodOfA();
|
||
?>
|
||
|
||
--- Source: other.xml ---
|
||
<?php
|
||
echo yield -1;
|
||
// Was previously interpreted as
|
||
echo (yield) - 1;
|
||
// And is now interpreted as
|
||
echo yield (-1);
|
||
|
||
yield $foo or die;
|
||
// Was previously interpreted as
|
||
yield ($foo or die);
|
||
// And is now interpreted as
|
||
(yield $foo) or die;
|
||
?>
|
||
|
||
--- Source: other.xml ---
|
||
<?php
|
||
function foo($a, $b, $unused, $unused) {
|
||
//
|
||
}
|
||
?>
|
||
|
||
--- Source: other.xml ---
|
||
<?php
|
||
function foo($x) {
|
||
$x++;
|
||
var_dump(func_get_arg(0));
|
||
}
|
||
foo(1);?>
|
||
|
||
--- Source: other.xml ---
|
||
<?php
|
||
switch (1) {
|
||
default:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
?>
|
||
|
||
--- Source: strings.xml ---
|
||
<?php
|
||
var_dump("0x123" == "291");
|
||
var_dump(is_numeric("0x123"));
|
||
var_dump("0xe" + "0x1");
|
||
var_dump(substr("foo", "0x1"));
|
||
?>
|
||
|
||
--- Source: strings.xml ---
|
||
<?php
|
||
$str = "0xffff";
|
||
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
|
||
if (false === $int) {
|
||
throw new Exception("Invalid integer!");
|
||
}
|
||
var_dump($int); // int(65535)
|
||
?>
|
||
|
||
--- Source: foreach.xml ---
|
||
<?php
|
||
$array = [0, 1, 2];
|
||
foreach ($array as &$val) {
|
||
var_dump(current($array));
|
||
}
|
||
?>
|
||
|
||
--- Source: foreach.xml ---
|
||
<?php
|
||
$array = [0];
|
||
foreach ($array as &$val) {
|
||
var_dump($val);
|
||
$array[1] = 1;
|
||
}
|
||
?>
|
||
|
||
--- Source: variable-handling.xml ---
|
||
<?php
|
||
function f() {
|
||
// Valid in PHP 5 only.
|
||
global $$foo->bar;
|
||
|
||
// Valid in PHP 5 and 7.
|
||
global ${$foo->bar};
|
||
}
|
||
?>
|
||
|
||
--- Source: variable-handling.xml ---
|
||
<?php
|
||
list($a[], $a[], $a[]) = [1, 2, 3];
|
||
var_dump($a);
|
||
?>
|
||
|
||
--- Source: variable-handling.xml ---
|
||
<?php
|
||
list() = $a;
|
||
list(,,) = $a;
|
||
list($x, list(), $y) = $a;
|
||
?>
|
||
|
||
--- Source: variable-handling.xml ---
|
||
<?php
|
||
$array = [];
|
||
$array["a"] =& $array["b"];
|
||
$array["b"] = 1;
|
||
var_dump($array);
|
||
?>
|
||
|
||
--- Source: variable-handling.xml ---
|
||
<?php
|
||
function getArray() {
|
||
return [1, 2, 3];
|
||
}
|
||
|
||
function squareArray(array &$a) {
|
||
foreach ($a as &$v) {
|
||
$v **= 2;
|
||
}
|
||
}
|
||
|
||
// Generates a warning in PHP 7.
|
||
squareArray((getArray()));
|
||
?>
|
||
|
||
--- Source: error-handling.xml ---
|
||
<?php
|
||
// PHP 5 era code that will break.
|
||
function handler(Exception $e) { /* ... */ }
|
||
set_exception_handler('handler');
|
||
|
||
// PHP 5 and 7 compatible.
|
||
function handler($e) { /* ... */ }
|
||
|
||
// PHP 7 only.
|
||
function handler(Throwable $e) { /* ... */ }
|
||
?>
|
||
|
||
--- Source: integers.xml ---
|
||
<?php
|
||
var_dump(1 >> -1);
|
||
?>
|
||
|
||
--- Source: integers.xml ---
|
||
<?php
|
||
var_dump(3/0);
|
||
var_dump(0/0);
|
||
var_dump(0%0);
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
function fact($x)
|
||
{
|
||
$return = 1;
|
||
for ($i=2; $i <= $x; $i++) {
|
||
$return = gmp_mul($return, $i);
|
||
}
|
||
return $return;
|
||
}
|
||
|
||
echo gmp_strval(fact(1000)) . "\n";
|
||
?>
|
||
|
||
--- Source: intl-get-error-message.xml ---
|
||
<?php
|
||
if( Collator::getAvailableLocales() === false ) {
|
||
show_error( intl_get_error_message() );
|
||
}
|
||
?>
|
||
|
||
--- Source: intl-is-failure.xml ---
|
||
<?php
|
||
function check( $err_code )
|
||
{
|
||
var_export( intl_is_failure( $err_code ) );
|
||
echo "\n";
|
||
}
|
||
|
||
check( U_ZERO_ERROR );
|
||
check( U_USING_FALLBACK_WARNING );
|
||
check( U_ILLEGAL_ARGUMENT_ERROR );
|
||
?>
|
||
|
||
--- Source: intl-get-error-code.xml ---
|
||
<?php
|
||
$coll = collator_create( '<bad_param>' );
|
||
if( !$coll ) {
|
||
handle_error( intl_get_error_code() );
|
||
}
|
||
?>
|
||
|
||
--- Source: intl-error-name.xml ---
|
||
<?php
|
||
$coll = collator_create( 'en_RU' );
|
||
$err_code = collator_get_error_code( $coll );
|
||
|
||
printf( "Symbolic name for %d is %s\n.", $err_code, intl_error_name( $err_code ) );
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
$source = file_get_contents('example.php');
|
||
$tokens = token_get_all($source);
|
||
|
||
foreach ($tokens as $token) {
|
||
if (is_string($token)) {
|
||
// simple 1-character token
|
||
echo $token;
|
||
} else {
|
||
// token array
|
||
list($id, $text) = $token;
|
||
|
||
switch ($id) {
|
||
case T_COMMENT:
|
||
case T_DOC_COMMENT:
|
||
// no action on comments
|
||
break;
|
||
|
||
default:
|
||
// anything else -> output "as is"
|
||
echo $text;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
/* Read local file from /home/bar */
|
||
$localfile = file_get_contents("/home/bar/foo.txt");
|
||
|
||
/* Identical to above, explicitly naming FILE scheme */
|
||
$localfile = file_get_contents("file:///home/bar/foo.txt");
|
||
|
||
/* Read remote file from www.example.com using HTTP */
|
||
$httpfile = file_get_contents("http://www.example.com/foo.txt");
|
||
|
||
/* Read remote file from www.example.com using HTTPS */
|
||
$httpsfile = file_get_contents("https://www.example.com/foo.txt");
|
||
|
||
/* Read remote file from ftp.example.com using FTP */
|
||
$ftpfile = file_get_contents("ftp://user:pass@ftp.example.com/foo.txt");
|
||
|
||
/* Read remote file from ftp.example.com using FTPS */
|
||
$ftpsfile = file_get_contents("ftps://user:pass@ftp.example.com/foo.txt");
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
/* Send POST request to https://secure.example.com/form_action.php
|
||
* Include form elements named "foo" and "bar" with dummy values
|
||
*/
|
||
|
||
$sock = fsockopen("ssl://secure.example.com", 443, $errno, $errstr, 30);
|
||
if (!$sock) die("$errstr ($errno)\n");
|
||
|
||
$data = "foo=" . urlencode("Value for Foo") . "&bar=" . urlencode("Value for Bar");
|
||
|
||
fwrite($sock, "POST /form_action.php HTTP/1.0\r\n");
|
||
fwrite($sock, "Host: secure.example.com\r\n");
|
||
fwrite($sock, "Content-type: application/x-www-form-urlencoded\r\n");
|
||
fwrite($sock, "Content-length: " . strlen($data) . "\r\n");
|
||
fwrite($sock, "Accept: */*\r\n");
|
||
fwrite($sock, "\r\n");
|
||
fwrite($sock, $data);
|
||
|
||
$headers = "";
|
||
while ($str = trim(fgets($sock, 4096)))
|
||
$headers .= "$str\n";
|
||
|
||
echo "\n";
|
||
|
||
$body = "";
|
||
while (!feof($sock))
|
||
$body .= fgets($sock, 4096);
|
||
|
||
fclose($sock);
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
/* Create a compressed file containing an arbitrary string
|
||
* File can be read back using compress.zlib stream or just
|
||
* decompressed from the command line using 'gzip -d foo-bar.txt.gz'
|
||
*/
|
||
$fp = fopen("compress.zlib://foo-bar.txt.gz", "wb");
|
||
if (!$fp) die("Unable to create file.");
|
||
|
||
fwrite($fp, "This is a test.\n");
|
||
|
||
fclose($fp);
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
|
||
class VariableStream {
|
||
var $position;
|
||
var $varname;
|
||
|
||
function stream_open($path, $mode, $options, &$opened_path)
|
||
{
|
||
$url = parse_url($path);
|
||
$this->varname = $url["host"];
|
||
$this->position = 0;
|
||
|
||
return true;
|
||
}
|
||
|
||
function stream_read($count)
|
||
{
|
||
$ret = substr($GLOBALS[$this->varname], $this->position, $count);
|
||
$this->position += strlen($ret);
|
||
return $ret;
|
||
}
|
||
|
||
function stream_write($data)
|
||
{
|
||
$left = substr($GLOBALS[$this->varname], 0, $this->position);
|
||
$right = substr($GLOBALS[$this->varname], $this->position + strlen($data));
|
||
$GLOBALS[$this->varname] = $left . $data . $right;
|
||
$this->position += strlen($data);
|
||
return strlen($data);
|
||
}
|
||
|
||
function stream_tell()
|
||
{
|
||
return $this->position;
|
||
}
|
||
|
||
function stream_eof()
|
||
{
|
||
return $this->position >= strlen($GLOBALS[$this->varname]);
|
||
}
|
||
|
||
function stream_seek($offset, $whence)
|
||
{
|
||
switch ($whence) {
|
||
case SEEK_SET:
|
||
if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) {
|
||
$this->position = $offset;
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
break;
|
||
|
||
case SEEK_CUR:
|
||
if ($offset >= 0) {
|
||
$this->position += $offset;
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
break;
|
||
|
||
case SEEK_END:
|
||
if (strlen($GLOBALS[$this->varname]) + $offset >= 0) {
|
||
$this->position = strlen($GLOBALS[$this->varname]) + $offset;
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function stream_metadata($path, $option, $var)
|
||
{
|
||
if($option == STREAM_META_TOUCH) {
|
||
$url = parse_url($path);
|
||
$varname = $url["host"];
|
||
if(!isset($GLOBALS[$varname])) {
|
||
$GLOBALS[$varname] = '';
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
stream_wrapper_register("var", "VariableStream")
|
||
or die("Failed to register protocol");
|
||
|
||
$myvar = "";
|
||
|
||
$fp = fopen("var://myvar", "r+");
|
||
|
||
fwrite($fp, "line1\n");
|
||
fwrite($fp, "line2\n");
|
||
fwrite($fp, "line3\n");
|
||
|
||
rewind($fp);
|
||
while (!feof($fp)) {
|
||
echo fgets($fp);
|
||
}
|
||
fclose($fp);
|
||
var_dump($myvar);
|
||
|
||
?>
|
||
|
||
--- Source: zend-thread-id.xml ---
|
||
<?php
|
||
$thread_id = zend_thread_id();
|
||
|
||
echo 'Current thread id is: ' . $thread_id;
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
|
||
]>
|
||
<book id="listing">
|
||
<title>My lists</title>
|
||
<chapter id="books">
|
||
<title>My books</title>
|
||
<para>
|
||
<informaltable>
|
||
<tgroup cols="4">
|
||
<thead>
|
||
<row>
|
||
<entry>Title</entry>
|
||
<entry>Author</entry>
|
||
<entry>Language</entry>
|
||
<entry>ISBN</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>The Grapes of Wrath</entry>
|
||
<entry>John Steinbeck</entry>
|
||
<entry>en</entry>
|
||
<entry>0140186409</entry>
|
||
</row>
|
||
<row>
|
||
<entry>The Pearl</entry>
|
||
<entry>John Steinbeck</entry>
|
||
<entry>en</entry>
|
||
<entry>014017737X</entry>
|
||
</row>
|
||
<row>
|
||
<entry>Samarcande</entry>
|
||
<entry>Amine Maalouf</entry>
|
||
<entry>fr</entry>
|
||
<entry>2253051209</entry>
|
||
</row>
|
||
<!-- TODO: I have a lot of remaining books to add.. -->
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</chapter>
|
||
</book>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
|
||
class Vegetable {
|
||
public $edible;
|
||
|
||
public $color;
|
||
|
||
public function __construct($edible, $color = "green")
|
||
{
|
||
$this->edible = $edible;
|
||
$this->color = $color;
|
||
}
|
||
|
||
public function isEdible()
|
||
{
|
||
return $this->edible;
|
||
}
|
||
|
||
public function getColor()
|
||
{
|
||
return $this->color;
|
||
}
|
||
}
|
||
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
|
||
class Spinach extends Vegetable {
|
||
public $cooked = false;
|
||
|
||
public function __construct()
|
||
{
|
||
parent::__construct(true, "green");
|
||
}
|
||
|
||
public function cook()
|
||
{
|
||
$this->cooked = true;
|
||
}
|
||
|
||
public function isCooked()
|
||
{
|
||
return $this->cooked;
|
||
}
|
||
}
|
||
|
||
?>
|
||
|
||
--- Source: examples.xml ---
|
||
<?php
|
||
|
||
// register autoloader to load classes
|
||
spl_autoload_register();
|
||
|
||
function printProperties($obj)
|
||
{
|
||
foreach (get_object_vars($obj) as $prop => $val) {
|
||
echo "\t$prop = $val\n";
|
||
}
|
||
}
|
||
|
||
function printMethods($obj)
|
||
{
|
||
$arr = get_class_methods(get_class($obj));
|
||
foreach ($arr as $method) {
|
||
echo "\tfunction $method()\n";
|
||
}
|
||
}
|
||
|
||
function objectBelongsTo($obj, $class)
|
||
{
|
||
if (is_subclass_of($obj, $class)) {
|
||
echo "Object belongs to class " . get_class($obj);
|
||
echo ", a subclass of $class\n";
|
||
} else {
|
||
echo "Object does not belong to a subclass of $class\n";
|
||
}
|
||
}
|
||
|
||
// instantiate 2 objects
|
||
$veggie = new Vegetable(true, "blue");
|
||
$leafy = new Spinach();
|
||
|
||
// print out information about objects
|
||
echo "veggie: CLASS " . get_class($veggie) . "\n";
|
||
echo "leafy: CLASS " . get_class($leafy);
|
||
echo ", PARENT " . get_parent_class($leafy) . "\n";
|
||
|
||
// show veggie properties
|
||
echo "\nveggie: Properties\n";
|
||
printProperties($veggie);
|
||
|
||
// and leafy methods
|
||
echo "\nleafy: Methods\n";
|
||
printMethods($leafy);
|
||
|
||
echo "\nParentage:\n";
|
||
objectBelongsTo($leafy, Spinach::class);
|
||
objectBelongsTo($leafy, Vegetable::class);
|
||
|
||
?>
|
||
|