<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Gergely Hodicska</title>
	
	<link>http://blog.felho.hu</link>
	<description>Random secrets of PHP, web development</description>
	<lastBuildDate>Fri, 30 Nov 2007 10:16:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/felho" /><feedburner:info uri="felho" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Extending Zend_Acl to support custom roles and resources</title>
		<link>http://feedproxy.google.com/~r/felho/~3/hx-gWqV8voQ/extending-zend_acl-to-support-custom-roles-and-resources.html</link>
		<comments>http://blog.felho.hu/extending-zend_acl-to-support-custom-roles-and-resources.html#comments</comments>
		<pubDate>Thu, 29 Nov 2007 16:08:03 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend acl]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/extending-zend_acl-to-support-custom-roles-and-resources.html</guid>
		<description><![CDATA[Few days ago I played a little with the Zend_Acl package, which provides lightweight and flexible access control list functionality and privileges management. It was very easy to use, but I found that the base Zend_Acl package has some limitation/problem if you want to use it in a bigger real life project. Zend_Acl supports only [...]]]></description>
			<content:encoded><![CDATA[<p>Few days ago I played a little with the Zend_Acl package, which provides lightweight and flexible access control list functionality and privileges management. It was very easy to use, but I found that the base Zend_Acl package has some limitation/problem if you want to use it in a bigger real life project. Zend_Acl supports only logical roles, resources so I decided to extend it to allow using custom roles and resources which can represent existing entities (for example users/groups and topics in a database). You will find the full source code and sample sql dump in the end of the post.<span id="more-56"></span></p>
<h2>Zend_Acl</h2>
<p>The package provides classical ACL functionality. There are roles, resources and privileges, and you can assign them to each other via deny and allow rules. For example you can say that <code>XY user</code>(role) is allowed to <code>moderate</code>(privilege) the <code>PHP topic</code>(resource) in a forum. You don&#8217;t have to always specify all the three part, for example you can say, that <code>administrator</code> can <code>moderate</code> any topic.</p>
<p>I won&#8217;t introduce the <code>Zend_Acl</code> package, it has an easy to understand <a href="http://framework.zend.com/manual/en/zend.acl.html" title="Zend_Acl's manual page">manual page</a>. Some observation which could be interesting related to this post:</p>
<ul>
<li>
There is no separate user and group in Zend_Acl, the concept of role includes both of them. A role can have multiple parents, so roles compose a directed graph.
</li>
<li>
Resources can have only one parent so they compose a tree.
</li>
</ul>
<h2>Zend_Acl limitations/problems</h2>
<p>Consider a forum where you have a lot of users/groups and a lot of resources (topics). You have have to add all of them (manually one at a time) to the <code>Acl</code> object which is very memory and time consuming task. Of course once you build the <code>Acl</code> object you can save it (in a serialized form) and reuse it next time but it will eat a lot of memory too. To make this clear check the following code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #0000ff;">$acl</span> = <span style="color: #000000; font-weight: bold;">new</span> Zend_Acl<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">addRole</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Zend_Acl_Role<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'guest'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; -&gt;<span style="color: #006600;">addRole</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Zend_Acl_Role<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'member'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; -&gt;<span style="color: #006600;">addRole</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Zend_Acl_Role<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'admin'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #0000ff;">$parents</span> = <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'guest'</span>, <span style="color: #ff0000;">'member'</span>, <span style="color: #ff0000;">'admin'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">addRole</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Zend_Acl_Role<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'someUser'</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #0000ff;">$parents</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Zend_Acl_Resource<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'someResource'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">deny</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'guest'</span>, <span style="color: #ff0000;">'someResource'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">allow</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'member'</span>, <span style="color: #ff0000;">'someResource'</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'someUser'</span>, <span style="color: #ff0000;">'someResource'</span><span style="color: #66cc66;">&#41;</span> ? <span style="color: #ff0000;">'allowed'</span> : <span style="color: #ff0000;">'denied'</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>You can see that if I want to reference a role or a resource in the <code>allow/deny</code> method, first I have to add it to the <code>Acl</code> object.</p>
<p>My other problem is that the Zend_Acl doesn&#8217;t support different type of roles/resources. Of course you can use a prefix, but maybe different roles/resources should be handled in a different way.</p>
<p>I wanted to come up with a solution where I have to define only the access rules and the Acl automatically checks if the referenced entity exists and automatically handles its relations (parent[s]), something like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #0000ff;">$acl</span> = <span style="color: #000000; font-weight: bold;">new</span> Zend_Acl<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">deny</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'guest'</span>, <span style="color: #ff0000;">'someResource'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">allow</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'members'</span>, <span style="color: #ff0000;">'otherResource'</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'someUser'</span>, <span style="color: #ff0000;">'someResource'</span><span style="color: #66cc66;">&#41;</span> ? <span style="color: #ff0000;">'allowed'</span> : <span style="color: #ff0000;">'denied'</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>You may have immeditaley a problem with this code: how can we distinguish the different roles/resources? Yes, we need one more step to have enough felxibility:<br />
<?php<br />
$acl = new Zend_Acl();</p>
<p>$acl->deny(&#8216;group:guest&#8217;, &#8216;topic:membersonly&#8217;);</p>
<p>echo $acl->isAllowed(&#8216;user:someUser&#8217;, &#8216;topic:membersonly&#8217;) ? &#8216;allowed&#8217; : &#8216;denied&#8217;;<br />
?><br />
With this notation we can have any type of roles and resources. In a typical application you will have a user and a group roles, but you can have for example an ldapuser too.</p>
<h2>Foo_Acl</h2>
<p>After a little planning I find out the following structure:<br />
<a href="http://blog.felho.hu/wp-content/fooaclclassdiagram.png" title="Foo_Acl class diagram"><img src="http://blog.felho.hu/wp-content/fooaclclassdiagram497.png" alt="Foo_Acl class diagram" /></a></p>
<p>Zend_Acl has a RoleRegistry but I needed more functionality so I extended it. In Zend_Acl there is no ResourceRegistry, so I added to the Foo_Acl package, its functionality is very similar to the RoleRegistry. For both of them I defined an interface, they can handle any role/resource which implements it. This interfaces extends the proper interfaces in the Zend_Acl package, and defines some more basic functionality: getting the relation(s) of the role/resource and loading it. For example the Foo_Acl_Role_Interface is the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/**<br />
&nbsp;* Interface of custom roles, Foo_Acl_Role_Registry can handle an object which implements it.<br />
&nbsp;* &nbsp; <br />
&nbsp;* @category &nbsp; Foo<br />
&nbsp;* @package &nbsp; &nbsp;Foo_Acl<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">interface</span> Foo_Acl_Role_Interface <span style="color: #000000; font-weight: bold;">extends</span> Zend_Acl_Role_Interface<br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Returns the array of the identifier of th parent roles<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return array<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getParents<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Returns the specified role if it exists or null. <br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return Foo_Acl_Role_Interface<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> load<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$resourceId</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>The functionality of different roles/resources is very similar, so I created a default implementation for both of this interfaces, and you can easily create custom ones by extending it. The default implementation of the Foo_Acl_Role_Interface is the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/**<br />
&nbsp;* The base implementation of Foo_Acl_Role_Interface, custom roles can extend it.<br />
&nbsp;* <br />
&nbsp;* @category &nbsp; Foo<br />
&nbsp;* @package &nbsp; &nbsp;Foo_Acl<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">class</span> Foo_Acl_Role_CustomBase implements Foo_Acl_Role_Interface<br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Unique id of Role<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @var string<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; protected <span style="color: #0000ff;">$_roleType</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Unique id of Role<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @var string<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; protected <span style="color: #0000ff;">$_roleId</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Array of the identifiers of the Role's parents<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; protected <span style="color: #0000ff;">$_parents</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Sets the Role data<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @param &nbsp;string $id<br />
&nbsp; &nbsp; &nbsp;* @param &nbsp;array $parents<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;* @return void<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$roleId</span>, <span style="color: #0000ff;">$parents</span> = <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$this</span>-&gt;_roleId = <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">&#41;</span> <span style="color: #0000ff;">$roleId</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$this</span>-&gt;_parents = <span style="color: #0000ff;">$parents</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$className</span> = <span style="color: #000066;">get_class</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span><span style="color: #66cc66;">&#41;</span>; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$this</span>-&gt;_roleType = <span style="color: #000066;">strtolower</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066;">substr</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$className</span>, <span style="color: #000066;">strrpos</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$className</span>, <span style="color: #ff0000;">'_'</span><span style="color: #66cc66;">&#41;</span><span style="color: #cc66cc;">+1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Defined by Zend_Acl_Role_Interface; returns the Role identifier<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return string<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getRoleId<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$this</span>-&gt;_roleType.<span style="color: #ff0000;">':'</span>.<span style="color: #0000ff;">$this</span>-&gt;_roleId;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Defined by Foo_Acl_Role_Interface; returns the Role's parents<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return array<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getParents<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$this</span>-&gt;_parents;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Returns the specified role if it exists or null. <br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return Foo_Acl_Role_Interface<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> load<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$roleId</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">null</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>If you want to create a custom role you should extend this class and overwrite the load function which responsibility is to check if the specified role exists and to instantiate the proper role object. I wrote some sample custom rules, the following is for representing users:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/**<br />
&nbsp;* Custom role representing users in the forum.<br />
&nbsp;* <br />
&nbsp;* @category &nbsp; Foo<br />
&nbsp;* @package &nbsp; &nbsp;Foo_Acl<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">class</span> Foo_Acl_Role_Custom_User <span style="color: #000000; font-weight: bold;">extends</span> Foo_Acl_Role_CustomBase<br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* Returns the specified role if it exists or null.<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @return Foo_Acl_Role_Interface<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> load<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$roleId</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// For more flexibility we support to refer a role with its name.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$lookUpByName</span> = !<span style="color: #000066;">ctype_digit</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$roleId</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp;if ($cache = Foo_Cache_Factory::getInstance()) {</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ($lookUpByName) {</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ($storedRoleId = $cache-&gt;fetch('acl.role.user.name2id.'.$roleId)) {</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$roleId = $storedRoleId;</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ($storedRole = $cache-&gt;fetch('acl.role.user.obj.'.$roleId)) {</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return &nbsp;$storedRole;</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$query</span> = <span style="color: #0000ff;">$lookUpByName</span> ?<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">'SELECT u.user_id, g.group_id FROM user u LEFT JOIN user2group g ON u.user_id = g.user_id WHERE u.nickname = ?'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">'SELECT u.user_id, g.group_id FROM user u LEFT JOIN user2group g ON u.user_id = g.user_id WHERE u.user_id = ?'</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$rows</span> = <span style="color: #0000ff;">$GLOBALS</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'DB'</span><span style="color: #66cc66;">&#93;</span>-&gt;<span style="color: #006600;">getAll</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$query</span>, <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$roleId</span><span style="color: #66cc66;">&#41;</span>, DB_FETCHMODE_ASSOC<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$rows</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$parents</span> = <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// If the user belongs to some groups we set them as its parents.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>!<span style="color: #000066;">is_null</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$rows</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'group_id'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">foreach</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$rows</span> <span style="color: #b1b100;">as</span> <span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$parents</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span> = Foo_Acl_Role_Custom_Group::<span style="color: #006600;">load</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'group_id'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$lookUpByName</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ($cache) {</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$cache-&gt;store('acl.role.user.name2id.'.$roleId, $row['user_id'], 1800);</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$roleId</span> = <span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'user_id'</span><span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$role</span> = <span style="color: #000000; font-weight: bold;">new</span> self<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$roleId</span>, <span style="color: #0000ff;">$parents</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ($cache) {</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$cache-&gt;store('acl.role.user.obj.'.$roleId, $role, 1800);</span><br />
<span style="color: #808080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$role</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">null</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>You can see it is very straightforward to create a new role. I commented out the caching codes because I am in changing the cache implementations and I could not put it to sample code.</p>
<p>The Foo_Acl package provide an effective and convenient way to handle a huge number of entity:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #808080; font-style: italic;">//insert into topic values(1, null);</span><br />
<span style="color: #808080; font-style: italic;">//insert into topic values(2, null);</span><br />
<span style="color: #808080; font-style: italic;">//insert into topic values(3, null);</span><br />
<span style="color: #808080; font-style: italic;">//insert into topic values(4, 1);</span><br />
<span style="color: #808080; font-style: italic;">//insert into topic values(5, 2);</span><br />
<span style="color: #808080; font-style: italic;">//insert into topic values(6, 4);</span><br />
<span style="color: #808080; font-style: italic;">//insert into user_group values(1, 'group1');</span><br />
<span style="color: #808080; font-style: italic;">//insert into user_group values(2, 'group2');</span><br />
<span style="color: #808080; font-style: italic;">//insert into user values(1, 'user1');</span><br />
<span style="color: #808080; font-style: italic;">//insert into user values(2, 'user2');</span><br />
<span style="color: #808080; font-style: italic;">//insert into user values(3, 'user3');</span><br />
<span style="color: #808080; font-style: italic;">//insert into user values(4, 'user4');</span><br />
<span style="color: #808080; font-style: italic;">//insert into user2group values (1,1);</span><br />
<span style="color: #808080; font-style: italic;">//insert into user2group values (2,1);</span><br />
<span style="color: #808080; font-style: italic;">//insert into user2group values (3,2);</span><br />
<span style="color: #808080; font-style: italic;">//insert into user2group values (4,2);</span><br />
<br />
<span style="color: #0000ff;">$acl</span> = <span style="color: #000000; font-weight: bold;">new</span> Foo_Acl<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">allow</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:1'</span>, <span style="color: #ff0000;">'dummy:foo'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">var_dump</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:1'</span>, <span style="color: #ff0000;">'dummy:foo'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// true</span><br />
<span style="color: #000066;">var_dump</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:1'</span>, <span style="color: #ff0000;">'dummy:bar'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// flase</span><br />
<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">allow</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'group:group1'</span>, <span style="color: #ff0000;">'dummy:coverpage'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">var_dump</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:user2'</span>, <span style="color: #ff0000;">'dummy:coverpage'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// true</span><br />
<span style="color: #000066;">var_dump</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:user3'</span>, <span style="color: #ff0000;">'dummy:coverpage'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// flase</span><br />
<br />
<span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">allow</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'group:group1'</span>, <span style="color: #ff0000;">'hierarchy:1'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">var_dump</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:1'</span>, <span style="color: #ff0000;">'hierarchy:4'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// true</span><br />
<span style="color: #000066;">var_dump</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:2'</span>, <span style="color: #ff0000;">'hierarchy:6'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// true</span><br />
<span style="color: #000066;">var_dump</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$acl</span>-&gt;<span style="color: #006600;">isAllowed</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user:1'</span>, <span style="color: #ff0000;">'hierarchy:2'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// flase</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>I tested it on the database of a bigger forum and it worked very well. You can download the <a href='http://blog.felho.hu/wp-content/fooacl.zip' title='Source code of Foo_Acl package and some sample code.'>sample code here</a>.</p>
<img src="http://feeds.feedburner.com/~r/felho/~4/hx-gWqV8voQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/extending-zend_acl-to-support-custom-roles-and-resources.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/extending-zend_acl-to-support-custom-roles-and-resources.html</feedburner:origLink></item>
		<item>
		<title>What is new in PHP 5.3 – part 4: __callStatic, OpenID support, user.ini, XSLT profiling and more</title>
		<link>http://feedproxy.google.com/~r/felho/~3/3nv_kez2ZbI/what-is-new-in-php-53-part-4-__callstatic-openid-support-userini-xslt-profiling-and-more.html</link>
		<comments>http://blog.felho.hu/what-is-new-in-php-53-part-4-__callstatic-openid-support-userini-xslt-profiling-and-more.html#comments</comments>
		<pubDate>Tue, 20 Nov 2007 03:23:13 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[php 5.3]]></category>
		<category><![CDATA[spl]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[xslt]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/what-is-new-in-php-53-part-4-__callstatic-openid-support-userini-xslt-profiling-and-more.html</guid>
		<description><![CDATA[We are already familiar with namespaces, late static binding and mysqlnd but PHP 5.3 has a lot more cool features. We can find some information about the features of the upcoming PHP version from Johannes SchlÃ¼ter&#8217;s (the release manager of PHP 5.3) blog entry and from the PHP Release Management Wiki. Some of the features [...]]]></description>
			<content:encoded><![CDATA[<p>We are already familiar with <a href="http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html" title="Whatâ€™s new in PHP 5.3 - part 1: namespaces">namespaces</a>, <a href="http://blog.felho.hu/what-is-new-in-php-53-part-2-late-static-binding.html" title="What is new in PHP 5.3 - part 2: late static binding">late static binding</a> and <a href="http://blog.felho.hu/what-is-new-in-php-53-part-3-mysqlnd.html" title="What is new in PHP 5.3 - part 3: mysqlnd">mysqlnd</a> but PHP 5.3 has a lot more cool features. We can find some information about the features of the upcoming PHP version from <a href="http://schlueters.de/blog/" title="Johannes SchlÃ¼ter's blog">Johannes SchlÃ¼ter&#8217;s</a> (the release manager of PHP 5.3) <a href="http://schlueters.de/blog/archives/59-PHP-5.3-update.html" title="PHP 5.3 Update">blog entry</a> and from the <a href="http://wiki.pooteeweet.org/PhP53" title="PHP Release Management Wiki">PHP Release Management Wiki</a>. Some of the features are interesting only for internals, but there are a lot of great ones for end users too: __callStatic, dynamic static call, OpenID support, improved ini handling, XSLT profiling, SQLite 3 support and more.<span id="more-46"></span></p>
<h2><code>__callStatic()</code></h2>
<p>Probably you are familiar with <a href="http://php.net/oop5.magic" title="PHP's magic methods">PHP&#8217;s magic methods</a>. PHP 5.3  introduces a new magic method: __callStatic, which is very similar to <a href="http://www.garfieldtech.com/blog/php-magic-call" title="Magical PHP: __call()">__call</a> but it is for static calls. It is cool, we are waiting for the __get, __set etc. counterparts. <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
Foo::<span style="color: #006600;">bar</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; <br />
<span style="color: #000000; font-weight: bold;">class</span> Foo <br />
<span style="color: #66cc66;">&#123;</span> <br />
&nbsp; &nbsp; <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> __callStatic<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$method</span>, <span style="color: #0000ff;">$arguments</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// $mathod == &amp;qout;bar&amp;qout;... </span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> <br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<h2>Dynamic static calls</h2>
<p>I think <a href="http://php.net/language.variables.variable" title="variable variables">variable variables</a> are one of the most useful things in PHP. In PHP 5.3 there is a new possibility on this area, the following code is possible:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #0000ff;">$class</span> = <span style="color: #ff0000;">'bar'</span>;<br />
<span style="color: #0000ff;">$class</span>::<span style="color: #006600;">method</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$class</span>::<span style="color: #0000ff;">$member</span>;<br />
<span style="color: #0000ff;">$class</span>::<span style="color: #006600;">CONST</span>;<br />
<br />
<span style="color: #0000ff;">$namespace</span> = <span style="color: #ff0000;">'foo'</span>;<br />
<span style="color: #0000ff;">$namespace</span>::<span style="color: #0000ff;">$class</span>::<span style="color: #006600;">method</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>You can find here a useful example from <a href="http://www.colder.ch/" title="Etienne Kneuss">Etienne Kneuss</a>, who implemented the patch for this functionality.</p>
<h2>Improved ini handling</h2>
<p>Jani Taskinen <a href="http://news.php.net/php.cvs/46324" title="created a patch">created a patch</a> providing improved ini handling. We can get some insight of how it will be working from the commit message:</p>
<ul>
<li>Added &#8220;.htaccess&#8221; style user-defined php.ini files support for CGI/FastCGI.</li>
<li>Added support for special [PATH=/opt/httpd/www.example.com/] sections in php.ini. All directives set in these sections will not be able to be overridden in user-defined ini-files or during runtime in the specified path.</li>
<li>Improved php.ini handling:
<ul>
<li>Added better error reporting for syntax errors in php.ini files</li>
<li>Allowed &#8220;ini-variables&#8221; to be used almost everywhere ini php.ini files</li>
<li>Allowed using alphanumeric/variable indexes in &#8220;array&#8221; ini options</li>
<li>Fixed get_cfg_var() to be able to return &#8220;array&#8221; ini options</li>
</ul>
</li>
</ul>
<p>And we can get some more information from the related php.ini addition:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><div class="ini" style="font-family: monospace;">+<span style="color: #666666; font-style: italic;">;;;;;;;;;;;;;;;;;;;;</span><br />
+<span style="color: #666666; font-style: italic;">; php.ini Options &nbsp;;</span><br />
+<span style="color: #666666; font-style: italic;">;;;;;;;;;;;;;;;;;;;;</span><br />
+<span style="color: #666666; font-style: italic;">; Name for user-defined php.ini (.htaccess) files. Default is &amp;qout;user.ini&amp;qout;</span><br />
+<span style="color: #666666; font-style: italic;">;user_ini.filename = &amp;qout;user.ini&amp;qout;</span><br />
+<br />
+<span style="color: #666666; font-style: italic;">; To disable this feature set this option to empty value</span><br />
+<span style="color: #666666; font-style: italic;">;user_ini.filename =</span><br />
+<br />
+<span style="color: #666666; font-style: italic;">; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)</span><br />
+<span style="color: #666666; font-style: italic;">;user_ini.cache_ttl = 300</span></div></td></tr></table></div>

<h2>OpenID support</h2>
<p>In PHP 5.3 the openssl extension will provide high speed Diffie-Hellman support, which is important for OpenID. You can get more information from <a href="http://marc.info/?l=php-internals&#038;m=118595872426344&#038;w=2" title="Dmitry Stogov's proposal">Dmitry Stogov&#8217;s proposal</a>.</p>
<h2><code>XSLT</code> profiling</h2>
<p><a href="http://blog.liip.ch/" title="Christian Stocker's blog">Christian Stocker</a> mentioned <a href="http://blog.liip.ch/archive/2007/10/02/added-xslt-profiling-to-php-5-3-and-6-cvs.html" title="Added xslt profiling to PHP 5.3 and 6 CVS">in his blog</a> that he added his <a href="http://blog.liip.ch/archive/2007/04/13/profile-xslt-transformations-within-php.html" title="Profile XSLT transformations within PHP">XSLT profiling</a> to the official PHP source.</p>
<h2><code>getopt()</code> on any platform</h2>
<p>As from PHP 5.3 the <code><a href="http://php.net/getopt" title="getopt()">getopt()</a></code> function will be available even on Windows systems, and <code>getopt()</code> will support <code>longopts</code> on every system.</p>
<h2>Error levels</h2>
<p><code>E_STRICT</code> will be splitted to <code>E_STRICT</code> and <code>E_DEPRECATED</code>. <code>E_STRICT</code> error will mean common bad practices and <code>E_DEPRECATED</code> will be triggered when you try to use such a language feature which is likely to go away from a later version. <code>E_STRICT</code> will be part of <code>E_ALL</code>.</p>
<h2>Other improvements</h2>
<ul>
<li>Sqlite3 support via the ext/sqlite extension</li>
<li><code>array_replace[_recursive]</code> functions</li>
<li>
SPL improvements:</p>
<ul>
<li>DirectoryIterator implements ArrayAccess</li>
<li>Implementing Spl(Array|Index|Member)Reference</li>
<li>Implement DualIterator</li>
<li>Implement RecursiveTreeIterator</li>
</ul>
</li>
</ul>
<img src="http://feeds.feedburner.com/~r/felho/~4/3nv_kez2ZbI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/what-is-new-in-php-53-part-4-__callstatic-openid-support-userini-xslt-profiling-and-more.html/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/what-is-new-in-php-53-part-4-__callstatic-openid-support-userini-xslt-profiling-and-more.html</feedburner:origLink></item>
		<item>
		<title>What is new in PHP 5.3 – part 3: mysqlnd</title>
		<link>http://feedproxy.google.com/~r/felho/~3/ZiKT6WKsZrk/what-is-new-in-php-53-part-3-mysqlnd.html</link>
		<comments>http://blog.felho.hu/what-is-new-in-php-53-part-3-mysqlnd.html#comments</comments>
		<pubDate>Sat, 17 Nov 2007 20:49:40 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqlnd]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php 5.3]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/what-is-new-in-php-53-part-3-mysqlnd.html</guid>
		<description><![CDATA[In the first two parts of this series I wrote about namespaces and late static binding. In this part I will cover mysqlnd (MySQL native driver for PHP), which is also a really cool feature of PHP 5.3. This a replacement library (not an extension) for libmysql (MySQL Client Library) offering a lot of advantage [...]]]></description>
			<content:encoded><![CDATA[<p>In the first two parts of this series I wrote about <a href="http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html" title="Whatâ€™s new in PHP 5.3 - part 1: namespaces">namespaces</a> and <a href="http://blog.felho.hu/what-is-new-in-php-53-part-2-late-static-binding.html" title="What is new in PHP 5.3 - part 2: late static binding">late static binding</a>. In this part I will cover <a href="http://dev.mysql.com/downloads/connector/php-mysqlnd/" title="MySQL native driver for PHP - mysqlnd">mysqlnd</a> (MySQL native driver for PHP), which is also a really cool feature of PHP 5.3. This a replacement library (not an extension) for libmysql (MySQL Client Library) offering a lot of advantage over it. While libmysql was developed primarily for C and C++, mysqlnd was designed and optimized for PHP, it takes advantages of the internal structure of Zend Engine. By the time of this writing <a href="http://php.net/mysql" title="mysql">mysql</a> and <a href="http://php.net/mysql" title="mysqli">mysqli</a> are supported, and the integration to <a href="http://php.net/pdo" title="PDO">PDO</a> is in <a href="http://blog.ulf-wendel.de/?p=166" title="PHP: mysqlnd to support PDO, mysqlnd in PHP 5.3">working progress</a>.<span id="more-45"></span></p>
<p>The overview of the advantages of mysqlnd over libmysql: high integration with the Zend Engine, faster execution, lower memory footprint, performance statistics for bottle-neck analysis, easier compilation, own development life cycle, usage of PHP stream API, client side query cache and a lot of possibility for future features.  </p>
<p>Over the technical advantages theres is a licensing one. MySQL is rely on the GPL license which is not compatible with the PHP license, using libmysql with PHP needs the <a href="http://www.mysql.com/company/legal/licensing/foss-exception.html" title="FLOSS exception">FLOSS exception</a>, but mysqlnd is licensed under the PHP license so this is no more a problem (check the <a href="http://blogs.mysql.com/kaj/?p=71" title="mysqlnd FAQ">mysqlnd FAQ</a>).</p>
<p>The installation process will be easier, you won&#8217;t need to have libmysql on the server. Libmysql is shipped with the MySQL server, updating libmysql means that you have to update the MySQL server too. With myslqnd this bounding no more exists, it has its own release and development life cycle. Mysqlnd has a common code base for PHP5 and PHP6, so the maintenance of the code is easier, a bug should be fixed only at one place. </p>
<h2>High integration with the Zend Engine</h2>
<p>Mysqlnd is highly integrated with the Zend engine, so it can leverage all the internal PHP infrastructure for communication and memory management, it can do a lot of tricky thing to improve performance. If you are curious about the details you should check <a href="http://www.hristov.com/andrey/" title="Andrey Hristov's homepage">Andrey Hristov&#8217;s</a> <a href="http://www.hristov.com/andrey/projects/php_stuff/pres/mysqlnd_vikinger.pdf" title="presentation from mysqlnd">presentation from mysqlnd</a> (I get some illustration from it). You can find here <a href="http://blog.ulf-wendel.de/?p=138" title="About the performance of mysqlnd-5.0.0-alpha">a little benchmark</a> about the performance of mysqlnd.</p>
<h2>Comply with the <code>memory_limit</code> settings</h2>
<p><img src='http://blog.felho.hu/wp-content/memorylimitsupport.png' alt='Memory limit support' /><br />
Myslqnd uses the Zend Engine&#8217;s memory management so it comply (in contrast to libmysql) with the memory limit setting. It allocates bigger chunk of memory (allocating memory is relatively expensive task), it tries to reuse zvals using zval cache to save CPU cycle.</p>
<h2>Memory savings</h2>
<p><img src='http://blog.felho.hu/wp-content/readonlyvariables.png' alt='Read only variables' /><br />
Mysqlnd introduces an interesting concept: read only variables with which it can save a huge amount of memory. You can read about it in the mentioned presentation or in <a href="http://blog.ulf-wendel.de" title="Ulf Wendel's blog">Ulf Wendel&#8217;s</a> <a href="http://blog.ulf-wendel.de/?p=157" title="PHP: mysqlnd saves 40% memory, finally (new tuning options)!">blog entry</a>. To completely understand this you should be familiar with the internal representation of variables in PHP (I&#8217;ll write about it soon), the short version is the following. When you run a buffered query libmysql reads first the data into its own buffer, and then when you run <code>mysql_fetch_*()</code> function the data is get copied from this buffer into another memory area which represents the PHP variables. Mysqlnd uses a read buffer too, but when you run the <code>mysql_fetch_*()</code> function it isn&#8217;t copy the data but links the PHP variables to this memory area. This way it can consume only half as much memory as libmysql.</p>
<h2>Usage of the PHP stream API</h2>
<p><img src='http://blog.felho.hu/wp-content/mysqlndstreamapi.png' alt='Mysqlnd uses the PHP stream API' /><br />
Mysqlnd uses the PHP stream API, which holds a lot of possibility because it makes possible to hook into the communication with MySQL. Exposing the streams to users is not yet implemented, if it is done one can easily write a custom proxy using stream filters.</p>
<h2>Persistent connections</h2>
<p>You may know that persistent connections was disabled in mysqli extension, but with mysqlnd you will have again the possibility to use persistent connection (<code>mysqli_connect('p:localhost', ...);</code>). <a href="http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/" title="Are PHP persistent connections evil ?">This is an interesting</a> post about this topic.</p>
<h2>Statistical data collection</h2>
<p>Mysqlnd collects a lot of statistics which you can use for tuning your application. This statistical information will simplify the process of finding bottlenecks in your system, you can easily monitor your application and you can even build automatic problem detection into it. You can access these data via <code>phpinfo()</code>, <code>mysqli_get_client_stats()</code> (per process statistics), <code>mysqli_get_connection_stats()</code> (per connections statistics) functions. Currently 59 statistical information are collected by mysqlnd, you can read more about this at <a href="http://blog.ulf-wendel.de/?p=163" title="PHP: 59 tuning screws for mysqlnd">Ulf&#8217;s blog</a>. It collects information about its internal zval cache, this you can get with the <code>mysqli_get_cache_stat()</code>, which could bu useful to tweak you zval cahe related php.ini settings, or to find an incidental bad habits in your code (for example you needlessly modify the fetched data and hence you lose the memory saving option). </p>
<h2>Client-side query cache</h2>
<p>Mysqlnd supports client-side query cache which could be very useful in some situation because it eliminates communication overhead (network latency), memory allocation overhead. By client side query cache it could be interesting the invalidation of the cache, mysqlnd currently supports only TTL (time-to-live) invalidation which you can control via <code>php.ini</code> settings. This part of the library is experimental, will change a lot in the future.</p>
<h2>Possible future improvements, features</h2>
<p>There is a lot of possibility in this area, just to name a few: improving the client side query cache, exposing PHP streams to users, prepared statement cache, automatic load balancing, built-in profiling. More foretastes for gourmands: the <a href="http://pooteeweet.org/files/mysqlabphpdriver06/php_driver_wish_list.pdf" title="Wishlist of Lukas for mysqlnd">wishlist of Lukas</a>, and <a href="http://www.mysqlperformanceblog.com/2006/10/28/wishes-for-new-pure-php-mysql-driver/" title="wishlist of Peter Zaitsev for mysqlnd">Peter Zaitsev</a> (<a href="http://www.mysqlperformanceblog.com" title="MySQL Performance Blog">MySQL Performance Blog</a>).</p>
<p>Enjoy your meal! <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/felho/~4/ZiKT6WKsZrk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/what-is-new-in-php-53-part-3-mysqlnd.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/what-is-new-in-php-53-part-3-mysqlnd.html</feedburner:origLink></item>
		<item>
		<title>What is new in PHP 5.3 – part 2: late static binding</title>
		<link>http://feedproxy.google.com/~r/felho/~3/bIXycxgPNbo/what-is-new-in-php-53-part-2-late-static-binding.html</link>
		<comments>http://blog.felho.hu/what-is-new-in-php-53-part-2-late-static-binding.html#comments</comments>
		<pubDate>Thu, 15 Nov 2007 02:26:40 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[late static binding]]></category>
		<category><![CDATA[php 5.3]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/what%e2%80%99s-new-in-php-53-part-2-late-static-binding.html</guid>
		<description><![CDATA[In the first part of this series I wrote about namespaces, in the second part we will deal with late static binding, which is a very exciting new feature in PHP 5.3 and which promise some really nifty code.   This topic attracted attention after Zend&#8217;s webcast about the Zend Framework. There was a [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html" title="Whatâ€™s new in PHP 5.3 - part 1: namespaces">first part</a> of this series I wrote about namespaces, in the second part we will deal with late static binding, which is a very exciting new feature in PHP 5.3 and which promise some really nifty code. <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  This topic attracted attention after <a href="http://www.phparch.com/webcasts/player/Main_content.php?p=L3RyYWluaW5nL3NsaWRlcy9aRkNBU1QvcmVjb3JkaW5ncy9yZWNvcmQuZmx2" title="Zend Framework webcast">Zend&#8217;s webcast</a> about the <a href="http://framework.zend.com/" title="Zend Framework">Zend Framework</a>. There was a little outcry in the PHP blogosphere, that the ActiveRecord examples presented in this webcast can&#8217;t work in PHP even with the version 5.2. Now with late static binding it is possible to implement this style of ActiveRecord <strong>almost</strong> correctly.<span id="more-43"></span></p>
<h2>Late static binding basic</h2>
<p>First let me introduce what late static binding is about. I am not going to write too much about the basics, because fortunately I get a <a href="http://livedocs.phpdoc.info/manual/en/language.oop5.late-static-bindings.php" title="Late Static Bindings">helping hand</a> <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . So the base problem is the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #000000; font-weight: bold;">class</span> A <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> who<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">echo</span> <span style="color: #000000; font-weight: bold;">__CLASS__</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> test<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; self::<span style="color: #006600;">who</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> &nbsp;<br />
<span style="color: #66cc66;">&#125;</span> &nbsp;<br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> B <span style="color: #000000; font-weight: bold;">extends</span> A <span style="color: #66cc66;">&#123;</span>&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> who<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">echo</span> <span style="color: #000000; font-weight: bold;">__CLASS__</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> &nbsp;<br />
<span style="color: #66cc66;">&#125;</span> &nbsp; <br />
&nbsp; &nbsp; <br />
B::<span style="color: #006600;">test</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Output: &amp;qout;A&amp;qout;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>Static references to the current class like self:: or __CLASS__ are resolved using the class in which the function belongs, as in where it was defined, so when we call the <code>test()</code> method on class <code>B</code> it will call the <code>who()</code> method of class <code>A</code>. </p>
<p>PHP 5.3 introduces a new possibility by allowing a keyword that references the class that was initially called at runtime:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #000000; font-weight: bold;">class</span> A <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> who<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">echo</span> <span style="color: #000000; font-weight: bold;">__CLASS__</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> test<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">static</span>::<span style="color: #006600;">who</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Here comes Late Static Bindings&nbsp; &nbsp; </span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> &nbsp;<br />
<span style="color: #66cc66;">&#125;</span> &nbsp;<br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> B <span style="color: #000000; font-weight: bold;">extends</span> A <span style="color: #66cc66;">&#123;</span>&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> who<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">echo</span> <span style="color: #000000; font-weight: bold;">__CLASS__</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> &nbsp;<br />
<span style="color: #66cc66;">&#125;</span> &nbsp; <br />
<br />
B::<span style="color: #006600;">test</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Output: &quot;B&quot;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>This is the basic behavior of the static keyword in this context, you can get more information in the manual. Now back to the ActiveRecord.</p>
<h2>Facing the problem</h2>
<p>Zend&#8217;s proposal was something similar:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> ActiveRecord <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> findByPk<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// something maqic</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> Blog <span style="color: #000000; font-weight: bold;">extends</span> ActiveRecord <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
<br />
Blog::<span style="color: #006600;">findByPk</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>The conception is nice, the base implementation of <code>findByPk()</code> finds out from the name of the child class the name of the table on which it should be operate. There is only one (huge) problem with this code, when <code>findByPk()</code> is called it can&#8217;t determines the name of the class on which it was called. There was an ugly workaround using <code>debug_backtrace()</code>, but its performance was quite poor, so finally it was not used in ZF. </p>
<p>After the late static binding introduction you may come up with the following code in PHP 5.3:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">class</span> ActiveRecord <br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> getClass<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">__CLASS__</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> findByPk<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$calledClass</span> = <span style="color: #000066;">static</span>::<span style="color: #006600;">getClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// The magic...</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> Blog <span style="color: #000000; font-weight: bold;">extends</span> ActiveRecord <br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> getClass<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">__CLASS__</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
Blog::<span style="color: #006600;">findByPk</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>Running this code the value of <code>$calledClass</code> will be &#8220;Blog&#8221;. This is great, but it would be very annoying if we have to add the <code>getClass()</code> method to every child class. Fortunately with the late static binding we get a great new function too: <code>get_called_class()</code>, which returns the name of the current calling scope. Using this function we get a nifty code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> ActiveRecord <br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> findByPk<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$calledClass</span> = get_called_class<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// The magic remains...</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> Blog <span style="color: #000000; font-weight: bold;">extends</span> ActiveRecord <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
<br />
Blog::<span style="color: #006600;">findByPk</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>This works very well, but unfortunately we can&#8217;t be absolutely happy, because there is a big flaw (I believe it is) in the current implementation of late static binding. <a href="http://www.digitalsandwich.com/" title="Michael Lively's blog">Michael Lively</a> <a href="http://www.mail-archive.com/internals@lists.php.net/msg30731.html" title="Design flaw in the current implementation of late static binding">pointed to this problem</a> on the internal list and <a href="http://www.digitalsandwich.com/archives/65-Late-static-binding....sorta.html" title="Late static binding....sorta :/">on his blog</a>. How does this problem affect our example? Imagine that we want a simple logging functionality only in the Blog class. Consider the following code (it seems to a logical and suitable solution for this task):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> ActiveRecord <br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> findByPk<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$calledClass</span> = get_called_class<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// The magic remains...</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> Blog <span style="color: #000000; font-weight: bold;">extends</span> ActiveRecord <br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066;">static</span> <span style="color: #000000; font-weight: bold;">function</span> findByPk<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// We want to log something.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// Then the parent should do the magic.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parent::<span style="color: #006600;">findByPk</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
Blog::<span style="color: #006600;">findByPk</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>If you try to run this program maybe you will surprise, because the value of the <code>$calledClass</code> variable will be &#8220;ActiveRecord&#8221;. OOPS! What here happens: parent will resolve to ActiveRecord and this breaks late static binding. From the manual: &#8220;Late static bindings&#8217; reslution will stop at a fully resolved static call with no fallback&#8221;. It is possible that this explanation is not completely exact (maybe somebody from the internal list can explain it more precisely), but the substance is that this is a legitimate usage of late static binding and is not currently supported. I hope it will be fixed/supported in the final version of PHP 5.3.</p>
<p>I believe that this feature holds a lot of potential, for example you should check <a href="http://personal.schmalls.com/" title="Joshua Thompson's blog">Joshua Thompson&#8217;s</a> very interesting post: <a href="http://personal.schmalls.com/2007/10/29/return-to-prototype-based-programming-in-php/" title="Return to Prototype Based Programming in PHP">Return to Prototype Based Programming in PHP</a>.</p>
<img src="http://feeds.feedburner.com/~r/felho/~4/bIXycxgPNbo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/what-is-new-in-php-53-part-2-late-static-binding.html/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/what-is-new-in-php-53-part-2-late-static-binding.html</feedburner:origLink></item>
		<item>
		<title>What’s new in PHP 5.3 – part 1: namespaces</title>
		<link>http://feedproxy.google.com/~r/felho/~3/2ICzkvm2lMM/whats-new-in-php-53-part-1-namespaces.html</link>
		<comments>http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html#comments</comments>
		<pubDate>Tue, 13 Nov 2007 21:59:59 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[namespaces]]></category>
		<category><![CDATA[php 5.3]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html</guid>
		<description><![CDATA[In my previous post I mentioned that PHP 5.3 will be released in early 2008 so I think it&#8217;s just in time to talk about the features of this version. It is started by this polling (in detail, in an ordered version) on the internal list. The big gun features are namespaces, late static binding [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://blog.felho.hu/international-php-conference-2007-megapost.html" title="International PHP Conference 2007 Megapost">previous post</a> I mentioned that PHP 5.3 will be released in early 2008 so I think it&#8217;s just in time to talk about the features of this version. It is started <a href="http://marc.info/?l=php-internals&#038;m=118989314505802&#038;w=2" title="Polling result about PHP 5.3 features">by this polling</a> (<a href="http://bb.prohost.org/53Features.pdf" title="Polling result in detail about PHP 5.3 features">in detail</a>, in an <a href="http://www.wolerized.com/articles/first-most-likely-featurelist-php-5-3" title="First most likely featurelist for PHP 5.3">ordered version</a>) on the internal list. The big gun features are namespaces, late static binding and mysqlnd, but there are other interesting improvements, for example __callStatic, dynamic static calls. In this part of this series we are going to analyze namespaces in detail.<span id="more-44"></span></p>
<h2>Namespaces basic</h2>
<p>Namespace support in PHP was a long-felt want feature. In PHP the main motivation behind adding namespace support to the language was to solve the problem of long class names. If you develop a bigger library, you have to use long class names to avoid naming conflicts, for example look at this monster: <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code>. </p>
<p>From the version 5.3 you can group your code into namespaces. Different namespaces can contains classes, functions, constants with the same name. Defining a namespace is very straightforward, you should use the <code>namespace</code> statement in the very beginning of the file, for example:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/** classes/my/foo/MyClass.php */</span><br />
<br />
namespace my::<span style="color: #006600;">foo</span>;<br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> MyClass <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;">// You can define functions and constants in the namespace too.</span><br />
<span style="color: #000000; font-weight: bold;">function</span> myFunc<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span><br />
const MY_CONST = <span style="color: #ff0000;">'foo'</span>;<br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>You have a lot of options to use items defined in this namespace:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/** test.php */</span><br />
<span style="color: #b1b100;">include</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'classes/my/foo/MyClass.php'</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">// You can always access anything âˆˆan object with fully qualified name.</span><br />
<span style="color: #0000ff;">$foo</span> = <span style="color: #000000; font-weight: bold;">new</span> my::<span style="color: #006600;">foo</span>::<span style="color: #006600;">MyClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">// You can use the use statement to import a namespace.</span><br />
use my::<span style="color: #006600;">foo</span>;<br />
<span style="color: #808080; font-style: italic;">// After the above statement you can reffer for the my::foo namespace with foo.</span><br />
<span style="color: #0000ff;">$foo</span> = <span style="color: #000000; font-weight: bold;">new</span> foo::<span style="color: #006600;">MyClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">// You can import only one class.</span><br />
use my::<span style="color: #006600;">foo</span>::<span style="color: #006600;">MyClass</span>;<br />
<span style="color: #0000ff;">$foo</span> = <span style="color: #000000; font-weight: bold;">new</span> MyClass;<br />
<br />
<span style="color: #808080; font-style: italic;">// You can create aliases.</span><br />
use my::<span style="color: #006600;">foo</span> <span style="color: #b1b100;">as</span> MyFoo;<br />
use my::<span style="color: #006600;">foo</span>::<span style="color: #006600;">MyClass</span> <span style="color: #b1b100;">as</span> MyFooClass;<br />
<span style="color: #0000ff;">$foo</span> = <span style="color: #000000; font-weight: bold;">new</span> MyFoo::<span style="color: #006600;">MyClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$foo</span> = <span style="color: #000000; font-weight: bold;">new</span> MyFooClass<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">// Note, that the following two statements are equivalent:</span><br />
use my::<span style="color: #006600;">foo</span>;<br />
use my::<span style="color: #006600;">foo</span> <span style="color: #b1b100;">as</span> foo;<br />
<br />
<span style="color: #808080; font-style: italic;">// You can access functions and constants in the same way:</span><br />
my::<span style="color: #006600;">foo</span>::<span style="color: #006600;">myFunc</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
myFoo::<span style="color: #006600;">myFunc</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
my::<span style="color: #006600;">foo</span>::<span style="color: #006600;">MY_CONST</span>;<br />
myFoo::<span style="color: #006600;">MY_CONST</span>;<br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>Only namespaces and classes can be imported with the <code>use</code> statement, for example you can&#8217;t say: <code>use my::foo::MY_CONST;</code>. A use statement takes effect from its definition to the end of the file, you can use it everywhere in the global scope. You can use the same namespace in more files, but one file should contain only one namespace (this behavior maybe will changed in the final version, or the maybe the <code>namespace</code> keyword will be replaced with <code>package</code> <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). While you can&#8217;t import a function or a constant, you should always use some kind of prefix if you want to access any of them from a namespace. In the earlier versions of PHP 5.3 the <code>import</code> keyword was used insted of <code>use</code>, but few weeks ago <a href="http://marc.info/?l=php-internals&#038;m=119308858512331&#038;w=2" title="Using keyword<br />
'use' instead of 'import'">it was changed</a>. </p>
<h3>The &#8220;empty&#8221; namespace (<code>::</code>)</h3>
<p>If you use the <code>::</code> prefix by function and class names, they are interpreted as global independently from the current import rules. This is useful inside a namespace.</p>
<h2>Life with namesapces (porting code to PHP 5.3)</h2>
<p>If you decide to use namespaces there are some pitfalls you should pay attention. </p>
<h3>Class naming convention</h3>
<p>You should forget to use reserved words in you class names. Consider the following code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/** classes/my/form/element/static.php */</span><br />
<span style="color: #000000; font-weight: bold;">class</span> MyFormElementStatic <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>The equivalent would be this using namespace:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/** classes/my/form/element/static.php */</span><br />
namespace my::<span style="color: #006600;">form</span>::<span style="color: #006600;">element</span>;<br />
<span style="color: #000000; font-weight: bold;">class</span> <span style="color: #000066;">Static</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>But <code><del datetime="2007-11-14T19:41:25+00:00">Date</del>Static</code> is a reserved word <del datetime="2007-11-14T19:41:25+00:00">(and an existent internal class)</del> so this code ends in fatal error. This could be a bad news if you have a lot of similar classes.</p>
<h3>Autoloading</h3>
<p>From PHP 5.3 <code>__autoload()</code> will get the fully qualified class name. This mean that you have to modify you <code>__autoload</code> funciton if you have used one. A basic example:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/** test.php */</span><br />
<span style="color: #000000; font-weight: bold;">function</span> __autoload<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$className</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">'classes/'</span>.<span style="color: #000066;">str_replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'::'</span>, DIRECTORY_SEPARATOR, <span style="color: #0000ff;">$className</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #ff0000;">'.php'</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
<span style="color: #0000ff;">$foo</span> = <span style="color: #000000; font-weight: bold;">new</span> my::<span style="color: #006600;">foo</span>::<span style="color: #006600;">MyClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>Or you prefer the <a href="http://www.php.net/~helly/php/ext/spl/" title="SPL - Standard PHP Library">SPL way</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #808080; font-style: italic;">/** classes/my/core/classloader.php */</span><br />
namespace my::<span style="color: #006600;">core</span>;<br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> classLoader<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$className</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">'classes/'</span>.<span style="color: #000066;">str_replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'::'</span>, DIRECTORY_SEPARATOR, <span style="color: #0000ff;">$className</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #ff0000;">'.php'</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
spl_autoload_register<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'my::core::classLoader'</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #808080; font-style: italic;">/** test.php */</span><br />
<span style="color: #b1b100;">require</span> <span style="color: #ff0000;">'classes/my/core/classLoader.php'</span>;<br />
<span style="color: #0000ff;">$foo</span> = <span style="color: #000000; font-weight: bold;">new</span> my::<span style="color: #006600;">foo</span>::<span style="color: #006600;">MyClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></table></div>

<h3><code>get_class()</code>, <code>get_parent_class()</code>, etc.</h3>
<p>When you use these type of functions you should take into consideration that they returns fully qualified class names too.</p>
<h3>Reflection API</h3>
<p>The Reflection API should reflect (;)) to this new language feature. The plan is the following:</p>
<ul>
<li>Create a new <code>ReflectionNamespace</code> class with the following methods: <code>getName()</code>, <code>getClasses()</code>, <code>getFunctions()</code>, <code>getFiles()</code>
	</li>
<li>Extend the <code>ReflectionClass</code> and <code>ReflectionFunction</code> classes with a new <code>getNamespace()</code> method.
	</li>
</ul>
<h2>Life inside a namespace</h2>
<p>There is some special knowledge you should be familiar with, if you want to write codes in namespaces.</p>
<h3>The <code>__NAMESPACE__</code> constant</h3>
<p>There is a new special constant: __NAMESPACE__, which contains the name of the current namespace. For example you can write the SPL autoloader in the following way:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #808080; font-style: italic;">/** classes/my/core/classloader.php */</span><br />
namespace my::<span style="color: #006600;">core</span>;<br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> classLoader<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$className</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">'classes/'</span>.<span style="color: #000066;">str_replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'::'</span>, DIRECTORY_SEPARATOR, <span style="color: #0000ff;">$className</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #ff0000;">'.php'</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
spl_autoload_register<span style="color: #66cc66;">&#40;</span>__NAMESPACE__.<span style="color: #ff0000;">'::classLoader'</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></table></div>

<h3>Resolving names inside a namespace</h3>
<p>I don&#8217;t want to describe the complete rule set here, you can read it in the <a href="http://cvs.php.net/viewvc.cgi/php-src/README.namespaces?revision=1.7&#038;view=markup" title="PHP namespaces README">PHP namespaces README</a>. The main point is, that PHP try to resolve a name first according to the current namesapce. Let&#8217;s see some example:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
namespace my::<span style="color: #006600;">foo</span>;<br />
...<br />
bar<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
...<br />
::<span style="color: #006600;">bar</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>When you call <code>bar()</code> then PHP try to find the function in the <code>my::foo</code> namespace. If it finds it will call it, if not it will try to call the <strong>internal</strong> <code>bar()</code> function, so it is important to notice, that using this notation, you can&#8217;t call user defined function inside a namespace. Using the <code>::bar()</code> form PHP will call the <code>bar()</code> function in the <strong>global</strong> namespace, so it could be an internal or a user defined function. This logic is true when you try to create a new object.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
namespace my::<span style="color: #006600;">foo</span>;<br />
<br />
core::<span style="color: #006600;">bar</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
::<span style="color: #006600;">core</span>::<span style="color: #006600;">bar</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>In this case of <code>core::bar()</code> PHP first tries to call function <code>bar()</code> from namespace <code>my::foo::core</code> then calls method <code>bar()</code> of <strong>internal</strong> class <code>core</code>. In the case of <code>::core::bar()</code> it first tries to call function <code>bar()</code> from namespace <code>core</code> then calls method <code>bar()</code> of class <code>core</code> from <strong>global</strong> scope.</p>
<p>The namespace support in PHP is not yet finished, it is possible some modifications in the future.</p>
<img src="http://feeds.feedburner.com/~r/felho/~4/2ICzkvm2lMM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html/feed</wfw:commentRss>
		<slash:comments>29</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html</feedburner:origLink></item>
		<item>
		<title>International PHP Conference 2007 Megapost</title>
		<link>http://feedproxy.google.com/~r/felho/~3/MjSV07Du6h8/international-php-conference-2007-megapost.html</link>
		<comments>http://blog.felho.hu/international-php-conference-2007-megapost.html#comments</comments>
		<pubDate>Sun, 11 Nov 2007 03:43:28 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[conference]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[agile development]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[ez components]]></category>
		<category><![CDATA[pdf generating]]></category>
		<category><![CDATA[phing]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[regexp]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[unit testing]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/international-php-conference-2007-megapost.html</guid>
		<description><![CDATA[UPDATED: I added the following three talks to the post. If you know any other presentation which is accessible and is missing from here, please notify me! TIA
Beautiful code with AOP and DI &#8211; Robert Lemke
This was a really great presentation, watch out: you will be infected! Robert shows us advanced programming concepts such as [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATED:</strong> I added the following three talks to the post. If you know any other presentation which is accessible and is missing from here, please notify me! TIA</p>
<p><a href="http://typo3.org/fileadmin/teams/5.0-development/ipc2007-beautifulcode.pdf" title="Beautiful code with AOP and DI">Beautiful code with AOP and DI</a> &#8211; <a href="http://robertlemke.de/en/home/blog.html" title="Robert Lemke's blog">Robert Lemke</a><br />
This was a really great presentation, watch out: you will be infected! Robert shows us advanced programming concepts such as DDD (<a href="http://domaindrivendesign.org/" title="Domain Driven Design">Domain Driven Design</a>), AOP (<a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" title="Aspect-Oriented Programming">Aspect-Oriented Programming</a>), DI (<a href="http://martinfowler.com/articles/injection.html" title="Inversion of Control Containers and the Dependency Injection pattern">Dependency Injection</a>). This concepts serves a common aims to produce higher quality, maintainable, flexible software. Robert is the member of the Typo3 5.0 development team, and they are using this methods in their every day work. If you are interested in this topic you can find useful information in <a href="http://typo3.org/teams/50-development/" title="TYPO3 5.0 Development Team">their home page</a> or you should read the Bibles <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  :<br />
<a href='http://blog.felho.hu/wp-content/recommendedliterature.png' title='Recommended literature'><br />
<img src='http://blog.felho.hu/wp-content/recommendedliteraturethumb.png' alt='Recommended literature' /><br />
</a></p>
<p><a href="http://talks.frankkleine.de/streamwrappers.pdf" title="Enhanced StreamWrappers">Enhanced StreamWrappers</a> &#8211; <a href="http://frankkleine.de/" title="Frank Kleine's blog">Frank Kleine</a><br />
This talk is about a really cool and unfortunately rarely used PHP feature: <a href="http://php.net/stream" title="PHP streams">PHP streams</a>. Frank will shows you how you can create custom stream wrappers, and some useful and advanced examples how you can use them.</p>
<p><a href="http://blog.felho.hu/wp-content/eclipse-hands-on.pdf" title="Eclipse Hands On to development">Eclipse Hands On to development</a> &#8211; Bastian Feder<br />
Bastian&#8217;s mini talk is about how to integrate external tool to Eclipse. He is now setting up his blog, so you can download his presentation <a href='http://blog.felho.hu/wp-content/eclipse-hands-on.pdf' title='Eclipse Hands On to development'>from my blog</a>.<span id="more-40"></span></p>
<p><a href="http://www.frontalaufprall.com/wp-content/uploads/2007/11/tales-from-the-extreme-side_ipc_07.pdf">Tales from the eXtreme side</a> | <a href="http://www.frontalaufprall.com/" title="Lars Jankowfsky">Lars Jankowfsky</a><br />
Lars give us useful practical advices how to organize a team if you want to use extreme programming practices: ideal number of a team, office layout, daily tasks/routine, refactoring tips. He emphasizes the importance of writing always tests even for JavaScript codes. He talks about <a href="http://martinfowler.com/articles/continuousIntegration.html" title="Continuous Integration">Continuous Integration</a> and mentions useful tools to assure code quality: <a href="http://sebastian-bergmann.de/archives/690-PHPUnit-as-a-Project-Mess-Detector.html" title="PHPUnit Project Mess Detector">PHPUnit PMD </a>(Project Mess Detector), <a href="http://pear.php.net/package/PHP_CodeSniffer" title="PHP_CodeSniffer">CodeSniffer</a>, <a href="http://en.wikipedia.org/wiki/Software_metric" title="Software metrics">Software Metrics</a>, <a href="http://xdebug.org/" title="Xdebug - Debugger and Profiler Tool for PHP">xDebug&#8217;s</a> code coverage.</p>
<p><a href="http://www.frontalaufprall.com/wp-content/uploads/2007/11/agile-development-for-beginners_ipc_07.pdf">Practising Agile Development for Beginners</a> | <a href="http://www.frontalaufprall.com/" title="Lars Jankowfsky">Lars Jankowfsky</a><br />
Lars had an other interesting session about agile development. If you are interested in this topic you should look over the slides because they contain a lot of great information and resources.</p>
<p><a href="http://www.slideshare.net/sebastian_bergmann/testing-with-phpunit-and-selenium-156187" title="Testing with PHPUnit and Selenium">Testing with PHPUnit and Selenium</a> | <a href="http://sebastian-bergmann.de/" title="Sebastian Bergmann">Sebastian Bergmann</a>, <a href="http://www.maxhorvath.com" title="Max HorvÃ¡th">Max HorvÃ¡th</a><br />
<img src='http://blog.felho.hu/wp-content/debuggingsuckststingrocks.png' alt='Debugging sucks, testing rocks' /><br />
This is a comprehensive talk about testing web applications. You can get information about the different type of tests,  in which situation are they usable. It shows you the evolution from inline test codes to using complex testing tools and running the test automatically. Sebastian and Max present a very detailed example (a bowling game) how to develop an application using the TDD (Test Driven Development) methodology, how to organize your test suites. Then they talk about more advanced topics: software metrics, <a href="http://www.openqa.org/selenium/" title="Selenium">Selenium</a>, testing object interaction (mock objects), database testing.</p>
<p><a href="http://downloads.stubbles.net/?download_category=presentations&#038;download_id=ipc2007-slides-phpdp&#038;download_file=design-patterns-workshop.pdf">PHP Design Patterns</a> | <a href="http://www.stubbles.org/authors/1-Stephan-Schmidt" title="Stephan Schmidt on Stubblog">Stephan Schmidt</a>, <a href="http://www.stubbles.org/authors/2-Frank-Kleine" title="Frank Kleine on Stubblog">Frank Kleine</a><br />
Unfortunately the slides are in German, but I think it would be a great workshop, you can through the slides and maybe you will find some interesting information crumbs as I did.</p>
<p><a href="http://pooteeweet.org/files/phpconf07/sql_un_patterns.pdf" title="Common challenges in SQL apps">Common challenges in SQL apps</a> | <a href="http://pooteeweet.org/" title="Lukas Smith's blog">Lukas Smith</a><br />
Lukas Smith (PEAR::MDB2) talks about general database and SQL (un)patterns. His presentation touches on topics like: schema design (data types, normalization, trees, queues etc.), indexes and constraints (over indexing, covering indexes, full text indexes, foreign key etc.), SELECT magic (optimization, using CASE statement, pivot tables, random ordering, ranking etc.), data changes (SQL injection, optimistic locking, MVCC, smart transactions, CSV import/export etc.) It is worth studying this presentation I am sure that you will find a lot of interesting points (which maybe will you guide to further reading/research).</p>
<p><a href="http://www.slideshare.net/hozn/putting-phing-to-work-for-you" title="Putting Phing to Work for You">Putting Phing to Work for You</a> | Hans Lellelid (<a href="http://propel.phpdb.org/trac/" title="Propel - A PHP Object Relational Mapping framework">Propel</a>, <a href="http://phing.info/trac/" title="PHing Is Not GNU make">Phing</a>)<br />
Hans talks about Phing (what a surprise about the title <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). He deal with the following topics in his presentation: phing basics, creating a first build file, transforming directories and files, performing PDO tasks, gathering user input, building phpdoc, running unit tests, integrating with Continuous Integration tools, using PHP code in a build file, building a simple task, writing more complex task, creating a shared type, custom filters, custom selectors, custom loggers/listeners, input handlers.</p>
<p><a href="http://derickrethans.nl/files/tdd-ffm2007.pdf" title="Test Driven Development">Test Driven Development</a> | <a href="http://derickrethans.nl/" title="Derick Rethans">Derick Rethans</a><br />
This talks is about TDD too, this topic is getting more and more important in the PHP world too.</p>
<p><a href="https://ltsgwascl006.sby.ibm.com/developerworks/blogs/resources/phpblog/zeroPHPforIPC.pdf" title="IBM Project Zero">IBM Project Zero</a> | Rob Nicholson (<a href="http://www.projectzero.org/wiki/bin/view/" title="Project Zero">Project Zero</a>)<br />
Unfortunately the URL of the slides are dead, but I put a comment at IBM website, and I&#8217;ll update the post, if anything is happen.</p>
<p><a href="http://inside.e-novative.de/uploads/PHP6ALookAhead.pdf" title="PHP6 - A look ahead">PHP6 &#8211; A look ahead</a> | <a href="http://inside.e-novative.de/" title="Stefan Priebsch's blog">Stefan Priebsch</a><br />
Stefan talks about the new features of the upcoming PHP 6. It is worth running trough the slides, because a lot of feature originally planned for PHP 6 will be part of PHP 5.3 which will be released in early <del datetime="2007-11-11T10:38:57+00:00">2007</del>2008.</p>
<p><a href="http://inside.e-novative.de/uploads/PHPToolsandAutomation.pdf" title="PHP Tools and Automation">PHP Tools and Automation</a> | <a href="http://inside.e-novative.de/" title="Stefan Priebsch's blog">Stefan Priebsch</a><br />
This talks enumerate a lot of tools which a developer may need to working effectively and to automating repetitive tasks: <a href="http://subversion.tigris.org" title="Subversion">Subversion</a>, <a href="https://addons.mozilla.org/de/firefox/addon/60" title="Webdevloper Toolbar">Webdevloper Toolbar</a>, <a href="https://addons.mozilla.org/de/firefox/addon/1843" title="Firebug">Firebug</a>, <a href="http://www.xdebug.org" title="xDebug">xDebug</a> (<a href="http://kcachegrind.sourceforge.net/cgi-bin/show.cgi" title="KCachegrind - Profiling Visualization">KCachegrind</a>), <a href="http://www.eclipse.org/pdt" title="Eclipse - PDT">Eclipse &#8211; PDT</a>,  <a href="http://www.phpdoc.org/" title="phpDocumentor: The complete documentation solution for PHP">PHPDocumentor</a>, <a href="http://www.phpunit.de/" title="PHPUnit">PHPUnit</a>, <a href="http://www.openqa.org/selenium/" title="Selenium">Selenium</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/1192" title="XPather">XPather</a>, <a href="http://pear.php.net/package/PHP_CodeSniffer" title="PHP CodeSniffer">PHP CodeSniffer</a>, <a href="http://pear.php.net/package/PHP_CompatInfo" title="PHP CompatInfo">PHP CompatInfo</a>, <a href="http://pear.php.net/package/PHP_Beautifier" title="PHP Beautifier">PHP Beautifier</a>, <a href="http://phing.info" title="Build Automation: phing">phing</a>, Virtual Machines, <a href="http://cruisecontrol.sourceforge.net" title="Continuous Integration:<br />
CruiseControl">CruiseControl</a>.</p>
<p><a href="http://kore-nordmann.de/talks/IPC_07_11_regular_expressions.tar.bz2" title="RegExp - Magic with text">RegExp &#8211; Magic with text</a> | <a href="http://kore-nordmann.de/blog.html" title="Kore Nordmann's blog">Kore Nordmann</a><br />
Support for regular expressions advanced a lot with PCRE 6 and 7. After an introduction into the basics of regular expressions this session covers the recent additions like recursive patterns and conditional subpatterns.</p>
<p><a href="http://www.slideshare.net/dustin.whittle/diving-into-symfony-2007/" title="Diving into symfony">Diving into symfony</a> | <a href="http://dustinwhittle.com/" title="Dustin Whittle">Dustin Whittle</a><br />
This is a talk about the <a href="http://www.symfony-project.com/" title="symfony framework">symfony framework</a>, which is a full featured PHP application framework, supports the full development lifecycle. You can get an in-depth introduction about all parts of symfony.</p>
<p><a href="http://www.slideshare.net/hozn/propel-your-php-applications" title="Propel Your PHP Applications">Propel Your PHP Applications</a> | Hans Lellelid (<a href="http://propel.phpdb.org/trac/" title="Propel - A PHP Object Relational Mapping framework">Propel</a>, <a href="http://phing.info/trac/" title="PHing Is Not GNU make">Phing</a>)<br />
This talk introduces the Propel PHP <a href="http://en.wikipedia.org/wiki/Object-relational_mapping" title="Object-relational mapping">ORM tool</a>. It shows you an overview of Propel, a typical work cycle, then you can get some more in-depth usage and advanced features.</p>
<p><a href="http://www.slideshare.net/hozn/phing-building-with-php" title="Phing: Building with PHP">Phing: Building with PHP</a> | Hans Lellelid (<a href="http://propel.phpdb.org/trac/" title="Propel - A PHP Object Relational Mapping framework">Propel</a>, <a href="http://phing.info/trac/" title="PHing Is Not GNU make">Phing</a>)<br />
Hans talks about why can be useful a build tool. Todays application is getting more complex, you have to do a lot of CLI task related to your project: run unit tests, build API docs, install and package. Even deploying the application can be a complex task: setting permission, running generator, validating the contents of files (for example JavaScript, XML, PHP), etc., Phing can help you on these tasks. </p>
<p><a href="http://thomas.weinert.info/xslt-and-fpdf.download.02fde2c163c742c898d493881a49b6b6" title="Generating PDF using XSLT and FPDF">Generating PDF using XSLT and FPDF</a> | <a href="http://thomas.weinert.info/" title="Thomas Weinert">Thomas Weinert</a><br />
Generate PDFs from XML content using XSLT/<a href="http://www.fpdf.org/" title="FPDF Library">FPDF</a> gives you several new features. You can add covers, create multicolumn pages, change the page orientation depending on the content and more. All in your corporate design.</p>
<p><a href="http://typo3.org/fileadmin/teams/5.0-development/T3CON07-JSR-283.pdf" title="A JSR-283 CR in pure PHP">A JSR-283 CR in pure PHP</a> | <a href="http://www.k-fish.de/" title="Karsten Dambekalns">Karsten Dambekalns</a><br />
A Content Repository (CR) allows the storage and retrieval of arbitrary content as nodes and properties in a tree structure. The API for using a CR is standardized in the <a href="http://jcp.org/en/jsr/detail?id=170" title="JSR 170: Content Repository for JavaTM technology API">JSR-170</a> and <a href="http://jcp.org/en/jsr/detail?id=283" title="JSR 283: Content Repository for JavaTM Technology API Version 2.0">JSR-283</a> specifications. The Typo3 team decided to port the JSR-283 specification as a part of the new Typo3 5.0 project. You can read about this work in this presentation.</p>
<p><a href="http://schlitt.info/applications/blog/exit.php?url_id=4383&#038;entry_id=571" title="Webdav with eZ Components">Webdav with eZ Components</a> | <a href="http://schlitt.info/applications/blog/" title="Tobias Schlitt">Tobias Schlitt</a><br />
This talk gives us a little introduction to <a href="http://ez.no/ezcomponents" title="eZ Components">eZ Components</a>, then it introduces WebDAV and the <a href="http://ez.no/ezpublish/documentation/development/libraries/ez_webdav" title="eZ webdav">eZ webdav</a> component.   </p>
<p><a href="http://schlitt.info/applications/blog/exit.php?url_id=4382&#038;entry_id=571" title="Hands on eZ Components">Hands on eZ Components</a> | <a href="http://schlitt.info/applications/blog/" title="Tobias Schlitt">Tobias Schlitt</a><br />
If you follow this slides you can get an impression of the power of <a href="http://ez.no/ezcomponents" title="eZ Components">eZ Components</a>. It is worth being familiar with possibilities of this library, any time you could need them.</p>
<p><a href="http://www.slideshare.net/sebastian_bergmann/workflow-engine-for-php-5/" title="A Workflow Engine for PHP 5">A Workflow Engine for PHP 5</a> | <a href="http://sebastian-bergmann.de/" title="Sebastian Bergmann">Sebastian Bergmann</a><br />
Workflow Management (WfM) is becoming more and more important. For the development and maintainance of software that supports workflows, a new layer on top of the base programming language is needed. Graph-Oriented Programming (GOP) is such a layer. This session presents the <a href="http://ez.no/doc/components/view/latest/(file)/classtrees_Workflow.html" title="eZ Components' workflow engine">eZ Components&#8217; workflow engine</a>, its possible applications and the underlying principles and techniques.</p>
<img src="http://feeds.feedburner.com/~r/felho/~4/MjSV07Du6h8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/international-php-conference-2007-megapost.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/international-php-conference-2007-megapost.html</feedburner:origLink></item>
		<item>
		<title>WordPress quicktag toolbar tweaking again</title>
		<link>http://feedproxy.google.com/~r/felho/~3/29OgzwUXdEw/wordpress-quicktag-toolbar-tweaking-again.html</link>
		<comments>http://blog.felho.hu/wordpress-quicktag-toolbar-tweaking-again.html#comments</comments>
		<pubDate>Sat, 10 Nov 2007 20:39:03 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/wordpress-quicktag-toolbar-tweaking-again.html</guid>
		<description><![CDATA[It is said that it is a good behavior to set title attribute to a tags. I usually put to the title the text of the link. The process is: I put the link to the clipboard, go to the editor, select the text, press Ctrl-A, insert the link to the dialog box, press enter, [...]]]></description>
			<content:encoded><![CDATA[<p>It is said that it is a good behavior to set <code>title</code> attribute to <code>a</code> tags. I usually put to the <code>title</code> the text of the link. The process is: I put the link to the clipboard, go to the editor, select the text, press <code>Ctrl-A</code>, insert the link to the dialog box, press enter, then put the text of the link to the clipboard, go to the opening <code>a</code> tag, insert <code> title=""</code> and finally paste the text from the clipboard to the attribute. This is a repetitive and tedious task, so like in the <a href="http://blog.felho.hu/posting-source-code-in-wordpress-escaping-and-syntax-highlighting-the-inserted-code.html" title="previous case">previous case</a> I automate it. <span id="more-42"></span></p>
<p>To get <a href="http://wordpress.org/" title="WordPress">WordPress</a> to insert the <code>title</code> attribute automatically to <code>a</code> tag we had to modify the <a href="http://" title="wp-includes/js/quicktags.js">wp-includes/js/quicktags.js</a> file by adding a few lines of code to the <code>edInsertTag</code> function at two places:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>341
342
343
</pre></td><td class="code"><div class="javascript" style="font-family: monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>edButtons<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">id</span> == <span style="color: #3366CC;">'ed_link'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; edButtons<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">tagStart</span> = edButtons<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">tagStart</span>.<span style="color: #006600;">replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066FF;">/&gt;/</span>, <span style="color: #3366CC;">' title=&amp;qout;'</span>+selectedText+<span style="color: #3366CC;">'&amp;qout;&gt;'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>357
358
359
</pre></td><td class="code"><div class="javascript" style="font-family: monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>edButtons<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">id</span> == <span style="color: #3366CC;">'ed_link'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; edButtons<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">tagStart</span> = edButtons<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">tagStart</span>.<span style="color: #006600;">replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066FF;">/&gt;/</span>, <span style="color: #3366CC;">' title=&amp;qout;'</span>+selectedText+<span style="color: #3366CC;">'&amp;qout;&gt;'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></table></div>

<p>You can download the fully modified version <a href="http://blog.felho.hu/wp-includes/js/quicktags.js" title="The modified version of quicktags.js">from here</a> (this file contains my former modifications).</p>
<img src="http://feeds.feedburner.com/~r/felho/~4/29OgzwUXdEw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/wordpress-quicktag-toolbar-tweaking-again.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/wordpress-quicktag-toolbar-tweaking-again.html</feedburner:origLink></item>
		<item>
		<title>Hungarian unicode qwerty keyboard layout</title>
		<link>http://feedproxy.google.com/~r/felho/~3/FNXiWdyw1Y0/hungarian-unicode-qwerty-keyboard-layout.html</link>
		<comments>http://blog.felho.hu/hungarian-unicode-qwerty-keyboard-layout.html#comments</comments>
		<pubDate>Fri, 09 Nov 2007 01:44:44 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[mac os x]]></category>
		<category><![CDATA[keyboard layout]]></category>
		<category><![CDATA[ukelele]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/hungarian-unicode-qwerty-keyboard-layout.html</guid>
		<description><![CDATA[Unfortunately in the official Hungarian keyboard layout on Mac OS X the z and y letter are replaced. I like to program with English keyboard layout but for writing forum posts or emails I usually use Hungarian keyboard. It was a very schizophrenic situation that z and y was always changing, so I decided to [...]]]></description>
			<content:encoded><![CDATA[<p>Unfortunately in the official Hungarian keyboard layout on Mac OS X the z and y letter are replaced. I like to program with English keyboard layout but for writing forum posts or emails I usually use Hungarian keyboard. It was a very schizophrenic situation that z and y was always changing, so I decided to create my own Hungarian keyboard layout. Fortunately there is a program named <a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&#038;id=ukelele" title="Unicode Keyboard Layout Editor for Mac OS X">Ukelele</a> with which it was quite easy to create a new keyboard layout. This is a unicode layout so you can even enter Å‘, Å± in Firefox, which was not possible with the popular custom Hungarian layouts.<span id="more-31"></span></p>
<p>The keyboard layout when no modifier pressed:<br />
<img src='http://blog.felho.hu/wp-content/defaultlayout.png' alt='The keyboard layout when no modifier pressed' /><br />
The keyboard layout when SHIFT is pressed:<br />
<img src='http://blog.felho.hu/wp-content/shiftlayout.png' alt='The keyboard layout when SHIFT is pressed' /><br />
The keyboard layout when ALT is pressed:<br />
<img src='http://blog.felho.hu/wp-content/altlayout.png' alt='The keyboard layout when ALT is pressed' /><br />
The keyboard layout when FN is pressed:<br />
<img src='http://blog.felho.hu/wp-content/fnlayout.png' alt='The keyboard layout when FN is pressed' /></p>
<p>If you like it you can <a href='http://blog.felho.hu/wp-content/felhokeylayout.zip' title='Hungarian PRO FB keyboard layout'>download it here</a>.</p>
<img src="http://feeds.feedburner.com/~r/felho/~4/FNXiWdyw1Y0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/hungarian-unicode-qwerty-keyboard-layout.html/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/hungarian-unicode-qwerty-keyboard-layout.html</feedburner:origLink></item>
		<item>
		<title>Fixing some problems in Template Lite</title>
		<link>http://feedproxy.google.com/~r/felho/~3/VKbTGjBvkXE/fixing-some-problems-in-template-lite.html</link>
		<comments>http://blog.felho.hu/fixing-some-problems-in-template-lite.html#comments</comments>
		<pubDate>Thu, 08 Nov 2007 06:49:15 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[high traffic website]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[template lite]]></category>
		<category><![CDATA[high traffic]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/fixing-some-problems-in-template-lite.html</guid>
		<description><![CDATA[As a PHP developer probably you are familiar with Smarty, which is maybe the de facto PHP template engine. Smarty is sometimes criticized that it has too many feature and is too big. I think that in an average development Smarty could be a good choice, it gives you a lot of potential, and its [...]]]></description>
			<content:encoded><![CDATA[<p>As a PHP developer probably you are familiar with <a href="http://smarty.php.net/" title="Smarty Template Engine">Smarty</a>, which is maybe the de facto PHP template engine. Smarty is sometimes criticized that it has too many feature and is too big. I think that in an average development Smarty could be a good choice, it gives you a lot of potential, and its speed and memory footprint has no impact on the overall performance of the application. But if you develop a really high traffic website these issues could become very important. <a href="http://templatelite.sourceforge.net/" title="Template Lite - The smaller, faster templating solution">Template Lite</a> could be a good compromise between the features of Smarty and the performance. It is a lightweight version of Smarty, it is much faster and has much lower memory footprint. It has almost the same features like Smarty, so you won&#8217;t have any problem using it after Smarty. While Template Lite works very well, it needs a few improvements.<span id="more-29"></span></p>
<h2>The name of the compiled template file</h2>
<p>By default the name of the compiled template file is the encoded version of the original template file. If turn off this behavior by setting the <code>$encode_file_name</code> variable to <code>false</code>. The problem is, that in this case Template Lite does not include into the name of the compiled file the <code>$template_dir</code> variable. Consider the following situation:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/*<br />
&nbsp;* Template layout:<br />
&nbsp;* /templates<br />
&nbsp;* &nbsp; &nbsp; /domain1.com<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /header.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /index.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /footer.tpl<br />
&nbsp;* /templates<br />
&nbsp;* &nbsp; &nbsp; /domain2.com<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /header.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /index.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /footer.tpl<br />
&nbsp;*/</span><br />
<br />
<span style="color: #808080; font-style: italic;">// This common code handles both domain.</span><br />
<span style="color: #0000ff;">$template</span> = <span style="color: #000000; font-weight: bold;">new</span> Template_Lite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$template</span>-&gt;<span style="color: #006600;">template_dir</span> = <span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'SERVER_NAME'</span><span style="color: #66cc66;">&#93;</span>;<br />
<span style="color: #0000ff;">$template</span>-&gt;<span style="color: #006600;">display</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'index.tpl'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>The code looks good, but there is a big problem. If you get the index page on domain1.com, and then the index page on domain2.com, the secondly generated compiled file will overwrite the first one. To solve this problem you should modify the source code in the following way:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #808080; font-style: italic;">//$name = ($this-&gt;encode_file_name) ? md5((($this-&gt;_resource_type == 1) ? $this-&gt;template_dir.$file : $this-&gt;_resource_type . &amp;qout;_&amp;qout; . $file)).'.php' : str_replace(&amp;qout;.&amp;qout;, &amp;qout;_&amp;qout;, str_replace(&amp;qout;/&amp;qout;, &amp;qout;_&amp;qout;, $this-&gt;_resource_type . &amp;qout;_&amp;qout; . $file)).'.php';</span><br />
<span style="color: #0000ff;">$name</span> = <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">encode_file_name</span><span style="color: #66cc66;">&#41;</span> ? <span style="color: #000066;">md5</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type == <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> ? <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span>.<span style="color: #0000ff;">$file</span> : <span style="color: #0000ff;">$this</span>-&gt;_resource_type . &amp;qout;_&amp;qout; . <span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #ff0000;">'.php'</span> : <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">str_replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span>&amp;qout;:&amp;qout;, &amp;qout;.&amp;qout;, &amp;qout;/&amp;qout;, &amp;qout;\\&amp;qout;<span style="color: #66cc66;">&#41;</span>, &amp;qout;_&amp;qout;, <span style="color: #0000ff;">$this</span>-&gt;_resource_type.&amp;qout;_&amp;qout;.<span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span>.<span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #ff0000;">'.php'</span>;</div></td></tr></table></div>

<p>This modification should be done in several places in the source code. To find all the places you should search for the &#8220;encode_file_name&#8221; string.</p>
<h2>Writing out the compiled template file</h2>
<p>Template Lite by default opens a new file, and writes the compiled template content to it. This is not a good solution if the site has high traffic, because in the time of writing out the file it is not accessible for other processes which will cause error. A better solution is if you write to a temporary file, and when you finish it rename the temporary file to the final name. The name of the temporary file should be unique, you can achieve this by using a suffix like this: <code><a href="http://php.net/getmypid" title="Gets PHP's process ID">getmypid</a>()."_".<a href="http://php.net/microtime" title="Return current Unix timestamp with microseconds">microtime</a>(TRUE)</code>. Now if we have multiple request on the same time, and there isn&#8217;t a compiled version of the template, every request starts to generate the compiled version. The renames will be atomic and are ordered by the OS, so this way we can eliminate this type of error. The only drawback is that in Windows we can&#8217;t rename to an existing file, but usually you won&#8217;t serve a high traffic site on a Windows machine with PHP, so this is not a big problem.</p>
<p>To get Template Lite to work in this way, we should slightly modify its source (<code>class.template.php</code>) in the following way:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #808080; font-style: italic;">/*<br />
// Original code<br />
$f = fopen($this-&gt;compile_dir.'c_'.$name, &amp;qout;w&amp;qout;);<br />
fwrite($f, $output);<br />
fclose($f);<br />
*/</span><br />
<span style="color: #808080; font-style: italic;">// We write to a temporary file at first, and then we rename it to the final name.</span><br />
<span style="color: #808080; font-style: italic;">// Renaming is atomic so we won't have probelm on concurrent requests.</span><br />
<span style="color: #0000ff;">$compiledFile</span> = <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">compile_dir</span>.&amp;qout;c_&amp;qout;.<span style="color: #0000ff;">$name</span>;<br />
<span style="color: #0000ff;">$tempFile</span> = <span style="color: #0000ff;">$compiledFile</span>.&amp;qout;_&amp;qout;.<span style="color: #000066;">getmypid</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.&amp;qout;_&amp;qout;.<span style="color: #000066;">microtime</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">TRUE</span><span style="color: #66cc66;">&#41;</span>.&amp;qout;.tmp&amp;qout;;<br />
<span style="color: #0000ff;">$f</span> = <span style="color: #000066;">fopen</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tempFile</span>, &amp;qout;w&amp;qout;<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">fwrite</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span>, <span style="color: #0000ff;">$output</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">fclose</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #808080; font-style: italic;">// This won't work on Windwos, if the target file exists!!!</span><br />
<span style="color: #000066;">rename</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tempFile</span>, <span style="color: #0000ff;">$compiledFile</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></table></div>

<h2>The value of the <code>$this->_file</code> variable</h2>
<p>The <code>Template_Lite</code> class holds in this variable the name of the currently used template file. If the currently processed template includes an other template, Template Lite stops the processing of the current template and starts to process the included one (it works like a function call). At this stage the value of the <code>$this->_file</code> will be the name of the included template. Unfortunately when the processing step back to the original template, the value of <code>$this->_file</code> won&#8217;t change back. Generally this has no effect, but I sucked a little through it when I tried to extend Template Lite (you can read about this soon).</p>
<p>To correct this issue you should modify the <code>class.template.php</code> file on two places:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>749
750
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #0000ff;">$prev_file_name</span> = <span style="color: #0000ff;">$this</span>-&gt;_file;<br />
<span style="color: #0000ff;">$this</span>-&gt;_file = <span style="color: #0000ff;">$file</span>;</div></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>796
797
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #0000ff;">$this</span>-&gt;_file = <span style="color: #0000ff;">$prev_file_name</span>;<br />
<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$output</span>;</div></td></tr></table></div>

<h2>Some other little typos</h2>
<p>The following snippet comes from the original <code>template.class.php</code> file:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type == <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$f</span> = <span style="color: #000066;">fopen</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span> . <span style="color: #0000ff;">$file</span>, &amp;qout;r&amp;qout;<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">$size</span> = <span style="color: #000066;">filesize</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span> . <span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$size</span> &gt; <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$file_contents</span> = <span style="color: #000066;">fread</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span>, <span style="color: #0000ff;">$size</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #b1b100;">else</span><br />
<span style="color: #ff0000">if<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type == &amp;qout;file&amp;qout;<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$f</span> = <span style="color: #000066;">fopen</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$file</span>, &amp;qout;r&amp;qout;<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">$size</span> = <span style="color: #000066;">filesize</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$size</span> &gt; <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$file_contents</span> = <span style="color: #000066;">fread</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span>, <span style="color: #0000ff;">$size</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #66cc66;">&#125;</span></span><br />
<span style="color: #b1b100;">else</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">call_user_func_array</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_plugins<span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'resource'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$file</span>, &amp;<span style="color: #0000ff;">$file_contents</span>, &amp;<span style="color: #0000ff;">$this</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #0000ff;">$this</span>-&gt;_file = <span style="color: #0000ff;">$file</span>;<br />
<span style="color: #000066;">fclose</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></table></div>

<p>Maybe you notice, that no file is opened in the else statement, but <code>fclose($f)</code> is always called. You should move this command to the <code>if</code> and <code>else if</code> statement.</p>
<p>Another little typo is here:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>257
258
259
260
261
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066;">in_array</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$key</span>, <span style="color: #0000ff;">$this</span>-&gt;_vars<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// The array key should be $key.</span><br />
&nbsp; &nbsp; <span style="color: #000066;">unset</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_vars<span style="color: #66cc66;">&#91;</span><span style="color: #0000ff;">$index</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></table></div>

<p>You can download the <a href='http://blog.felho.hu/wp-content/classtemplate.zip' title='The corrected version of the template.class.php'>corrected version</a>. The comments are in Hungarian, but after reading the article you won&#8217;t need them, and anyway it is a beautiful language. <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/felho/~4/VKbTGjBvkXE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/fixing-some-problems-in-template-lite.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/fixing-some-problems-in-template-lite.html</feedburner:origLink></item>
		<item>
		<title>How to use Smarty resources</title>
		<link>http://feedproxy.google.com/~r/felho/~3/IgULXWST9CE/how-to-use-smarty-resources.html</link>
		<comments>http://blog.felho.hu/how-to-use-smarty-resources.html#comments</comments>
		<pubDate>Tue, 06 Nov 2007 21:19:21 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[smarty]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[smarty resources]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/how-to-use-smarty-resources.html</guid>
		<description><![CDATA[Have you ever faced the situation, that the content of a variable is a Smarty template like string, and you want to fetch or display it? I worked on project where we decided that our language file entries will be Smarty templates, because we need the flexibility of the template engine (sprintf was not enough). [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever faced the situation, that the content of a variable is a <a href="http://www.smarty.net/" title="Smarty template engine">Smarty</a> template like string, and you want to fetch or display it? I worked on project where we decided that our language file entries will be Smarty templates, because we need the flexibility of the template engine (<a href="http://php.net/sprintf" title="Return a formatted string">sprintf</a> was not enough). The problem is, that by default Smarty&#8217;s fetch/display method accepts a template file name. Of course we could write the text to a temporary file, but it would be bigger hack than PHPNuke. <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Fortunately Smarty has the mechanism to solve this problem via defining custom resource types.<span id="more-27"></span></p>
<h2>Smarty resources</h2>
<p>Smarty supports several type of plug-ins including <a href="http://www.smarty.net/manual/en/plugins.resources.php" title="Smarty manual - Resources">resource plug-ins</a>. Resource plug-ins allow you to change the way Smarty looks for templates. For example you can create a <code>db</code> resource plug-in, which allows you to store your templates in database. To use this plug-in you should refer to the templates with a <code>db:</code> prefix. For example <code>$smarty->display('db:login.tpl');</code> or in templates <code>{include file='db:header.tpl'}</code>.   The plug-in will find the template in the database, and return it.</p>
<h2>Register a Smarty resource plug-in</h2>
<p>You can register a custom Smarty resource plug-in with the<code><a href="http://www.smarty.net/manual/en/api.register.resource.php" title="Smarty manual - register_resource() method">register_resource()</a></code> method:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #0000ff;">$smarty</span>-&gt;<span style="color: #006600;">register_resource</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'db'</span>, <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #ff0000;">'db_get_template'</span>,<br />
&nbsp; &nbsp; <span style="color: #ff0000;">'db_get_timestamp'</span>,<br />
&nbsp; &nbsp; <span style="color: #ff0000;">'db_get_secure'</span>,<br />
&nbsp; &nbsp; <span style="color: #ff0000;">'db_get_trusted'</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>The first parameter is the name of the resource (should be at least two characters in length) and the second is an array with four function name which implement the plug-in. Every function will receive the requested resource as the first parameter and the Smarty object as the last parameter. The rest of parameters depend on the function. </p>
<p>From the Smarty manual:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><div class="php" style="font-family: monospace;">bool smarty_resource_name_source <span style="color: #66cc66;">&#40;</span>string <span style="color: #0000ff;">$rsrc_name</span>, string &amp;<span style="color: #0000ff;">$source</span>, object &amp;<span style="color: #0000ff;">$smarty</span><span style="color: #66cc66;">&#41;</span><br />
<br />
bool smarty_resource_name_timestamp <span style="color: #66cc66;">&#40;</span>string <span style="color: #0000ff;">$rsrc_name</span>, int &amp;<span style="color: #0000ff;">$timestamp</span>, object &amp;<span style="color: #0000ff;">$smarty</span><span style="color: #66cc66;">&#41;</span><br />
<br />
bool smarty_resource_name_secure <span style="color: #66cc66;">&#40;</span>string <span style="color: #0000ff;">$rsrc_name</span>, object &amp;<span style="color: #0000ff;">$smarty</span><span style="color: #66cc66;">&#41;</span><br />
<br />
bool smarty_resource_name_trusted <span style="color: #66cc66;">&#40;</span>string <span style="color: #0000ff;">$rsrc_name</span>, object &amp;<span style="color: #0000ff;">$smarty</span><span style="color: #66cc66;">&#41;</span></div></td></tr></table></div>

<ul>
<li>
      The first function, source() is supposed to retrieve the resource. Its second parameter $source is a variable passed by reference where the result should be stored. The function is supposed to return TRUE if it was able to successfully retrieve the resource and FALSE otherwise.</p>
<li>
      The second function, timestamp() is supposed to retrieve the last modification time of the requested resource, as a UNIX timestamp. The second parameter $timestamp is a variable passed by reference where the timestamp should be stored. The function is supposed to return TRUE if the timestamp could be successfully determined, or FALSE otherwise.
	</li>
<li>
      The third function, secure()is supposed to return TRUE or FALSE, depending on whether the requested resource is secure or not. This function is used only for template resources but should still be defined.
	</li>
<li>
      The fourth function, trusted() is supposed to return TRUE or FALSE, depending on whether the requested resource is trusted or not. This function is used for only for PHP script components requested by {include_php} tag or {insert} tag with the src attribute. However, it should still be defined even for template resources.
	</li>
</ul>
<p>You can find on the manual page a possible implementation of the <code>db</code> resource plugin.</p>
<h2>Solution for our original problem: text resource</h2>
<p>We can create a custom <code>text</code> resource to solve the problem mentioned in the introduction. The necessary code will be very straightforward:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> smarty_resource_text_get_template<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tpl_name</span>, &amp;<span style="color: #0000ff;">$tpl_source</span>, &amp;<span style="color: #0000ff;">$smarty_obj</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$tpl_source</span> = <span style="color: #0000ff;">$tpl_name</span>;<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">true</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> smarty_resource_text_get_timestamp<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tpl_name</span>, &amp;<span style="color: #0000ff;">$tpl_timestamp</span>, &amp;<span style="color: #0000ff;">$smarty_obj</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$tpl_timestamp</span> = <span style="color: #000066;">time</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">true</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> smarty_resource_text_get_secure<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tpl_name</span>, &amp;<span style="color: #0000ff;">$smarty_obj</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">true</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> smarty_resource_text_get_trusted<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tpl_name</span>, &amp;<span style="color: #0000ff;">$smarty_obj</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
<br />
<br />
<span style="color: #b1b100;">include</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Smarty-2.6.18/libs/Smarty.class.php'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$smarty</span> = <span style="color: #000000; font-weight: bold;">new</span> Smarty<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$smarty</span>-&gt;<span style="color: #006600;">register_resource</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'text'</span>, <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #ff0000;">'smarty_resource_text_get_template'</span>, <br />
&nbsp; &nbsp; <span style="color: #ff0000;">'smarty_resource_text_get_timestamp'</span>, <br />
&nbsp; &nbsp; <span style="color: #ff0000;">'smarty_resource_text_get_secure'</span>, <br />
&nbsp; &nbsp; <span style="color: #ff0000;">'smarty_resource_text_get_trusted'</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#41;</span>;<br />
<br />
<br />
<span style="color: #0000ff;">$smarty</span>-&gt;<span style="color: #006600;">assign</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'foo'</span>, <span style="color: #ff0000;">'world'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$smarty</span>-&gt;<span style="color: #006600;">fetch</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'text:Hello {$foo}!'</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Hello world!</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>Smarty resources could be very useful in some situations, keep in mind this feature! </p>
<img src="http://feeds.feedburner.com/~r/felho/~4/IgULXWST9CE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/how-to-use-smarty-resources.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://blog.felho.hu/how-to-use-smarty-resources.html</feedburner:origLink></item>
	</channel>
</rss>

