پی اچ پی (PHP) 8.4 منتشر شد! - آموزش تغییرات جدید PHP 8.4

بالاخره پی اچ پی 8.4 منتشر شد و قراره در این پست کامل تغییراتش رو بررسی کنیم. اگه یادتون باشه قبلا هم ما یک سری تغییرات پی اچ پی 8.4 بررسی کردیم قبل از انتشار نسخه اصلی.

PHP 8.4 نسخه‌ای است که با تمرکز بر بهبود تجربه توسعه‌دهندگان، افزایش کارایی، و افزودن قابلیت‌های جدید به زبان منتشر شده است. این نسخه شامل تغییراتی در زبان، کتابخانه‌ها و عملکرد کلی است.

Property hooks

در نسخه های قبلی پی اچ پی شما مجبور بودید برای ست (set) کردن و گت (get) کردن یک پراپرتی کلاس از __construct استفاده کنند یا حتی متد:

class Locale
{
    private string $languageCode;
    private string $countryCode;

    public function __construct(string $languageCode, string $countryCode)
    {
        $this->setLanguageCode($languageCode);
        $this->setCountryCode($countryCode);
    }

    public function getLanguageCode(): string
    {
        return $this->languageCode;
    }

    public function setLanguageCode(string $languageCode): void
    {
        $this->languageCode = $languageCode;
    }

    public function getCountryCode(): string
    {
        return $this->countryCode;
    }

    public function setCountryCode(string $countryCode): void
    {
        $this->countryCode = strtoupper($countryCode);
    }

    public function setCombinedCode(string $combinedCode): void
    {
        [$languageCode, $countryCode] = explode('_', $combinedCode, 2);

        $this->setLanguageCode($languageCode);
        $this->setCountryCode($countryCode);
    }

    public function getCombinedCode(): string
    {
        return sprintf("%s_%s", $this->languageCode, $this->countryCode);
    }
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->getCountryCode()); // BR
var_dump($brazilianPortuguese->getCombinedCode()); // pt_BR

اما در نسخه جدید پی اچ پی شما میتونید ست یا گت رو در همان پراپرتی تعریف کنید و واقعا عالیه:

class Locale
{
public string $languageCode;

public string $countryCode
{
set (string $countryCode) {
$this->countryCode = strtoupper($countryCode);
}
}

public string $combinedCode
{
get => sprintf("%s_%s", $this->languageCode, $this->countryCode);
set (string $value) {
[$this->countryCode, $this->languageCode] = explode('_', $value, 2);
}
}

public function __construct(string $languageCode, string $countryCode)
{
$this->languageCode = $languageCode;
$this->countryCode = $countryCode;
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->countryCode); // BR
var_dump($brazilianPortuguese->combinedCode); // pt_BR

با این آپدیت حجم کد ها به شدت میاد پایین و خیلی کارمون لذت بخش تر میکنه.

#[Deprecated] Attribute

در نسخه های قبلی پی اچ پی شما برای اینکه بخواید یک تکه کد رو مسنوخ کنید، شما میتونید از phpdoc ها استفاده کنید:

class PhpVersion
{
    /**
     * @deprecated 8.3 use PhpVersion::getVersion() instead
     */
    public function getPhpVersion(): string
    {
        return $this->getVersion();
    }

    public function getVersion(): string
    {
        return '8.3';
    }
}

$phpVersion = new PhpVersion();
// No indication that the method is deprecated.
echo $phpVersion->getPhpVersion();

اما در نسخه جدید پی اچ پی شما میتونید از اتربیوت Depreacated استفاده کنید:

class PhpVersion
{
    #[Deprecated(
        message: "use PhpVersion::getVersion() instead",
        since: "8.4",
    )]
    public function getPhpVersion(): string
    {
        return $this->getVersion();
    }

    public function getVersion(): string
    {
        return '8.4';
    }
}

