1
0
mirror of https://github.com/php/doc-tr.git synced 2026-03-23 23:02:09 +01:00
Files
archived-doc-tr/language/oop5/magic.xml
2023-11-16 06:02:59 +03:00

655 lines
19 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 5e15a6c3e4d5819102361ae78e73c90a06238c8a Maintainer: nilgun Status: ready -->
<!-- CREDITS: tpug, sezer -->
<sect1 xml:id="language.oop5.magic" xmlns="http://docbook.org/ns/docbook">
<title>Sihirli Yöntemler</title>
<para>
Sihirli yöntemler, bir nesne üzerinde belirli eylemler gerçekleştirildiğinde
PHP'nin öntanımlı eylemini geçersiz kılan özel yöntemlerdir.
</para>
<caution>
<simpara>
<literal>__</literal> ile başlayan tüm yöntem isimleri PHP tarafından
ayrılmıştır. Bu nedenle, PHP'nin davranışını geçersiz kılmadıkça bu tür
yöntem adlarının kullanılması önerilmez.
</simpara>
</caution>
<para>
Aşağıdakiler sihirli yöntem olarak ele alınır:
<!-- Should be an itemized list ? -->
<link linkend="object.construct">__construct()</link>,
<link linkend="object.destruct">__destruct()</link>,
<link linkend="object.call">__call()</link>,
<link linkend="object.callstatic">__callStatic()</link>,
<link linkend="object.get">__get()</link>,
<link linkend="object.set">__set()</link>,
<link linkend="object.isset">__isset()</link>,
<link linkend="object.unset">__unset()</link>,
<link linkend="object.sleep">__sleep()</link>,
<link linkend="object.wakeup">__wakeup()</link>,
<link linkend="object.serialize">__serialize()</link>,
<link linkend="object.unserialize">__unserialize()</link>,
<link linkend="object.tostring">__toString()</link>,
<link linkend="object.invoke">__invoke()</link>,
<link linkend="object.set-state">__set_state()</link>,
<link linkend="object.clone">__clone()</link>,
<link linkend="object.debuginfo">__debugInfo()</link>,
<link linkend="object.clone">__clone()</link> ve
<link linkend="object.debuginfo">__debugInfo()</link>.
</para>
<warning>
<!-- See for a code example of this behaviour: https://3v4l.org/Bov34 -->
<simpara>
<link linkend="object.construct">__construct()</link>,
<link linkend="object.destruct">__destruct()</link> ve
<link linkend="object.clone">__clone()</link> hariç tüm sihirli yöntemler
<emphasis>mutlaka</emphasis> <literal>public</literal> olarak
bildirilmelidir, aksi takdirde bir <constant>E_WARNING</constant>
çıktılanır. PHP 8.0.0 öcesinde,
<link linkend="object.sleep">__sleep()</link>,
<link linkend="object.wakeup">__wakeup()</link>,
<link linkend="object.serialize">__serialize()</link>,
<link linkend="object.unserialize">__unserialize()</link> ve
<link linkend="object.set-state">__set_state()</link> sihirli yöntemleri
için böyle bir uyarı yapılmazdı.
</simpara>
</warning>
<warning>
<para>
Bir sihirli yöntemin tanımında yapılan tür bildirimleri bu belgede
ıklandığı gibi yapılmalıdır. Aksi takdirde, ölümcül hata çıktılanır.
PHP 8.0.0 öncesinde hiçbir uyarı yapılmazdı.
Bundan başka, <link linkend="object.construct">__construct()</link> ve
<link linkend="object.destruct">__destruct()</link> yöntemleri de
bir dönüş türü bildirmemelidir, yoksa ölümcül hata oluşur.
</para>
</warning>
<sect2 xml:id="language.oop5.magic.sleep">
<title>
<link linkend="object.sleep">__sleep()</link> ve
<link linkend="object.wakeup">__wakeup()</link>
</title>
<methodsynopsis xml:id="object.sleep">
<modifier>public</modifier>
<type>array</type><methodname>__sleep</methodname>
<void/>
</methodsynopsis>
<methodsynopsis xml:id="object.wakeup">
<modifier>public</modifier>
<type>void</type><methodname>__wakeup</methodname>
<void/>
</methodsynopsis>
<para>
<function>serialize</function> işlevi, sınıfın
<link linkend="object.sleep">__sleep()</link>
adında sihirli bir işleve sahip olup olmadığına bakar. Böyle bir işlev
varsa herhangi bir dizileştirme işleminden önce bu işlev çalıştırılır.
Bu işlev ile nesne üzerinde temizlik yapılabilir ve dizileştirilmesi
gereken nesnenin tüm değişken isimlerinin bir dizi halinde döndürülmesi
sağlanabilir. Eğer işlev hiçbir şey döndürmemişse &null;
dizileştirilir ve bir <constant>E_NOTICE</constant> çıktılanır.
</para>
<note>
<para>
Ebeveyn sınıflardaki private özelliklerin isimlerini döndürmek
<link linkend="object.sleep">__sleep()</link> için imkansızdır. Bu
yapılırsa <constant>E_NOTICE</constant> seviyesinde bir hata
iletisi çıktılanır. Bunun yerine <classname>Serializable</classname>
arayüzünü kullanılabilir.
</para>
</note>
<note>
<para>
PHP 8.0.0 ve sonrasında, <link linkend="object.sleep">__sleep()</link>
işlevinden dizi olmayan bir değerin döndürülmesi uyarı üretimine sebep olur.
Evvelce, bildirim üretimine sebep oluyordu.
</para>
</note>
<para>
<link linkend="object.sleep">__sleep()</link> 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 bir nesne sözkonusu
olduğunda da bu işlevden yararlanılabilir.
</para>
<para>
<function>unserialize</function> işlevi tersine bir işlem yaparak
<link linkend="object.wakeup">__wakeup()</link> 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.
</para>
<para>
<link linkend="object.wakeup">__wakeup()</link> işlevinin asıl kullanım
amacı, dizileştirme sırasında kaybedilebilen veritabanı bağlantılarını
yeniden oluşturmak ve diğer ilklendirme işlemlerini yeniden yapmaktır.
</para>
<example>
<title>- Uyutma ve uyandırma</title>
<programlisting role="php">
<![CDATA[
<?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->bağlan();
}
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();
}
}?>
]]>
</programlisting>
</example>
</sect2>
<sect2 xml:id="language.oop5.magic.serialize">
<title>
<link linkend="object.serialize">__serialize()</link> ve
<link linkend="object.unserialize">__unserialize()</link>
</title>
<methodsynopsis xml:id="object.serialize">
<modifier>public</modifier> <type>array</type><methodname>__serialize</methodname>
<void/>
</methodsynopsis>
<methodsynopsis xml:id="object.unserialize">
<modifier>public</modifier> <type>void</type><methodname>__unserialize</methodname>
<methodparam><type>array</type><parameter>data</parameter></methodparam>
</methodsynopsis>
<para>
<function>serialize</function> işlevi, sınıfın
<link linkend="object.serialize">__serialize()</link> sihirli adına
sahip bir işlevinin olup olmadığına bakar. Varsa, bu işlev herhangi
bir dizileştirmeden önce çalıştırılır. Nesnenin dizileştirilmiş biçimini
temsil eden ilişkisel bir anahtar/değer çiftleri dizisi oluşturmalı ve
döndürmelidir. Hiçbir dizi döndürülmezse, bir
<classname>TypeError</classname> yavrulanır.
</para>
<note>
<para>
Aynı nesnede hem <link linkend="object.serialize">__serialize()</link>
hem de <link linkend="object.sleep">__sleep()</link> tanımlanmışsa,
sadece <link linkend="object.serialize">__serialize()</link>
çağrılır. <link linkend="object.sleep">__sleep()</link> ise yok
sayılır. Nesne <link linkend="class.serializable">Serializable</link>
arayüzünü gerçekliyorsa, arayüzün <literal>serialize()</literal> yöntemi
yok sayılır ve yerine <link linkend="object.serialize">__serialize()</link>
kullanılır.
</para>
</note>
<para>
<link linkend="object.serialize">__serialize()</link> yönteminin
amaçlanan kullanımı, nesnenin dizileştirmeye uygun keyfi bir gösterimini
tanımlamaktır. Dizinin öğeleri, nesnenin özelliklerine karşılık gelebilir,
ancak bu gerekli değildir.
</para>
<para>
<function>unserialize</function> işlevi ise tersine sınıfın
<link linkend="object.unserialize">__unserialize()</link> sihirli adına
sahip bir işlevinin olup olmadığına bakar. Varsa, bu işlev
<link linkend="object.serialize">__serialize()</link> işlevinden
döndürülen geri yüklenmiş diziye aktarılır. Daha sonra nesnenin
özelliklerini uygun şekilde bu diziden geri yükleyebilir.
</para>
<note>
<para>
Aynı nesnede hem <link linkend="object.unserialize">__unserialize()</link>
hem de <link linkend="object.wakeup">__wakeup()</link> tanımlanmışsa,
yalnızca <link linkend="object.unserialize">__unserialize()</link>
çağrılır. <link linkend="object.wakeup">__wakeup()</link> ise yok sayılır.
</para>
</note>
<note>
<para>
Özellik PHP 7.4.0'dan beri kullanılabilmektedir.
</para>
</note>
<example>
<title>- Dizileştirme ve Nesneleştirme</title>
<programlisting role="php">
<![CDATA[
<?php
class Connection
{
protected $link;
private $dsn, $username, $password;
public function __construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}
private function connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}
public function __serialize(): array
{
return [
'dsn' => $this->dsn,
'user' => $this->username,
'pass' => $this->password,
];
}
public function __unserialize(array $data): void
{
$this->dsn = $data['dsn'];
$this->username = $data['user'];
$this->password = $data['pass'];
$this->connect();
}
}?>
]]>
</programlisting>
</example>
</sect2>
<sect2 xml:id="language.oop5.magic.tostring">
<title><link linkend="object.tostring">__toString()</link></title>
<methodsynopsis xml:id="object.tostring">
<modifier>public</modifier>
<type>string</type><methodname>__toString</methodname>
<void/>
</methodsynopsis>
<para>
<link linkend="object.tostring">__toString()</link> 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. Örneğin, <literal>echo $obj;</literal> ile ne basılacağı gibi.
</para>
<warning>
<para>
PHP 8.0.0'dan itibaren, dönüş değerine standart PHP tür anlamlandırması
uygulanmaktadır, yani
<link linkend="language.types.declarations.strict">katı kodlama</link>
devre dışı bırakılırsa, mümkün olduğu takdirde değer <type>string</type>
türe zorlanır.
</para>
<para>
<link linkend="language.types.declarations.strict">strict typing</link>
etkinken <interfacename>Stringable</interfacename> nesnesi
<type>string</type> tür bildirimi tarafından kabul edilmez.
Bunun olması isteniyorsa <interfacename>Stringable</interfacename> ve
<type>string</type> türleri birleşim türü bildirimi içinde
birleştirilmelidir.
</para>
<para>
PHP 8.0.0'dan itibaren, <link linkend="object.tostring">__toString()</link>
yöntemi içeren her sınıf örtük olarak
<interfacename>Stringable</interfacename> arayüzünü de gerçekler ve
dolayısıyla bu arayüz için tür sınamaları yapılmaz. Bu durumda,
arayüzün doğrudan gerçeklenmesi tercih edilmelidir.
</para>
<para>
PHP 7.4'te, döndürülen değer <emphasis>mutlaka</emphasis>
<type>string</type> türünde olmalıdır, aksi takdirde bir
<classname>Error</classname> yavrulanır.
</para>
<para>
PHP 7.4.0 öncesinde, döndürülen değer <emphasis>mutlaka</emphasis>
<type>string</type> türünde olmalıydı, aksi takdirde ölümcül bir
<constant>E_RECOVERABLE_ERROR</constant> çıktılanırdı.
</para>
</warning>
<warning>
<simpara>
<link linkend="object.tostring">__toString()</link> yönteminin içinden
bir istisna yavrulatılamaz. PHP 7.4.0 öncesinde, bunun yapılması ölümcül
hata ile sonuçlanırdı.
</simpara>
</warning>
<example>
<title>- Basit bir örnek</title>
<programlisting role="php">
<![CDATA[
<?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;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Merhaba
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.magic.invoke">
<title><link linkend="object.invoke">__invoke()</link></title>
<methodsynopsis xml:id="object.invoke">
<type>mixed</type><methodname>__invoke</methodname>
<methodparam rep="repeat"><parameter>values</parameter></methodparam>
</methodsynopsis>
<para>
<link linkend="object.invoke">__invoke()</link> yöntemi, bir betik bir
nesneyi bir işlev olarak çağırmaya çalışırsa çağrılır.
</para>
<example>
<title>- <link linkend="object.invoke">__invoke()</link> kullanımı</title>
<programlisting role="php">
<![CDATA[
<?php
class CallableClass
{
public function __invoke($x)
{
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
int(5)
bool(true)
]]>
</screen>
</example>
<example>
<title>- <link linkend="object.invoke">__invoke()</link> kullanımı</title>
<programlisting role="php">
<![CDATA[
<?php
class Sort
{
private $key;
public function __construct(string $key)
{
$this->key = $key;
}
public function __invoke(array $a, array $b): int
{
return $a[$this->key] <=> $b[$this->key];
}
}
$müşteriler = [
['no' => 1, 'isim' => 'John', 'soyisim' => 'Do'],
['no' => 3, 'isim' => 'Alice', 'soyisim' => 'Gustav'],
['no' => 2, 'isim' => 'Bob', 'soyisim' => 'Filipe']
];
// $müşterileri isme göre sırala
usort($müşteriler, new Sort('isim'));
print_r($müşteriler);
// $müşterileri soyisme göre sırala
usort($müşteriler, new Sort('soyisim'));
print_r($müşteriler);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => Array
(
[no] => 3
[isim] => Alice
[soyisim] => Gustav
)
[1] => Array
(
[no] => 2
[isim] => Bob
[soyisim] => Filipe
)
[2] => Array
(
[no] => 1
[isim] => John
[soyisim] => Do
)
)
Array
(
[0] => Array
(
[no] => 1
[isim] => John
[soyisim] => Do
)
[1] => Array
(
[no] => 2
[isim] => Bob
[soyisim] => Filipe
)
[2] => Array
(
[no] => 3
[isim] => Alice
[soyisim] => Gustav
)
)
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.magic.set-state">
<title><link linkend="object.set-state">__set_state()</link></title>
<methodsynopsis xml:id="object.set-state">
<modifier>static</modifier>
<type>object</type><methodname>__set_state</methodname>
<methodparam><type>array</type><parameter>özellikler</parameter></methodparam>
</methodsynopsis>
<para>
Bu <link linkend="language.oop5.static">statik</link> yöntem,
<function>var_export</function> tarafından ihraç edilen
sınıflar için çağrılır.
</para>
<para>
Bu yöntemin tek bağımsız değişkeni
<literal>['</literal><replaceable>özellik</replaceable><literal>' =>
</literal><replaceable>değer</replaceable><literal>, ...]</literal>
biçeminde ihraç edilen özellikleri içeren bir dizidir.
</para>
<example>
<title>- <link linkend="object.set-state">__set_state()</link> kullanımı
</title>
<programlisting role="php">
<![CDATA[
<?php
class A
{
public $var1;
public $var2;
public static function __set_state($bir_dizi)
{
$obj = new A;
$obj->var1 = $bir_dizi['var1'];
$obj->var2 = $bir_dizi['var2'];
return $obj;
}
}
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
$b = var_export($a, true);
var_dump($b);
eval('$c = ' . $b . ';');
var_dump($c);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(60) "A::__set_state(array(
'var1' => 5,
'var2' => 'foo',
))"
object(A)#2 (2) {
["var1"]=>
int(5)
["var2"]=>
string(3) "foo"
}
]]>
</screen>
</example>
<note>
<simpara>
Bir nesne ihraç edilirken, <function>var_export</function> işlevi
<link linkend="object.set-state">__set_state()</link> nesnenin sınıfı
tarafından gerçeklenmiş mi diye bakmaz, dolayısıyla böyle nesnelerin
yeniden ithali __set_state() hiç gerçeklenmemiş gibi bir
<classname>Error</classname> istisnası yavrulanmasına sebep olur.
Bu kısmen bazı dahili sınıfları da etkiler.
</simpara>
<simpara>
Sadece, __set_state() gerçekleyen sınıfın nesnelerinin yeniden ithal
edilmesini sağlamak yazılımcının sorumluluğundadır.
</simpara>
</note>
</sect2>
<sect2 xml:id="language.oop5.magic.debuginfo">
<title><link linkend="object.debuginfo">__debugInfo()</link></title>
<methodsynopsis xml:id="object.debuginfo">
<type>array</type><methodname>__debugInfo</methodname>
<void/>
</methodsynopsis>
<para>
Gösterilmesi gereken özelliklerini döndürmek için bir nesne
dökümleneceği zaman bu yöntem <function>var_dump</function> tarafından
çağrılır.
</para>
<example>
<title>- <link linkend="object.debuginfo">__debugInfo()</link>
kullanımı</title>
<programlisting role="php">
<![CDATA[
<?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));
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(C)#1 (1) {
["propSquared"]=>
int(1764)
}
]]>
</screen>
</example>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->