@brisphp1
https://brisphp.com
#BrisPHP
Giveaway: brisphp.com/pizza
@brisphp1
https://brisphp.com
#BrisPHP
<?php
var_dump(unserialize('i:5;i:6;'));
// Warning: unserialize(): Extra data starting at offset 4 of 8 bytes
// int(5)
var_dump(unserialize('N;i:6;'));
// Warning: unserialize(): Extra data starting at offset 2 of 6 bytes
// NULL
var_dump(unserialize('b:1;i:6;'));
// Warning: unserialize(): Extra data starting at offset 4 of 8 bytes
// bool(true)
var_dump(unserialize('a:1:{s:3:"foo";b:1;}i:6;'));
// Warning: unserialize(): Extra data starting at offset 20 of 24 bytes
// array(1) {
// ["foo"]=>
// bool(true)
// }
@brisphp1
https://brisphp.com
#BrisPHP
class Test {
private const int A = 1;
public const mixed B = 1;
public const int C = 1;
public const Foo|Stringable|null D = null;
}
class Test2 extends Test {
// This is legal since Test::A is private
public const string A = 'a';
// This is legal since int is a subtype of mixed
public const int B = 0;
// This is illegal since mixed is a supertype of int
public const mixed C = 0;
// This is legal since Foo&Stringable is more restrictive than Foo|Stringable
public const (Foo&Stringable)|null D = null;
}
@brisphp1
https://brisphp.com
#BrisPHP
class Foo {
public function __construct(
public readonly DateTime $bar,
public readonly DateTime $baz
) {}
public function __clone()
{
$this->bar = clone $this->bar; // Works
$this->cloneBaz();
}
private function cloneBaz()
{
unset($this->baz); // Also works
}
}
$foo = new Foo(new DateTime(), new DateTime());
$foo2 = clone $foo;
// Foo2::$bar is cloned deeply
// Foo2::$baz becomes uninitialized
@brisphp1
https://brisphp.com
#BrisPHP
readonly class A
{
public function doStuff()
{
// ...
}
}
class B extends A
{
private int $doStuffCounter = 0;
public function doStuff()
{
++$this->doStuffCounter;
parent::doStuff();
}
public function getDoStuffCounter(): int
{
return $this->doStuffCounter;
}
}
@brisphp1
https://brisphp.com
#BrisPHP
function foo() {
static $i = 1;
echo $i++, "\n";
}
foo();
// 1
foo();
// 2
foo();
// 3
@brisphp1
https://brisphp.com
#BrisPHP
function bar() {
echo "bar() called\n";
return 1;
}
function foo() {
static $i = bar();
echo $i++, "\n";
}
foo();
// bar() called
// 1
foo();
// 2
foo();
// 3
@brisphp1
https://brisphp.com
#BrisPHP
function foo() {
static $x = 1;
var_dump($x);
static $x = 2;
var_dump($x);
}
foo();
// Previously:
// 2
// 2
// Now:
// Fatal error: Duplicate declaration of static variable $x
@brisphp1
https://brisphp.com
#BrisPHP
$input = [1, 2, 3, 4];
$output = array_sum($input);
// 10
$output = array_reduce($input, fn($carry, $value) => $carry + $value, 0);
// 10
$output = array_product($input);
// 24
$output = array_reduce($input, fn($carry, $value) => $carry * $value, 1);
// 24
@brisphp1
https://brisphp.com
#BrisPHP
$input = ["1", "2", "3", "4"];
$output = array_sum($input);
// 10
$output = array_reduce($input, fn($carry, $value) => $carry + $value, 0);
// 10
$output = array_product($input);
// 24
$output = array_reduce($input, fn($carry, $value) => $carry * $value, 1);
// 24
@brisphp1
https://brisphp.com
#BrisPHP
$input = ["1", "2", "3", "four"];
$output = array_sum($input);
// 6
$output = array_reduce($input, fn($carry, $value) => $carry + $value, 0);
// Fatal error
$output = array_product($input);
// 0
$output = array_reduce($input, fn($carry, $value) => $carry * $value, 1);
// Fatal error
@brisphp1
https://brisphp.com
#BrisPHP