$phpVersion = new PhpVersion();
// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() instead
echo $phpVersion->getPhpVersion();

Object API for BCMath

در پی اچ پی ورژن های قبلی شما میتونید برای کار با اکستنشن bcmath باید از فانکشن ها استفاده میکردید:

$num1 = '0.12345';
$num2 = 2;
$result = bcadd($num1, $num2, 5);

echo $result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false

اما الان میتونید از آبجکت استفاده کنید:

use BcMathNumber;

$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;

echo $result; // '2.12345'
var_dump($num1 > $num2); // false

این آبجکت از اینترفیس "Stringable" استفاده میکنند و شما میتونید خروجی با echo نمایش بدید.

New array_*() functions

در نسخه های قبلی پی اچ پی شما برای اینکه چک کنید یک آیتم در آرایه هست یا در کل کار با آرایه اغلب نیاز به حلقه داشت:

$animal = null;
foreach (['dog', 'cat', 'cow', 'duck', 'goose'] as $value) {
    if (str_starts_with($value, 'c')) {
        $animal = $value;
        break;
    }
}

var_dump($animal); // string(3) "cat"

اما الان شما میتونید از فانکشن های جدید استفاده کنید: (array_find()array_find_key()array_any()array_all())

$animal = array_find(
    ['dog', 'cat', 'cow', 'duck', 'goose'],
    static fn (string $value): bool => str_starts_with($value, 'c'),
);

var_dump($animal); // string(3) "cat"

PDO Driver specific SQL parsers

در پی اچ پی نسخه های قبل زمانی که از کلاس "PDO" استفاده میکردید، مقدار PDO برمیگردوند:

$connection = new PDO(
    'sqlite:foo.db',
    $username,
    $password,
); // object(PDO)

$connection->sqliteCreateFunction(
    'prepend_php',
    static fn ($string) => "PHP {$string}",
);

$connection->query('SELECT prepend_php(version) FROM php');

اما الان کلاس مربوطه برمیگردونه:

$connection = PDO::connect(
    'sqlite:foo.db',
    $username,
    $password,
); // object(PdoSqlite)

$connection->createFunction(
    'prepend_php',
    static fn ($string) => "PHP {$string}",
); // Does not exist on a mismatching driver.

$connection->query('SELECT prepend_php(version) FROM php');

new MyClass()->method() without parentheses

در نسخه های قبلی پی اچ پی شما برای ساخت یک شی جدید از "new" استفاده میکردید و نیاز به پرانتز داشتید:

class PhpVersion
{
    public function getVersion(): string
    {
        return 'PHP 8.3';
    }
}

var_dump((new PhpVersion())->getVersion());

اما در نسخه جدید پی اچ پی شما نیازی دیگه به پرانتز ندارید:

class PhpVersion
{
    public function getVersion(): string
    {
        return 'PHP 8.4';
    }
}

var_dump(new PhpVersion()->getVersion());

New ext-dom features and HTML5 support

کلاس "DOM" برای کار با HTML در پی اچ پی استفاده میشد:

$dom = new DOMDocument();
$dom->loadHTML(
    <<<'HTML'
        
            PHP 8.4 is a feature-rich release!
            PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.
        
        HTML,
    LIBXML_NOERROR,
);

$xpath = new DOMXPath($dom);
$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0];
$classes = explode(" ", $node->className); // Simplified
var_dump(in_array("featured", $classes)); // bool(true)

اما الان شما از کلاس مخصوص خودش استفاده کنید:

$dom = DomHTMLDocument::createFromString(
    <<
            PHP 8.4 is a feature-rich release!
            PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.
        
        HTML,
    LIBXML_NOERROR,
);

$node = $dom->querySelector('main > article:last-child');
var_dump($node->classList->contains("featured")); // bool(true)

Asymmetric Visibility

در نسخه های قبلی پی اچ پی شما برای اینکه یک پراپرتی قابل get یا set کردن نباشه باید نوع اون رو private میکردید:

