5. Sınıflar
Sözlük: Bir sınıf (class), bir PHP türüdür. Bu türden bir değişkene nesne denir. Bir nesne, sınıfın bir örneğidir.
5.1. Komut dosyalarının ağaç yapısı

5.2. Herhangi bir değişken, özniteliklere sahip bir nesne haline gelebilir
[classes-01.php] komut dosyası şu şekildedir:
<?php
// genel bir nesne
// $obj1=new stdClass();
// Her değişken, yapısı gereği özniteliklere sahip olabilir
$obj1->attr1 = "un";
$obj1->attr2 = 100;
// nesneyi görüntüler
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
// nesneyi değiştirir
$obj1->attr2 += 100;
// nesneyi görüntüler
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
// nesne1'in değerini (işaret edilen nesnenin adresi) nesne2'ye kopyalar
// bu durumda iki değişken farklıdır ancak aynı nesneye işaret eder
$obj2 = $obj1;
// obj2'yi değiştirir
$obj2->attr2 = 0;
// iki nesneyi görüntüler
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
print "objet2=[$obj2->attr1,$obj2->attr2]\n";
// obj1'in işaret ettiği nesneyi değiştirir
$obj1 = new stdClass();
print "obj1 :\n";
print_r($obj1);
print "obj2 :\n";
print_r($obj2);
// objet2'nin referansını (adresini) objet3'e atar
// $obj2 ve $obj3 artık tek ve aynı değişkendir
$obj3 = &$obj2;
print "obj2 :\n";
print_r($obj2);
print "obj3 :\n";
print_r($obj3);
// obj3'ü değiştirir
$obj3->attr2 = 10;
// iki nesneyi de görüntüler
print "objet2=[$obj2->attr1,$obj2->attr2]\n";
print "objet3=[$obj3->attr1,$obj3->attr2]\n";
//, obj2'nin işaret ettiği nesneyi değiştirir
$obj2 = new stdClass();
$obj2->attr3 = "deux";
$obj2->attr4 = 20;
//, $obj2 ve $obj3 adlı iki nesneyi görüntüler
print "obj2 :\n";
print_r($obj2);
print "obj3 :\n";
print_r($obj3);
// bir nesne bir sözlük mü?
print count($obj3) . "\n";
while (list($attribut, $valeur) = each($obj3)) {
print "obj3[$attribut]=$valeur\n";
}
// son
exit;
Sonuçlar:
Warning: Creating default object from empty value in C:\Data\st-2019\dev\php7\php5-exemples\exemples\exemple_14.php on line 6
objet1=[un,100]
objet1=[un,200]
objet1=[un,0]
objet2=[un,0]
obj1 :
stdClass Object
(
)
obj2 :
stdClass Object
(
[attr1] => un
[attr2] => 0
)
obj2 :
stdClass Object
(
[attr1] => un
[attr2] => 0
)
obj3 :
stdClass Object
(
[attr1] => un
[attr2] => 0
)
objet2=[un,10]
objet3=[un,10]
obj2 :
stdClass Object
(
[attr3] => deux
[attr4] => 20
)
obj3 :
stdClass Object
(
[attr3] => deux
[attr4] => 20
)
Warning: count(): Parameter must be an array or an object that implements Countable in C:\Data\st-2019\dev\php7\php5-exemples\exemples\exemple_14.php on line 50
1
Deprecated: The each() function is deprecated. This message will be suppressed on further calls in C:\Data\st-2019\dev\php7\php5-exemples\exemples\exemple_14.php on line 51
obj3[attr3]=deux
obj3[attr4]=20
Açıklamalar
- 6. satır: $obj->attr notasyonu, $obj değişkeninin attr özniteliğini belirtir. Bu öznitelik mevcut değilse oluşturulur ve böylece $obj değişkeni, özniteliklere sahip bir nesne haline gelir. PHP'in varsayılan olarak stdClass türünde bir nesne oluşturduğunu görmüştük;
- 16. satır: $obj2=$obj1 ifadesi, $obj1 bir nesne olduğunda, referans yoluyla nesnelerin kopyalanmasıdır: $obj2 ve $obj1, aynı nesneye ait referanslardır (adreslerdir). Nesnenin kendisi, bu referanslardan herhangi biri aracılığıyla değiştirilebilir;
- 23-27. satırlar: $obj1 ve $obj2'in iki farklı değişken olduğunu göstermeyi amaçlamaktadır: bunlar aynı bellek adresinde değildir:
- $obj2=$obj1, $obj1'in değerini $obj2 değişkenine kopyalamıştır (yukarıdaki işlem 1). $obj1'in değeri bir nesnenin adresidir. Dolayısıyla $obj1 ve $obj2 aynı nesneye işaret eder. $obj değişkeni ile işlem yapıldığında ve bu değişken bir nesneye işaret ediyorsa, PHP, $obj değişkeninin işaret ettiği nesneyi işler. Aşağıdaki şemaya göre, işaret edilen nesneyi hem $obj1 hem de $obj2 aracılığıyla değiştirebileceğimiz görülmektedir. Sonuçların 4. ve 5. satırları da bunu göstermektedir;

- 30. satır: $obj3=&$obj2 ifadesi, $obj2 ve $obj3'in aynı adres olan [1 ci-dessous]'te olmasını sağlar. Bu iki değişkenin aynı bellek konumunun takma adları olduğu söylenebilir. Her ikisi de aşağıdaki Nesne A’ya işaret eder: [2];
- $obj2=new stdClass() işlemi, yeni bir nesne olan Nesne B'nin ([3 ci-dessous]) oluşturulmasını sağlar ve bu yeni nesnenin adresi $obj2 değişkenine atanır. $obj2 ve $obj3, aynı bellek konumunun iki takma adı olduğundan, $obj3 de yeni Nesne B'ye işaret eder. Sonuçların 16-27 ve 30-41. satırları bunu göstermektedir;

