Kurucular ve Yıkıcılar

Kurucular

__construct(mixed...$değerler = ""): void

PHP geliştiricilerin sınıflar için kurucu yöntemler bildirmesine imkan verir. Bir kurucu yöntemi olan sınıflar her yeni nesne oluşturuluşunda bu yöntemi çağırırlar, bu bakımdan nesne kullanılmadan önce yapılması gereken ilklendirmeler için kurucular çok uygundur.

Bilginize: Çocuk sınıflardan kurucusu olanlar için örtük olarak ebeveyn sınıfın kurucusu çağrılmaz. Ebeveyn sınıfın kurucusunu çocuk sınıftan çağırmak için, çocuk sınıf içinden parent::__construct() çağrısı yapılması gerekir. Çocuğun bir kurucu tanımlamaması halinde, normal sınıf yöntemi gibi (eğer private olarak tanımlanmadıysa) ana sınıftan miras alınabilir.

Örnek 1 - Miras almada kurucuların kullanımı

<?php
class AnaSınıf {
function
__construct() {
print
"AnaSınıf kurucusundayız\n";
}
}

class
AltSınıf extends AnaSınıf {
function
__construct() {
parent::__construct();
print
"AltSınıf kurucusundayız\n";
}
}

class
DiğerAltSınıf extends AnaSınıf {
// AnaSınıf'ın kurucusunu miras alır
}

// AnaSınıf kurucusunda
$obj = new AnaSınıf();

// AnaSınıf kurucusunda
// AltSınıf kurucusunda
$obj = new AltSınıf();

// AnaSınıf kurucusunda
$obj = new DiğerAltSınıf();
?>

Diğer yöntemlerin tersine, __construct() genişletilirken olağan bağımsız değişken sırası uyumluluk kurallarından muaftır.

Kurucular, karşılık gelen nesnelerinin somutlaştırılması sırasında çağrılan sıradan yöntemlerdir. Bu nedenle, gerekli olabilen, bir türe ve öntanımlı bir değere sahip olabilen rastgele sayıda bağımsız değişken tanımlayabilirler. Kurucu bağımsız değişkenleri, sınıf adından sonra gelen parantezlerin içine yerleştirilerek çağrılır.

Örnek 2 - Kurucu bağımsız değişkenlerinin kullanımı

<?php
class Point {
protected
int $x;
protected
int $y;

public function
__construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}
// Bağımsız değişkenlerin ikisini de aktaralım
$p1 = new Point(4, 5);
// Yalnız gerekli bağımsız değişkeni aktaralım.
// $y öntanımlı olan 0 değerini alır.
$p2 = new Point(4);
// isimli bağımsız değişken kullanımı (PHP 8.0 ve sonrası):
$p3 = new Point(y: 5, x: 4);
?>

Bir sınıf kurucuya sahip değilse veya kurucu bağımsız değişkensizse yaylı ayraçlar konmayabilir.

Eski tarz kurucular

PHP 8.0.0'dan önce, genel isim alanındaki sınıflar, eski tarz kurucu ile aynı adı taşıyan bir yöntemi yorumlar. Bu sözdizimi kaldırılmış olup bir E_DEPRECATED hatasıyla sonuçlanırsa da yöntem yine de bir kurucu olarak çağrılır. Hem __construct() hem de aynı adı taşıyan yöntem tanımlanmışsa __construct() çağrılır.

İsim alanlı sınıflarda veya PHP 8.0.0 öncesinde herhangi bir sınıfta, sınıfla aynı ismi taşıyan bir yöntemin özel bir anlamı yoktur.

Yeni kodlarda daima __construct() kullanın.

Kurucu Tanıtımı

PHP 8.0.0'dan itibaren, kurucu bağımsız değişkenleri de bir nesne özelliğine karşılık gelecek şekilde tanıtılabilir. Kurucu bağımsız değişkenlerinin kurucudaki bir özelliğe atanması, ancak başka şekilde çalıştırılmaması çok yaygındır. Kurucu tanıtımı, bu kullanım durumu için kestirme bir yol sağlar. Yukarıdaki örnek aşağıdaki gibi yeniden yazılabilir.