class PhpVersion
{
    private string $version = '8.3';

    public function getVersion(): string
    {
        return $this->version;
    }

    public function increment(): void
    {
        [$major, $minor] = explode('.', $this->version);
        $minor++;
        $this->version = "{$major}.{$minor}";
    }
}

اما الان یک آپدیت فوق العاددددددددددده عالی داده. این آپدیت به این شکل است که شما میتونید یک پراپرتی public درست کنید اما بگید در زمان set یا get اون private باشه و پشمام:

class PhpVersion
{
    public private(set) string $version = '8.4';

    public function increment(): void
    {
        [$major, $minor] = explode('.', $this->version);
        $minor++;
        $this->version = "{$major}.{$minor}";
    }
}

متد جدید "createFromTimestamp" در کلاس DateTimeImmutable🔗

در پی اچ پی 8.4 شما قابلیت ساخت تاریخ از روی timestamp با استفاده از متد جدید کلاس DateTimeImmutable دارید:

$dt = DateTimeImmutable::createFromTimestamp(1718641845);$dt->format('Y-m-d'); // 2024-06-17

البته متد های شبیه هم وجود داشته از قبل:

$dt = DateTimeImmutable::createFromFormat('U', (string) 1718641845);$dt->format('Y-m-d'); // "2024-06-17

New Classes, Interfaces, and Functions

  • اضافه شدن Lazy Objects
  • پیاده سازی JIT بر اساس فریم ورک IR
  • اضافه شدن فانکشن "()request_parse_body"
  • اضافه شدن فانکشن های "bcceil(), bcdivmod(), bcfloor(), bcround()"
  • اضافه شدن فانکشن "()grapheme_str_split"
  • اضافه شدن متد های جدید برای کلاس "XMLReader" ب: "XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString(), XMLWriter::toStream(), XMLWriter::toUri(), XMLWriter::toMemory()
  • اضافه شدن فانکشن های "http_get_last_response_headers()" و "http_clear_last_response_headers()"
  • اضافه شدن فانکشن "fpow()"
  • اضافه شدن متد های جدید به رفلکشن ها: "ReflectionClassConstant::isDeprecated(), ReflectionGenerator::isClosed(), ReflectionProperty::isDynamic()"
  • اضافه شدن فانکشن های جدید: "pcntl_getcpu(), pcntl_getcpuaffinity(), pcntl_getqos_class(), pcntl_setns(), pcntl_waitid()"

Deprecations and backward compatibility breaks

  • انتقال IMAP, OCI8, PDO_OCI, pspell به اکستنشن "PECL"
  • منسوخ شدن پارامتر ها از نوع nullable
  • مسنوخ شدن نام کلاس ها با "_"
  • منسوخ شدن ضرب عدد صفر با اعداد منفی
  • زمانی که مد درستی به فانکشن "round()" پاس ندید، ValueError برمیگردونه
  • کلاس "GMP" به کلاس final تبدیل شد
  • ثابت (constant) های حذف شدند: "MYSQLI_SET_CHARSET_DIR, MYSQLI_STMT_ATTR_PREFETCH_ROWS, MYSQLI_CURSOR_TYPE_FOR_UPDATE, MYSQLI_CURSOR_TYPE_SCROLLABLE, and MYSQLI_TYPE_INTERVAL"
  • منسوخ شدن فانکشن های مای اس کیو ال: "mysqli_ping(), mysqli_kill(), mysqli_refresh()"
  • منسوخ شدن متد های مای اس کیو ال: "mysqli::ping(), mysqli::kill(), mysqli::refresh()"
  • منسوخ شدن ثابت "MYSQLI_REFRESH_*"
  • تغییر رفتار "exit()"
  • ثابت "E_STRICT" منسوخ شد

1 🔥
0 🎉
0 😮
0 👍
0 💜
1 👏
میلاد خسروی
نویسنده کد نیوز

برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