<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Overloading</title> </head> <body><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="language.oop5.traits.html">Traits</a></div> <div class="next" style="text-align: right; float: right;"><a href="language.oop5.iterations.html">Object Iteration</a></div> <div class="up"><a href="language.oop5.html">Classes and Objects</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div><hr /><div id="language.oop5.overloading" class="sect1"> <h2 class="title">Overloading</h2> <p class="para"> Overloading in PHP provides means to dynamically "<span class="quote">create</span>" properties and methods. These dynamic entities are processed via magic methods one can establish in a class for various action types. </p> <p class="para"> The overloading methods are invoked when interacting with properties or methods that have not been declared or are not <a href="language.oop5.visibility.html" class="link">visible</a> in the current scope. The rest of this section will use the terms "<span class="quote">inaccessible properties</span>" and "<span class="quote">inaccessible methods</span>" to refer to this combination of declaration and visibility. </p> <p class="para"> All overloading methods must be defined as <em>public</em>. </p> <blockquote class="note"><p><strong class="note">Note</strong>: <p class="para"> None of the arguments of these magic methods can be <a href="functions.arguments.html#functions.arguments.by-reference" class="link">passed by reference</a>. </p> </p></blockquote> <blockquote class="note"><p><strong class="note">Note</strong>: <p class="para"> PHP's interpretation of "<span class="quote">overloading</span>" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments. </p> </p></blockquote> <div class="sect2" id="language.oop5.overloading.changelog"> <h3 class="title">Changelog</h3> <p class="para"> <table class="doctable informaltable"> <thead> <tr> <th>Version</th> <th>Description</th> </tr> </thead> <tbody class="tbody"> <tr> <td>5.3.0</td> <td> Added <a href="language.oop5.overloading.html#object.callstatic" class="link">__callStatic()</a>. Added warning to enforce public visibility and non-static declaration. </td> </tr> <tr> <td>5.1.0</td> <td> Added <a href="language.oop5.overloading.html#object.isset" class="link">__isset()</a> and <a href="language.oop5.overloading.html#object.unset" class="link">__unset()</a>. </td> </tr> </tbody> </table> </p> </div> <div class="sect2" id="language.oop5.overloading.members"> <h3 class="title">Property overloading</h3> <div class="methodsynopsis dc-description" id="object.set"> <span class="modifier">public</span> <span class="type"><span class="type void">void</span></span> <span class="methodname"><strong>__set</strong></span> ( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span> , <span class="methodparam"><span class="type"><a href="language.pseudo-types.html#language.types.mixed" class="type mixed">mixed</a></span> <code class="parameter">$value</code></span> )</div> <div class="methodsynopsis dc-description" id="object.get"> <span class="modifier">public</span> <span class="type"><a href="language.pseudo-types.html#language.types.mixed" class="type mixed">mixed</a></span> <span class="methodname"><strong>__get</strong></span> ( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span> )</div> <div class="methodsynopsis dc-description" id="object.isset"> <span class="modifier">public</span> <span class="type">bool</span> <span class="methodname"><strong>__isset</strong></span> ( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span> )</div> <div class="methodsynopsis dc-description" id="object.unset"> <span class="modifier">public</span> <span class="type"><span class="type void">void</span></span> <span class="methodname"><strong>__unset</strong></span> ( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span> )</div> <p class="para"> <a href="language.oop5.overloading.html#object.set" class="link">__set()</a> is run when writing data to inaccessible properties. </p> <p class="para"> <a href="language.oop5.overloading.html#object.get" class="link">__get()</a> is utilized for reading data from inaccessible properties. </p> <p class="para"> <a href="language.oop5.overloading.html#object.isset" class="link">__isset()</a> is triggered by calling <span class="function"><a href="function.isset.html" class="function">isset()</a></span> or <span class="function"><a href="function.empty.html" class="function">empty()</a></span> on inaccessible properties. </p> <p class="para"> <a href="language.oop5.overloading.html#object.unset" class="link">__unset()</a> is invoked when <span class="function"><a href="function.unset.html" class="function">unset()</a></span> is used on inaccessible properties. </p> <p class="para"> The <var class="varname"><var class="varname">$name</var></var> argument is the name of the property being interacted with. The <a href="language.oop5.overloading.html#object.set" class="link">__set()</a> method's <var class="varname"><var class="varname">$value</var></var> argument specifies the value the <var class="varname"><var class="varname">$name</var></var>'ed property should be set to. </p> <p class="para"> Property overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods should not be declared <a href="language.oop5.static.html" class="link">static</a>. As of PHP 5.3.0, a warning is issued if one of the magic overloading methods is declared <em>static</em>. </p> <blockquote class="note"><p><strong class="note">Note</strong>: <p class="para"> The return value of <a href="language.oop5.overloading.html#object.set" class="link">__set()</a> is ignored because of the way PHP processes the assignment operator. Similarly, <a href="language.oop5.overloading.html#object.get" class="link">__get()</a> is never called when chaining assignments together like this: <em><div class="cdata"><pre> $a = $obj->b = 8; </pre></div></em> </p> </p></blockquote> <div class="example" id="example-214"> <p><strong>Example #1 Overloading properties via the <a href="language.oop5.overloading.html#object.get" class="link">__get()</a>, <a href="language.oop5.overloading.html#object.set" class="link">__set()</a>, <a href="language.oop5.overloading.html#object.isset" class="link">__isset()</a> and <a href="language.oop5.overloading.html#object.unset" class="link">__unset()</a> methods </strong></p> <div class="example-contents"> <div class="phpcode"><code><span style="color: #000000"> <span style="color: #0000BB"><?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">PropertyTest<br /></span><span style="color: #007700">{<br /> </span><span style="color: #FF8000">/** Location for overloaded data. */<br /> </span><span style="color: #007700">private </span><span style="color: #0000BB">$data </span><span style="color: #007700">= array();<br /><br /> </span><span style="color: #FF8000">/** Overloading not used on declared properties. */<br /> </span><span style="color: #007700">public </span><span style="color: #0000BB">$declared </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /><br /> </span><span style="color: #FF8000">/** Overloading only used on this when accessed outside the class. */<br /> </span><span style="color: #007700">private </span><span style="color: #0000BB">$hidden </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /><br /> public function </span><span style="color: #0000BB">__set</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">)<br /> {<br /> echo </span><span style="color: #DD0000">"Setting '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' to '</span><span style="color: #0000BB">$value</span><span style="color: #DD0000">'\n"</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">] = </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br /> }<br /><br /> public function </span><span style="color: #0000BB">__get</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">)<br /> {<br /> echo </span><span style="color: #DD0000">"Getting '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">'\n"</span><span style="color: #007700">;<br /> if (</span><span style="color: #0000BB">array_key_exists</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">data</span><span style="color: #007700">)) {<br /> return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">];<br /> }<br /><br /> </span><span style="color: #0000BB">$trace </span><span style="color: #007700">= </span><span style="color: #0000BB">debug_backtrace</span><span style="color: #007700">();<br /> </span><span style="color: #0000BB">trigger_error</span><span style="color: #007700">(<br /> </span><span style="color: #DD0000">'Undefined property via __get(): ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$name </span><span style="color: #007700">.<br /> </span><span style="color: #DD0000">' in ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$trace</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'file'</span><span style="color: #007700">] .<br /> </span><span style="color: #DD0000">' on line ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$trace</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'line'</span><span style="color: #007700">],<br /> </span><span style="color: #0000BB">E_USER_NOTICE</span><span style="color: #007700">);<br /> return </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br /> }<br /><br /> </span><span style="color: #FF8000">/** As of PHP 5.1.0 */<br /> </span><span style="color: #007700">public function </span><span style="color: #0000BB">__isset</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">)<br /> {<br /> echo </span><span style="color: #DD0000">"Is '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' set?\n"</span><span style="color: #007700">;<br /> return isset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">]);<br /> }<br /><br /> </span><span style="color: #FF8000">/** As of PHP 5.1.0 */<br /> </span><span style="color: #007700">public function </span><span style="color: #0000BB">__unset</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">)<br /> {<br /> echo </span><span style="color: #DD0000">"Unsetting '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">'\n"</span><span style="color: #007700">;<br /> unset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">]);<br /> }<br /><br /> </span><span style="color: #FF8000">/** Not a magic method, just here for example. */<br /> </span><span style="color: #007700">public function </span><span style="color: #0000BB">getHidden</span><span style="color: #007700">()<br /> {<br /> return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">hidden</span><span style="color: #007700">;<br /> }<br />}<br /><br /><br />echo </span><span style="color: #DD0000">"<pre>\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">PropertyTest</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">a </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">a </span><span style="color: #007700">. </span><span style="color: #DD0000">"\n\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(isset(</span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">a</span><span style="color: #007700">));<br />unset(</span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">a</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(isset(</span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">a</span><span style="color: #007700">));<br />echo </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">declared </span><span style="color: #007700">. </span><span style="color: #DD0000">"\n\n"</span><span style="color: #007700">;<br /><br />echo </span><span style="color: #DD0000">"Let's experiment with the private property named 'hidden':\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #DD0000">"Privates are visible inside the class, so __get() not used...\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">getHidden</span><span style="color: #007700">() . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #DD0000">"Privates not visible outside of class, so __get() is used...\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">hidden </span><span style="color: #007700">. </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?></span> </span> </code></div> </div> <div class="example-contents"><p>The above example will output:</p></div> <div class="example-contents screen"> <div class="cdata"><pre> Setting 'a' to '1' Getting 'a' 1 Is 'a' set? bool(true) Unsetting 'a' Is 'a' set? bool(false) 1 Let's experiment with the private property named 'hidden': Privates are visible inside the class, so __get() not used... 2 Privates not visible outside of class, so __get() is used... Getting 'hidden' Notice: Undefined property via __get(): hidden in <file> on line 70 in <file> on line 29 </pre></div> </div> </div> </div> <div class="sect2" id="language.oop5.overloading.methods"> <h3 class="title">Method overloading</h3> <div class="methodsynopsis dc-description" id="object.call"> <span class="modifier">public</span> <span class="type"><a href="language.pseudo-types.html#language.types.mixed" class="type mixed">mixed</a></span> <span class="methodname"><strong>__call</strong></span> ( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span> , <span class="methodparam"><span class="type">array</span> <code class="parameter">$arguments</code></span> )</div> <div class="methodsynopsis dc-description" id="object.callstatic"> <span class="modifier">public static</span> <span class="type"><a href="language.pseudo-types.html#language.types.mixed" class="type mixed">mixed</a></span> <span class="methodname"><strong>__callStatic</strong></span> ( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span> , <span class="methodparam"><span class="type">array</span> <code class="parameter">$arguments</code></span> )</div> <p class="para"> <a href="language.oop5.overloading.html#object.call" class="link">__call()</a> is triggered when invoking inaccessible methods in an object context. </p> <p class="para"> <a href="language.oop5.overloading.html#object.callstatic" class="link">__callStatic()</a> is triggered when invoking inaccessible methods in a static context. </p> <p class="para"> The <var class="varname"><var class="varname">$name</var></var> argument is the name of the method being called. The <var class="varname"><var class="varname">$arguments</var></var> argument is an enumerated array containing the parameters passed to the <var class="varname"><var class="varname">$name</var></var>'ed method. </p> <div class="example" id="example-215"> <p><strong>Example #2 Overloading methods via the <a href="language.oop5.overloading.html#object.call" class="link">__call()</a> and <a href="language.oop5.overloading.html#object.callstatic" class="link">__callStatic()</a> methods </strong></p> <div class="example-contents"> <div class="phpcode"><code><span style="color: #000000"> <span style="color: #0000BB"><?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MethodTest<br /></span><span style="color: #007700">{<br /> public function </span><span style="color: #0000BB">__call</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #FF8000">// Note: value of $name is case sensitive.<br /> </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Calling object method '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' "<br /> </span><span style="color: #007700">. </span><span style="color: #0000BB">implode</span><span style="color: #007700">(</span><span style="color: #DD0000">', '</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">). </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /> }<br /><br /> </span><span style="color: #FF8000">/** As of PHP 5.3.0 */<br /> </span><span style="color: #007700">public static function </span><span style="color: #0000BB">__callStatic</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #FF8000">// Note: value of $name is case sensitive.<br /> </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Calling static method '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' "<br /> </span><span style="color: #007700">. </span><span style="color: #0000BB">implode</span><span style="color: #007700">(</span><span style="color: #DD0000">', '</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">). </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /> }<br />}<br /><br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">MethodTest</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$obj</span><span style="color: #007700">-></span><span style="color: #0000BB">runTest</span><span style="color: #007700">(</span><span style="color: #DD0000">'in object context'</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">MethodTest</span><span style="color: #007700">::</span><span style="color: #0000BB">runTest</span><span style="color: #007700">(</span><span style="color: #DD0000">'in static context'</span><span style="color: #007700">); </span><span style="color: #FF8000">// As of PHP 5.3.0<br /></span><span style="color: #0000BB">?></span> </span> </code></div> </div> <div class="example-contents"><p>The above example will output:</p></div> <div class="example-contents screen"> <div class="cdata"><pre> Calling object method 'runTest' in object context Calling static method 'runTest' in static context </pre></div> </div> </div> </div> </div><hr /><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="language.oop5.traits.html">Traits</a></div> <div class="next" style="text-align: right; float: right;"><a href="language.oop5.iterations.html">Object Iteration</a></div> <div class="up"><a href="language.oop5.html">Classes and Objects</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div></body></html>