<?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>Rommel Santor&#039;s Clog &#187; namespace</title>
	<atom:link href="https://rommelsantor.com/clog/tag/namespace/feed/" rel="self" type="application/rss+xml" />
	<link>https://rommelsantor.com/clog</link>
	<description>my exploits and misadventures in programming</description>
	<lastBuildDate>Thu, 04 Feb 2016 12:56:01 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.0.38</generator>
	<item>
		<title>PHP 5.3 Dynamic Namespace Resolution</title>
		<link>https://rommelsantor.com/clog/2011/04/10/php-5-3-dynamic-namespace-resolution/</link>
		<comments>https://rommelsantor.com/clog/2011/04/10/php-5-3-dynamic-namespace-resolution/#comments</comments>
		<pubDate>Mon, 11 Apr 2011 05:52:23 +0000</pubDate>
		<dc:creator><![CDATA[rommel]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[namespace]]></category>
		<category><![CDATA[php 5.3]]></category>

		<guid isPermaLink="false">http://rommelsantor.com/clog/?p=176</guid>
		<description><![CDATA[As PHP continues evolving, it just keeps getting better and better. One of the features added in version 5.3 is support for namespaces. If you&#8217;ve started trying to actually use PHP namespaces, you&#8217;ve probably run into some of the more obvious quirks that require you to either retrofit your code or implement a workaround. I [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>As PHP continues evolving, it just keeps getting better and better. One of the features added in version 5.3 is support for <a href="http://www.php.net/manual/en/language.namespaces.rationale.php">namespaces</a>. If you&#8217;ve started trying to actually use PHP namespaces, you&#8217;ve probably run into some of the more obvious quirks that require you to either retrofit your code or implement a workaround. I started with the former before realizing that thanks to the namespace feature itself, a simple set of workarounds could do the job.</p>
<p>Specifically, I&#8217;m referring to the fact that namespace resolution happens at compile time, which means that if you attempt to reference a namespaced class or method as a string, it won&#8217;t be recognized unless that string explicitly includes the namespace name. The most apparent case is when calling <code>class_exists()</code>. For example, let&#8217;s say you define class Settings in namespace OssumCMS:</p>
<pre>namespace OssumCMS;

class Settings {
  const MEMCACHED_ADDR = 'none';
  public static function do_something() {
  }
}</pre>
<p>In your code, you might want to do some things like:</p>
<pre>// ...
if (class_exists('Settings'))
  if (@constant('Settings::MEMCACHED_ADDR') != 'none')
    call_user_func(array('Settings', 'do_something'));</pre>
<p>But that would never work because class Settings is defined within namespace OssumCMS. PHP resolves namespaces at compile time, so when class_exists(), constant(), and call_user_func() are called at run time, they won&#8217;t ever find class Settings because it&#8217;s checking only the global namespace.<span id="more-176"></span> The obvious fix is to include the namespace name before every occurrence of the class name:</p>
<pre>// ...
if (class_exists('OssumCMS\Settings'))
  if (@constant('OssumCMS\Settings::MEMCACHED_ADDR') != 'none')
    call_user_func(array('OssumCMS\Settings', 'do_something'));</pre>
<p>Now PHP will know to check for the class within the namespace in which it&#8217;s actually defined. Small victory, especially when you&#8217;re dealing with thousands of lines of pre-existing code. You definitely don&#8217;t want to find every occurrence of every class and prefix it with the namespace. Another small step in the right direction would be to use a function to automatically prefix a string with the current namespace if needed by using a function:</p>
<pre>namespace OssumCMS;

function ns($i_name) {
  if (!is_scalar($i_name))
    return $i_name;
  return strpos($i_name, '\\') !== false ? $i_name : (__NAMESPACE__ . '\\' . $i_name);
}</pre>
<p>This would allow you to simply wrap all your class name strings in that function call, for example:</p>
<pre>if (class_exists(ns($class_name)))
  do_something();</pre>
<p>
<div style="float:left;margin:0 10px 10px 0">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-7639656561235411";
/* Square (250x250) */
google_ad_slot = "8522038794";
google_ad_width = 250;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<br />
But that would still require you to traverse all line of all your source code files doing a search/replace. Wouldn&#8217;t it be easier if instead of manipulating your class name references, you could override the built-in PHP functions? In the old days, you wouldn&#8217;t be able to do something like that, but thanks to namespaces, it&#8217;s entirely possible. All we have to do is create our own class_exists(), constant(), and call_user_func() type functions within our own namespace and add to string arguments the namespace prefix whenever necessary, then call the corresponding global functions.</p>
<pre>namespace OssumCMS;

function ns($i_name) {
  if (!is_scalar($i_name))
    return $i_name;
  return strpos($i_name, '\\') !== false ? $i_name : (__NAMESPACE__ . '\\' . $i_name);
}

function un_ns($i_name) {
  if (!is_scalar($i_name))
    return $i_name;
  return preg_replace('#^' . preg_quote(__NAMESPACE__, '#') . '\\#i', '', $i_name);
}

function constant($i_name)        { return @\constant(ns($i_name)); }
function class_exists($i_name)    { return \class_exists(ns($i_name)); }

function call_user_func_array($i_func, $i_args) {
  is_array($i_func)
    ? (!is_object($i_func[0]) &#038;&#038; ($i_func[0] = ns($i_func[0])))
    : (!is_object($i_func) &#038;&#038; !function_exists($i_func) &#038;&#038; ($i_func = ns($i_func)));
  return \call_user_func_array($i_func, $i_args);
}

function call_user_func($i_func) {
  return call_user_func_array($i_func, array_shift($args = func_get_args()));
}</pre>
<p>Given these overrides, our example block of code would be evaluated as follows</p>
<pre>// ...
if (OssumCMS\class_exists(OssumCMS\ns('Settings')))
  if (OssumCMS\constant(OssumCMS\ns('Settings::MEMCACHED_ADDR')) != 'none')
    OssumCMS\call_user_func(array(OssumCMS\ns('Settings'), 'do_something'));</pre>
<p>There are surely other functions that need overriding, but these are the most obvious suspects. This was a useful little hack for me and I hope you find it useful as well.</p>
<p><script type="text/javascript">//< ![CDATA[
$("pre").attr({name:'code'}).addClass('php:nocontrols:nogutter');
//]]&gt;</script></p>
]]></content:encoded>
			<wfw:commentRss>https://rommelsantor.com/clog/2011/04/10/php-5-3-dynamic-namespace-resolution/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
