PHP 8'deki yenilikler: Tüm bilmeniz gereken!

Yayınlanan: 2021-01-06

PHP8 ile 26 Kasım 2020'de iletişime geçeceğiz ve kesinlikle bu takdir edilen sürümde gelecek özelliklerle ilgili çok şey yazılıyor.

PHP 8

Büyük bir sürüm olduğu için, her şeyin değiştiğinin farkında olmayı önemli kılan değişiklikler ve yeni özellikler olacak. PHP8'in uygulamalarınızı nasıl etkileyeceğini ve sorunsuz bir şekilde yükseltme yapabilmenizi sağlamak için hangi işlemlerin yapılması gerektiğini düşünmeyi kolaylaştıracaktır.

Bir sonraki PHP sürümünde neler elde edeceğimizi ve neyin eleştirmeye değer olduğunu anlamak için en önemli birkaç değişiklikten geçtik.

genel bakışla başlayalım!

PHP 8'e Genel Bakış

Yukarıda bahsedildiği gibi, PHP 8, dile bir dizi yeni özellik, iyileştirme, işlev ve kullanımdan kaldırma paketi sunar. Tüm bunlar arasında en çok tartışılan özellik JIT derleyicisidir. Bununla birlikte, JIT gibi performans geliştirici özellikler ilgi odağı olmayı hak ediyor, ancak sözdizimsel iyileştirmelerin PHP uygulayıcıları için “en azından kısa vadede” daha fazla gerçek bir başarı sağlaması bekleniyor.

Bir değişim tarihi

Birkaç PHP değişikliği önerildi, tartışıldı, uygulandı ve kısa sürede onaylandı. Popülerdirler, tartışmasızdırlar ve bunları uygulamak için doğal bir yöntemi vardır.

Ve ondan sonra, denenen, başarısız olan ve sonunda kabul etmeden önce defalarca geri dönenler gelir. Birkaç kez, uygulamanın çözülmesi uzun zaman alır ve bazen fikrin kendisi sadece yarı pişmiş haldedir ve bazen topluluğun kendisi henüz fikre ısınmamıştır - “henüz zamanı değil.”

Krediler tam olarak tür kategorisine girer. İlk olarak 2016 yılında PHP 7.1 için önerildiler. Ancak inatçı bir direnişle karşılaştılar ve kabul oyu büyük bir farkla kaybettiler. Şimdi, dört yıl ileri saralım ve kapsamı biraz daraltılmış olsa da oldukça benzer bir teklif, yalnızca bir muhalifle gündeme geldi. Belli ki zamanı gelmiş bir fikir!

Eski kodla ilgili sorunlar nelerdir?

PHP 8 çok büyük bir yeni sürüm olduğundan, eski kodun artık uyumlu olmamasını beklemeliyiz. Ancak, komplikasyonlar önerebilecek değişikliklerin çoğu zaten 7.2 , 7.3 ve 7.4 sürümlerinde aktarılmıştı . Şimdi son değişikliklerden bahsedelim. Onlar:

Sihirli tırnak mirası

  • gerçek tip
  • FILTER_SANITIZE_MAGIC_QUOTES filtresi
  • $ this'i statik olmayan kapanışlardan ayırma
  • nesnelerle array_key_exists()
  • 3. argüman olarak kodlama ile mb_strrpos()
  • Yansıma dışa aktarma() yöntemleri
  • convert_cyr_string() işlevi
  • implode() parametre sipariş karışımı
  • restore_include_path() işlevi
  • hebrevc() işlevi
  • para_format() işlevi
  • allow_url_include ini yönergesi
  • ezmlm_hash() işlevi

PHP 8'deki Yeni İşlevler

str_contains

Bir dize başka bir dize içeriyorsa, öğrenmenin birçok yolu vardır.

Genellikle, strpos() kullanırsınız. Bildiğiniz gibi, strpos() aramak istediğiniz iğnenin yanına bir samanlık alır. İğneyi gördüğünüz ilk konumu gösteren bir tamsayı döndürür.

