<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged aop</title>
    <link href="https://passingcuriosity.com/tags/aop/aop.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/aop/aop.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2010-01-18T00:00:00Z</updated>
    <entry>
    <title>Attribute Oriented Programming in PHP</title>
    <link href="https://passingcuriosity.com/2010/oplm2010-4-aop-in-php/" />
    <id>https://passingcuriosity.com/2010/oplm2010-4-aop-in-php/</id>
    <published>2010-01-18T00:00:00Z</published>
    <updated>2010-01-18T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>The fourth talk at the <a href="http://blogs.tucs.org.au/oplm/">Open Programming Language Miniconf 2010</a> was
Peter Serwylo’s presentation about <em><a href="http://blogs.tucs.org.au/oplm/programme/#aopphp">Attribute Oriented Programming in
PHP</a></em>. His <a href="http://lca2010.serwylo.com/">notes</a> are available online.</p>
<h2 id="attributes">Attributes</h2>
<p>Attributes are “extra” bits embedded in source code that doesn’t <em>necessarily</em>
mean anything in the language. Common examples include the documentation
annotations in many comment systems (such as the tags used in Javadoc
comments), JVM annotations, and .Net attributes.</p>
<p>A testing framework, for example, might use a <code>TestFunction</code> attribute to
identify which methods should be called.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="at">@TestFunction</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> function <span class="fu">testValidation</span><span class="op">()</span> <span class="op">{</span><span class="kw">...</span><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb2"><pre class="sourceCode cs"><code class="sourceCode cs"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="op">[</span>TestFunction<span class="op">]</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> function <span class="fu">testValidation</span><span class="op">()</span> <span class="op">{...}</span></span></code></pre></div>
<h2 id="use-cases">Use cases</h2>
<p>In Java EE you have “beans” which encapsulate business logic. Each bean
requires a bunch of wrappers for remote access, “home” access (whatever that
means), XML files, etc. Keeping all this relatively “boiler-plate” code in
synch is painful. Annotating the bean classes and methods with attributes
makes it possible to generate most of this automatically. No more manual
synching XML files.</p>
<p>Java, though, (as of Java 5) has built in support for <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html">annotations</a> and
is a compiled language. This makes it relatively simple to do this analysis
and generation at build time. PHP, on the other hand, doesn’t have an
annotation mechanism and doesn’t <em>have</em> a built time.</p>
<p>Instead, Peter’s approach is to use PHP comments to add the attributes. At
load time, these comments are processed using the reflection API and this is
used to build a data structure to use for access control. See the
<a href="http://lca2010.serwylo.com/06_ivt_example.html">permissions example</a>.</p>
<h2 id="a-more-complex-case">A more complex case</h2>
<p>To take this a little further, Peter <a href="http://lca2010.serwylo.com/07_php_zend_example.html">wrote a Zend
extension</a> that makes it
possible to [sort of] do aspect oriented programming (on function points) in
PHP. The <code>add_function_hook()</code> function allows you to register an attribute
and a callback and the extension will call your callback before a function
with that attribute is executed:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;?php</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> RequiresLogging</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>	<span class="co">/**</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="co">	 * </span><span class="an">@log</span><span class="co"> notice &quot;Secret action performed by user [user]</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="co">	 */</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>	<span class="kw">public</span> <span class="kw">function</span> secretAction()</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>	{</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>		<span class="co">// perform secret action...</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>	}</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="co">// </span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a><span class="co">// The callback function</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a><span class="co">//</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> performLog( <span class="va">$message</span> )</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>	<span class="va">$parts</span> <span class="op">=</span> <span class="cn">split</span>( <span class="st">&quot; &quot;</span><span class="ot">,</span> <span class="va">$message</span><span class="ot">,</span> <span class="dv">2</span> )<span class="ot">;</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>	<span class="va">$level</span> <span class="op">=</span> <span class="va">$parts</span>[<span class="dv">0</span>]<span class="ot">;</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>	<span class="va">$message</span> <span class="op">=</span> <span class="va">$parts</span>[<span class="dv">1</span>]<span class="ot">;</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>	Logger::<span class="fu">log</span>( <span class="va">$level</span><span class="ot">,</span> <span class="va">$message</span> )<span class="ot">;</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a><span class="co">// </span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a><span class="co">// Register the callback</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a><span class="co">// </span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a>add_function_hook( <span class="st">&quot;log&quot;</span><span class="ot">,</span> <span class="st">&quot;performLog&quot;</span> )<span class="ot">;</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a><span class="co">// Now code like this will result in a log message being recorded</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a><span class="va">$object</span> <span class="op">=</span> <span class="kw">new</span> RequiresLogging()<span class="ot">;</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a><span class="va">$object</span>-&gt;secretAction()<span class="ot">;</span></span></code></pre></div>
<p>This type approach is flexible and extremely powerful. You can inject
permission checking code and raise an exception before the real function is
even called.</p>
<p>There are a bunch of memory leaks and possible bugs in the Zend extension, but
it is working and in production use!</p>]]></summary>
</entry>

</feed>
