<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom"><generator uri="http://www.habariproject.org/" version="0.10-alpha">Habari</generator><id>tag:mattread.com,2020-02-06:php/8570b76d965d9aabc07ffb82b7ac6c3a35ed2dea</id><title>Matt Read, Weblog</title><subtitle>It says little, does less, means  nothing.</subtitle><updated>2008-09-29T00:55:09-04:00</updated><link rel="alternate" href="https://mattread.com/tag/php"/><link rel="self" href="https://mattread.com/tag/php/atom"/><entry><title>Javascript Prototype Behaviour in PHP</title><link rel="alternate" href="https://mattread.com/javascript-prototype-behaviour-in-php"/><link rel="edit" href="https://mattread.com/javascript-prototype-behaviour-in-php/atom"/><author><name>Matt Read</name><uri>https://mattread.com</uri></author><id>tag:mattread.com,2008:javascript-prototype-behaviour-in-php/1222664109</id><updated>2008-09-29T00:55:09-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-20T12:43:28-04:00</app:edited><published>2008-09-29T02:01:57-04:00</published><category term="code"/><category term="php"/><category term="javascript"/><category term="prototype"/><content type="html">&lt;p&gt;One of the &amp;#8220;neat&amp;#8221; things in Javascript is you are able to dynamically add or change methods of a class and automatically update every instance of that class. Some of the things I usually find useful are adding to the String class, like so:&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;
&lt;![CDATA[
String.prototype.htmlSpecialChars = function() {
    return this.replace(/\&lt;/g,'&lt;').replace(/\&gt;/g,'&gt;');
}
String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, '');
}
]]&gt;
&lt;/pre&gt;

&lt;p&gt;Obviously we cannot do this in PHP, and why would we, right? However we can emulate this behaviour to a certain extent using my &amp;#8220;neat&amp;#8221; little &lt;a href="https://gist.github.com/576295"&gt;Prototype&lt;/a&gt; class. With this Prototype class we can dynamically add properties and methods to any class, and they will be inherited by all instances of that class.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s look at the following &amp;#8220;normal&amp;#8221; PHP code.&lt;/p&gt;

&lt;pre class="highlight php"&gt;
&lt;![CDATA[
class Person extends Prototype
{
    public $name;
    public $gender;
   
    public function gender()
    {
        printf("%s is %s\n", $this-&gt;name, $this-&gt;gender);
    }
}

$matt = new Person;
$matt-&gt;name = 'Matt';
$matt-&gt;gender = 'male';
$matt-&gt;gender();

// Matt is male
]]&gt;
&lt;/pre&gt;

&lt;p&gt;Now, there is nothing magical or out-of-the-ordinary going on here. We just instantiate the Person class and setup some properties. Calling the &lt;code&gt;gender()&lt;/code&gt; method outputs a nice little string for us.&lt;/p&gt;

&lt;p&gt;However, you see that the Person class is actually a child of the Prototype class. This will allow us to do some of that &amp;#8220;neat&amp;#8221; Javascript stuff. Using Prototype, let us expand the Person class to add an &lt;code&gt;$age&lt;/code&gt; property and an &lt;code&gt;age()&lt;/code&gt; method to output a nice string. Like so:&lt;/p&gt;

&lt;pre class="highlight php"&gt;
&lt;![CDATA[
Person::add_property('age');
Person::add_method('age', 'printf("%s is a %d year old %s\n", $this-&gt;name, $this-&gt;age, $this-&gt;gender);');

$matt-&gt;age = 28;
$matt-&gt;age();

// Matt is a 28 year old male
]]&gt;
&lt;/pre&gt;

&lt;p&gt;Now all instances of Person inherit the &lt;code&gt;$age&lt;/code&gt; property and &lt;code&gt;age()&lt;/code&gt; method. So we can create a new Person, Susie, and this object will now have the age stuff.&lt;/p&gt;

&lt;pre class="highlight php"&gt;
&lt;![CDATA[
$susie = new Person;
$susie-&gt;name = 'Susie';
$susie-&gt;gender = 'female';
$susie-&gt;age = 21;
$susie-&gt;age();

// Susie is a 21 year old female
]]&gt;
&lt;/pre&gt;

&lt;p&gt;One limitation of the Prototype class though, is you cannot overload a current method. So the following code, that attempts to overload the &lt;code&gt;gender()&lt;/code&gt; method, will not work.&lt;/p&gt;

&lt;pre class="highlight php"&gt;
&lt;![CDATA[
Person::add_method('gender', 'printf("%s is a %d year old %s\n", $this-&gt;name, $this-&gt;age, $this-&gt;gender);');

$matt-&gt;gender();

// Matt is male
]]&gt;
&lt;/pre&gt;