Şimdi, bir başka dizgenin konumunu döndürdüğü için, strpos()'un onu keşfedip keşfetmediğini kontrol edemezsiniz; "0" döndürürse (konumlar sıfır dizinlidir ve 1 yerine 0 ile başlar), o zaman koşul, onu yanlış bir değer olarak değerlendirecek ve bulunamadığını belirtecektir.

Bu ne anlama geliyor?

Koşullu –“strpos($haystack, $needle) !== false” yazmanız gerekecek. False, dizenin konumunu bulamadığını gösterir. Bu, bir dizede bir dize aramak için şeffaf olmayan ve ezoterik bir yöntemdir! Pekala, o kadar kafa karıştırıcı değil.

Bunu önlemek için PHP 8, str_contains() öğesini getirir. str_contains() işlevinin işi, samanlıkta iğnenin bulunup bulunmadığını gösteren basit bir boole döndürmektir. Bunu yazmak çok daha kolay, ayrıca kodu koruyan biri olarak anlaşılır, değil mi?

 if (str_contains( 'Foo Bar Baz' , 'Foo' )) { // FOUND }

PHP 8: Motor Özellikleri ve Değişiklikler

Bazı yeni motor özellikleri ve PHP 8'de fark edilen değişiklikler var. Başlık özelliği şüphesiz yeni JIT derleyicisidir.

JIT Derleyici

  • LSP Uygulaması
  • Uyumsuz yöntem imzalarında önemli hatalar
  • Kaynak "Sınıflar"
  • XML-RPC artık PECL'de
  • Onaylama davranışı
  • Yansıma değişiklikleri

Bu blogun temel amacı uğruna, JIT derleyicisine, kaynak "sınıflarına" ve son olarak yansıma API değişikliklerine odaklanacağız.

Tam Zamanında Derleyici ( RFC )

PHP7'nin piyasaya sürülmesinden önce yapılan hız iyileştirmeleri nedeniyle, Just-In-Time (veya JIT) derleyicisinin doğuşu gerçekleşti. PHP8'e tanıtılıyor çünkü bir JIT kullanmadan getirilebilecek hızda neredeyse hiç iyileştirme yok. Buradaki fikir, PHP performansını artıracağıdır.

PHP kodu yürütüldüğünde bayt kodlarına çevrilir ve bu bayt kodları programdaki adımları yürütmek için daha fazla kullanılır.

PHP, yürüttüğünüz kodu analiz eder, JIT'in anlamı budur. Ayrıca, siz kodu yürütürken performans iyileştirmeleri dışında gerçek zamanlı kararlar verebilir. Sadece web tabanlı senaryolarda değil, CPU yoğun uygulamalarda da oldukça kullanışlı olacak.

Bu sunucu tarafı PHP uygulamalarını yansıtır, PHP yerleşik JIT sistemi ile kesinlikle daha yaygın olabilir.

Kullanmak istiyorsanız önce JIT'i etkinleştirmeniz gerekir. Test sistemimizde (Ubuntu 20.04), çekirdek PHP8 paketi ile kurduğumuz PHP opcache modülünü zaten kurduk. /etc/php/8.0/cli/conf.d/10-opcache.ini dizinine yerleştirilen dosyada yapılandırdık.

Şimdi, JIT'i etkinleştirmeye hazırsınız, değil mi?  

  • opcache'yi etkinleştir

opcache.jit_buffer_size ayarına bellek depolama alanı atayabilirsiniz. Dosyanız sistemimde bu şekilde görünecek.

  1. zend_extension=opcache.so
  2. opcache.enable_cli=1
  3. ; php opcache modülü için yapılandırma
  4. opcache.jit_buffer_size=256M

Ayrıca, etkin olup olmadığından emin olmak için opcache_get_status() işlevini kullanın. Bakışlarınızı bu dizinin 'jit' kısmına çevirin ve JIT'in mevcut durumu hakkında bilgi alın.


var_dump(opcache_get_status()['jit']);

JIT mükemmel bir şekilde etkinleştirildiyse, bunun aşağıda gösterildiği gibi yazdırılması gerekir.

  1. dizi(7) {
  2. [“etkin”]=>
  3. bool(doğru)
  4. [“açık”]=>
  5. bool(doğru)
  6. [“tür”]=>
  7. int(5)
  8. [“opt_level”]=>
  9. int(4)
  10. [“opt_flags”]=>
  11. int(6)
  12. [“buffer_size”]=>
  13. int(268435440)
  14. ["buffer_free"]=>
  15. int(268432880)
  16. }

Peki daha hızlı mıydı? Tek kelimeyle, sıcak bir "evet" diye haykırırdık.

Birkaç kişinin bir mandelbrot seti yardımıyla kıyaslama yaptığını fark ettik, bu yüzden bir süre önce oluşturduğumuz ve PHP'de farklı türde fraktallar çizen bir kütüphane kullanmaya karar verdik. Tek yaptığımız üç fraktal oluşturmak ve mikrotom() işlevini kullanmanın ne kadar sürdüğünü izlemekti. PHP 7.4.8 için sonuçları aşağıda gösterdik.

  • Yakma Gemisi – 84.20269203186
  • Mandlebrot – 21.552599906921
  • Üç Boynuzlu - 32.685042858124

Aynı kodu PHP8'de çalıştırdığımızda oldukça hızlıydı. Rakamlar kendileri için konuşacak. .

  • Yakma Gemisi – 15.272277116776
  • Mandlebrot -3.7528541088104
  • Üç Boynuzlu -4.4957919120789

Bu büyük hız artışı oldukça ilginç. Burada kullandığımız kod çok büyük boyutlu fraktallar yaratıyor, ancak kodu oluştururken zamanımızın çoğunu fraktalların oluşturulmasını bekleyerek harcadığımızı hatırlıyoruz.

PHP'yi bazı durumlarda (fraktal oluşturmanın dışında) sınırlarını zorladığımız için bu ekleme bizim için ilginçtir. Bunun PHP'nin geleceği için büyük fayda sağladığını ve normal web sitesi dili dışındaki durumlar için dilin seçilmesine izin vereceğini fark edebiliriz.

WordPress veya Drupal gibi uygulamaların hız artışına bakmadık, ancak okuduklarımıza göre, bu tür uygulamalarda kesinlikle çok az fark var. Gelecekte, JIT'in orada ne tür bir fark yarattığını anlamak için bu platformlarda kıyaslamalar yapacağız.

Birlik Tipleri ( RFC )

PHP7'den beri, ne tür dönüş değerleri ve argüman türlerinin şart koşulduğu ve mümkün olmuştur. Bu, ilettiğiniz argüman türünün beklenen türle aynı olmayan bir sıralama olması durumunda PHP'nin bir hata atmasına izin verecektir. PHP gibi gevşek yazılmış bir dilde işlevlerin mükemmel değer türlerini almasının yanı sıra üretmesini sağlamak çok önemlidir.

PHP8'de artık argümanlar ve dönüş değerleri için bir çizgi karakteriyle bölünmüş çeşitli sıralamalar şart koşmak mümkün.

Aşağıda, bir kayan nokta veya tamsayı değeri kabul edebilen bir işlevi gösterdik.

 function addNumbers(int|float $number1, int|float $number2) : int|float { return $number1 + $number2; }

Önceden, buna benzer bir işlevin herhangi bir tür ipucu olmadan üretilmesi gerekirdi çünkü PHP, geçirilen argümanın doğru olmaması durumunda türü sessizce gösterebiliyordu. Bu, argüman türünü bir tamsayı olarak ayarlamamız durumunda PHP'nin herhangi bir kayan nokta değerini bir tamsayı olarak göstereceği anlamına geliyordu. Birim testi yapmıyorsanız, kesinlikle yakalanması gereken birkaç zor hataya yol açabilir.

Yukarıdaki işlevi kullanmak için sadece diğerleri gibi diyoruz

 echo addNumbers(1, 1); // prints 2 echo addNumbers(1.1, 1.1); // prints 2.2

Aynı işleve bir dize iletmeye çalışmamız durumunda:

 echo addNumbers('one', 'two');

İşleve bir kayan nokta veya bir “int” geçirmemiz gerektiğini söyleyen bir PHP Fatal hatası alacağız.

void türünü bir birleşim türü olarak kullanamazsınız, çünkü işlevin hiçbir şey döndürmeyeceğini şart koşar. Basit bir deyişle, bir fonksiyonun bir boşluk veya tamsayı döndüreceğini iddia edemezsiniz; PHP ölümcül hatası alırsınız.

Gördüğümüz normal bir değişiklik olsa da, bu özelliğin biraz kullanılmasıydı, çünkü daha önce sadece yorumlarda çeşitli değer türlerini şart koşmak mümkündü, bu da doc blok yorumlarının koddan daha ayrıntılı hale gelmesine neden oldu.

Nullsafe Operatörü (RFC)

Boş birleştirme operatörünün yanı sıra, doğrudan yöntemlerden boş dönüş değerlerini algılama yeteneği de mümkündür. Bilmiyorsanız, boş birleştirme operatörü bir değer almanıza izin verir ve ilk değerin boş olması durumunda farklı bir değer döndürmenin yanı sıra değerin mevcut olup olmadığını test etmeniz gerekmez.

Yani, bunu “$_GET superglobal”den bir değer elde etmek için yapabiliriz. ve bu değerin olmaması durumunda “0”.


1. $page = $_GET['page'] ?? 0;

2. yankı $sayfa;

Boş güvenli operatörün çalışması aynıdır ancak kullanışlı bir kısayol oluşturmanıza ve bu değeri kullanmaya çalışmadan önce bir yoldan boş dönüşü test etmenize olanak tanır.

Bunun, "yöntemlerden dönüşlerin" veya "nesne özelliklerinin" kullanmadan önce içlerinde bir şeyler olduğundan emin olmak için çok sayıda kontrol kodu yazma eğiliminde olduğumuz Drupal'da nihayetinde yararlı olacağını fark ettik. Bu, içerdikleri içerik nedeniyle Drupal'daki nesnelerin bağlamsal durumu nedeniyle zorunludur. Bu değişiklik kesinlikle bazı kontrolleri basitleştirecektir.

Adlandırılmış Bağımsız Değişkenler ( RFC )

Adlandırılmış bağımsız değişkenler, farklı bir bağımsız değişken sırası ve çağrı işlevleri belirtmenize izin verir. İki parametresi olan aşağıdaki normal işlevi alın. Bir diziyi verilen uzunlukta doldurur.

 function fillArray(array $arrayToFill, int $number) : array { for ($i = 0 $i < $number; ++$i) { $arrayToFill[$i] =1; } return $arrayToFill; }

Argümanları tanımladıkları düzende iletebiliriz, bu tekniği normal şekilde adlandırabiliriz.

 $newArray = fillArray([], 2);

PHP8'den itibaren artık parametreleri işleve aktarırken adlandırabilirsiniz. Ayrıca parametreleri istediğimiz sırada göndermenizi sağlar.

 $newArray = fillArray(number: 2, arrayToFill: []);

Normal bir örnek, ancak kodu daha okunaklı hale de getirebilir.

Bu teknik, yalnızca kullanıcı tanımlı olanlarla değil, PHP'deki tüm işlevlerle çalışır. PHP dilinde, dizi ve dize işlevleri, aynı olmayan parametre sıralarına sahiptir. Yani, gerçekten hoş bir ek.

Nitelikler V2 ( RFC1 RFC2 RFC3 )

Öznitelikler, meta verileri PHP sınıflarına, işlevlere, sınıf özelliklerine, işlev parametrelerine ve sabitlere eklemek için bir mekanizma sağlar. Bunlara doğrudan kod aracılığıyla erişilemezler ve bunları, yansıma sınıflarında yerleşik PHP yardımıyla çıkarmanız gerekir.

ReflectionClass sınıfı PHP5'ten beri PHP'dedir; ancak getAttribute() yöntemi PHP8 için yenidir. Bu yöntem, öznitelikler hakkındaki bilgileri kucaklayacak bir dizi ReflectionAttribute nesnesi döndürür.

Bu ekleme, birkaç değişiklikle karşı karşıya kaldı (yukarıdaki birden çok RFC'den fark edebileceğimiz gibi). Sınıfı başlatmanız durumunda, ReflectionClass'ı kullanabilir ve bir sınıf düzeyinde bulunan öznitelik bilgilerini yazdırabilirsiniz. PHP8'de nitelikler oldukça fazladır, bu nedenle RFC'leri okumanızı ve gerçekte ne olduklarını ve bunları kodunuza nasıl entegre edebileceğinizi öğrenmenizi öneririz.

Eşleşme ifadesi ( RFC )

PHP 8'de, yeni eşleşme ifadesini bir steno anahtarı ifadesiyle karşılaştırabiliriz.

Girilen değer temelinde bir değer döndürecek bir işlev bildirimi gibi görünüyor.

PHP'deki switch ifadesi, birden çok if ifadesini birlikte eklemeden aynı ifadenin durumunu kontrol etmek istediğinizde harikadır.

Burada, özdeş bir ifade üzerinde temel bir if-else karşılaştırması getiriyoruz.

 <?php if ($i == 'apple') { echo 'i is apple'; } elseif ($i == 'cake') { echo 'i is cake'; } else { echo 'i is pizza'; }

Ve bu, önceki örneğimizin eşdeğer switch ifadesinin nasıl görüneceğidir.

 <?php switch ($i) { case 'apple': echo 'i is apple'; break; case 'cake': echo 'i is cake'; break; default: echo 'i is pizza'; }

Kaynak "Sınıflar"

Kaynak “sınıfları” PHP 8'deki büyük değişiklikler listesinde yer alır ve verilen kaynak türleri için anlık olmayan ikameler olarak hizmet eder. Mevcut değiştirmelerin şunları içerdiğini öğrenmek için aşağıya bakın:

  • CurlHandle — curl_init() şimdi bir curl kaynağıyla ilgili olarak CurlHandle'ı döndürür.
  • Socket / AddressInfo — Soket uzantısı tarafından verilir; socket_*() işlevlerinin miktarı bir Socket döndürürken, socket_address_info_lookup() işlevi bir AddressInfo örneği döndürür.
  • GdImage — Çok sayıda imagecreatefrom*() işlevi tarafından geri yüklenen bir GD kaynağını temsil eder.

Ayrıca, kaynakların curl_close() gibi işlevler tarafından yok edilmediğine dikkat etmek çok önemlidir. Bunun yerine, artık bir sınıf örneği olduğu için referansını kaldırmak için örneğin ayarını kaldırmanız () gerekir.
Fonksiyonlarınızda ve metotlarınızda sınıfları yazı tipi olarak belirleme yeteneği kazanırsınız.
Daha önce, yazılmamış değerleri döndürmemiz veya kaynak bağımsız değişkenleri bırakmamız ve bunları ek açıklamalar yoluyla belgelememiz gerekiyordu, ancak şimdi, açık türlere sahip olabilirsiniz ve bu, kodunuzu yalnızca daha okunabilir kılmakla kalmaz, aynı zamanda daha güvenli bir hale getirir.
Buradaki takas nedir?
Kaynakları yok etmek için kullanılan önceki işlevlerin yerine unset() yardımıyla kaynakları yok etmek istiyorsanız şimdi kodunuzu güncellemeniz gerekecek. Bu normalde arama ve değiştirme yoluyla gerçekleştirilebilir.

Yansıma API Değişiklikleri

Başka bir küçük, ancak PHP 8'deki hayati bir değişiklik, Reflection API ile ilgilidir. Öznitelik sistemini kullanırken, bu öznitelikleri, yansıma sınıfları ne olursa olsun, Yansıma API'si aracılığıyla rahatlıkla alabilirsiniz.
Karışık ve birleşim türlerinin eklenmesiyle, ReflectionParameter teknikleri getClass(), isCallable() ve isArray() artık kullanımdan kaldırılmıştır.
Senaryo böyledir, çünkü getType()'ı kullanmak çok daha iyidir ve belirli bir parametrenin karşıladığı türlerin tam listesini alırsınız.

PHP 8 Sözdizimi İyileştirmeleri

Fark ettiğimiz gibi, JIT manşetleri çalıyor; PHP 8 sözdizimsel iyileştirmeleri, PHP geliştiricileri için büyük yaşam kalitesi avantajları sağlar.
Yükseltilmiş kurucu argümanları arasında yaygın olan ortak kalıp levhasını ortadan kaldırmak veya geliştirilmiş istisna ve hata işlemesi ne olursa olsun, geliştiricilerin heyecan duyacakları çok şey var.

  • "karışık" sözde tip
  • Birlik Türleri
  • Sınıf Oluşturucu mülk promosyonu
  • İfadelerden istisnalar atma
  • Öznitellikler
  • ::sınıf yaygınlığı
  • Yalnızca türe göre yakalayın
  • Eşleşme İfadeleri

Bu blogun amaçlarını sürdürmek için birleşim türlerine, niteliklere ve eşleşme ifadelerine odaklanıyoruz.

Birlik Türleri

Birleşim türleri, bir değerin iki veya daha fazla belirtilen türden biri olduğunu gösterir. İzin verilen her tür arasına yerleştirilmiş dikey bir çubukla yapılır. Değerleri döndürmek veya parametrelerinizi belirlemek için PHP ek açıklamalarıyla ilgilenen birkaç geliştirici için, büyük olasılıkla bunu zaten yapıyorsunuz.
Birlik türleri, çok sayıda farklı türü kabul eden veya çok sayıda farklı türü iade edenler için anlamada çok karmaşıklık ve zorluk getirebilir.
Yine de, bu birkaç durumda çok yararlı olacaktır. Örneğin, yeni Stringable arabirimini (“string|Stringable”) uygulayan bir nesneyi veya bir dizeyi kabul edebilmeniz veya Traversable arabirimini uygulayan bir nesneyi (“array|Traversable”) veya bir diziyi kabul edebilmeniz durumunda .

Eşleşme İfadeleri

Eşleştirme ifadeleri, belirli bir anahtar durumunda kırılmanın kasıtlı olup olmadığını anlamaya yönelik tahminleri keser. Aynı zamanda, bir eşleşme temelinde bir değer atamanın normal düzenini de basitleştirir.
Kullanıldığında, match() öğesine ilettiğimiz değer, sol taraftaki ifade ne olursa olsun doğrudan karşılaştırılacaktır. Bu bir ifade veya değer ne olursa olsun, eşleşmeye () ilettiğiniz değerin seçilebilmesi için onunla eşleşmesi gerekir.
Eşleştirildiğinde, sağda bulunan ifade tahmin edilir ve dönüş değeri döndürülürken ifadeler yalnızca Lambda veya çağrılabilir işlevler olabilir ve çok satırlı kapatmalara izin verilmez.

Öznitellikler

PHP 8, öznitelikleri dil düzeyinde de bütünleştirir. Öznitelikler, docblock ek açıklamaları aracılığıyla 15 yıldan fazla bir süredir mevcut olsa da, bunları dile yerleştirmek daha iyi performans ve kesinlikle daha fazla güç ve daha fazla tutarlılık sunar. Takımların ve hızlı uygulamaların geliştirilmesinde yüksek oranda kullanılan öznitelikleri büyük olasılıkla göreceğiz.

Çözüm

Kesinlikle, PHP8'e giden bazı değişiklikler var. Yine de, kullanımdan kaldırılan kodun çoğunluğunun son zamanlarda kullanıldığını görmediğimiz eski özellikler için olduğu görülüyor.
JIT motorunun kullandığımız kod tabanları üzerinde ve ayrıca daha geniş PHP topluluğu üzerinde ne gibi bir etkisi olacağını görmekle oldukça ilgileniyoruz - PHP8 ile uyumsuzluklar için kod tabanınızı taramanızı ve PHP'nizin olduğundan emin olmak için birim testleri çalıştırmanızı şiddetle tavsiye ediyoruz. uygulamalar, yükseltmeye "evet" demeden önce mükemmel şekilde çalışır.