<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jean-Michel Feurprier &#187; php</title>
	<atom:link href="http://www.jmfeurprier.com/blog/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jmfeurprier.com/blog</link>
	<description>LAMP Web Developer</description>
	<lastBuildDate>Sat, 13 Feb 2010 00:16:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>method_exists() vs. is_callable()</title>
		<link>http://www.jmfeurprier.com/blog/2010/01/03/method_exists-vs-is_callable/</link>
		<comments>http://www.jmfeurprier.com/blog/2010/01/03/method_exists-vs-is_callable/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 07:17:24 +0000</pubDate>
		<dc:creator>Jean-Michel Feurprier</dc:creator>
				<category><![CDATA[php5]]></category>
		<category><![CDATA[tips and tricks]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.jmfeurprier.com/blog/2010/01/03/method_exists-vs-is_callable/</guid>
		<description><![CDATA[One thing I often see when re-factoring PHP applications, is the improper use of the method_exists() function, and I think this needs a little bit of clarification.]]></description>
			<content:encoded><![CDATA[<p>One thing I often see when re-factoring PHP applications, is the improper use of the <a href="http://www.php.net/manual/en/function.method-exists.php">method_exists()</a> function, and I think this needs a little bit of clarification.<br />
<span id="more-221"></span><br />
Here is a typical example of what I&#8217;m talking about:</p>
<pre class="brush: php">

if (method_exists($object, &#039;SomeMethod&#039;))
{
  $object-&gt;SomeMethod($this, TRUE);
}
</pre>
<p>The purpose of this code snippet is quite easy to understand (even if I don&#8217;t encourage to do this kind of not-very-OOP-stuff): having an object named &#8220;$object&#8221;, we try to know if it has a method named &#8220;SomeMethod&#8221;, if so, we call it, and provide some arguments to it.</p>
<h3>Yes, but&#8230;</h3>
<p>This code will probably run very well during all its lifetime, but what if the object&#8217;s method is not visible from the current scope (like&#8230; a private or protected method)? PHP&#8217;s <a href="http://www.php.net/manual/en/function.method-exists.php">method_exists()</a> function does what it says: it checks if the provided class or object has a method named like the provided one, and returns TRUE if so, or FALSE if not, visibility is not questionned. So, if you provide a private or protected existing method name (being out of current scope) to <a href="http://www.php.net/manual/en/function.method-exists.php">method_exists()</a>, you&#8217;ll get TRUE as the return value, and a nice &#8220;Fatal error: Call to private method&#8230;&#8221;, immediately terminating the current script execution.</p>
<h3>The right tool for the right job</h3>
<p>The real intent of the previous code snippet was in fact to know if the application could <strong>call</strong> a method on the object, from the current scope.</p>
<p>This is why (among other reasons) <a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> is part of the PHP built-in functions.</p>
<h3>How does it work?</h3>
<p><a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> receives a <a href="http://www.php.net/manual/en/language.pseudo-types.php#language.types.callback">callback</a> as its first argument, which, in our case, consists of an array of two values: the first being an object (or a string holding a class name), and the second being a string holding a method name. <a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> returns TRUE when the provided callback can be called from the current scope, or FALSE if not. </p>
<pre class="brush: php">

if (is_callable(array($object, &#039;SomeMethod&#039;)))
{
  $object-&gt;SomeMethod($this, TRUE);
}
</pre>
<p>Here is another snippet of code to illustrate the differences between <a href="http://www.php.net/manual/en/function.method-exists.php">method_exists()</a> and <a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> in action:</p>
<pre class="brush: php">
class Foo {
  public function PublicMethod() {}
  private function PrivateMethod() {}
  public static function PublicStaticMethod() {}
  private static function PrivateStaticMethod() {}
}

$foo = new Foo();

$callbacks = array(
  array($foo, &#039;PublicMethod&#039;),
  array($foo, &#039;PrivateMethod&#039;),
  array($foo, &#039;PublicStaticMethod&#039;),
  array($foo, &#039;PrivateStaticMethod&#039;),
  array(&#039;Foo&#039;, &#039;PublicMethod&#039;),
  array(&#039;Foo&#039;, &#039;PrivateMethod&#039;),
  array(&#039;Foo&#039;, &#039;PublicStaticMethod&#039;),
  array(&#039;Foo&#039;, &#039;PrivateStaticMethod&#039;),
);

foreach ($callbacks as $callback) {
  var_dump($callback);
  var_dump(method_exists($callback[0], $callback[1])); // 0: object / class name, 1: method name
  var_dump(is_callable($callback));
  echo str_repeat(&#039;-&#039;, 40), &quot;\n&quot;;
}
</pre>
<p>Run it, and you&#8217;ll see that every test returns TRUE with <a href="http://www.php.net/manual/en/function.method-exists.php">method_exists()</a>, even private methods, while <a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> returns FALSE for these (and will also trigger strict errors with non-static methods being queried as static ones, be aware of this).</p>
<h3>More details</h3>
<p><a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> has other uses, like checking the syntax of the provided callback, without checking if there really is a class or a method with the provided names.<br />
Like <a href="http://www.php.net/manual/en/function.method-exists.php">method_exists()</a>, <a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> can trigger a class autoloading process if the provided class is not already loaded.<br />
If an object has the magic <a href="http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods">__call()</a> method implemented, then <a href="http://www.php.net/manual/en/function.is-callable.php">is_callable()</a> will return TRUE for any non-existent method, while <a href="http://www.php.net/manual/en/function.method-exists.php">method_exists()</a> will return FALSE. I guess the same behavior can be observed with the recent (PHP 5.3.0) <a href="http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods">__callStatic()</a> magic method, but I did not test it (yet).<br />
Everything else you need to know is in the <a href="http://www.php.net/manual/">PHP manual</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jmfeurprier.com/blog/2010/01/03/method_exists-vs-is_callable/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Improving performance with return values caching</title>
		<link>http://www.jmfeurprier.com/blog/2009/02/04/improving-performance-with-return-values-caching/</link>
		<comments>http://www.jmfeurprier.com/blog/2009/02/04/improving-performance-with-return-values-caching/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 06:26:29 +0000</pubDate>
		<dc:creator>Jean-Michel Feurprier</dc:creator>
				<category><![CDATA[concepts and principles]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tips and tricks]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://www.jmfeurprier.com/blog/2009/02/04/improving-performance-with-return-values-caching/</guid>
		<description><![CDATA[A simple technique to improve a PHP project overall performance.]]></description>
			<content:encoded><![CDATA[<p>Many functions (and methods) in a project will often provide the same return value for the same arguments, like:</p>
<ul>
<li>mathematical functions:</li>
</ul>
<pre class="brush: php">
function SomeMaths($x)
{
	return $x + pow($x, 3.2) - cos($x);
}
</pre>
<ul>
<li>functions which retrieve content from a file:</li>
</ul>
<p><span id="more-38"></span></p>
<pre class="brush: php">
function GetConfiguration()
{
	return parse_ini_file(&#039;configuration.ini&#039;);
}
</pre>
<ul>
<li>functions which retrieve content from a database:</li>
</ul>
<pre class="brush: php">
function GetArticleById($id)
{
	$sqlId  = mysql_real_escape_string($id);
	$result = mysql_query(&quot;SELECT `id`, `title` FROM `article` WHERE `id` = &#039;$sqlId&#039; LIMIT 1&quot;);

	if (FALSE === $result)
	{
		throw new Exception(&#039;Query failed.&#039;);
	}

	return mysql_fetch_assoc($result);
}
</pre>
<p>If your project holds a function like one of these, and:</p>
<ul>
<li>your <a title="Xdebug" href="http://www.xdebug.org/">prefered</a> <a title="KCachegrind" href="http://kcachegrind.sourceforge.net/">profiling</a> <a title="WinCacheGrind" href="http://sourceforge.net/projects/wincachegrind/">tool</a> reveals that a lot of the execution time is spent in this function</li>
<li>its returned value is always the same during a single run (script execution), when providing the same arguments</li>
<li>this function is called more than once per run</li>
</ul>
<p>Then consider caching (saving) its return values.</p>
<p>Here is how it can be achieved (yes, there are <a href="http://memcached.org/">more advanced</a> <a href="http://blog.digitalstruct.com/2008/02/27/php-performance-series-caching-techniques/">techniques</a> to do it, but this is not the point of this post): add a static variable in the body of the function, which will hold an associative array, mapping every parameter combination with a return value:</p>
<pre class="brush: php">
function GetArticleById($id)
{
	static $cache = array();

	// Return value is not in cache yet?
	if (!isset($cache[$id]))
	{
		$sqlId  = mysql_real_escape_string($id);
		$result = mysql_query(&quot;SELECT `id`, `title` FROM `article` WHERE `id` = &#039;$sqlId&#039; LIMIT 1&quot;);

		if (FALSE === $result)
		{
			throw new Exception(&#039;Query failed.&#039;);
		}

		// Add return value to cache
		$cache[$id] = mysql_fetch_assoc($result);
	}

	// Return cache content
	return $cache[$id];
}
</pre>
<p>Here it is, the (possibly heavy) process of querying the database will only be executed once at the first function call. Every other function call with the same argument will use the cached return value.</p>
<p>Keep in mind that the amount of cached return values must be reasonable (available memory is limited). If there are millions of possible arguments combinations for a function in a single run, you&#8217;ll have to consider a more elaborate way of optimizing it (this could be the subject of a future post).</p>
<p>Also, always, <strong>always</strong>, <strong>ALWAYS</strong> profile your code <strong>BEFORE</strong> you decide to apply an optimization like this one (and wait for your project to be nearly completed before profiling).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jmfeurprier.com/blog/2009/02/04/improving-performance-with-return-values-caching/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
