__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() ve __debugInfo() işlev isimleri PHP sınıflarında sihirli işlemler yaparlar. İşlevlerinize sihirli bir işlevsellik kazandırmak istemedikçe bu isimleri sınıfınızın içinde işlev ismi olarak kullanamazsınız.
PHP, __ ile baslayan tüm işlev isimlerini sihirli işlevlere ayırmıştır. Belgelenmiş bir kaç sihirli işlevsellik dışında __ ile başlayan işlev isimleri kullanmamanızı öneririz.
serialize() işlevi, sınıfınızın
__sleep()
adında sihirli bir işleve sahip olup olmadığına bakar. Böyle bir işlev
varsa herhangi bir serileştirme işleminden önce bu işlev çalıştırılır.
Bu işlev ile nesne üzerinde temizlik yapabilir ve serileştirilmesi
gereken nesnenin tüm değişken isimlerinin bir dizi halinde döndürülmesini
sağlayabilirsiniz. Eğer işlev hiçbir şey döndürmemişse NULL
serileştirilir ve bir E_NOTICE
çıktılanır.
Bilginize:
Ebeveyn sınıflardaki private özelliklerin isimlerini döndürmek __sleep() için imkansızdır. Bunu yapmaya kalkışırsanız
E_NOTICE
seviyesinde bir hata iletisi alırsınız. Bunun yerine Serializable arayüzünü kullanabilirsiniz.
__sleep() işlevinin asıl kullanım amacı askıdaki veriyi göndermek gibi temizliğe benzer işlemler yapmaktır. Ayrıca, tümüyle kaydedilmesi gerekmeyen büyük veri parçaları sözkonusu olduğunda da bu işlevden yararlanabilirsiniz.
unserialize() işlevi tersine bir işlem yaparak __wakeup() adında bir sihirli işlevin varlığını araştırır. Böyle bir işlev varsa, bu işlev nesnenin sahip olduğu tüm özkaynakları yeniden oluşturabilir.
__wakeup() işlevinin asıl kullanım amacı, serileştirme sırasında kaybedilebilen veritabanı bağlantılarını yeniden oluşturmak ve diğer ilklendirme işlemlerini yeniden yapmaktır.
Örnek 1 - Uyutma ve uyandırma
<?php
class Bağlantı
{
protected $hat;
private $dsn, $kullanıcı, $parola, $db;
public function __construct($dsn, $kullanıcı, $parola, $db)
{
$this->dsn = $dsn;
$this->kullanıcı = $kullanıcı;
$this->parola = $parola;
$this->db = $db;
$this->connect();
}
private function bağlan()
{
$this->hat = new PDO($this->dsn, $this->kullanıcı, $this->parola);
}
public function __sleep()
{
return array('dsn', 'kullanıcı', 'parola');
}
public function __wakeup()
{
$this->bağlan();
}
}?>
__toString() yöntemi, sınıf bir
dizgeye dönüştürüldüğünde sınıfın nasıl tepki vereceğine karar vermeyi
sağlar. Bu yöntem bir dizge döndürmelidir, aksi takdirde
E_RECOVERABLE_ERROR
seviyesinde ölümcül bir hata
çıktılanır.
You cannot throw an exception from within a __toString() yöntemin içinden bir istisna oluşturamazsınız. Bunu yapılması ölümcül hata ile sonuçlanır.
Örnek 2 - Basit bir örnek
<?php
// Basit bir sınıf tanımlayalım
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Merhaba');
echo $class;
?>
Yukarıdaki örneğin çıktısı:
Merhaba
PHP 5.2.0'dan önce __toString()
yönteminin, doğrudan echo ya da
print işlevleri ile birlikte çağrılmadıkça bir önemi
yoktu. PHP 5.2.0'dan beri sadece dizge bağlamlarında
(%s değiştiricili printf()
gibi) çağrılabilmekte, diğer bağlamlarda (%d
değiştiricili printf() gibi) çağrılamamaktadır. PHP
5.2.0'dan beri nesneleri
__toString() yöntemi olmaksızın
dizgeye dönüştürme işlemi E_RECOVERABLE_ERROR
hatasına yol açmaktadır.
__invoke() yöntemi, bir betik bir nesneyi bir işlev olarak çağırmaya çalışırsa çağrılır.
Bilginize:
Bu özellik PHP 5.3.0'dan beri mevcuttur.
Örnek 3 - __invoke() kullanımı
<?php
class CallableClass
{
public function __invoke($x)
{
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>
Yukarıdaki örneğin çıktısı:
int(5) bool(true)
$özellikler
) : objectBu duruk yöntem, PHP 5.1.0 sürümünden beri var_export() tarafından ihraç edilen sınıflar için çağrılmaktadır.
Bu yöntemin tek değiştirgesi array('özellik' => değer, ...) biçeminde ihraç edilen özellikleri içeren bir dizidir.
Örnek 4 - __set_state() kullanımı (PHP 5.1.0 ve sonrası)
<?php
class A
{
public $var1;
public $var2;
public static function __set_state($bir_dizi) // PHP 5.1.0'dan beri
{
$obj = new A;
$obj->var1 = $bir_dizi['var1'];
$obj->var2 = $bir_dizi['var2'];
return $obj;
}
}
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
// 'var1' => 5,
// 'var2' => 'foo',
// ));
var_dump($b);
?>
Yukarıdaki örneğin çıktısı:
object(A)#2 (2) { ["var1"]=> int(5) ["var2"]=> string(3) "foo" }
Bilginize: Bir nesne ihraç edilirken, __set_state() nesnenin sınıfı tarafından gerçeklenmiş mi diye var_export() bakmaz, dolayısıyla böyle nesnelerin yeniden ithali __set_state() hiç gerçeklenmemiş gibi başarısız olur. Bu kısmen bazı dahili sınıfları da etkiler. Sadece, __set_state() gerçekleyen sınıfın nesnelerinin yeniden ithal edileceğini doğrulamak yazılımcının sorumluluğundadır.
Gösterilmesi gereken özelliklerini döndürmek için bir nesne dökümleneceği zaman bu yöntem var_dump() tarafından çağrılır.
Bu özellik PHP 5.6.0 sürümünde eklendi.
Örnek 5 __debugInfo() kullanımı
<?php
class C {
private $prop;
public function __construct($val) {
$this->prop = $val;
}
public function __debugInfo() {
return [
'propSquared' => $this->prop ** 2,
];
}
}
var_dump(new C(42));
?>
Yukarıdaki örneğin çıktısı:
object(C)#1 (1) { ["propSquared"]=> int(1764) }