php-doc-en/language/oop5/magic.xml
Adam Harvey 4307b3bcdf Document __debugInfo().
git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@334638 c90b9560-bf6c-de11-be94-00142212c4b1
2014-08-28 05:28:06 +00:00

363 lines
10 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<sect1 xml:id="language.oop5.magic" xmlns="http://docbook.org/ns/docbook">
<title>Magic Methods</title>
<para>
The function names
<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.tostring">__toString()</link>,
<link linkend="object.invoke">__invoke()</link>,
<link linkend="object.set-state">__set_state()</link>,
<link linkend="object.clone">__clone()</link> and
<link linkend="object.debuginfo">__debugInfo()</link>
are magical in PHP classes. You
cannot have functions with these names in any of your
classes unless you want the magic functionality associated
with them.
</para>
<caution>
<simpara>
PHP reserves all function names starting with __ as magical.
It is recommended that you do not use function names with
__ in PHP unless you want some documented magic functionality.
</simpara>
</caution>
<sect2 xml:id="language.oop5.magic.sleep">
<title>
<link linkend="object.sleep">__sleep()</link> and
<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">
<type>void</type><methodname>__wakeup</methodname>
<void/>
</methodsynopsis>
<para>
<function>serialize</function> checks if your class has a function with
the magic name <link linkend="object.sleep">__sleep()</link>. If so, that function is
executed prior to any serialization. It can clean up the object
and is supposed to return an array with the names of all variables
of that object that should be serialized.
If the method doesn't return anything then &null; is serialized and
<constant>E_NOTICE</constant> is issued.
</para>
<note>
<para>
It is not possible for <link linkend="object.sleep">__sleep()</link> to return names of
private properties in parent classes. Doing this will result in an
<constant>E_NOTICE</constant> level error. Instead you may use the
<classname>Serializable</classname> interface.
</para>
</note>
<para>
The intended use of <link linkend="object.sleep">__sleep()</link> is to commit pending
data or perform similar cleanup tasks. Also, the function is
useful if you have very large objects which do not need to be
saved completely.
</para>
<para>
Conversely, <function>unserialize</function> checks for the
presence of a function with the magic name
<link linkend="object.wakeup">__wakeup()</link>. If present, this function can
reconstruct any resources that the object may have.
</para>
<para>
The intended use of <link linkend="object.wakeup">__wakeup()</link> is to
reestablish any database connections that may have been lost
during serialization and perform other reinitialization
tasks.
</para>
<example>
<title>Sleep and wakeup</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 __sleep()
{
return array('dsn', 'username', 'password');
}
public function __wakeup()
{
$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>
The <link linkend="object.tostring">__toString()</link> method allows a class to decide
how it will react when it is treated like a string. For example,
what <literal>echo $obj;</literal> will print. This method must
return a string, as otherwise a fatal <constant>E_RECOVERABLE_ERROR</constant>
level error is emitted.
</para>
<warning>
<simpara>
You cannot throw an exception from within a
<link linkend="object.tostring">__toString()</link> method. Doing so will
result in a fatal error.
</simpara>
</warning>
<example>
<title>Simple example</title>
<programlisting role="php">
<![CDATA[
<?php
// Declare a simple class
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Hello
]]>
</screen>
</example>
<para>
It is worth noting that before PHP 5.2.0 the <link linkend="object.tostring">__toString()</link>
method was only called when it was directly combined with
<function>echo</function> or <function>print</function>.
Since PHP 5.2.0, it is called in any string context (e.g. in
<function>printf</function> with <literal>%s</literal> modifier) but not
in other types contexts (e.g. with <literal>%d</literal> modifier).
Since PHP 5.2.0, converting objects without <link linkend="object.tostring">__toString()</link>
method to string would cause <constant>E_RECOVERABLE_ERROR</constant>.
</para>
</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 choice="opt"><parameter>...</parameter></methodparam>
</methodsynopsis>
<para>
The <link linkend="object.invoke">__invoke()</link> method is called when a script tries to
call an object as a function.
</para>
<note>
<para>
This feature is available since PHP 5.3.0.
</para>
</note>
<example>
<title>Using <link linkend="object.invoke">__invoke()</link></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>
</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>properties</parameter></methodparam>
</methodsynopsis>
<para>
This <link linkend="language.oop5.static">static</link> method is called
for classes exported by <function>var_export</function> since PHP 5.1.0.
</para>
<para>
The only parameter of this method is an array containing exported
properties in the form <literal>array('property' => value, ...)</literal>.
</para>
<example>
<title>Using <link linkend="object.set-state">__set_state()</link> (since PHP 5.1.0)</title>
<programlisting role="php">
<![CDATA[
<?php
class A
{
public $var1;
public $var2;
public static function __set_state($an_array) // As of PHP 5.1.0
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['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);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(A)#2 (2) {
["var1"]=>
int(5)
["var2"]=>
string(3) "foo"
}
]]>
</screen>
</example>
</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>
This method is called by <function>var_dump</function> when dumping an
object to get the properties that should be shown. If the method isn't
defined on an object, then all public, protected and private properties
will be shown.
</para>
<para>
This feature was added in PHP 5.6.0.
</para>
<example>
<title>Using <link linkend="object.debuginfo">__debugInfo()</link></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
-->