Kurucular
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.
İ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, true);
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
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.