Örnek 3 - Kurucu özelliği tanıtımının kullanımı

<?php
class Point {
public function
__construct(protected int $x, protected int $y = 0) {
}
}

Bir kurucu bağımsız değişkeni değiştirici içerdiğinde, PHP bunu hem nesne özelliği hem de kurucu bağımsız değişkeni olarak yorumlar ve özelliğe bağımsız değişkenin değerini atar. Kurucu gövdesi boş olabilir veya başka ifadeler içerebilir. Bu ifadeler, bağımsız değişken değerleri karşılık gelen özelliklere atandıktan sonra yorumlanır.

Tüm bağımsız değişkenlerin tanıtımı gerekmez. Tanıtılan ve tanıtılmayan bağımsız değişkenleri herhangi bir sırayla karıştırmak ve eşleştirmek mümkündür. Tanıtılan bağımsız değişkenlerin kurucuyu çağıran kod üzerinde hiçbir etkisi yoktur.

Bilginize:

Görünürlük değiştirici (public, protected veya private) kullanımı, özellik tanıtımı yapmanın en olası yoludur, ancak diğer herhangi bir tek değiştirici de (salt okunur gibi) aynı etkiye sahip olacaktır.

Bilginize:

Nesne özellikleri, ortaya çıkabilecek motor belirsizliği nedeniyle callable türde olamaz. Tanıtılan bağımsız değişkenler de bu nedenle callable türde olamaz. Bununla birlikte, başka herhangi bir tür bildirimine izin verilir.

Bilginize:

Tanıtılan özellikler, hem özellik hem de işlev bağımsız değişkenlerinin yeniden yorumlanmasını sağladığından, hem özellikler hem de bağımsız değişkenler için tüm adlandırma kısıtlamaları geçerlidir.

Bilginize:

Tanıtılan kurucu bağımsız değişkenlerine yerleştirilen öznitelikler, hem özelliğe hem de bağımsız değişkene atanır. Tanıtılan kurucu bağımsız değişkenindeki öntanımlı değerler, özelliğe değil, yalnızca bağımsız değişkene atanır.

İlkendiricilerde new kullanımı

PHP 8.1.0 ve sonrasında, nesneler öznitelik bağımsız değişkenlerinin yanısıra öntanımlı bağımsız değişkenler, statik bağımsız değişkenler ve küresel sabitler olarak kullanılabilmektedir. Buna ek olarak, nesneler define()'a da aktarılabilmektedir.

Bilginize:

Dinamik veya dizge olmayan bir sınıf adının veya anonim bir sınıfın kullanımına izin verilmez. Bağımsız değişken genişletmeye izin verilmez. Desteklenmeyen ifadelerin bağımsız değişken olarak kullanımına izin verilmez.

Örnek 4 Using new in initializers

<?php

// All allowed:
static $x = new Foo;

const
C = new Foo;

function
test($param = new Foo) {}

#[
AnAttribute(new Foo)]
class
Test {
public function
__construct(
public
$prop = new Foo,
) {}
}

// Hiçbirine izin verilmez (derleme-anı hatası):
function test(
$a = new (CLASS_NAME_CONSTANT)(), // dinamik sınıf adı
$b = new class {}, // anonim sınıf
$c = new A(...[]), // bağımsız değişken genişletme
$d = new B($abc), // desteklenmeyen sabit ifadesi
) {}
?>

Statik kurucu yöntemleri

PHP, sınıf başına yalnızca tek bir kurucuyu destekler. Bununla birlikte, bazı durumlarda, bir nesnenin farklı girdilere sahip farklı yollarla oluşturulabilmesi istenebilir. Bunu yapmanın önerilen yolu, kurucu sarmalayıcıları olarak statik yöntemler kullanmaktır.