- 52-54. satırlar: Bir nesnenin sözlük gibi taranabileceğini gösterir. Sözlüğün anahtarları özniteliklerin adları, değerleri ise bu özniteliklerin değerleridir;
- 51. satır: count işlevi bir nesneye uygulanabilir (bir uyarı ile), ancak beklendiği gibi öznitelik sayısını vermez. Dolayısıyla bir nesne, sözlükle benzerlikler gösterir ancak bir sözlük değildir;
5.3. Bildirilmiş öznitelikleri olmayan bir Personne sınıfı
[classes-02.php] komut dosyası şöyledir:
<?php
class Personne {
// sınıf öznitelikleri
// bildirilmemiş - dinamik olarak oluşturulabilir
// yöntem
function identite() {
// ilk bakışta, mevcut olmayan öznitelikler kullanıyor
return "[$this->prenom,$this->nom,$this->age]";
}
}
// test
// özellikler genel ve dinamik olarak oluşturulabilir
$p = new Personne();
$p->prenom = "Paul";
$p->nom = "Langevin";
$p->age = 48;
// yöntem çağrısı
print "personne=" . $p->identite() . "\n";
// son
exit;
Sonuçlar:
Açıklamalar
- 3-13. satırlar: Personne sınıfını tanımlar. Sınıf, nesnelerin oluşturulduğu bir kalıptır. Sınıf, öznitelikleri ve yöntem adı verilen işlevleri bir araya getirir. Özniteliklerin bildirilmesi zorunlu değildir;
- 8-11. satırlar: identité yöntemi, sınıfta bildirilmemiş üç özniteliğin değerini görüntüler. $this anahtar sözcüğü, yöntemin uygulandığı nesneyi belirtir;
- 17. satır: Personne türünde bir $p nesnesi oluşturulur. new anahtar sözcüğü, yeni bir nesne oluşturmak için kullanılır. Bu işlem, oluşturulan nesneye bir referans (yani bir adres) döndürür. Çeşitli yazım biçimleri mümkündür: new Personne(), new Personne, new personne. Sınıf adı büyük/küçük harf duyarlı değildir;
- 18-20. satırlar: identité yöntemine gerekli olan üç öznitelik, $p nesnesinde oluşturulur;
- 22. satır: Personne sınıfının identité yöntemi, $p nesnesine uygulanır. identité yönteminin kodunda (8-11. satırlar), $this, $p ile aynı nesneye başvurur;
5.4. Özellikleri bildirilmiş Personne sınıfı
[classes-03.php] komut dosyası şu şekildedir:
<?php
class Personne {
// sınıf öznitelikleri
var $prenom;
var $nom;
var $age;
// yöntem
function identite() {
return "[$this->prenom,$this->nom,$this->age]";
}
}
// test
// özellikler genel
$p = new Personne();
$p->prenom = "Paul";
$p->nom = "Langevin";
$p->age = 48;
// yöntem çağrısı
print "personne=" . $p->identite() . "\n";
// son
exit;
Sonuçlar:
Açıklamalar
- 6-8. satırlar: Sınıf öznitelikleri var anahtar sözcüğüyle açıkça tanımlanmıştır;
5.5. Oluşturucuya sahip Personne sınıfı
Önceki örneklerde, Personne gibi, PHP 4'te bulunabilecek sıra dışı sınıflar gösterilmişti. Bu örnekleri takip etmeniz tavsiye edilmez. Şimdi, PHP 7'deki iyi uygulamalara uygun bir Personne [classes-04.php] sınıfını sunuyoruz:
<?php
// fonksiyon parametrelerinin beyan edilen türlerine sıkı bir şekilde uyulması
declare (strict_types=1);
class Personne {
// sınıf öznitelikleri
private $prenom;
private $nom;
private $age;
// getter ve setter'lar
public function getPrenom(): string {
return $this->prenom;
}
public function getNom(): string {
return $this->nom;
}
public function getAge(): int {
return $this->age;
}
public function setPrenom(string $prenom): void {
$this->prenom = $prenom;
}
public function setNom(string $nom): void {
$this->nom = $nom;
}
public function setAge(int $age): void {
$this->age = $age;
}
// yapıcı
public function __construct(string $prenom, string $nom, int $age) {
// set yöntemleri kullanılır
$this->setPrenom($prenom);
$this->setNom($nom);
$this->setAge($age);
}
// toString yöntemi
public function __toString(): string {
return "[$this->prenom,$this->nom,$this->age]";
}
}
// test
// Kişi nesnesinin oluşturulması
$p = new Personne("Paul", "Langevin", 48);
// bu kişinin kimliği
print "personne=$p\n";
// yaşın değiştirilmesi
$p->setAge(14);
// kişinin kimliği
print "personne=$p\n";
// son
exit;
Sonuçlar:
Yorumlar
- 6-50. satırlar: Personne sınıfı;
- 7-9. satırlar: sınıfın özel (private) öznitelikleri. Bu öznitelikler yalnızca sınıfın içinde görülebilir. Kullanılabilecek diğer anahtar kelimeler şunlardır:
- public: özniteliği sınıfın dışından görülebilen bir öznitelik haline getirir,
- protected: özniteliği, sınıfın içinden ve ondan türetilen sınıflardan görülebilen bir protégé özniteliği haline getirir;
- Özellikler özel olduğundan, sınıfın dışından bunlara erişilemez. Dolayısıyla aşağıdaki kod yazılamaz:
Burada, Personne sınıfının dışındayız. nom özniteliği özel olduğundan, 2. satır hatalıdır. $p nesnesinin özel alanlarını başlatmak için iki yol vardır:
- 12-34. satırlardaki set ve get adlı genel yöntemleri kullanmak (bu yöntemlerin adı herhangi bir şey olabilir). Bu durumda şöyle yazabiliriz:
- 37-42. satırlardaki oluşturucuyu kullanmak. Bu durumda şöyle yazılır:
Yukarıdaki kod, Personne sınıfındaki __construct adlı yöntemi otomatik olarak çağırır;
- 59. satır: Bu satır, $p kişisini bir karakter dizisi biçiminde görüntüler. Bunun için, Personne sınıfının __toString adlı yöntemi (45-47. satırlar) kullanılır;
- sınıfın tüm yöntemleri (fonksiyonlar), fonksiyonun sınıfın dışında da görülebilir olduğunu belirten public anahtar sözcüğüyle ön eklenmiştir. Kullanılabilecek diğer anahtar sözcükler, özniteliklerde olduğu gibi ve aynı anlamla, private ve protected'tır. Açıkça belirtilmiş bir görünürlük özniteliği olmadığında, fonksiyonun görünürlüğü varsayılan olarak public'tir;
5.6. Oluşturucuda geçerlilik denetimleri içeren Personne sınıfı
Bir sınıfın oluşturucusu, nesnenin başlatma değerlerinin doğru olup olmadığını kontrol etmek için uygun yerdir. Ancak bir nesne, set veya eşdeğer yöntemleriyle de başlatılabilir. Aynı kontrolleri iki farklı yere yazmaktan kaçınmak için, bu kontrolleri set yöntemlerine yerleştirebiliriz. Bir nesnenin başlatma değerlerinden birinin yanlış olduğu tespit edilirse, bir istisna atılır. İşte bir örnek.
Öncelikle, Personne sınıfının tanımını kendi dosyası olan [Personne.php]'e taşıyoruz:
<?php
// fonksiyon parametrelerinin beyan edilen türlerine sıkı sıkıya uyulması
declare (strict_types=1);
// ad alanı;
namespace Exemples;
// Personne sınıfı
class Personne {
// sınıfın öznitelikleri
private $prenom;
private $nom;
private $age;
// getter ve setter'lar
public function getPrenom(): string {
return $this->prenom;
}
public function getNom(): string {
return $this->nom;
}
public function getAge(): int {
return $this->age;
}
public function setPrenom(string $prénom): void {
// ad alanı boş olmamalıdır
$prénom = trim($prénom);
if ($prénom === "") {
throw new \Exception("Le prénom doit être non vide");
} else {
$this->prenom = $prénom;
}
}
public function setNom(string $nom): void {
// soyadı boş olmamalıdır
$nom = trim($nom);
if ($nom === "") {
throw new \Exception("Le nom doit être non vide");
} else {
$this->nom = $nom;
}
}
public function setAge(int $âge): void {
// yaş geçerli olmalıdır
if ($âge < 0) {
throw new \Exception("L'âge doit être un entier positif ou nul");
} else {
$this->age = $âge;
}
}
// yapıcı
public function __construct(string $prenom, string $nom, int $age) {
// set yöntemleri kullanılır
$this->setPrenom($prenom);
$this->setNom($nom);
$this->setAge($age);
}
// yöntem
public function initWithPersonne(Personne $p): void {
// geçerli nesneyi bir kişiyle başlatır $p
$this->__construct($p->prenom, $p->nom, $p->age);
}
// yöntem toString
function __toString(): string {
return "[$this->prenom,$this->nom,$this->age]";
}
}
Açıklamalar
- 4. satır: fonksiyon parametrelerinin türlerinin, tanımlandıkları şekilde korunması istenir;
- 7. satır: bir ad alanı (namespace) tanımlar. Personne sınıfının tam adı (qualifié olarak adlandırılır) bu durumda \Exemples\Personne olur. Nitelikli adın başında yer alan \ karakterine dikkat edin: bu durumda nitelikli ad absolu olur. Bu karakter yoksa, nitelikli ad relatif olur (geçerli ad alanına göre). Dolayısıyla, A ve B sınıfları aynı E ad alanına aitse, A sınıfının kodunda B sınıfına relative B notasyonu ile erişilebilir. A sınıfı E1 ad alanına, B sınıfı ise E2 ad alanına aitse, A sınıfının kodunda B sınıfına absolue \E2\ notasyonu ile erişilir.B. Bir ad alanı içinde sınıf tanımlamak zorunlu değildir, ancak NetBeans bunu yapmazsanız bir uyarı verir. Bu nedenle bunu yapacağız. Ayrıca, ad alanları dosya dizin yapısına uygun olmalıdır. Dolayısıyla, E1 ad alanında bulunan A sınıfı, E1/A.php dosyasının içinde yer almalıdır. Bu zorunlu değildir, ancak yine de yapılmazsa NetBeans bir uyarı verir. [\Exemples\Personne] sınıfı örneğinde, [Personne.php] dosyasının dizin yapısı [exemples/classes/Personne.php] olduğu ve dolayısıyla ad alanıyla uyuşmadığı için NetBeans bir uyarı verir. Ağaç yapısı ile ad alanı karıştırılmamalıdır. Bir sınıfın tam nitelikli adı bir ad alanı kullanır ve sınıfın PHP dosyasının ağaç yapısıyla hiçbir ilgisi yoktur. Ağaç yapısı ile ad alanı arasındaki bağlantı isteğe bağlıdır ve burada yaptığımız gibi göz ardı edilebilir;
- 12-14. satırlar: sınıfın üç özel özniteliği;
- 29-37. satırlar: prenom özniteliğinin başlatılması ve başlatma değerinin doğrulanması;
- 31. satır: trim($chaine) işlevi, $chaine'in başındaki ve sonundaki boşlukları kaldırır. Dolayısıyla trim("abcd ") "abcd" dizesi olur ve trim" " ise boş bir dize olur;
- 32. satır: İsim boşsa bir istisna atılır (33. satır), aksi takdirde isim kaydedilir (35. satır). Burada istisna atmak için önceden tanımlanmış [Exception] sınıfı kullanılmıştır. Burada, sınıfın mutlak adı olan [\Exception]'i kullanmak zorundayız. Eğer göreceli adı olan [Exception] kullanılırsa, bu sınıf o anki ad alanında, yani Personne sınıfının [Exemples] ad alanında aranacaktır. Böylece PHP yorumlayıcısı, mevcut olmayan [\Exemples\Exception] adlı bir sınıfı arayacaktır;
[Personne] sınıfı, aşağıdaki [classes-05.php] betiği tarafından kullanılır:
<?php
// fonksiyon parametrelerinin türüne sıkı bir şekilde uyulur
declare(strict_types=1);
// Personne sınıfının tanımının dahil edilmesi
require_once __DIR__."/Personne.php";
// Personne sınıfının nitelikli adı
use \Exemples\Personne;
// test
// Personne nesnesinin oluşturulması
$p = new Personne("Paul", "Langevin", 48);
// bu kişinin kimliği
print "Exemple1, personne=$p\n";
// hatalı bir Kişi nesnesinin oluşturulması
try {
$p = new Personne("xx", "yy", "zz");
} catch (\Exception $e1) {
print "Exemple2, erreur : " . $e1->getMessage() . "\n";
} catch (\TypeError $e2) {
print "Exemple2, erreur : " . $e2->getMessage() . "\n";
}
// hatalı bir Kişi nesnesinin oluşturulması
try {
$p = new Personne("", "yy", 10);
} catch (\Exception $e1) {
print "Exemple3, erreur : " . $e1->getMessage() . "\n";
} catch (\TypeError $e2) {
print "Exemple3, erreur : " . $e2->getMessage() . "\n";
}
// son
exit;
Yorumlar
- 7. satır: Komut dosyası, [Personne] sınıfını kullanacaktır. Bu durumda, PHP yorumlayıcısına bu sınıfın tanımını nerede bulabileceğini belirtmek gerekir. Bu, [include fichier] ve [require fichier] komutlarının görevidir. Burada ise [include] komutu kullanılmıştır. İki komut arasındaki fark şudur: [include fichier] komutu, [fichier]'i yüklerken hatalarla karşılaşırsa, [E_WARNING] düzeyinde bir hata verilir, ancakyürütme devam eder; oysa aynı durumda [require] komutu ölümcül bir hata üretir ve komut dosyasının yürütülmesi durur. Her iki komutun da [include_once] ve [require_once] adlı varyantları vardır. Bu iki varyant, aynı dosyanın birden fazla kez dahil edilmesi durumunu yönetmeye olanak tanır. Burada, birkaç PHP komut dosyasından oluşan ve bunlardan birçoğunun [Personne] sınıfına başvurduğu bir proje düşünülür. Bu komut dosyalarının çalıştırılması, [Personne.php] dosyasının birden fazla kez dahil edilmesine neden olacak ve bir sınıfın iki kez tanımlanamayacağı için bir hata ortaya çıkaracaktır. Çözüm, dosyanın projenin genel komut dosyasına yalnızca bir kez dahil edilmesini sağlayan [_once] varyantlarını kullanmaktır;
- 7. satır: [__DIR__] sabiti, PHP sabitidir ve [__DIR__] sabitini içeren komut dosyasının bulunduğu klasörün tam adını belirtir. Dolayısıyla, 17. satırdaki ifade:
require_once __DIR__."/Personne.php";
şuna eşdeğer olacaktır:
require_once ‘C:\Data\st-2019\dev\php7\php5-exemples\exemples\classes/Personnes.php’
Dosya yolunda / ve \ işaretleri birbirinin yerine kullanılabilir;
- 14. satır: Az önce tanımladığımız [Personne] sınıfı kullanılmaktadır. [classes-05.php] komut dosyasında ad alanı yoktur. 14. satırda, [Personne] sınıfının ad alanı içermeyen göreceli adı kullanılmaktadır. [Personne] sınıfının ad alanı olmadığı için, bu sınıf [classes-05.php] komut dosyasında aranır ve dolayısıyla bulunamaz. Bu sorunun iki çözümü vardır:
- [\Exemples\Personne] sınıfının tam adını kullanmak;
- 10. satırdaki use deyimini kullanmak. Bu, takip eden kodun [\Exemples\Personne] sınıfını kullandığını belirtir;
- 10. satır: use komutu, yorumlayıcının 14. satırda atıfta bulunulan [Personne] sınıfının aslında [\Exemples\Personne] sınıfı olduğunu bilmesini sağlar. Peki, yorumlayıcı bu sınıfın kodunu nereden bulacak? Bunu 7. satır belirtir. Bu satır, mevcut komut dosyasını çalıştırmak için [Personne.php] komut dosyasının da yüklenmesi gerektiğini gösterir. Burada dosyanın göreceli adı kullanılmıştır. Dolayısıyla, bu dosya [classes-05.php] komut dosyasını içeren klasörde aranacaktır. Bu nedenle, [Personne.php] ve [classes-05.php] komut dosyalarının aynı klasörde olması gerekir. Burada durum böyledir; her ikisi de [exemples/classes] klasöründedir. 10. satırdaki komut şuna eşdeğerdir:
use \Exemples\Personne as Personne;
Yukarıdaki [use] komutu, [Personne] takma adının [\Exemples\Personne] sınıfını işaret ettiğini belirtir;
- 14. satır: bir [Personne] nesnesi oluşturulur. Burada, [Personne] sınıfının [__construct] yöntemi örtük olarak yürütülecektir;
- 16. satır: $p Kişisini görüntüler. Ekrana yansıtılabilmesi için $p değişkeninin değeri bir karakter dizisine dönüştürülmelidir. Bu durumda, örtük olarak [Personne.__toString] yöntemi yürütülür. Dolayısıyla bu yöntem bir karakter dizisi döndürmelidir;
- [Personne] sınıfının oluşturucusunun [\Exception] türünde bir istisna atabileceğini görmüştük. Bu nedenle bu istisnayı yönetmek gerekir. Dolayısıyla 14. satırdaki kod eksiktir. Oluşabilecek istisnayı doğru şekilde yönetmek için 18-24. satırlardaki kod kullanılmalıdır. Burada, tamsayı olmayan bir yaş değeri geçirerek kasıtlı olarak bir istisna üretiliyor. Bu özel durumda ortaya çıkan istisna, [Personne] sınıfının kodu tarafından değil, PHP yorumlayıcısı tarafından tetiklenir. Nitekim, [Personne.__construct] yönteminin imzası şöyledir:
function __construct(string $prenom, string $nom, int $age)
Bu nedenle, oluşturucuya aktarılan [age] parametresinin tamsayı türü olması gerekir. Aksi takdirde, PHP yorumlayıcısı, [TypeError] türünde bir hata verir. Ayrıca, [Personne] sınıfındaki [set] yöntemleri ise [\Exception] türünde bir istisna oluşturur. Bu yöntemleri çağıran yapıcıda try/catch yapısı bulunmadığından, istisna bir üst seviyeye, yani yapıcıyı çağıran koda, yani [classes-05.php] komut dosyasının koduna iletilir. Sonuç olarak, [classes-05.php] komut dosyası iki tür istisna alabilir: \Exception veya \TypeError. Geliştirici, belirli istisnaların meydana gelmeyeceğinden emin olduğunda, ilgili catch seçeneklerini kullanmayacaktır. Burada bunlar, yalnızca örnekleme amacıyla sistematik olarak kullanılmaktadır. Ancak catch seçenekleri, olasılığı düşük olsa bile tüm olası istisnalar için kullanılacaktır;
Bu nedenle, 18-24. satırlardaki try yapısı, iki istisna türünü ayrı ayrı yönetmek için iki catch içerir;
- 20. satır: [Exception] veya [\Exception] şeklinde yazılabilir:
- İlk versiyon, betiğin ad alanına göre sınıfın göreceli adını kullanır. Betiğin kendi ad alanı yoktur. Dolayısıyla betiğin ad alanı, ad alanlarının kökü olan \'dir. Bu nedenle, buraya [Exception] yazmak, [\Exception] yazmakla aynı anlama gelir. Oysa [Exception] sınıfı, [\] ad alanında yer almaktadır;
Ad alanı içermeyen bir komut dosyasında, PHP gibi önceden tanımlanmış istisnaların mutlak adını kullanmak daha uygundur. Böylece, bu komut dosyasına bir ad alanı atamaya karar verilirse, sınıfların mutlak adlarının yazımı geçerliliğini korur; oysa diğer durumda, ad alanındaki değişiklik sınıfların göreceli adlarında hatalara neden olacaktır;
- 21. satır: Bir istisna oluştuğunda, [Exception→getMessage] yöntemi istisnanın hata mesajını almayı sağlar. Aynı durum [TypeError] türündeki bir hata için de geçerlidir. [Personne.setPrenom] yönteminde şunlar yazılmıştır:
public function setPrenom(string $prénom) {
// ad alanı boş olmamalıdır
$prénom = trim($prénom);
if ($prénom === "") {
throw new \Exception("Le prénom doit être non vide");
} else {
$this->prenom = $prénom;
}
}
- satırda, [Le prénom doit être non vide] hata mesajıyla bir istisna atılır. [classes-05.php] komut dosyasının 29. satırındaki [Exception→getMessage] yöntemi bu istisnayı alır.
Sonuçlar:
Exemple1, personne=[Paul,Langevin,48]
Exemple2, erreur : Argument 3 passed to Exemples\Personne::__construct() must be of the type integer, string given, called in C:\Data\st-2019\dev\php7\php5-exemples\exemples\exemple_18.php on line 19
Exemple3, erreur : Le prénom doit être non vide
5.7. İkinci bir oluşturucu görevi gören bir yöntem eklenmesi
PHP 7'de, bir nesneyi çeşitli şekillerde oluşturmaya olanak tanıyan farklı parametrelere sahip birden fazla oluşturucu kullanmak mümkün değildir. Bu durumda, oluşturucu görevi gören yöntemler kullanılabilir:
// yöntem
public function initWithPersonne(Personne $p) {
// geçerli nesneyi bir Kişi ile başlatır $p
$this->__construct($p->prenom, $p->nom, $p->age);
}
Açıklamalar
- 2-5. satırlar: initWithPersonne yöntemi, başka bir Personne nesnesinin özniteliklerinin değerlerini geçerli nesneye atamaya olanak tanır. Burada, __construct oluşturucusunu çağırmaktadır, ancak bu zorunlu değildir. [Personne] sınıfının özniteliklerini kendisi de başlatabilir;
Yeni [Personne] sınıfı, aşağıdaki [classes-06.php] komut dosyası tarafından kullanılır:
<?php
// Kişi sınıfının tanımının dahil edilmesi
require_once __DIR__."/Personne.php";
// Personne sınıfının nitelikli adının bildirilmesi
use \Exemples\Personne;
// test
// Kişi nesnesinin oluşturulması
try {
$p = new Personne("Paul", "Langevin", 48);
} catch (\Exception $e) {
print "erreur : " . $e->getMessage();
exit;
}
// bu kişinin kimliği
print "personne=$p\n";
// ikinci bir kişinin oluşturulması
try {
$p2 = new Personne("Laure", "Adeline", 67);
} catch (\Exception $e) {
print "erreur : " . $e->getMessage();
exit;
}
// birincisinin, ikincisinin değerleriyle başlatılması
try {
$p->initWithPersonne($p2);
} catch (\Exception $e) {
print "erreur : " . $e->getMessage();
exit;
}
// doğrulama
print "personne=$p\n";
// son
exit;
- 14., 23. ve 30. satırlar: Bir istisna sonrasında, karşılaşılan hata düzeltilemezse konsol betiğinin yürütülmesini durdurmak sıkça gerekir. Web komut dosyasında durum böyle değildir: komut dosyasının yürütülmesi durdurulmaz, bunun yerine bir hata sayfası görüntülenir. Bir işlev içindeysek, exit komutu değil return komutu kullanılır: komut dosyasının yürütülmesini durdurmayız (exit), ancak bir hata ayarladıktan sonra işlevden çıkarız (return);
Sonuçlar:
5.8. [Personne] nesne dizisi
Aşağıdaki [classes-07.php] örneği, nesne dizilerinin olabileceğini göstermektedir.
<?php
require_once __DIR__."/Personne.php";
use \Exemples\Personne;
// test
// Kişi nesnelerinden oluşan bir dizi oluşturma
// kodun anlaşılmasını kolaylaştırmak için olası istisnalar işlenmez
$groupe = [new Personne("Paul", "Langevin", 48), new Personne("Sylvie", "Lefur", 70)];
// bu kişilerin kimlikleri
for ($i = 0; $i < count($groupe); $i++) {
print "groupe[$i]=$groupe[$i]\n";
}
// son
exit;
Sonuçlar:
Açıklamalar
- 9. satır: 2 kişilik bir dizi oluşturuluyor;
- 12. satır: tablonun taranması;
- 13. satır: $groupe[$i], Personne türünde bir nesnedir. [Personne.__toString] yöntemi, bu nesneyi görüntülemek için kullanılır;
5.9. Personne sınıfından türetilmiş bir sınıfın oluşturulması
[Enseignant.php] adlı bir dosyada aşağıdaki [Enseignant] sınıfı oluşturulur:
<?php
// fonksiyon parametrelerinin beyan edilen türlerine sıkı sıkıya uyulması
declare (strict_types=1);
// ad alanı
namespace Exemples;
// “kişi” sınıfından türetilmiş bir sınıf
class Enseignant extends Personne {
// özellikler
private $discipline; // öğretilen ders
// getter ve setter
public function getDiscipline(): string {
return $this->discipline;
}
public function setDiscipline(string $discipline): void {
$this->discipline = $discipline;
}
// yapıcı
public function __construct(string $prénom, string $nom, int $âge, string $discipline) {
// üst sınıf özellikleri
parent::__construct($prénom, $nom, $âge);
// diğer özellikler
$this->setDiscipline($discipline);
}
// üst sınıfın __toString işlevinin aşırı yüklenmesi
public function __toString(): string {
return "[" . parent::__toString() . ",$this->discipline]";
}
}
Açıklamalar
- 7. satır: [Enseignant] sınıfı da [Exemples] ad alanının bir parçasıdır;
- 10. satır: Enseignant sınıfı, Personne. sınıfından türetilmiştir (extends). Türetilmiş sınıf Enseignant, üst sınıfının özniteliklerini ve yöntemlerini miras alır;
- 12. satır: Enseignant sınıfı, kendisine özgü yeni bir discipline özniteliği ekler;
- 25. satır: Enseignant sınıfının oluşturucusu, ana sınıfını (ad, soyad, yaş) başlatmak için 3 parametre alır;
- 3 tanesi üst sınıfını başlatmak için (ad, soyad, yaş), satır 27;
- 1 tanesi kendi başlatılması için (disiplin), satır 29;
- 27. satır: türetilmiş sınıf, parent :: anahtar sözcüğü aracılığıyla üst sınıfının yöntemlerine ve oluşturucularına erişebilir. Burada parametreler (ad, soyad, yaş) üst sınıfın oluşturucusuna aktarılır;
- 33-35. satırlar: türetilmiş sınıfın __toString yöntemi, üst sınıfın __toString yöntemini kullanır;
[Enseignant] sınıfı, aşağıdaki [classes-08.php] betiği tarafından kullanılır:
<?php
// iki sınıfın tanımlarının dahil edilmesi
require_once __DIR__."/Personne.php";
require_once __DIR__."/Enseignant.php";
// kullanılan iki sınıfın bildirilmesi
use \Exemples\Personne;
use \Exemples\Enseignant;
// test
// Personne nesneleri ve türevlerinden oluşan bir dizi oluşturma
// örneğin basitliği için istisnalar işlenmiyor
$groupe = array(new Enseignant("Paul", "Langevin", 48, "anglais"), new Personne("Sylvie", "Lefur", 70));
// bu kişilerin kimlik bilgileri
for ($i = 0; $i < count($groupe); $i++) {
print "groupe[$i]=$groupe[$i]\n";
}
// son
exit;
Açıklamalar
- 4-5. satırlar: PHP yorumlayıcısına, [Enseignant, Personne] sınıflarının nerede bulunduğunu belirtmemiz gerekir;
- 7-8. satırlar: İki sınıfın tam adlarının bildirilmesi. Bu, kodda onları ad alanlarının sonekleri olmadan sadece adlarıyla belirtmemizi sağlayacaktır;
- 13. satır: [Personne] ve [Enseignant] türlerini içeren bir dizi oluşturulur;
- 16-18. satırlar: dizinin elemanlarını görüntüler;
- 17. satır: Her bir $groupe[$i] öğesinin __toString yöntemi çağrılacaktır. Personne sınıfının bir __toString yöntemi vardır. Enseignant sınıfının ise iki yöntemi vardır: üst sınıfının yöntemi ve kendi yöntemi. Hangisinin çağrılacağı merak edilebilir. Yürütme sonucu, Enseignant sınıfının yönteminin çağrıldığını gösterir. Bu her zaman böyledir: Bir nesne üzerinde bir yöntem çağrıldığında, bu yöntem şu sırayla aranır: önce nesnenin kendisinde, varsa üst sınıfında, ardından üst sınıfın üst sınıfında vb. Yöntem bulunur bulunmaz arama sona erer.
Sonuçlar:
5.10. Personne sınıfından türetilmiş ikinci bir sınıfın oluşturulması
Aşağıdaki örnek, [Etudiant.php] dosyasında, Personne sınıfından türetilen Etudiant sınıfını oluşturur:
<?php
// fonksiyon parametrelerinin beyan edilen türlerine sıkı sıkıya uyulması
declare (strict_types=1);
// ad alanı
namespace Exemples;
class Etudiant extends Personne {
// özellikler
private $formation; // alınan eğitim
// getter ve setter
public function getFormation(): string {
return $this->formation;
}
public function setFormation(string $formation): void {
$this->formation = $formation;
}
// yapıcı
public function __construct(string $prénom, string $nom, int $âge, string $formation) {
// üst öznitelikler
parent::__construct($prénom, $nom, $âge);
// diğer özellikler
$this->setFormation($formation);
}
// üst sınıfın __toString işlevinin aşırı yüklenmesi
public function __toString(): string {
return "[" . parent::__toString() . ",$this->formation]]";
}
}
Bu sınıf, aşağıdaki [classes-09.php] komut dosyası tarafından kullanılır:
<?php
// komut dosyası tarafından kullanılan sınıfların dahil edilmesi ve tanımlanması
require_once __DIR__."/Personne.php";
use \Exemples\Personne;
require_once __DIR__."/Enseignant.php";
use \Exemples\Enseignant;
require_once __DIR__."/Etudiant.php";
use \Exemples\Etudiant;
// test
// Kişi ve türev nesnelerden oluşan bir dizi oluşturma
// örneğin anlaşılmasını kolaylaştırmak için istisnalar işlenmemektedir
$groupe = array(new Enseignant("Paul", "Langevin", 48, "anglais"), new Personne("Sylvie", "Lefur", 70), new Etudiant("Steve", "Boer", 23, "iup2 qualité"));
// bu kişilerin kimlikleri
for ($i = 0; $i < count($groupe); $i++) {
print "groupe[$i]=$groupe[$i]\n";
}
// son
exit;
Sonuçlar:
groupe[0]=[[Paul,Langevin,48],anglais]
groupe[1]=[Sylvie,Lefur,70]
groupe[2]=[[Steve,Boer,23],iup2 qualité]
5.11. Türetilmiş sınıfın oluşturucusunun üst sınıfın oluşturucusuyla ilişkisi
Bazı nesne yönelimli dillerde, türetilmiş bir sınıfın oluşturucusu otomatik olarak üst sınıfının oluşturucusunu çağırır. Aşağıdaki [classes-16.php] kodu, PHP 7 ile durumun böyle olmadığını göstermektedir:
<?php
class Classe1 {
// oluşturucu
public function __construct() {
print "constructeur de la classe Classe1\n";
}
}
class Classe2 extends Classe1 {
// yapıcı
public function __construct() {
// üst sınıfın oluşturucusu örtük olarak çağrılmıyor
print "constructeur de la classe Classe2\n";
}
}
class Classe3 extends Classe1 {
// yapıcı
public function __construct() {
// üst sınıfın oluşturucusunun açıkça çağrılması
parent::__construct();
// Sınıf3'e özgü kod
print "constructeur de la classe Classe3\n";
}
}
// testler
print "test1---------\n";
new Classe2();
print "test2---------\n";
new Classe3();
Sonuçlar
5.12. Üst sınıftaki bir yöntemin yeniden tanımlanması
Daha önce, üst sınıftaki bir yöntemin alt sınıfta yeniden tanımlanabileceğini görmüştük. Bu şekilde, [Personne] sınıfındaki (bkz. bağlantı) [__toString] yöntemi, [Enseignant] (bkz. bağlantı) ve [Etudiant] (bkz. bağlantı) alt sınıflarında yeniden tanımlanmıştır. [classes-13.php] komut dosyası bu kavramı bir kez daha örneklemektedir:
<?php
// fonksiyon parametrelerinin türlerine sıkı uyum
declare(strict_types=1);
// ana sınıf
class Classe1 {
public function f(): int {
return 1;
}
function g(): int {
return 2;
}
}
// türetilmiş sınıf
class Classe2 extends Classe1 {
// üst sınıftaki f fonksiyonunu yeniden tanımlama
public function f(): int {
return parent::f() + 10;
}
}
// kod
$c2 = new Classe2();
print $c2->f() . "\n";
print $c2->g() . "\n";
$c1=new Classe1();
print $c1->f()."\n";
Açıklamalar
- 7-17. satırlar: [Classe1] sınıfı, f ve g adlı iki yöntem tanımlar;
- 20-27. satırlar: [Classe2] sınıfı, [Classe1] sınıfını genişletir ve bu sınıfın f yöntemini yeniden tanımlar;
Sonuçlar
Açıklamalar
- kodun 30. satırı, [Classe2] türünde bir $c2 nesnesi oluşturur;
- kodun 31. satırı, $c2 nesnesinin f yöntemini çağırır. Bu yöntem mevcut olduğu için yürütülür;
- kodun 32. satırı, $c2 nesnesinin g yöntemini çağırır. Bu yöntem mevcut olmadığı için üst sınıfta aranır, burada bulunur ve yürütülür;
- kodun 33. satırı, [Classe1] türünde bir $c1 nesnesi oluşturur;
- kodun 34. satırı, $c1 nesnesinin f yöntemini çağırır. Bu yöntem mevcut olduğu için yürütülür;
5.13. Bir nesnenin fonksiyon parametresi olarak aktarılması
Aşağıdaki [classes-14.php] komut dosyasını ele alalım:
<?php
// fonksiyon parametrelerinin türüne sıkı bir şekilde uyulur
declare(strict_types=1);
// ana sınıf
class Classe1 {
public function f(): int {
return 1;
}
function g(): int {
return 2;
}
}
// türetilmiş sınıf
class Classe2 extends Classe1 {
// üst sınıftaki f fonksiyonu yeniden tanımlanıyor
public function f(): int {
return parent::f() + 10;
}
}
// fonksiyon parametresinin türü Sınıf1 veya türetilmiş sınıftır
function doSomething(Classe1 $c1): void {
print $c1->f() + $c1->g() . "\n";
}
// kod
// Classe1'den türetilmiş Classe2 türünde bir nesne oluşturuluyor
$c2 = new Classe2();
// doSomething işlevi şu parametrelerle çağrılıyor
doSomething($c2);
Açıklamalar
- 7-17. satırlar: [Classe1] sınıfı;
- 20-27. satırlar: [Classe1] sınıfından türetilmiş bir [Classe2] sınıfı;
- 30. satır: [Classe1] türünde bir parametre bekleyen bir işlev. Beklenen tür bir sınıf olduğunda, fiili parametre beklenen türden veya türetilmiş bir nesne olabilir;
- 35-38. satırlar: [doSomething] işlevi, [Classe2] türünde bir parametreyle çağrılıyor; oysa beklenen tür [Classe1]’tir;
Sonuçlar
5.14. Soyut sınıflar
Soyut sınıf, örneklenemeyen eksik bir sınıftır. Kullanılabilmesi için mutlaka bir alt sınıfın türetilmesi gerekir.
Soyut sınıf ne işe yarar? Bazen bir veya birkaç yöntemi paylaşan, ancak diğer yöntemler veya öznitelikler açısından farklılık gösteren sınıflar olabilir. Bu durumda, ortak olan her şeyi bir üst sınıfta bir araya getirmek istenir. Şu an için soyut sınıfa ihtiyacımız yok. Ancak, alt sınıfların yalnızca M yöntemiyle farklılaştığını varsayalım: yöntemin imzası tüm alt sınıflarda aynı olur, ancak uygulaması farklılık gösterir. Alt sınıfların M yöntemini uygulamalarını zorunlu kılmak için:
- M yönteminin imzasını üst sınıfta tanımlayacağız. Üst sınıf bu yöntemi nasıl uygulayacağını bilmediğinden, yöntemin başına abstract anahtar sözcüğünü ekleriz: bu, M yönteminin uygulamasının alt sınıflara devredildiği anlamına gelir;
- ana sınıf tam olarak uygulanmamış olduğundan, o da aynı "abstract" anahtar sözcüğüyle soyut olarak tanımlanır. Bu, sınıfın artık örneklenemeyeceği anlamına gelir. Ana sınıfın gövdesinin kullanılabilir olması için, M yönteminin uygulamasını tanımlayacak bir alt sınıfın oluşturulması zorunludur;
İşte bir örnek [classes-15.php]:
<?php
// fonksiyon parametrelerinin türlerine sıkı sıkıya uyulur
declare(strict_types=1);
// soyut ana sınıf
abstract Class Classe1 {
// tüm türetilmiş sınıflar tarafından bilinen yöntem
public function f(): int {
return 1;
}
// soyut g yöntemi - türetilmiş sınıflar tarafından tanımlanacaktır
abstract function g(): int;
}
// türetilmiş sınıf
Class Classe2 extends Classe1 {
// üst sınıfın g yöntemi tanımlanmalıdır
public function g(): int {
return parent::f() + 10;
}
}
// türetilmiş sınıf
Class Classe3 extends Classe1 {
// üst sınıfın g yöntemi tanımlanmalıdır
public function g(): int {
return parent::f() + 20;
}
// üst sınıfın f yöntemini yeniden tanımlayabilirsiniz
public function f(): int {
return 2;
}
}
// kod
$c2 = new Classe2();
print $c2->f() . "\n";
print $c2->g() . "\n";
$c3 = new Classe3();
print $c3->f() . "\n";
print $c3->g() . "\n";
Açıklamalar
- 7-16. satırlar: [Classe1] sınıfı, 15. satırdaki g yöntemini uygulayamadığı için (7. satır) soyuttur. Dolayısıyla kullanılabilmesi için mutlaka bir alt sınıfı oluşturulması gerekir;
- 19-26. satırlar: [Classe2] sınıfı, [Classe1] sınıfını genişletir ve üst sınıfının g yöntemini yeniden tanımlar (22-24. satırlar);
- satır 29-41: [Classe3] sınıfı, [Classe1] sınıfını genişletir ve üst sınıfının g yöntemini yeniden tanımlar (satır 32-34);
- satır 37-39: [Classe3] sınıfı, üst sınıfının f yöntemini yeniden tanımlar;
- satır 44-49: [Classe2] ve [Classe3] türünde iki nesne oluşturulur ve bunların f ve g yöntemleri çağrılır;
Sonuçlar
5.15. Nihai sınıflar
Nihai sınıf, türetilemeyen bir sınıftır. Aşağıdaki [classes-11.php] betiğini ele alalım:
<?php
// ad alanı
namespace Exemples;
// türetilemeyen sınıf
final Class Classe1 {
}
// türetilmiş sınıf
Class Classe2 extends Classe1 {
}
// kod - hata vermelidir
new Classe2();
Açıklamalar
- 7-9. satırlar: final anahtar sözcüğü, [Classe1] sınıfını türetilemeyen bir son sınıf haline getirir;
- 12-14. satırlar: [Classe2] sınıfı, final sınıf olan [Classe1] sınıfını genişletir; bu bir hatadır;
- 17. satır: Hata, [Classe2] türünde bir nesneyi işlemeyi denediğimizde, komut dosyasının çalıştırılması sırasında bildirilecektir;
Sonuçlar
5.16. Final yöntemler
Final yöntem, türetme yoluyla yeniden tanımlanamayan bir yöntemdir. İşte bir örnek: [classes-12.php]:
<?php
// fonksiyon parametrelerinin türüne sıkı uyum
declare(strict_types=1);
// ad alanı
namespace Exemples;
// ana sınıf
Class Classe1 {
// bu yöntem, türetilmiş bir sınıfta yeniden tanımlanamaz
public final function f(): int {
return 1;
}
}
// türetilmiş sınıf
Class Classe2 extends Classe1 {
public function f(): int {
return 2;
}
}
// kod - hata vermelidir
new Classe2();
Yorumlar
- 13. satır: [Classe1] sınıfının f yöntemi, final anahtar sözcüğüyle final olarak tanımlanmıştır;
- 20. satır: [Classe2] sınıfı, [Classe1] sınıfını genişletir;
- 22-23. satırlar: üst sınıf [Classe1]'in f işlevi yeniden tanımlanıyor. Bu durum bir hataya neden olmalıdır;
- 29. satır: [Classe2] türünde bir nesne oluşturulur; bu, PHP yorumlayıcısını [Classe2] sınıfını incelemesi için zorlar;
Sonuçlar
5.17. Statik yöntemler ve öznitelikler
Statik yöntem, tanımlandığı sınıfa bağlı olan ve sınıfın örnek nesnelerine bağlı olmayan bir yöntemdir. Dolayısıyla, C sınıfı M adlı bir statik yöntem bildirirse, bu yöntemi kullanmak için sınıfın dışındaysak şöyle yazılır:
- C::M (sınıfın dışındaysak);
- sınıfın içindeysek self::M;
İşte bir örnek [classes-17.php]:
<?php
class Classe1 {
// statik yöntem
static function say(string $message): void {
print "$message\n";
}
}
// test -------------------
Classe1::say("hello");
Açıklamalar
- 6. satır: [say] yöntemi, static anahtar sözcüğüyle statik olarak tanımlanmıştır;
- 13. satır: [say] statik yöntemi, Classe1::say notasyonu ile çağrılmıştır;
Sonuçlar
Şimdi şu [classes-18.php] kodunu ele alalım:
<?php
class Classe1 {
// statik öznitelik
private static $nbObjects = 0;
public function __construct() {
print "constructeur Classe1\n";
self::$nbObjects++;
}
// statik yöntem
static function say(): void {
print self::$nbObjects ." objets de type [Classe1] ont été construits\n";
}
}
// test -------------------
new Classe1();
new Classe1();
Classe1::say();
Açıklamalar
- 5. satır: Oluşturulan [Classe1] sınıfının örneklerinin sayısını sayacak statik bir öznitelik tanımlanıyor. Bu, sınıfın bir örneğine ait olabilecek bir öznitelik değildir. Nitekim, O1 ve O2 adlı iki nesne oluşturulursa, ikisi de birbirinden haberdar değildir. Örnekte bir sayaç bulundurmak mantıklı değildir: yeni bir nesne oluşturulduğunda, hangi örnekte sayaç artırılacaktır? Diğer örneklerin sayaçlarını göz ardı ederek belirli bir nesnenin sayacını artırmak zorunda kalınır. Statik öznitelik, sınıfın bir özniteliğidir, sınıf örneğinin değil;
- 7-10. satırlar: Oluşturulan nesneleri saymak için yapıcı kullanılır, çünkü her yeni nesnenin oluşturulması yapıcının çalıştırılmasına neden olur;
- 14. satır: Yürütülen kodun bulunduğu sınıfın statik özniteliğine atıfta bulunulduğunu belirtmek için self::$nbObjects notasyonu kullanılır;
- 13-15. satırlar: [say] statik yönteminin görevi, oluşturulan nesnelerin sayısını görüntülemektir;
- 20-22. satırlar: İki nesne oluşturulur ve nesne sayacı görüntülenir;
Sonuçlar
constructeur Classe1
constructeur Classe1
2 objets de type [Classe1] ont été construits
5.18. Ana sınıf ile alt sınıf arasında görünürlük
Aşağıdaki [classes-19.php] betiğini inceleyelim:
<?php
class SomeParent {
// özellik
private $attributeOfParent = 4;
// yöntem
public function doTest(): void {
// kim çağırıyor?
print "parent :\n";
var_dump($this);
// üst nesne görüntüleme
print "parent : attributeOfParent={$this->attributeOfParent}\n";
print "parent : attributeOfChild={$this->attributeOfChild}\n";
}
}
class SomeChild extends SomeParent {
// özellik
private $attributeOfChild = 14;
// yöntem
public function doTest(): void {
// alt görüntüleme
print "child : attributeOfParent={$this->attributeOfParent}\n";
print "child : attributeOfChild={$this->attributeOfChild}\n";
// üst
parent::doTest();
}
}
// ana komut dosyası
print "---test1\n";
(new SomeParent())->doTest();
print "---test2\n";
(new SomeChild())->doTest();
Açıklamalar
- 3-17. satırlar: [SomeParent] sınıfı;
- 19-32. satırlar: [SomeChild] alt sınıfı. Bu sınıfın, [SomeParent] sınıfını genişlettiği görülmektedir (19. satır);
- 5. satır: [SomeParent] sınıfının tek bir özniteliği vardır;
- satır 8-17: [SomeParent::doTest] yönteminin amacı iki özniteliği görüntülemektir:
- [$attributeOfParent], [SomeParent] sınıfına aittir;
- [$attributeOfChild], [SomeChild] sınıfına aittir (21. satır);
- 10-11. satırlar: arayanın kimliği görüntülenir; aslında bu yöntemi iki farklı şekilde çağıracağız:
- üst sınıf [SomeParent]'ten;
- çocuk sınıf [SomeChild]'ten;
- satır 13-14: iki özniteliğin görüntülenmesi;
- satır 19-32: [SomeParent] sınıfını genişleten [SomeChild] alt sınıfı (satır 19);
- 21. satır: [SomeChild] sınıfının tek bir özniteliği vardır;
- satır 24: [SomeChild::doTest] yönteminin amacı, iki özniteliği görüntülemektir:
- [$attributeOfParent], [SomeParent] sınıfına aittir;
- [SomeChild] sınıfına ait olan [$attributeOfChild];
- 26-27. satırlar: iki özniteliğin görüntülenmesi;
- 30. satır: üst sınıfın [doTest] yönteminin çağrılması; bu yöntem de sırayla iki özniteliği görüntüler;
- satır 36: [SomeParent::doTest] yöntemi çağrılır;
- satır 38: [SomeChild::doTest] yöntemi çağrılır;
İlk testte, her iki özniteliğin görünürlüğü [private]'tir. Dolayısıyla, alt sınıfın üst sınıfının özniteliğini görmemesi beklenebilir. Bunun için özniteliğin görünürlük düzeyinin en az [protected] olması gerekir. Peki ya alt sınıfın özniteliği? Üst sınıfta görünür mü?
İşte bu ilk testin sonuçları:
Yorumlar
- 1-10. satırlar: [SomeParent::doTest] yönteminin çağrıldığı ilk testin sonuçları;
- satır 3-6: yöntemi çağıran nesnenin [SomeParent] türü olduğu görülüyor;
- 7. satır: [$attributeOfParent] özniteliğinin görüntülenmesi;
- 9-10. satırlar: [SomeParent::$attributeOfChild] özniteliğinin mevcut olmadığı görülmektedir. Dolayısıyla görüntülenmemektedir;
- satır 11-30: [SomeChild::doTest] yönteminin çağrıldığı 2. testin sonuçları;
- satır 13-14: [SomeChild::$attributeOfParent] özniteliğinin mevcut olmadığı görülüyor. Bu nedenle görüntülenmez. Bu normaldir: [SomeParent::$attributeOfParent] özniteliği, [private]'tir ve dolayısıyla alt sınıfta bilinmemektedir;
- 15. satır: [$attributeOfChild] özniteliğinin görüntülenmesi;
- 16-30. satırlar: alt sınıf tarafından çağrılan [SomeParent::doTest] yöntemindeyiz;
- 17-22. satırlar: [$this]'in, iki özel özniteliğe sahip [SomeChild] türünde olduğu görülüyor;
- 23. satır: oldukça şaşırtıcı bir şekilde, [SomeChild] türündeki [$this], burada üst sınıf [$attributeOfParent]’in özniteliğini görüyor;
- 25-30. satırlar: aynı derecede şaşırtıcı bir şekilde, [SomeChild] türündeki [$this], [$attributeOfChild] özniteliğini görmüyor;
Bu sonuç oldukça şaşırtıcı: 17-21. satırlarda [$this]'in [SomeChild] türü olduğu belirtilse de, [SomeParent::doTest] yönteminin içindeki bu [$this], [SomeChild] sınıfının değil, [SomeParent] sınıfının bir örneğiymiş gibi davranıyor.
Şimdi [classes-20.php] betiği ile yeni bir test yapalım. [$attributeOfParent] özniteliğinin görünürlüğü artık [protected] olarak ayarlanmıştır (5. satır):
<?php
class SomeParent {
// özellik
protected $attributeOfParent = 4;
// yöntem
public function doTest(): void {
// kim çağırıyor?
print "parent :\n";
var_dump($this);
// üst nesne
print "parent : attributeOfParent={$this->attributeOfParent}\n";
print "parent : attributeOfChild={$this->attributeOfChild}\n";
}
}
class SomeChild extends SomeParent {
// özellik
private $attributeOfChild = 14;
// yöntem
public function doTest(): void {
// alt görüntüleme
print "child : attributeOfParent={$this->attributeOfParent}\n";
print "child : attributeOfChild={$this->attributeOfChild}\n";
// üst
parent::doTest();
}
}
// ana komut dosyası
print "---------------------------test1\n";
(new SomeParent())->doTest();
print "---------------------------test2\n";
(new SomeChild())->doTest();
Sonuçlar
Yorumlar
- 12. satır: [SomeChild] sınıfı artık üst nesnesi [$attributeOfParent]'in özniteliğini görebiliyor. Bu normaldir, çünkü söz konusu özniteliğin kapsamı artık [protected]'tir;
- [someParent::doTest] yönteminde, [$this] nesnesi [SomeChild] türündedir (satır 15-20). Bu nesne, üst nesnesi olan [$attributeOfparent]'in özniteliğini görebilir (21. satır), ancak kendi özniteliği olan [$attributeOfChild]'i hâlâ göremez (23-28. satırlar);
- denemede, [$attributeOfChild] özniteliğinin de [protected] kapsamı vardır:
<?php
class SomeParent {
// özellik
protected $attributeOfParent = 4;
// yöntem
public function doTest(): void {
// kim çağırıyor?
print "parent :\n";
var_dump($this);
// üst nesne
print "parent : attributeOfParent={$this->attributeOfParent}\n";
print "parent : attributeOfChild={$this->attributeOfChild}\n";
}
}
class SomeChild extends SomeParent {
// özellik
protected $attributeOfChild = 14;
// yöntem
public function doTest(): void {
// alt görüntüleme
print "child : attributeOfParent={$this->attributeOfParent}\n";
print "child : attributeOfChild={$this->attributeOfChild}\n";
// üst
parent::doTest();
}
}
// ana komut dosyası
print "---------------------------test1\n";
(new SomeParent())->doTest();
print "---------------------------test2\n";
(new SomeChild())->doTest();
Çalıştırma sonuçları şu şekildedir:
- 22. satır: bu sefer, üst öğenin içinde, [$this], [SomeChild] türünde (15-20. satırlar) kendi sınıfı olan [SomeChild]'in korumalı özniteliği [$attributeOfChild]'i görüyor.
Bu testlerden ne çıkarılabilir?
- Bir üst sınıfın örneği olan ve üst sınıfın bir yönteminde kullanılan [$this],
- ana sınıfın özniteliklerini ve yöntemlerini, görünürlük durumlarına bakılmaksızın görebilir;
- alt sınıflarının öznitelik ve yöntemlerini hiç görmez;
Bu, beklenen davranıştır.
- [$this], bir alt sınıfın örneği olup, alt sınıfın bir yönteminde kullanıldığında şunları görür:
- ana sınıfın özniteliklerini ve yöntemlerini, en az [protected] görünürlük düzeyine sahip olmaları durumunda görür. [private] görünürlük düzeyine sahip olanlar görülmez;
- alt sınıfın öznitelikleri ve yöntemleri, görünürlük düzeyleri ne olursa olsun;
Bu, beklenen davranıştır.
- [$this], bir alt sınıfın örneği olup, üst sınıfın bir yönteminde kullanıldığında şunları görür:
- ana sınıfın özniteliklerini ve yöntemlerini, görünürlük düzeylerine bakılmaksızın;
- kendi sınıfının özniteliklerini ve yöntemlerini yalnızca görünürlükleri en az [protected] ise görebilir. Görünürlükleri [private] olan öznitelikler ve yöntemler görülmez;
Bu, beklenmedik bir davranıştır.
5.19. Bir sınıfın jSON kodlaması
Bir sınıfta genellikle [__toString] yöntemi bulunur: bu yöntem, kendisini çağıran nesneyi temsil eden bir karakter dizesi döndürmesi beklenir. Bu dizgenin bir jSON dizesi olması cazip gelebilir. Şimdi bu yolu inceleyeceğiz.