&lt;p&gt;There are also many, many, many other problems with this Prototype class. Some of which are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &amp;#8216;$this&amp;#8217; keyword is reserved, so it actually does a string replace and uses &amp;#8216;$self&amp;#8217; instead.&lt;/li&gt;
&lt;li&gt;You cannot access/add new methods or properties statically (until PHP 5.3 with __callStatic()).&lt;/li&gt;
&lt;li&gt;It uses create_function, so every &amp;#8220;method&amp;#8221; is actually defined in the global namespace.&lt;/li&gt;
&lt;li&gt;Iteration does not work, although it could possibly be done with Iterator, Countable, et al.&lt;/li&gt;
&lt;li&gt;You cannot reference static variables/methods in your add method.&lt;/li&gt;
&lt;li&gt;You cannot share methods between classes.&lt;/li&gt;
&lt;li&gt;And so on and so forth&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This class was just an experiment to see if it was at all possible to implement something like Javascript&amp;#8217;s prototype behaviour in PHP with out using the &lt;a href="http://pecl.php.net/package/runkit"&gt;Runkit PECL extension&lt;/a&gt;. I had no intention of actually making this usable in production, for many reasons ;), although it was fun.&lt;/p&gt;
</content></entry><entry><title>Persistent Static Variables</title><link rel="alternate" href="https://mattread.com/persistent-static-variables-across-instances-in-php"/><link rel="edit" href="https://mattread.com/persistent-static-variables-across-instances-in-php/atom"/><author><name>Matt Read</name><uri>https://mattread.com</uri></author><id>tag:mattread.com,2008:persistent-static-variables-across-instances-in-php/1213249473</id><updated>2008-06-12T01:44:33-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-22T10:57:47-04:00</app:edited><published>2008-06-12T01:26:40-04:00</published><category term="code"/><category term="php"/><content type="html">&lt;p&gt;Wait, What? Yeah that&amp;#8217;s what I thought too. Still no Idea what I&amp;#8217;m talking about? Well, let&amp;#8217;s take a look at the following code. Let&amp;#8217;s call it &amp;#8220;fred&amp;#8221;.&lt;/p&gt;

&lt;pre class="highlight php"&gt;
class foo {
    function bar( $b = 0 )
    {
        static $a = 0;
        if ( $b ) {
            $a = $b;
        }   
         echo $a;
    }
}

$faz = new foo;
$faz-&gt;bar(3);
$baz = new foo;
$baz-&gt;bar();
foo::bar();
foo:bar(1); 
$faz-&gt;bar();
&lt;/pre&gt;

&lt;p&gt;The code above, named &amp;#8220;fred&amp;#8221;, basically creates a static variable &lt;code&gt;$a&lt;/code&gt; inside the function &lt;code&gt;foo()&lt;/code&gt;. When you call &lt;code&gt;foo(0)&lt;/code&gt; it outputs the value of &lt;code&gt;$a&lt;/code&gt;. When you call &lt;code&gt;foo('x')&lt;/code&gt; , where x can be anything, it updates the value of &lt;code &gt;$a&lt;/code&gt; with &lt;code&gt;'x'&lt;/code&gt;, and outputs the new result.&lt;/p&gt;

&lt;p&gt;Now, what would expect &amp;#8220;fred&amp;#8221; to output? If your like me, then you are completely wrong. &amp;#8220;fred&amp;#8221; will actually output the following code.&lt;/p&gt;

&lt;pre class="highlight php"&gt;
&lt;![CDATA[
/*
Actual Outputs:
$faz-&gt;bar(3); ==&gt; 3
$baz-&gt;bar();  ==&gt; 3
foo::bar();      ==&gt; 3
foo:bar(1);     ==&gt; 1
$faz-&gt;bar();   ==&gt; 1
 
Expected outputs:
$faz-&gt;bar(3); ==&gt; 3
$baz-&gt;bar();  ==&gt; 0
foo::bar();      ==&gt; 0
foo:bar(1);     ==&gt; 1
$faz-&gt;bar();   ==&gt; 3
*/
]]&gt;
&lt;/pre&gt;

&lt;p&gt;Yes, that&amp;#8217;s what I said at the start, &amp;#8220;Persistent Static Variables Across Instances&amp;#8221;. The static variable &lt;code&gt;$a&lt;/code&gt; actually persists across the two instances of foo that &amp;#8220;fred&amp;#8221; created, and even into the static method call. This was completely unexpected, at least by me. So I&amp;#8217;ll ask, does anyone know if this is actually the expected behaviour, and why it is or is not?&lt;/p&gt;
</content></entry></feed>
