├── .gitignore ├── README.md ├── composer.json ├── php8.1.jpg └── src ├── array_is_list.php ├── assoc_array_unpacking.php ├── enums.php ├── fibers.php ├── fibers.png ├── fibers.xlsx ├── final_constants.php ├── first_class_callable.php ├── intersection_types.php ├── never.php ├── new_in_initializers.php ├── octal_notation.php └── readonly.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /composer.lock 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP 8.1 2 | 3 | - [PHP Дайджест](https://t.me/s/phpdigest) 4 | - [PHP.Watch](https://php.watch/versions/8.1) 5 | - [stitcher.io](https://stitcher.io/blog/new-in-php-81) 6 | 7 | ## New Features 8 | - Intersection Types 9 | - Enums 10 | - `never` return type 11 | - Fibers 12 | - Readonly Properties 13 | - New in initializers 14 | - `final` class constants 15 | - New `fsync` and `fdatasync` functions 16 | - New `array_is_list` function 17 | - New Sodium `XChaCha20` functions 18 | - GD: AVIF image support 19 | - Intl: New `IntlDatePatternGenerator` class 20 | - Phar: Added OpenSSL-256 and OpenSSL-512 signature algorithms 21 | - GD: Lossless WebP encoding support 22 | - New `#[ReturnTypeWillChange]` attribute 23 | - First-class Callable Syntax 24 | - `$_FILES`: New `full_path` value for directory-uploads 25 | - Array unpacking support for string-keyed arrays 26 | - Explicit Octal numeral notation 27 | - Hash functions accept algorithm-specific `$options` 28 | - MurmurHash3 hash algorithm support 29 | - xxHash hash algorithms support 30 | - FPM: Configurable child-process spawn rate 31 | - Curl: DNS-over-HTTPS support 32 | - Curl: File uploads from strings with `CURLStringFile` 33 | - MySQLi: New `MYSQLI_REFRESH_REPLICA` constant 34 | 35 | ## Syntax/Functionality Changes 36 | - HTML entity en/decode functions process single quotes and substitute by default 37 | - `$GLOBALS` variable restrictions 38 | - Phar: Default signature algorithm changed from SHA1 to SHA256 39 | - `SplFixedArray` implements `JsonSerializable`, and json-encodes as an array 40 | - CLI: Interactive shell (`php -a`) requires `readline` extension 41 | - MySQLi: Default error mode set to exceptions 42 | - Configurable line endings for `fputcsv` and `SplFileObject::fputcsv` 43 | - `version_compare` operator restrictions 44 | - Warning on `compact` function calls with non-string and non-array string parameters 45 | - finfo Extension: `file_info` resource are migrated to existing `finfo` objects 46 | - IMAP: `imap` resources are `IMAP\Connection` class objects 47 | - FTP Extension: Connection resources are `FTP\Connection` class objects 48 | - GD Extension: Font identifiers are `GdFont` class objects 49 | - LDAP: resources migrated to `LDAP\Connection`, `LDAP\Result`, and `LDAP\ResultEntry` objects 50 | - PostgreSQL: `resource`s migrated to `PgSql\Connection`, `PgSql\Result`, and `PgSql\Lob` objects 51 | - Pspell: `pspell`, `pspell config` resources are `PSpell\Dictionary`, `PSpell\Config` class objects 52 | 53 | ## Deprecations 54 | - Passing `null` to non-nullable internal function parameters is deprecated 55 | - Return types in PHP built-in class methods and deprecation notices 56 | - `Serializable` interface deprecated 57 | - Implicit incompatible float to int conversion is deprecated 58 | - `mysqli::get_client_info` method and `mysqli_get_client_info`($param) is deprecated 59 | - `date_sunrise`, `date_sunset` functions and related INI settings are deprecated 60 | - `strptime` function is deprecated 61 | - `mhash*()` functions (hash extension) are deprecated 62 | - `filter.default` and `filter.default_options` INI settings are deprecated 63 | - `PDO::FETCH_SERIALIZE` is deprecated 64 | - `auto_detect_line_endings` INI directive is deprecated 65 | - `strftime` and `gmstrftime` functions are deprecated 66 | - MySQLi: `mysqli_driver->driver_version` property is deprecated 67 | 68 | ## Useful commands and tools 69 | 70 | - [Psalm](https://psalm.dev/) 71 | - [PHPStan](https://phpstan.org/) 72 | - [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility) 73 | - `composer why-not php ^8.1` 74 | - `composer require symfony/polyfill-php81` 75 | 76 | ## Fibers 77 | 78 | - https://clue.engineering/2021/fibers-in-php 79 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vudaltsov/php81", 3 | "type": "project", 4 | "require": { 5 | "php": "8.1.*", 6 | "symfony/polyfill-php81": "^1.23", 7 | "symfony/http-foundation": "^5.3", 8 | "symfony/var-dumper": "^5.3", 9 | "symfony/validator": "^5.4@rc", 10 | "psr/log": "^3.0", 11 | "symfony/console": "^5.3", 12 | "box/spout": "^3.3" 13 | }, 14 | "license": "MIT", 15 | "autoload": { 16 | "psr-4": { 17 | "PHP81\\": "src/" 18 | } 19 | }, 20 | "authors": [ 21 | { 22 | "name": "Valentin Udaltsov", 23 | "email": "udaltsov.valentin@gmail.com" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /php8.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phppoint/php81/31588f4d0a57ee5d82bac74cc6d393685f9b759a/php8.1.jpg -------------------------------------------------------------------------------- /src/array_is_list.php: -------------------------------------------------------------------------------- 1 | */ 14 | -------------------------------------------------------------------------------- /src/assoc_array_unpacking.php: -------------------------------------------------------------------------------- 1 | 8.0], 12 | ...new \ArrayIterator(['latest_stable_php' => 8.1]), 13 | ] 14 | ); 15 | -------------------------------------------------------------------------------- /src/enums.php: -------------------------------------------------------------------------------- 1 | 'Русский', 21 | self::EN => 'Английский', 22 | self::FR => 'Французский', 23 | }; 24 | } 25 | 26 | public function getIterator(): Traversable 27 | { 28 | yield from self::cases(); 29 | } 30 | } 31 | 32 | dump(iterator_to_array(Locale::FR)); 33 | -------------------------------------------------------------------------------- /src/fibers.php: -------------------------------------------------------------------------------- 1 | open(__DIR__.'/fibers.xlsx'); 24 | 25 | foreach (new \LimitIterator($reader->getSheetIterator(), limit: 1) as $sheet) { 26 | foreach ($sheet->getRowIterator() as $row) { 27 | // do parse Excel ... 28 | \Fiber::suspend(); 29 | } 30 | } 31 | 32 | $reader->close(); 33 | } 34 | 35 | (new SingleCommandApplication()) 36 | ->setName('Import large Excel file') 37 | ->setCode(function (InputInterface $input, OutputInterface $output) { 38 | $progressBar = new ProgressBar($output); 39 | $fiber = new \Fiber(parseLargeExcel(...)); 40 | 41 | $progressBar->start(); 42 | $progressBar->setFormat("%current% rows [%bar%] %elapsed:6s% %memory:6s%"); 43 | 44 | $fiber->start(); 45 | 46 | while (!$fiber->isTerminated()) { 47 | $progressBar->advance(); 48 | $fiber->resume(); 49 | } 50 | 51 | $progressBar->finish(); 52 | $output->writeln(''); 53 | }) 54 | ->run() 55 | ; 56 | -------------------------------------------------------------------------------- /src/fibers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phppoint/php81/31588f4d0a57ee5d82bac74cc6d393685f9b759a/src/fibers.png -------------------------------------------------------------------------------- /src/fibers.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phppoint/php81/31588f4d0a57ee5d82bac74cc6d393685f9b759a/src/fibers.xlsx -------------------------------------------------------------------------------- /src/final_constants.php: -------------------------------------------------------------------------------- 1 | isFinal(); 24 | -------------------------------------------------------------------------------- /src/first_class_callable.php: -------------------------------------------------------------------------------- 1 | $stream 12 | * @return \Traversable&\Countable 13 | */ 14 | public function cache(\Generator $stream): \Traversable&\Countable; 15 | } 16 | -------------------------------------------------------------------------------- /src/never.php: -------------------------------------------------------------------------------- 1 | logger->alert('PHP {version} released 🤩', [ 22 | 'version' => 8.1, 23 | ]); 24 | } 25 | } 26 | 27 | final class Request 28 | { 29 | #[Assert\All( 30 | constraints: [ 31 | new Assert\NotBlank(), 32 | new Assert\Uuid(), 33 | ] 34 | )] 35 | public array $uuids; 36 | } 37 | -------------------------------------------------------------------------------- /src/octal_notation.php: -------------------------------------------------------------------------------- 1 | email; 37 | } 38 | 39 | public function setEmail(string $email): void 40 | { 41 | self::validate($email); 42 | $this->email = $email; 43 | } 44 | 45 | public function withEmail(string $email): self 46 | { 47 | self::validate($email); 48 | $new = clone $this; 49 | $new->email = $email; 50 | 51 | return $new; 52 | } 53 | } 54 | 55 | dump( 56 | Email::fromString('nikic@php.net')->withEmail('nikita-ne-uhodi@php.net') 57 | ); 58 | --------------------------------------------------------------------------------