Aşağıdaki [Personne] sınıfını kullanacağız:
<?php
class Personne {
// özellikler
private $nom;
private $prénom;
private $âge;
private $enfants;
// global ayarlayıcı
public function setFromArray(array $arrayOfAttributes): Personne {
// sınıfın belirli özniteliklerinin başlatılması
foreach ($arrayOfAttributes as $attribute => $value) {
$this->$attribute = $value;
}
// nesneyi döndürür
return $this;
}
// alıcılar
public function getNom() {
return $this->nom;
}
public function getPrénom() {
return $this->prénom;
}
public function getÂge() {
return $this->âge;
}
public function getEnfants() {
return $this->enfants;
}
// __toString
public function __toString(): string {
// nesneyi tanımlama
var_dump($this);
// nesnenin öznitelikleri alınır
$attributes = \get_object_vars($this);
var_dump($attributes);
// özelliklerin jSON dizesi oluşturulur
return \json_encode($attributes, JSON_UNESCAPED_UNICODE);
}
}
Açıklamalar
- 5-8. satırlar: sınıfın dört özniteliği;
- 20-35. satırlar: bu özniteliklerin değerlerini almayı sağlayan getter yöntemleri;
- 11-18. satırlar: Sınıfın öznitelikleriyle aynı anahtarlara sahip olan [$arrayOfAttributes] adlı ilişkisel diziden öznitelikleri başlatmaya olanak tanıyan bir global setter;
- satır 38-46: Sınıfın [__toString] yöntemi;
- satır 42: PHP [get_object_vars] işlevi, sınıfın özniteliklerinin değerlerini [‘soyadı’=>’soyadı1’, ‘adı’=>’adı1’, ‘yaş’=>’yaş1’, ‘çocuklar’=>[]] biçiminde bir ilişkisel dizi olarak elde etmeyi sağlar;
- 45. satır: Bu öznitelik tablosundan jSON dizesi döndürülür;
[Personne] sınıfını kullanan [json-01.php] betiğini inceleyelim:
<?php
// Kişi sınıfı
require "Personne.php";
// babanın örneği oluşturulur
$père = new Personne();
// babanın başlatılması
$père->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Dieudonné",
"âge" => 58
]);
// çocuk1'in örneklenmesi ve başlatılması
$enfant1 = (new Personne())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Sylvain",
"âge" => 17
]);
// çocuk2'nin örneklenmesi ve başlatılması
$enfant2 = (new Personne())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Géraldine",
"âge" => 12
]);
// babanın çocuklarının başlatılması
$père->setFromArray([
"enfants" => [$enfant1, $enfant2]
]);
// babanın öğelerinin görüntülenmesi
$enfant1=($père->getEnfants())[0];
$enfant2=($père->getEnfants())[1];
print "------------------------enfant1\n";
print "enfant1=$enfant1\n";
print "------------------------enfant2\n";
print "enfant2=$enfant2\n";
print "------------------------père\n";
print "père=$père\n";
Açıklamalar
- 6-13. satırlar: [Personne] [$père] nesnesini, [Personne::setFromArray] yöntemiyle başlatıyoruz; bu yöntem,[Personne] nesnesini, [Personne] sınıfının öznitelikleriyle aynı anahtarlara sahip bir dizi ile başlatmak;
- satır 14-19: aynı şekilde bir [Personne] [$enfant1] nesnesi başlatılır;
- satır 21-25: [Personne] ve [$enfant2] nesneleri başlatılır;
- satır 27-29: [$père→enfants] özniteliği, iki çocuğun bulunduğu bir dizi ile başlatılır;
- 32-33. satırlar: iki çocuk, babaya atanır;
- 35. satır: [print] işlemi, [$enfant1] nesnesini bir karakter dizisine dönüştürmeye çalışır. Bunun için nesnenin [__toString] yöntemini kullanır. Dolayısıyla, nesnenin jSON karakter dizisini görmeyi umuyoruz;
- 38-39. satırlar: aynı işlem babası için de yapılır;
Sonuçlar şu şekildedir:
------------------------enfant1
object(Personne)#2 (4) {
["nom":"Personne":private]=>
string(11) "Bertholomé"
["prénom":"Personne":private]=>
string(7) "Sylvain"
["âge":"Personne":private]=>
int(17)
["enfants":"Personne":private]=>
NULL
}
array(4) {
["nom"]=>
string(11) "Bertholomé"
["prénom"]=>
string(7) "Sylvain"
["âge"]=>
int(17)
["enfants"]=>
NULL
}
enfant1={"nom":"Bertholomé","prénom":"Sylvain","âge":17,"enfants":null}
------------------------enfant2
object(Personne)#3 (4) {
["nom":"Personne":private]=>
string(11) "Bertholomé"
["prénom":"Personne":private]=>
string(10) "Géraldine"
["âge":"Personne":private]=>
int(12)
["enfants":"Personne":private]=>
NULL
}
array(4) {
["nom"]=>
string(11) "Bertholomé"
["prénom"]=>
string(10) "Géraldine"
["âge"]=>
int(12)
["enfants"]=>
NULL
}
enfant2={"nom":"Bertholomé","prénom":"Géraldine","âge":12,"enfants":null}
------------------------père
object(Personne)#1 (4) {
["nom":"Personne":private]=>
string(11) "Bertholomé"
["prénom":"Personne":private]=>
string(10) "Dieudonné"
["âge":"Personne":private]=>
int(58)
["enfants":"Personne":private]=>
array(2) {
[0]=>
object(Personne)#2 (4) {
["nom":"Personne":private]=>
string(11) "Bertholomé"
["prénom":"Personne":private]=>
string(7) "Sylvain"
["âge":"Personne":private]=>
int(17)
["enfants":"Personne":private]=>
NULL
}
[1]=>
object(Personne)#3 (4) {
["nom":"Personne":private]=>
string(11) "Bertholomé"
["prénom":"Personne":private]=>
string(10) "Géraldine"
["âge":"Personne":private]=>
int(12)
["enfants":"Personne":private]=>
NULL
}
}
}
array(4) {
["nom"]=>
string(11) "Bertholomé"
["prénom"]=>
string(10) "Dieudonné"
["âge"]=>
int(58)
["enfants"]=>
array(2) {
[0]=>
object(Personne)#2 (4) {
["nom":"Personne":private]=>
string(11) "Bertholomé"
["prénom":"Personne":private]=>
string(7) "Sylvain"
["âge":"Personne":private]=>
int(17)
["enfants":"Personne":private]=>
NULL
}
[1]=>
object(Personne)#3 (4) {
["nom":"Personne":private]=>
string(11) "Bertholomé"
["prénom":"Personne":private]=>
string(10) "Géraldine"
["âge":"Personne":private]=>
int(12)
["enfants":"Personne":private]=>
NULL
}
}
}
père={"nom":"Bertholomé","prénom":"Dieudonné","âge":58,"enfants":[{},{}]}
Açıklamalar
- 2-11. satırlar: [$enfant1] nesnesi;
- satır 12-21: [$enfant1] nesnesinin öznitelik tablosu. Hepsini aldık;
- 22. satır: [$enfant1] nesnesinin jSON dizesi de mevcut;
- satır 23-44: [$enfant2] nesnesi için de durum aynı;
- 45-112. satırlar: baba için durum biraz farklıdır, çünkü onun [enfants] özniteliği, çocuklarda olduğu gibi NULL değildir;
- 112. satır: Babanın jSON dizesinde çocukların eksik olduğu görülüyor;
- 79-111. satırlar: Babanın öznitelik tablosunda, çocuk 1'in (89-98. satırlar) bir nesne olarak kaldığı görülüyor; aynı durum çocuk 2 için de (99-110. satırlar) geçerli. Açıkça ifade etmek gerekirse, [$this]'in babayı temsil ettiği [\get_object_vars($this)] ifadesi özyinelemeli değildir: [Personne] sınıfının bir özniteliği kendisi bir nesne ise, [\get_object_vars($this)] ifadesi onun öznitelik tablosunu almaya çalışmaz;
Bunu iyileştirebiliriz. [Personne] sınıfını aşağıdaki [Personne2] sınıfına dönüştürürüz:
<?php
class Personne2 {
// özellikler
private $nom;
private $prénom;
private $âge;
private $enfants;
// global ayarlayıcı
public function setFromArray(array $arrayOfAttributes): Personne2 {
…
// nesneyi döndürme
return $this;
}
// alıcılar
public function getNom() {
return $this->nom;
}
…
// __toString
public function __toString(): string {
// nesnenin özniteliklerini alır
$attributes = $this->getAttributes($this);
$enfants = $attributes["enfants"];
if ($enfants != NULL) {
$attributes["enfants"] = [$enfants[0]->getAttributes(), $enfants[1]->getAttributes()];
}
// özelliklerin dizesini döndürür JSON
return \json_encode($attributes, JSON_UNESCAPED_UNICODE);
}
public function getAttributes(): array {
return \get_object_vars($this);
}
}
Açıklamalar
- 36-38. satırlar: [getAttributes] işlevi, kendisini çağıran nesnenin öznitelik dizisini döndürür;
- 25-34. satırlar: [__toString] işlevi;
- 27. satır: [Personne] sınıfının öznitelikleri, [$attributes] dizisine alınır;
- satır 28: önceki örnekten, [$attributes["enfants"]]'in [Personne] türünde iki nesneden oluşan bir dizi olduğu bilinmektedir;
- 29-31. satırlar: iki nesne, öznitelik tablolarıyla değiştirilir;
- satır 33: geriye sadece oluşturulan öznitelik dizisini jSON olarak kodlamak kalır;
[json-02.php] komut dosyası, [Personne2] sınıfını şu şekilde kullanır:
<?php
// Personne2 sınıfı
require "Personne2.php";
// baba nesnesinin örneklenmesi
$père = new Personne2();
// başlatma
$père->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Dieudonné",
"âge" => 58
]);
// çocuk1'in örneklenmesi ve başlatılması
$enfant1 = (new Personne2())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Sylvain",
"âge" => 17
]);
// çocuk2'nin örneklenmesi ve başlatılması
$enfant2 = (new Personne2())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Géraldine",
"âge" => 12
]);
// babanın çocuklarının başlatılması
$père->setFromArray([
"enfants" => [$enfant1, $enfant2]
]);
// babanın görüntülenmesi
print "------------------------père\n";
print "père=$père\n";
[json-02.php] komut dosyası, [json-01.php] komut dosyasıyla aynıdır; tek fark, [Personne] sınıfının yerine [Personne2] sınıfının kullanılmasıdır.
Çalıştırma sonuçları şöyledir:
Bu sefer, babayla birlikte çocukları da doğru bir şekilde elde ettik.
Önceki çözüm tatmin edici değildir, çünkü çocukların kendilerinin de çocukları olabilir. Böylece önceki sorun tekrar ortaya çıkar.
[Personne3] sınıfı bu sorunu şu şekilde çözmektedir:
<?php
class Personne3 {
// özellikler
private $nom;
private $prénom;
private $âge;
private $enfants;
// global ayarlayıcı
public function setFromArray(array $arrayOfAttributes): Personne3 {
…
}
// alıcılar
…
// __toString
public function __toString(): string {
// JSON öznitelik dizisini döndürür
$attributes = [];
$this->getRecursiveAttributes($attributes, $this, []);
// JSON dizesini özniteliklere dönüştürür
return \json_encode($attributes, JSON_UNESCAPED_UNICODE);
}
public function getAttributes(): array {
return \get_object_vars($this);
}
private function getRecursiveAttributes(array &$attributes, $value, $keys): void {
// [$value] değerinin analizi
// $keys bir tablodur [key1, key2, .., keyn]
// $value=$attributesQZXW2HTMLBW2tleTFdZQXQZXW2HTMLBW2tleTJdZQX….[keyn]
// eğer [$value] bir nesne ise, onun [getAttributes] yöntemini kullanırız
if (\is_object($value)) {
// [$value] nesnesinin öznitelikleri
$objectAttributes = $value->getAttributes();
// sonuçla ne yapacağız?
if ($keys) {
// [$attributes] içinde, $value'i özniteliği tablosuyla değiştireceğiz
// $attributesQZXW2HTMLBW2tleTFdZQXQZXW2HTMLBW2tleTJdZQX…[keyn] öğesini oluşturmamız gerekiyor
// burada $keys, [key1, key2, .., keyn] dizisidir
// burada [$attributes] tablosunun referansı alınır
$attribute = &$attributes;
// anahtar tablosu taranır
foreach ($keys as $key) {
// özniteliğin referansı alınır
$attribute = &$attribute[$key];
}
// burada $attribut ve $attributesQZXW2HTMLBW2tleTFdZQXQZXW2HTMLBW2tleTJdZQX…[key(n)] aynıdır
// aynı bellek konumunu paylaşıyorlar
// [$value] nesnesi, öznitelik tablosuyla değiştirilir;
// $attributesQZXW2HTMLBW2tleTFdZQXQZXW2HTMLBW2tleTJdZQX… yazılmalıdır[keyn]=$objectAttributes
// bu, $attribute = $objectAttributes'e eşdeğerdir
$attribute = $objectAttributes;
} else {
// anahtar yok - nesnenin keşfine yeni başlıyoruz
// $objectAttributes, sınıfın 1. düzey özniteliklerini temsil eder
$attributes += $objectAttributes;
}
// belki de [$objectAttributes] içinde hâlâ nesneler vardır
// [$objectAttributes]'in özniteliklerini inceliyoruz
$this->getRecursiveAttributes($attributes, $objectAttributes, $keys);
} else {
if (\is_array($value)) {
// bir diziye sahibiz – dizideki her bir elemanı inceliyoruz
foreach ($value as $key => $élément) {
// diziye geçerli anahtarı ekliyoruz $keys
\array_push($keys, $key);
// $élément'i analiz ediyoruz
$this->getRecursiveAttributes($attributes, $élément, $keys);
// $keys dizisinden az önce analiz edilen anahtarı kaldırıyoruz
\array_pop($keys);
}
}
}
}
Yorumlar
- 21-22. satırlar: Bu sefer, [__toString] yöntemi, sınıfının özniteliklerini ister ve bunun özyinelemeli olarak yapılmasını talep eder: Bir öznitelik bir nesne veya nesnelerden oluşan bir dizi ise, o zaman her nesne, sınıfın nihai öznitelik dizisinde kendi öznitelik dizisiyle değiştirilmelidir;
- 31-78. satırlar: [getRecursiveAttributes] işlevi bu işi yapar. Koduna açıklamalar eklenmiştir. Özyinelemeli bir fonksiyon yazmak genellikle karmaşık bir iştir. Burada da durum böyledir. Okuyucu bunu anlamasa da bir şey kaçırmış sayılmaz. Bu işi yapan kütüphaneler mevcuttur. Özyinelemeli çağrı 64. ve 72. satırlarda gerçekleşir;
- bu kodun önemi, yalnızca [Personne3] sınıfı için yazılmamış olmasıdır. Ana sınıf tarafından kullanılan sınıflar da, tıpkı ana sınıf gibi 27-29. satırlardaki [getAttributes] yöntemine sahip olduğu sürece, değerleri farklı nesne türleri olan özniteliklere sahip tüm sınıflar için geçerlidir.
[json-03.php] betiği, [Personne3] sınıfını şu şekilde kullanır:
<?php
// Personne3 sınıfı
require "Personne3.php";
// baba nesnesinin oluşturulması
$père = new Personne3();
// başlatma
$père->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Dieudonné",
"âge" => 58
]);
// çocuk1'in örneklenmesi ve başlatılması
$enfant1 = (new Personne3())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Sylvain",
"âge" => 27
]);
// çocuk2'nin örneklenmesi ve başlatılması
$enfant2 = (new Personne3())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Géraldine",
"âge" => 12
]);
// babanın çocuklarının başlatılması
$père->setFromArray([
"enfants" => [$enfant1, $enfant2]
]);
// çocuk11'in örneklenmesi ve başlatılması
$enfant11 = (new Personne3())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Gaëtan",
"âge" => 2
]);
// çocuk12'nin örneklenmesi ve başlatılması
$enfant12 = (new Personne3())->setFromArray([
"nom" => "Bertholomé",
"prénom" => "Mathilde",
"âge" => 1
]);
// çocuk1'in çocuklarının başlatılması
$enfant1->setFromArray([
"enfants" => [$enfant11, $enfant12]
]);
// babanın görüntülenmesi
print "------------------------père\n";
print "père=$père\n";
- 30-45. satırlar: [$enfant1] sınıfına iki alt sınıf atanır;
Çalıştırma sonuçları şöyledir:
Bu sonucu biçimlendirirsek, şu sonucu elde ederiz:
père={
"nom": "Bertholomé",
"prénom": "Dieudonné",
"âge": 58,
"enfants": [
{
"nom": "Bertholomé",
"prénom": "Sylvain",
"âge": 27,
"enfants": [
{
"nom": "Bertholomé",
"prénom": "Gaëtan",
"âge": 2,
"enfants": null
},
{
"nom": "Bertholomé",
"prénom": "Mathilde",
"âge": 1,
"enfants": null
}
]
},
{
"nom": "Bertholomé",
"prénom": "Géraldine",
"âge": 12,
"enfants": null
}
]
}
Baba nesneyi oluşturan tüm [Personne] nesnelerinden jSON dizesini başarıyla aldık.