Валентин Удальцов
Ведущий разработчик в
@vudaltsov, @phpyh
str_contains(string $haystack, string $needle): bool
assertSame(
$needle === '' || strpos($haystack, $needle) !== false,
str_contains($haystack, $needle),
);
str_starts_with(string $haystack, string $needle): bool
str_ends_with (string $haystack, string $needle): bool
assertSame(
strncmp($haystack, $needle, strlen($needle)) === 0,
str_starts_with($haystack, $needle),
);
get_debug_type(mixed $value ): string
$value | gettype($value) | get_debug_type($value) |
---|---|---|
null |
NULL |
null |
true |
boolean |
bool |
false |
boolean |
bool |
123 |
integer |
int |
3.141 |
double |
float |
'Foo' |
string |
string |
[1, 2] |
array |
array |
$value | gettype($value) | get_debug_type($value) |
---|---|---|
new Foo\Bar() |
object |
Foo\Bar |
function() {} |
object |
Closure |
new class {} |
object |
class@anonymous |
new class extends Foo {} |
object |
Foo@anonymous |
new class implements Foo {} |
object |
Foo@anonymous |
Ресурс | resource |
resource (TYPE) |
Закрытый ресурс | resource (closed) |
resource (closed) |
function preg_last_error_msg(): string
{
switch (preg_last_error()) {
case PREG_INTERNAL_ERROR:
return 'Internal error';
case PREG_BAD_UTF8_ERROR:
return 'Malformed UTF-8 characters...';
// ...
default:
return 'Unknown error';
}
}
Деление в соответствии со стандартом IEEE-754.
fdiv(float $x, float $y): float
assertSame(fdiv( 0.5, 0), INF);
assertSame(fdiv(-0.5, 0), -INF);
assertSame(fdiv( 0, 0), NAN);
function get_resource_id($resource): int
{
if (!is_resource($resource)) {
throw new TypeError();
}
return (int) $resource;
}
public static DateTime::createFromInterface(
DateTimeInterface $dateTime
): DateTime
public static DateTimeImmutable::createFromInterface(
DateTimeInterface $dateTime
): DateTimeImmutable
interface Stringable
{
public function __toString(): string;
}
Автоматически добавляется к классам, которые имплементируют __toString()
.
function printString(string|Stringable): void
{
}
$metadata = new WeakMap();
$object = new stdClass(); // ref_count=1
$metadata[$object] = 'some metadata'; // ref_count=1, not 2 🔴
var_dump(count($metadata)); // int(1)
unset($object); // ref_count=0
var_dump(count($metadata)); // int(0)
PHP < 8
foreach (token_get_all($code) as $token) {
if (!is_string($token)) {
[$pos, $text, $line] = $token;
}
}
PHP >= 8
foreach (PhpToken::tokenize($code) as $token) {
$token->id;
$token->line;
$token->pos;
$token->is([T_CLASS, T_CONST]);
}
- /**
- * @return resource|false
- */
- function curl_init() {}
+ function curl_init(): CurlHandle|false {}
Аналогично, GDImage
, Socket
, OpenSSL
.
null|bool|int|float|string|array|object|callable|resource
Объединение с любым типом, например, null|mixed
, бросит фатальную ошибку.
final class Example
{
public mixed $property;
public function method(mixed $argument): mixed {}
}
iterable = array|Traversable
?string = null|string
final class Number
{
private int|float $number;
public function __construct(int|float $number)
{
$this->number = $number;
}
public function toPrimitive(): int|float
{
return $this->number;
}
}
$returnType = (new ReflectionClass(Number::class))
->getMethod('toPrimitive')
->getReturnType()
;
if ($returnType instanceof ReflectionUnionType) {
foreach ($returnType->getTypes() as $type) {
// ...
}
}
abstract class ValueObject
{
final public static function fromString(string $value): static
{
return new static($value);
}
final public function withValue(string $value): static
{
$clone = clone $this;
$clone->value = $value;
return $clone;
}
}
$object::class === get_class($object); // true
static fn() => throw new Exception('have a nice day!');
$foo = isset($bar['baz'])
? $bar['baz']
: throw new Exception('$bar[baz] is not set');
$foo = $bar ?: throw new Exception('$bar is falsy');
$foo = $bar ?? throw new Exception('$bar is not set');
$foo ??= throw new Exception('$foo is not set');
PHP < 8
switch ($request->getMethod())
{
case 'POST':
$status = $this->handlePost($request);
break;
case 'GET':
case 'HEAD':
$status = $this->handleGet($request);
break;
default:
throw new Exception('Unsupported method');
}
PHP >= 8
$status = match($request->getMethod()) {
'POST' => $this->handlePost($request),
'GET', 'HEAD' => $this->handleGet($request),
default => throw new Exception('Unsupported method'),
};
final class AnswerQuestion
{
public function __construct(
string $respondentId,
string $questionId,
string $answerId,
) {}
}
static function () use(
$respondentId,
$questionId,
$answerId,
): void {}
PHP < 8
final class Point
{
public float $x;
public float $y;
public function __construct(float $x = 0.0, float $y = 0.0)
{
assert($x >= 0.0);
assert($y >= 0.0);
$this->x = $x;
$this->y = $y;
}
}
PHP >= 8
final class Point
{
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
) {
assert($x >= 0.0);
assert($y >= 0.0);
}
}
#[
ORM\Entity,
ORM\Table("recipient")
]
final class Recipient
{
/** @psalm-readonly */
#[ORM\Id, ORM\Column("uuid")]
private string $id;
#[ORM\Column("string", ORM\Column::UNIQUE)]
private string $email;
}
📝 Implementation RFC by Benjamin Eberlei
📝 Syntax RFC by Derick Rethans, Benjamin Eberlei
final class ApproveApplications
{
/**
* @Assert\All({
* @Assert\NotBlank(),
* @Assert\Uuid(),
* })
*/
public array $applicationsIds = [];
}
- htmlspecialchars($string, default, default, false);
+ htmlspecialchars($string, double_encode: false);
array_fill(...[
'start_index' => 0,
'count' => 100,
'value' => 50,
]);
#[@ORM\OneToMany(
targetEntity: Criterion::class,
indexBy: "criterionId",
)]
function identity(): ?Identity
{
$token = tokenStorage()->token();
if ($token === null) {
return null;
}
return $token->identity();
}
function identity(): ?Identity
{
return tokenStorage()->token()?->user();
}
class ValueError extends \Error
{
}
PHP < 8.0
strpos('s', 'small', 16);
// Warning: strpos(): Offset not contained in string in ... on line ...
PHP >= 8.0
strpos('s', 'small', 16);
// Uncaught ValueError: Offset not contained in string in ...:...
try {
return $container->get('logger');
}
- catch (NotFoundExceptionInterface $exception) {
+ catch (NotFoundExceptionInterface) {
return new NullLogger();
}
@
больше не влияет на вывод фатальных ошибок.PDO::ATTR_ERRMODE = PDO::ERRMODE_EXCEPTION
.ESQ + :q!
- error_reporting=E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
+ error_reporting=E_ALL
{
"require": {
"php": "^8.0",
- "ext-json": "*"
}
}
assert(true === false);
// Fatal error: Uncaught AssertionError ...
+ opcache.jit_buffer_size=32M
php -S localhost:0
[Wed Nov 25 20:35:59 2020] PHP 8.0.0 Development Server
(http://localhost:11584) started
var_dump($_SERVER['SERVER_PORT']);
Пых @phpyh
PHP Digest @phpdigest