Örnek 5 - Statik kurucu yöntemlerinin kullanımı

<?php
class Product {

private ?
int $id;
private ?
string $name;

private function
__construct(?int $id = null, ?string $name = null) {
$this->id = $id;
$this->name = $name;
}

public static function
fromBasicData(int $id, string $name): static {
$new = new static($id, $name);
return
$new;
}

public static function
fromJson(string $json): static {
$data = json_decode($json);
return new static(
$data['id'], $data['name']);
}

public static function
fromXml(string $xml): static {
// Özelleştirmeler buraya.
$data = convert_xml_to_array($xml);
$new = new static();
$new->id = $data['id'];
$new->name = $data['name'];
return
$new;
}
}

$p1 = Product::fromBasicData(5, 'Widget');
$p2 = Product::fromJson($some_json_string);
$p3 = Product::fromXml($some_xml_string);

Kurucu, haricen çağrılmasını önlemek için özel veya korumalı yapılabilir. Bu durumda, sınıfı yalnızca statik bir yöntem örnekleyebilir. Aynı sınıf tanımında olduklarından, aynı nesne örneğinde olmasa bile özel yöntemlere erişebilirler. Özel kurucu isteğe bağlıdır ve kullanım durumuna bağlı olarak anlamlı olabilir veya olmayabilir.

Nesneyi örneklemenin farklı yollarını göstermek için üç tür public static yöntem vardır.

  • fromBasicData() gerekli bağımsız değişkenleri alıp kurucuyu çalıştırarak nesney oluşturur vesonucu döndürür.
  • fromJson() bir JSON dizesi alıp bazı önişlemlerden geçirip kurucuya gereken biçime dönüştürür ve yeni nesneyi döndürür.
  • fromXml() bir XML dizesi alıp önişemden geçirerek çıplak bir nesne oluşurur. Kurucu hala çağrılabilirse de bağımsız değişkenlerin tamamı seçimlik olduğundan yöntem bunları yoksayar. Sonucu döndürmeden önce değerleri doğrudan nesne özelliklerine atar.

Üç durumda da, static anahtar sözcüğü, kodun bulunduğu sınıfın adına çevrilir. Bu durumda, Product.

Yıkıcılar

__destruct(): void

PHP C++ gibi nesne yönelimli dillerdekine benzer bir yıkıcı tasarımına sahiptir. Yıkıcı yöntem, belli bir nesneye başka bir gönderim yoksa veya nesne kapanma sırasında açıkça yok edildiği anda çalıştırılacaktır.

Örnek 6 - Yıkıcı Örneği

<?php
class YıkıcıSınıf
{
function
__construct()
{
print
"Kurucu çalıştı\n";
}

function
__destruct()
{
print
"" . __CLASS__ . " yok ediliyor\n";
}
}

$obj = new YıkıcıSınıf();
?>

Kurucularda olduğu gibi ebeveyn yıkıcılar çocuk sınıflar için dolaylı olarak çağrılmayacaktır. Ebeveyn sınıfın yıkıcısının çalışması için çocuk sınıfın yıkıcısından parent::__destruct() çağrısının yapılması gerekir. Ayrıca, kuruculardaki gibi, bir çocuk sınıf kendisininkini gerçeklemediyse ebeveyninin yıkıcısını miras alabilir.

Betiğin icrası exit() kullanılarak durdurulsa bile yıkıcı çağrılacaktır. exit() işlevinin bir yıkıcı içersinde çağrılması kalan kapanma yordamlarının icrasını engelleyecektir.

Bilginize:

Yıkıcılar, HTTP başlıklarının gönderilmiş olmasını sağlamak için betik sonlanırken çağrılırlar. Betiğin kapanma aşamasındaki çalışma dizini bazı SAPI’lerde (Apache gibi) farklı olabilir.

Bilginize:

Bir yıkıcı içinden bir istisna oluşturmaya çalışmak (betiğin sonlandırılması sırasında) ölümcül hata ile sonuçlanır.

To Top