gooh's weblog2016-08-09T15:16:54+00:00http://blog.gordon-oheim.bizGordon Oheimblog@gordon-oheim.bizThe 90 Minute Rule for better team productivity2014-12-09T00:00:00+00:00http://blog.gordon-oheim.biz/The-90-Minute-Rule-for-better-team-productivity<p>Have you ever been through a long day and wondered why you finished so little work?
Or have have you been stuck at a problem for hours and could not find a solution?
I know it happens to me.</p>
<p>A lot of things can disrupt your productivity. Sometimes it’s just hard to get
into the flow. Sometimes you get distracted by people, Facebook, IMs, eMails and
<a href="http://www.catgifpage.com">cats on the internet</a>. Sometimes it’s easy to see the root cause and sometimes you
just are baffled how time flies but work stays.</p>
<p>There is a simple common sense approach to solving that problem when working in a team.</p>
<h3 id="the-90-minute-rule-states">The <strong>90 Minute Rule</strong> states:</h3>
<blockquote>
<p>If you didn’t made significant progress within the last 90 minutes, ask for help!</p>
</blockquote>
<p>Asking for help should never be a problem in a good team. You all want to get
things done, so asking for help should be as natural as receiving it. The point
of <em>the 90 Minute Rule</em> is to get that help <em>as late and as early as possible</em>.</p>
<p>It should be <em>as late as possible</em>, because you don’t want to disturb your co-workers
with every single roadblock you hit. One of the key skills of a knowledge worker is
to find solutions to problems, so some time investment is expected.</p>
<p>It should be <em>as early as possible</em>, because it helps no one if you are stuck at the
same problem for the whole day. You are just burning money for no good reason. In order
to achieve the team goals, you are responsible to indicate when you need their help.</p>
<p>Note that it’s not that important <em>what</em> help you get, as long as you get it.</p>
<p>One example for getting help might simply be having a <a href="http://en.wikipedia.org/wiki/Rubber_duck_debugging">human rubberduck</a>.
I cannot recall the times I have stared at buggy code only to have the scales fall
from my eyes all on their own when I explained the problem to my coworker. Then
I wished I had fetched him earlier.</p>
<p>Another example might be you finding yourself unable to get into the flow. One
of your coworkers might suggest to <a href="http://en.wikipedia.org/wiki/Pair_programming">pair program</a> with you for an hour.
Having a coworker at your side can already help to you channel your attention.</p>
<p>Also, while it’s called <em>the 90 Minute Rule</em>, there is no reason you need to stick
with that number. If 90 minutes feels too long for you, pick a time that feels more
appropriate for your team needs.</p>
<p><strong>TL;DR:</strong> when you need help, ask in time.</p>
How to become a professional developer2013-08-19T00:00:00+00:00http://blog.gordon-oheim.biz/How-to-become-a-professional-developer<p>I’ve got an eMail today. The sender wanted to let me know that he was impressed by the clarity of one my answers on Stack Overflow. I admit I am flattered each time this happens, because knowing that my contribution helped someone feels good.</p>
<p>He then asked me whether there was any general advice I’d like to pass on to a young developer. That was a rather difficult question for me, because answering concrete questions on Stack Overflow is quite different from giving general advice to an aspiring developer.</p>
<p>General advice is hard. Basically, if you are too prescriptive, you sound like an elitist bigot. But when you are new to something, concrete advice might be more helpful.</p>
<p>So I chose to do both, explain the things I learned to value in my career, as well as offering some reading I know most of my fellow developers would agree is worth learning.</p>
<p>After I had send my reply, he wrote again stating that this was exactly what he was hoping for, which obviously made me happy again.</p>
<p>Now I figured if he found my advice useful, someone else might find, too. So I am sharing my reply here:</p>
<blockquote>
<p>Hi [name redacted],</p>
<p>thanks for your message. I am happy that you like my posts.</p>
<p>I can offer some general advice. I don’t know if it turns out to be useful to you, but here is some things I learned about software development throughout my career.</p>
<ol>
<li>
<p><strong>Long to be professional</strong>. That means identifying what it means to be a professional and then try to act like one. If you don’t want to be a professional, you can just as well abandon the entire journey.</p>
</li>
<li>
<p><strong>Challenge yourself and your ideas frequently</strong>. Don’t be afraid to fail. See failure as an opportunity to learn from failures. Obviously, you shouldn’t be reckless when trying things, but try them you must.</p>
</li>
<li>
<p><strong>Stand on the shoulders of giants</strong>. It may be more interesting to only look at the newest and hippest technology, but it is foolish to ignore the wisdom of the past. Current material is often distilled knowledge. Digging in the past can help you make more sense of it and connect the dots.</p>
</li>
<li>
<p><strong>Focus on concepts, not on Tools</strong>. Tools are realizations of concepts and they sure do make our life easier, but they are just tools and they will go away eventually as new and better tools emerge. Your single most useful tool is your brain.</p>
</li>
<li>
<p><strong>Look outside the box</strong>. It’s easy to just focus on the technical side of software development, but software development is essentially a people activity. Delivering successful software is a team effort. Learn how to improve yourself as a team player.</p>
</li>
<li>
<p><strong>Socialize</strong>. Go to conferences, meet-ups and user groups and other places where developers are and talk to them. Having a discussion that forces you to express and argue your theories about programming is a great way to make you more certain about or reject your opinions.</p>
</li>
</ol>
<p>Now I am not sure if this is what you were looking for in general advice and since you asked for reference, I’ll give you some more concrete pointers below.</p>
<p>The first ten books in my reading list at http://careers.stackoverflow.com/gordon really shaped how I approach and view software development. In general, the Addison Wesley Signature Series books are all quite good. It cannot hurt to also get a decent book about Software Engineering (try Pressman), but expect very dry reads.</p>
<p>There is also a book called Apprenticeship Patterns by O’Reilly collecting good advice to guide you on your way to Software Craftsmanship, the latter being a movement you want to check out, too.</p>
<p>You definitely want to google SOLID and GRASP if you are doing object-oriented programming. There is also the Google Clean Code talks by Misko Hevery worth checking out to help you with writing testable code.</p>
<p>Anyway, if you just got started, this is all an awful lot to consider. But it’s a journey and it takes time and you need patience and you need the dedication. But you know what: if in five to ten years from now, you’ll open your inbox and find a guy telling you how you impressed him and he’s asking your for guidance, you’ll know it was totally worth it. So thank you for making my journey worth it.</p>
</blockquote>
<p>And that’s it. Obviously, this list and advice does not pretend to be complete or correct. Like I said, this is the things I came to value from when I started my own (still unfinished) journey up to now. What are yours?</p>
Always Return Something?2013-03-13T00:00:00+00:00http://blog.gordon-oheim.biz/Always-Return-Something<p>There was a <a href="http://www.brandonsavage.net/always-return-something/">blog post recently by Brandon Savage</a> suggesting that</p>
<blockquote>
<p>You should always return something when writing a function or a method.</p>
</blockquote>
<p>I don’t think this is particular good advice and will outline my reasons below.</p>
<h2 id="command-query-separation-cqs">Command Query Separation (CQS)</h2>
<p>Always returning values, is a direct contradiction to <a href="https://en.wikipedia.org/wiki/Command%E2%80%93query_separation">Bertrand Meyer’s Command Query Separation principle</a>,
which states that a method should either be</p>
<ul>
<li>a command, changing observable state but not returning anything</li>
<li>or a query, returning something but not changing observable state.</li>
</ul>
<p>But not both. Following CQS adds an extremely valueable characteristic to the application: you can
safely query your application at any given point in time without fear of changing the application state
in any way. This lowers the complexity of your API immensly and <a href="http://www.osnews.com/story/19266/WTFs_m">protects from WTF moments</a>.</p>
<p>Just as with all principles, CQS is not a dogma though. Treat it as a <em>pretty good guideline</em>. If you find
yourself in a situation where not adhering to the principle adds a pragmatic benefit, then you may of course
not follow it. However, none of the arguments given in Brandon’s post are particularly pragmatic in my opinion.</p>
<h2 id="sanity-check">Sanity Check</h2>
<p>Brandon suggests that “when you’re writing code, you should always do a sanity check to verify that
the functions you’ve executed have been successful.” I have a hard time imagining what my code would have
to look like then. It sounds awfully like</p>
<div class="prettyprint linenums lang-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9</pre></td><td class="code"><pre>if (doSomething()) {
if (doSomethingElse()) {
// more nesting
} else {
// log and die
}
} else {
// log and die
}
</pre></td></tr></tbody></table>
</div>
</div>
<p>Why not just raise an Exception when something goes wrong? It’s a tried and tested mechanism. Just returning
<code class="highlighter-rouge">FALSE</code> will only tell me <em>that</em> something went wrong. An exception will tell me <em>why</em> an error occurred. So
instead of cluttering the caller with conditionals (cf. Martin, Clean Code, pg. 103), I will write</p>
<div class="prettyprint linenums lang-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre>function doSomething()
{
// assert preconditions or throw Exception
// do something
// assert postconditions or throw Exception
}
</pre></td></tr></tbody></table>
</div>
</div>
<p>This way my consuming code can simply <code class="highlighter-rouge">try</code> to <code class="highlighter-rouge">doSomething()</code> and <code class="highlighter-rouge">catch</code> any exceptional situations. It will
also keep the messages about stuff I can anticipate to go wrong close to where it happens. So I don’t
have to repeat the error messages each time I enter the <code class="highlighter-rouge">else</code> block.</p>
<h2 id="returning-null">Returning null</h2>
<p>There is one thing that struck me throughout the post. It constantly says <code class="highlighter-rouge">return null</code>, when it should mean
<code class="highlighter-rouge">return void</code>. Granted, <code class="highlighter-rouge">void</code> is only a pseudotype in PHP. PHP <em>will</em> return <code class="highlighter-rouge">null</code> whenever you don’t
include an explicit return statement. And there is value in Brandon’s suggestion not to return <code class="highlighter-rouge">null</code>.
It just should not lead you to the conclusion that you should <em>always return something</em>. In order to cut
down on <code class="highlighter-rouge">if</code>‘ing on return values, your <strong>Queries</strong> should return one type only though. That is, if you have
a function that should produce an array, have it return an empty array (given nothing went wrong). If you
cannot reasonably do that in a function or method, consider this advice from Michael Feathers:</p>
<blockquote>
<p>If you are tempted to return <code class="highlighter-rouge">null</code> from a method, consider throwing an Exception or returning a
Special Case object instead. <em>Source: Martin, Clean Code, pg 109</em></p>
</blockquote>
<p>Following this advice yields the same benefit as not sanity checking your code. You cut down on cluttering
the caller with conditionals. It will make your code more readable, less complex and thus, more robust.</p>
<h2 id="testing-setters">Testing Setters</h2>
<p>Brandon further suggests that testing a non-returning setter will be hard to test. And that having to retrieve
the value to an additional getter is just adding dependencies. I find that argument weird. What dependency does
it add? If you have the Getter in the class anyway, there is no additional dependency. You just use what is
there.</p>
<p>If you add the Getter just for the sake of being able to query the object, you are doing it wrong. <a href="http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html">PHPUnit
supports reading protected and private attributes through <code class="highlighter-rouge">assertAttributeEquals()</code></a>. But even if
it wouldn’t, there is no real problem. And that’s not because you could use Reflection to set the property
accessible. No, it’s because the object that has the Setter will have a method through which you can verify
that the Setter worked implicitly:</p>
<div class="prettyprint linenums lang-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15</pre></td><td class="code"><pre>class Link
{
public function setUrl($url)
{
$this->url = $url;
}
public function setLinkText($linkText)
{
$this->url = $url;
}
public function getHtml()
{
return '<a href="{$this->url}">{$this->linkText}</a>'
}
}
</pre></td></tr></tbody></table>
</div>
</div>
<p>Let’s ignore that ctor injection would probably be a better approach here. The point is, the setters in
the example class above do not need to return anything. You can easily test them through your <code class="highlighter-rouge">getHtml()</code>
method. In fact, doing so is the only <em>important</em> test in the entire TestCase.</p>
<h2 id="fluent-interfaces">Fluent Interfaces</h2>
<p>The next argument in Brandon’s article is that non-returning methods will break <a href="http://martinfowler.com/bliki/FluentInterface.html">Fluent Interfaces</a>.
That’s true and it’s one of the scenarios in which the benefit trumps CQS. The purpose of a Fluent Interface
is to build an internal Domain Specific Language (DSL) though. The point of a DSL is to provide a terse and
semantically meaningful API with little syntactic noise. A Fluent Interface will sit on top of a
Semantic Model that is hopefully build on sound design principles (like CQS). Think of a Fluent Interface
as a semantic Facade for your Domain Model.</p>
<p>Chaining Setters, like in Brandon’s example, is not a Fluent Interface though. It’s merely chaining and the
example he gives is what Uncle Bob would identify as a <em>sloppy Train Wreck</em> (cf Martin, Clean Code, pg 98).
Fowler also warns about chaining methods like this due to the negative readability impact it has on
the code. He also warns mixing chained APIs with CQS APIs. The inconsistency could confuse developers because
they will not know when and when not they can chain (cf. Fowler, Domain Specific Languages, pg. 374).
This is especially in true in PHP where you cannot deduce the return type from the API signature alone.</p>
<p>Also, just because Method Chaining is a key technique in creating DSLs, drawing the conclusion that
you should always return <code class="highlighter-rouge">$this</code> is invalid. You are not always creating a DSL. And keep in mind that
each method supporting Method Chaining is potentially more error prone. A typo here and a forgotten
return there happens to even the most seasoned developer. Since you have to add the returns manually,
your chances to make a mistake eventually are much higher than without chaining. A line not written is
a line without errors.</p>
<h2 id="conclusion">Conclusion</h2>
<p>When writing functions and methods, stick to tried and tested principles. CQS is such a principle. My
post has shown how to approach the issues Brandon raised without having to abandon it.</p>
Roadblock Architecture2013-02-24T00:00:00+00:00http://blog.gordon-oheim.biz/The-Roadblock-Architecture-Antipattern<p>The following describes something that I have experienced a number of times, either on the job or in software,
(especially in frameworks) and which I think is worth coining an AntiPattern for.</p>
<ul>
<li><em>AntiPattern Name:</em> Roadblock Architecture</li>
<li><em>Also Known As:</em> Obstacle Odyssey</li>
<li><em>Most Frequent Scale:</em> Application</li>
<li><em>Refactored Solution Name:</em> Refactoring of Responsibilities</li>
<li><em>Refactored Solution Type:</em> Software</li>
<li><em>Root Causes:</em> Miscommunication, Overengineering</li>
<li><em>Unbalanced Forces:</em> Management of Functionality, Performance, Complexity</li>
<li><em>Anecdotal Evidence:</em> “So to echo something, I just need to change these ten files?”</li>
</ul>
<h2 id="background">Background</h2>
<p><a href="https://en.wikipedia.org/wiki/Roadblock">A roadblock is a temporary installation set up to control or block traffic along a road.</a>
When you encounter a roadblock, you need to find another way to continue to your destination.
This takes time, especially if you do not know the area you are driving in and don’t have a
navigation system to lead you around that obstacle.</p>
<p>Roadblocks in code can be helpful if they detour the developer in a way that is benefiting the
overall system architecture, e.g. instead of taking a direct route, it forces a developer to
adhere to a certain way of doing things. In the Antipattern, these guiding characteristics are amiss.</p>
<h2 id="general-form">General Form</h2>
<p>In a Roadblock Architecture, each change to the application is ridiculously difficult or
unintuitive to achieve. The architecture forces you to take detour after detour to reach
a certain goal. In poorly architected systems, this is often accompanied by leading you
through parts and layers of the application that should not be part of the route. If you
have to run the gauntlet, you are likely facing a Roadblock Architecture.</p>
<p>Roadblock Architecture is different from a <a href="https://en.wikipedia.org/wiki/Big_ball_of_mud">Big Ball of Mud</a> in that it has a
perceivable architecture and often even sane software metrics, e.g. little code duplication,
high Code Coverage, no globals, etc. A Roadblock Architecture might even look sane and reasonable
when it is explained to you by the person who devised. It is only that when you start to work
with it that you realize it is suffering from unnecessary complexity.</p>
<h2 id="symptoms-and-consequences">Symptoms And Consequences</h2>
<p>Changing or adding features is more expensive in terms of time and effort than it needs to be.
To achieve a certain functionality you have to touch or create a multitude of files. Developers
new to a project will not come to speed because the flow of messages through the system is non-obvious.
This can be especially frustrating for experienced developers who are aware that the architecture
is not supporting but hindering progress.</p>
<h2 id="typical-causes">Typical Causes</h2>
<p>Typical causes are <a href="https://en.wikipedia.org/wiki/Overengineering">Over-Engineering</a>, bi-directional dependencies between software layers and
lack of documentation of how messages flow through the application or where things need to be configured.
This can also be a team smell when knowledge about the application is limited to certain people.
It can also occur when there is large experience gap between the lead architect(s) and the implementing
developers: the initial concept of the Roadblock might have made sense, but because it’s intention was not
well understood by other developers caused it to become an obstacle instead of a helpful artifact.
If there is no such experience gap Roadblock Architecture can also be caused by <a href="http://stevenimmons.org/2012/02/the-ivory-tower-anti-pattern/">Lead Architect(s) living
in an Ivory Tower</a>.</p>
<h2 id="known-exceptions">Known Exceptions</h2>
<p>Roadblocks used sparingly or in a sane fashion. It’s when there is too many roadblocks that it becomes a problem.</p>
<h2 id="variations">Variations</h2>
<p><a href="http://c2.com/cgi/wiki?PastaCode">Pasta Code (in particular Lasagna or Ravioli)</a>, <a href="http://sourcemaking.com/antipatterns/architecture-by-implication">Architecture by Implication</a>, <a href="http://sourcemaking.com/antipatterns/poltergeists">Poltergeists</a>.
A Roadblock Architecture is likely to contain one or more of these problems.</p>
<h2 id="refactored-solution">Refactored Solution</h2>
<p>A solution to Roadblock Architecture is to remove superfluous Roadblocks obviously. That means refactoring
complexity to a level that the code gets simpler and comprehensible (cf. <a href="https://en.wikipedia.org/wiki/KISS_principle">KISS</a> and <a href="https://en.wikipedia.org/wiki/YAGNI">YAGNI</a>). If there is any
bi-directional dependencies between software they need to be changed to <a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html">uni-directional, facing inwards</a>.
If there is isolated functionality, it should be checked whether it can be <a href="https://en.wikipedia.org/wiki/GRASP_%28object-oriented_design%29#Information_Expert">moved onto the objects using them instead</a>.</p>
<p>Since Roadblock Architecture is likely to contain one or more of the aforementioned variations, any refactorings
applying to them might apply to Roadblock Architecture, too.</p>
<p>Parts that cannot be reasonably refactored this way need to be documented and stored at a location easily available
to the developers. Pair Programming with new developers might also help to get them to speed. However, the latter
is curing symptoms only. It is not addressing the root cause.</p>
Modeling the Real World2012-02-13T00:00:00+00:00http://blog.gordon-oheim.biz/Modeling-the-Real-World<p>A few days ago, I was asked by <a href="https://twitter.com/__edorian" title="Edorian's Twitter Account">@__edorian</a> whether I’d agree to the statement that developers model the real world. I considered the question briefly and then <a href="https://twitter.com/#!/__edorian/status/165796820608491521" title="Quoted Tweet">replied</a></p>
<blockquote>
<p>We as Software Developers don’t model the real world, we abstract domain concepts into deterministic programs</p>
</blockquote>
<p>In this blog post I’ll expand on that statement by example.</p>
<h2 id="the-scenario">The Scenario</h2>
<p>Let’s say you are tasked to build a Online Car Reservation System (it’s always cars in OO tutorials) for a local Car Rental Service. You meet with the client for the first time, she explains her vision to you and after a few days, she hands you the requirements for a first UseCase:</p>
<h4 id="usecase-uc1-reserve-car">UseCase UC1: Reserve Car</h4>
<ul>
<li><strong>Primary Actor:</strong> Website Visitor</li>
<li><strong>Stakeholders and Interests:</strong> yaddayaddayadda</li>
<li><strong>Preconditions:</strong> none</li>
</ul>
<p><strong>Success Guarantee (Postconditions):</strong></p>
<ul>
<li>Reservation is saved.</li>
<li>Rental Cost is correctly calculated.</li>
<li>Car is reserved at Rental Station</li>
<li>Reservation Voucher is sent to Website Visitor via eMail</li>
</ul>
<p><strong>Main Success Scenario (Basic Flow):</strong></p>
<ul>
<li>Website Visitor arrives at Website</li>
<li>Website Visitor enters Rental Date and Website Visitor’s eMail</li>
<li>System records selected Rental Date and Website Visitor’s eMail</li>
<li>System determines available cars for Rental Date</li>
<li>Website Visitor selects Car to reserve</li>
<li>System records selected Car</li>
<li>System calculates and presents Rental Cost to Website Visitor</li>
<li>System secretly sells eMail address to Affiliate Marketer</li>
<li>Website Visitor confirms Car Reservation</li>
<li>System reserves Car at Rental Station</li>
<li>System confirms Car Reservation to Website Visitor</li>
<li>System sends Reservation Voucher to Website Visitor’s eMail</li>
</ul>
<p><strong>Extensions (Alternate Flow):</strong> more yaddayaddayadda</p>
<p>Doesn’t sound too difficult. On to modeling.</p>
<h2 id="dont-model-the-real-world">Don’t model the real world</h2>
<p>Now, let’s imagine you start to model the real world from this UseCase. What do you need? Obviously, the Car. What makes up a Car in the real world? Right, it got a motor, and tires and doors and a trunk and windows and windshield wipers and a fuel tank and an exhaust pipe and a handbrake and seats (dont forget the seats) and an AC and rear view mirrors and … are we there yet? No, because a Car has a couple thousand parts. And the vast majority of them are meaningless for your client’s Reservation System.</p>
<p>What you really want to model is a Car as it makes sense in the Business Domain of our client’s Car Rental Service <strong>and</strong> the purpose of the application at this stage.</p>
<h2 id="abstract-domain-concepts">Abstract Domain Concepts</h2>
<p>So instead of wasting your time creating unneeded complexity, you just look at the UseCase. But since you are not a Rental Agent, you decide to call up the client again to get some reaffirmation about your understanding of how this is supposed to work:</p>
<p><strong>You:</strong> Hi, can we talk about the UseCase once more? I’d like to make sure I understand what we are talking about before I start coding.</p>
<p><strong>Client:</strong> Of course. Let me just summarize it in my own words. Our <em>Clients</em> can make <em>Reservations</em> for specific <em>Cars</em> at a certain <em>Date</em>. And they should get a <em>Voucher</em> for that, which they can carry to our local rental station. And that’s where we make the actual <em>Rental</em>.</p>
<p><strong>You:</strong> Ok, about the Car, what’s important about it? Is there any particular criteria the Client can pick from when choosing the car?</p>
<p><strong>Client</strong>: Not really. We only have a dozen cars. Usually we just tell the client which <em>brand</em> and <em>model</em> that is and how much it will <em>cost</em> to rent it. In the summer, the clients often ask whether the car has an air condition, so I guess that is important to note online, too.</p>
<p><strong>You</strong>: That’s pretty simple. I thought there might be more about the Cars.</p>
<p><strong>Client</strong>: We do keep track of a lot more data about our cars, but for the UseCase it’s not important. Let’s keep it at the simple level for now.</p>
<p><strong>You</strong>: Got it. One last thing. Umm, do you really want to secretely sell the eMail adress of the client to an Affiliate Marketer?</p>
<p><strong>Client</strong>: Haha, no. I was just checking whether you were reading the UseCase.</p>
<p><strong>You</strong>: Thanks, I think I know all I need to know right now. I’ll send you a diagram in a couple minutes, visualizing what we just talked about.</p>
<p><img src="http://yuml.me/diagram/scruffy;dir:lr/class/%5BReservation|rentalDate;totalCost%5Dreserves-%5BCar|brand;model;id;price;hasAC%5D,%20%5BReservation%5DconfirmedIn-%5BVoucher%5D,%20%5BReservation%5DmadeFor-%5BClient|email%5D" alt="UML Model for Car Reservation UseCase - powered by yuml.de" /></p>
<h2 id="into-deterministic-programs">Into Deterministic Programs</h2>
<p>Now that you know how to think in the mental model of a Rental Agent, it’s time to add your own expert knowledge. The UML above is <a href="http://domaindrivendesign.org/node/132" title="supports Ubiquitous Language">good for communicating with your client</a>, but it’s not a runnable program. Don’t confuse it with class diagrams. It’s just the conceptual basis.</p>
<p>So the next step is translating your newfound knowledge into something a computer can execute. In this phase, you will design and ultimately code the components you need in the various layers in what the UseCase only calls “the System”.</p>
<p>For your client, these details are largely uninteresting. Whether you use a Framework or a particular Design pattern doesn’t matter to him. She trusts you to deliver a professional result.</p>
<p>She also likely won’t be interested in Class diagrams or similar UML artifacts. Whether you use those is up to you. What counts is that you concentrate on modeling your client’s view of their problem domain in a way that allows you and him to communicate and you to build a software system around it.</p>
<p>And that’s what my initial statement means.</p>
Why the PSR-0 Classloader does not belong into SPL2011-10-30T00:00:00+00:00http://blog.gordon-oheim.biz/Why-the-PSR0-classloader-does-not-belong-into-SPL<p>There is currently an <a href="https://wiki.php.net/rfc/splclassloader">RFC in the PHP Wiki proposed by the PSR Standards Group about
including a classloader into SPL</a> that will autoload classes following the PSR-0 File
and Class naming convention.</p>
<p>In case you dont know what the <a href="https://groups.google.com/group/php-standards">PSR Group</a> is, here is some background</p>
<blockquote>
<p>In the mid of 2009, several lead developers started an initiative called PHP Standards Group (aka. Framework Interoperability Group), which is mainly focused on interoperability between different Open Source projects.</p>
</blockquote>
<p>Let’s not discuss whether it was a good idea to adopt the name PHP Standards Working
Group although they are not in the position to define anything official for PHP at all.
Rather, let’s discuss whether we want to add code to native PHP that requires a
developer to adopt a certain <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Coding_conventions">code convention</a>. The term convention is important here,
because that’s what PSR-0 is. It is not a standard, but a convention; followed by
a certain interest group connected by a certain need: framework interoperability.</p>
<p>Framework interoperability is a reasonable goal. Being able to painlessly plug Doctrine
into Symfony and add ZF on top will surely make the lifes of those that need such setups
in their application easier. I’d claim though that for the majority of PHP users such
setups are not a requirement. Why would those people need to follow PSR-0 just to
use a piece of native PHP code then?</p>
<blockquote>
<p>Coding conventions are not enforced by compilers. As a result, not following some or all of the rules has no impact on the executable programs created from the source code.</p>
</blockquote>
<p>PHP works with any convention, not just one convention. PHP does not define a particular
coding <em>standard</em> for userland code. There is a few tips and <a href="http://docs.php.net/manual/en/userlandnaming.php">guidelines for how to
name code in the global scope</a>, but that is not a standard, nor a convention.
It’s incomplete.</p>
<p>One could assume that since all examples in the PHP Manual follow PEAR convention, PEAR
is the agreed upon convention in PHP, but that is simply not true. In fact, a lot of the
projects that now participate in PSR did grow to reasonable size by inventing their own
coding convention or tweaking an existing one. They didn’t need a general standard then,
so why force one unto us now? By their success they have already proven that we don’t
need such a thing in PHP.</p>
<p>The C implementation of the suggested ClassLoader is from PEAR’s own David Coallier.
Yet, despite PEAR and autoloading being around for much longer than the PSR group, we
do not have any code in PHP that requires us to follow PEAR convention. Ironically, if
all of the projects taking part in PSR had followed PEAR convention for file and
class naming right from the start they wouldnt have an interoperability problem now.
But apparently, they didnt feel PEAR was good enough then. Who guarantees that they
won’t abandon PSR in five years again? I’d rather have developers <a href="http://martinfowler.com/bliki/EnablingAttitude.html">follow a convention by
conviction</a> than by <a href="http://martinfowler.com/bliki/DirectingAttitude.html">embedding it into PHP</a>.</p>
<p>To stress this, I am not against having a native classloader. But I am against
putting it into SPL when it requires PSR-0. No other function in PHP requires us to use
a certain code convention. The argument that it is optional doesn’t count. It is not
a general purpose classloader when I have to follow PSR-0 for it and thus it
shouldn’t be in SPL.</p>
<p>Also, what the PSR group should take into account is that frameworks evolve and change
much faster and often than PHP. If they want their code to be in the PHP trunk, they
have to follow PHP’s release cycles, which will make it a lot harder to introduce new
features and BC breaks. Putting the classloader into a PECL extension would make much
more sense then.</p>
<p>Incidentally, there <a href="http://docs.php.net/manual/en/book.yaf.php">already is a project in PECL</a> that brings it’s own classloader.
And in fact, YAF sounds a lot like where the PSR group is heading. The ClassLoader is
just the tip of the iceberg. <a href="https://groups.google.com/group/php-standards/browse_thread/thread/44158f606ad39b1a">Once that one is in SPL, they want common interfaces to
follow</a>. Now why should PSR be in SPL, when YAF isn’t? Where do we draw the line?</p>
<p>In that sense, please keep PHP free from framework interests.
Don’t put the Classloader into SPL.
Thank you.</p>
<p>P.S. Some additional thoughts can be found in <a href="http://blog.ircmaxell.com/2011/11/on-psr-0-being-included-in-phps-core.html">ircmaxell’s blog</a></p>
How to install Zend Server from a local Repository2011-06-20T00:00:00+00:00http://blog.gordon-oheim.biz/How-to-install-Zend-Server-from-a-local-Repository<p>The following is a guide to do a manual install of Zend Server on RHEL 5/6. I needed this solution because I had to install Zend Server on a machine in an intranet with no WAN and the Zend Website only offered an RPM installer that required an internet connection.</p>
<p><em>Disclaimer: Note that the solution below worked for me. It doesn’t mean it will work for you. If you break something in the process, it’s not my fault. When in doubt, buy Zend Support.</em></p>
<p>##Step 1 - Mirror the Zend Server Repository</p>
<p>When you are using the installer script, it will try to download the appropriate Zend Server sources from</p>
<ul>
<li>http://repos-source.zend.com/zend-server/rpm/</li>
</ul>
<p>so open a command prompt and mirror that location</p>
<div class="highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>wget --mirror --no-parent http://repos-source.zend.com/zend-server/rpm/
</pre></td></tr></tbody></table>
</div>
</div>
<p>This will download <em>all</em> files at that location, including any optional extensions and some cruft. If you know
your required cpu architecture, you can limit wget to mirror only the appropriate folders. Once you hit Enter,
go make a coffee or something because this will take a while (about 315MB for Zend Server 5.1).</p>
<p>Upload the file to the target machine when done.</p>
<p>##Step 2 - Download the RPM installer</p>
<p>You can get this one from the zend.com Download section. When done, upload and extract the archive on the target machine</p>
<div class="highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>tar xzf /downloads/ZendServer-RepositoryInstaller-linux.tar.gz
</pre></td></tr></tbody></table>
</div>
</div>
<p>This will create the folder <code class="highlighter-rouge">ZendServer-RepositoryInstaller</code> in <code class="highlighter-rouge">/downloads</code> with all the contents of the archive.
<code class="highlighter-rouge">cd</code> into that directory now.</p>
<p>##Step 3 - Modify the repository file</p>
<p>You now have all the required files. Move the mirrored rpm folder to some convenient location, like
<code class="highlighter-rouge">/opt/zend-server/rpm</code> or whatever you deem convenient. Then tell your RHEL about the new location.</p>
<p>Modify <code class="highlighter-rouge">zend.rpm.repo</code> to read the following:</p>
<div class="highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13</pre></td><td class="code"><pre>[Zend]
name=Zend Server
baseurl=file:///opt/zend-server/rpm/$basearch
enabled=1
gpgcheck=0
gpgkey=http://repos.zend.com/zend.key
[Zend_noarch]
name=Zend Server - noarch
baseurl=file:///opt/zend-server/rpm/noarch
enabled=1
gpgcheck=0
gpgkey=http://repos.zend.com/zend.key
</pre></td></tr></tbody></table>
</div>
</div>
<p>##Step 4 - Install from the local repository</p>
<p>After you have made the changes to repo files, installing takes the same steps explained in the
Installation Guide. If you are <strong>not</strong> on SELinux you can skip the following step</p>
<div class="highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>setenforce permissive
</pre></td></tr></tbody></table>
</div>
</div>
<p>To install Zend Server, call the install script with the desired version, e.g. for 5.3 do</p>
<div class="highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>./install_zs.sh 5.3
</pre></td></tr></tbody></table>
</div>
</div>
<p>Confirm any prompts with yes.</p>
<p>Zend Server should now be running at these URIs</p>
<ul>
<li>https://localhost:10082/ZendServer (secure)</li>
<li>http://localhost:10081/ZendServer (non-secure)</li>
</ul>
<p>And that’s it. You can do a <code class="highlighter-rouge">yum clean all</code> to clean up any meta data if you want and add PHP to your PATH environment to make it available on CLI now. Details for that can be found in the Installation Guide.</p>
<h2 id="alternative-without-the-installer-script">Alternative without the installer script</h2>
<p>Instead of using the installer script, you can also add the <code class="highlighter-rouge">zend.rpm.repo</code> file to <code class="highlighter-rouge">/etc/yum.repos.de/</code> and then do a <code class="highlighter-rouge">yum install</code> manually. This is the same as explained in the Installation Guide. The only difference is the local repository.</p>
<h2 id="additional-packages">Additional Packages</h2>
<p>Because you mirrored the full repository, you will also have all the optional packages now. You can install any
of those with a regular <code class="highlighter-rouge">yum install package-name</code>. For the full list of additional packages, see</p>
<ul>
<li>http://static.zend.com/topics/server/Zend-Server-Installation-Guide.pdf</li>
</ul>
<h2 id="troubleshooting">Troubleshooting</h2>
<p>Error: Metadata file does not match checksum. Trying other mirror
Solution: <code class="highlighter-rouge">yum clean all</code></p>
<p>Error: php-5.3-page_cache-… not found
Solution: check the given path and make sure the file does not contain url encoded values, e.g. <code class="highlighter-rouge">%3a</code> instead of <code class="highlighter-rouge">:</code></p>
<h2 id="updating-and-uninstalling-zend-server">Updating and Uninstalling Zend Server</h2>
<p>Since your Zend Repo points to a local repository, you won’t get any updates. You have to replace updated content in the repository manually. Uninstalling works the same as with a non-local repository. See the Installation Guide for details.</p>
DPC 20112011-05-22T00:00:00+00:00http://blog.gordon-oheim.biz/Dutch-PHP-Conference-2011<p>From <a href="http://joind.in/event/view/603">May 18th to May 21st I was at DPC</a> in lovely Amsterdam. The line-up for this
conference promised a lot of interesting talks and good networking opportunities.
So I had to go.</p>
<h2 id="hotel">Hotel</h2>
<p>The speaker hotel for DPC11 was the ibis Hotel at Amsterdam Central Station.
I considered staying there at first, but this was about 6km from the conference
venue and (like any other hotel in downtown Amsterdam) it was quite expensive.</p>
<p>So I ended up in the <a href="http://www.citizenm.com/">CitizenM Hotel</a>, which is a pretty fancy design hotel with
rather small (no separate bathroom), but efficiently designed and quiet rooms.
The bed was spacious and comfortable. Geeks will love the Philips mood pad that
allows controlling various aspects of the room, like TV, blinds, air condition
and lighting (including color). They also offer a huge list of free movies and
WiFi is complimentary as well.</p>
<h2 id="venue">Venue</h2>
<p>The <a href="http://bit.ly/mGFH3R">RAI conference center was about 10 minutes walk through Beatrixpark from CitizenM</a>.
There is not much to say about the venue, which in this case means, it was well chosen.
The WiFi worked well. The rooms were large enough to accomodate the PHP Crowd
at the various talks. The main hall allowed for easy socializing. Some rooms
were bit too cold at times.</p>
<h3 id="catering">Catering</h3>
<p>I just might be a spoiled german here, but I was a bit disappointed by the
catering. There was sandwiches, warm pastry and Hot Dogs for lunch, which I was
told is pretty common for Dutch lunch. Unfortunately, the warm food was only
available in very limited quantities. So, if you didnt get to the food stands
immediately you were left with the sandwiches (which I wasn’t too fond of).
The only good thing about this was you couldn’t fall into a post-meal coma and since
I wasn’t there for the food anyways it’s just a minor complaint.</p>
<h3 id="workshop">Workshop</h3>
<p>Prior to the conference, there was a full day of workshops. Attendees got a free copy
of <a href="http://qualityassuranceinphpprojects.com/">thePHP.cc’s QA book</a>, which was a rather nice
and very much unexpected gift, especially since I didn’t own that yet and had
it on my wishlist.</p>
<p>I attended <a href="http://joind.in/talk/view/3217">“XP Principles and Practices” by Sebastian Schürmann</a>.
I already knew the theory behind XP, but the workshop helped me deepen and
solidify my knowledge and helped close some gaps. The presenter did a good
job moderating the workshop in a way that encouraged active participation
of all attendees. There was a tremendous amount of experience shared this way.</p>
<h2 id="conference-day-1">Conference Day 1</h2>
<p>The main conference started with <a href="http://joind.in/talk/view/3375">Aral Balkan’s keynote about “The Art of User Experience: making beautiful, delightful, fun things”</a>. While UX might not
be a too obvious thing to think about when you are in the bowels of a PHP
backend, Aral delivered an absolutely stunning and professional keynote that
got the argument across in an entertaining, enthusiastic and inspiring manner.</p>
<p>After the keynote I attended <a href="http://joind.in/talk/view/3225">Oracle’s Christopher Jones talk about Developing and Deploying High Performance PHP Applications</a>. The talk had an (expected)
sales-pitch nature, but I found it valuable to get an overview of current and
upcoming Oracle Techologies I might want to look more deeply into. As such,
the talk wasn’t so much about “How” but about “What with” and offered only
very little technical details. And I got a free USB Stick, so yay!</p>
<p>Since I recently read “REST In Practise” and “RESTful Web Service”, I was keen
to attend <a href="http://joind.in/talk/view/3231">Evert Pot’s session “So you think you know REST?”</a> then.
Unfortunately, the talk focused way too much on various HTTP features and was
very dry. I missed information about Resources, Representations, Richardson’s
Maturity Model, the role of Hypermedia (HATEOAS) and how REST enables us to
build Domain Application Protocols.</p>
<p>After the lunch break I attended <a href="http://joind.in/talk/view/3237">Jonas Marien’s “Implementing Comet using PHP”</a>.
Whenever I researched Comet for PHP in the past, I came to the conclusion that
PHP isn’t that well suited for it. I had hoped to gain some new insight on the topic,
but the talk mainly offered a (very thorough) overview of available Comet
technologies in general and not so much about the problems faced when wanting to
do Comet in PHP. So the title was somewhat of a misnomer.</p>
<p>For the final session on that day I attended <a href="http://joind.in/talk/view/3238">Rob Allen’s “Zend Framework 2.0: what’s new and what’s changed?”</a>. This was a good talk that delivered what
it promised. As I dont follow the ZF2 development too closely it was good to
learn that a number of things that bug me in ZF1 are on the ToDo list for
improvement in ZF2.</p>
<h3 id="socializing-event">Socializing Event</h3>
<p>The <a href="http://joind.in/talk/view/3376">socializing event</a> was scheduled from 2030 to 2300 in Club NL in downtown
Amsterdam. Unfortunately, that venue didnt work for me at all. The place was
way too small to accomodate all the attendees and it was definitely too noisy
to socialize without yelling at each other. I left early.</p>
<h2 id="conference-day-2">Conference Day 2</h2>
<p>The second day at DPC11 started with the <a href="http://joind.in/talk/view/3241">Helgi Þormar Þorbjörnsson keynote about “First Class APIs”</a>. Helgi emphasized the growing
importance of making Data available on the web via dedicated APIs. While this was
a solid keynote it paled in comparison to the furious keynote Aral Balkan delivered
on the first day. I also felt it was rather lengthy with the main argument being
sufficiently explained after about half of the keynote.</p>
<p>The first session I attended that day was <a href="http://joind.in/talk/view/3244">Juozas “Joe” Kaziukėnas “The new era of PHP frameworks”</a>. I didnt always get who Joe was refering to when he
said “we” but the talk gave a good overview over the current state of PHP
frameworks and what to expect from the next generation of PHP frameworks.
Some of what was suggested as desirable features in next-gen frameworks was
rather opinionated in my book and debatable (just add beer) but unfortunately,
there wasnt enough time to do so.</p>
<p>When I left Rob Allen’s ZF2 outlook the day before, I had asked him about a
specific problem I was currently facing in one of my ZF projects and he invited
me to his talk <a href="http://joind.in/talk/view/3245">“Optimising a Zend Framework application”</a>. This was a very
well done talk offering plenty of good practical advice (beyond what is already
offered in the ZF Performance Guide) to take home.</p>
<p>After that I attended <a href="http://joind.in/talk/view/3249">Qafoo’s “Modular Application Architecture”</a>. Kore
Nordmann and Tobias Schlitt presented different solutions to this problem and
compared them. The talk covered a lot in a very short time, which made it
sometimes hard to follow. For the short 45 minutes at DPC it might have made
sense to just focus on an overview and leave out the obscure real world examples
of Oxid and PHPBB. Still, a good talk.</p>
<p>The last talk for this day was <a href="http://joind.in/talk/view/3252">David Zuelke’s “Large-Scale Data Processing with Hadoop and PHP”</a>. David is a very entertaining speaker with a skill to sell
technologies to you in a very short time. Unfortunately, he had a headache this
day and wasn’t as jumpy as usual. But even with this slight handicap, David
delivered a professional and rock solid, well structured introduction to
Hadoop and HadooPHP with some live demos.</p>
<p>The <a href="http://joind.in/talk/view/3254">closing keynote of DPC11 was held by Cal Evans</a>. Cal talked about what
managers should know and do if they want developers to exhibit the same
passion and enthusiasm towards their jobs than they show for open source
projects they work on in their spare time. Though I am not sure I’d subscribe
to all what was said, this was a solid and entertaining keynote with a clear message.</p>
<h2 id="conclusion">Conclusion</h2>
<p>All in all, I really enjoyed DPC a lot. There was plenty of interesting topics
to pick from. And despite the failed Social Event, I still had my share
of socializing and networking between sessions. DPC11 was a rather valuable
conference for me and I am looking forward to come back here next year.</p>
<p>Thanks to everyone who made this happen.</p>
Iterating File Contents with SPL2011-05-16T00:00:00+00:00http://blog.gordon-oheim.biz/Iterating-File-Contents-With-SPL<p>I noticed a lot of people are still using the classic filepointer approach to read a file line by line:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre><span class="nv">$handle</span> <span class="o">=</span> <span class="nb">fopen</span> <span class="p">(</span><span class="s2">"file.txt"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nb">feof</span><span class="p">(</span><span class="nv">$handle</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$buffer</span> <span class="o">=</span> <span class="nb">fgets</span><span class="p">(</span><span class="nv">$handle</span><span class="p">);</span>
<span class="k">echo</span> <span class="nv">$buffer</span><span class="p">;</span>
<span class="p">}</span>
<span class="nb">fclose</span> <span class="p">(</span><span class="nv">$handle</span><span class="p">);</span>
</pre></td></tr></tbody></table>
</div>
</div>
<p>While there is nothing wrong with doing things the old school way, PHP also offers <code class="highlighter-rouge">SplFileObject</code> for quite some time now:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre><span class="nv">$file</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SplFileObject</span><span class="p">(</span><span class="s2">"file.txt"</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nv">$file</span><span class="o">-></span><span class="na">eof</span><span class="p">())</span> <span class="p">{</span>
<span class="k">echo</span> <span class="nv">$file</span><span class="o">-></span><span class="na">fgets</span><span class="p">();</span>
<span class="p">}</span>
</pre></td></tr></tbody></table>
</div>
</div>
<p>Not only does this shorten your code by two lines, but it also let’s you work with an Object instead of a Resource now. Almost all of the procedural functions available for file handling are also available as methods of <code class="highlighter-rouge">SplFileObject</code>.</p>
<p>If that’s not enough reason to switch already, <code class="highlighter-rouge">SplFileObject</code> also implements the <code class="highlighter-rouge">Iterator</code> interface, which means you can shorten the above code to a simple <code class="highlighter-rouge">foreach</code> loop:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="k">foreach</span> <span class="p">(</span><span class="k">new</span> <span class="nx">SplFileObject</span><span class="p">(</span><span class="s2">"file.txt"</span><span class="p">)</span> <span class="k">as</span> <span class="nv">$lineNumber</span> <span class="o">=></span> <span class="nv">$content</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">printf</span><span class="p">(</span><span class="s2">"Line %d: %s"</span><span class="p">,</span> <span class="nv">$lineNumber</span><span class="p">,</span> <span class="nv">$content</span><span class="p">);</span>
<span class="p">}</span>
</pre></td></tr></tbody></table>
</div>
</div>
<p>There is more. Because <code class="highlighter-rouge">SplFileObject</code> also implements <code class="highlighter-rouge">SeekableIterator</code> you can easily jump to specific lines without having to count lines via some temp variable in your loop. How much more convenient can it get?</p>
<div class="language-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="nv">$file</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SplFileObject</span><span class="p">(</span><span class="s2">"file.txt"</span><span class="p">);</span>
<span class="nv">$file</span><span class="o">-></span><span class="na">seek</span><span class="p">(</span><span class="mi">9</span><span class="p">);</span> <span class="c1">// zero-based, so it's line 10
</span><span class="k">echo</span> <span class="nv">$file</span><span class="o">-></span><span class="na">current</span><span class="p">();</span> <span class="c1">// outputs line 10
</span></pre></td></tr></tbody></table>
</div>
</div>
<p>And of course you can stack an <code class="highlighter-rouge">SplFileObject</code> into other Iterators, for instance the <code class="highlighter-rouge">LimitIterator</code> to limit how many lines should be iterated over:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8</pre></td><td class="code"><pre><span class="nv">$linesTenToTwentyIterator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">LimitIterator</span><span class="p">(</span>
<span class="k">new</span> <span class="nx">SplFileObject</span><span class="p">(</span><span class="s2">"file.txt"</span><span class="p">),</span>
<span class="mi">9</span><span class="p">,</span> <span class="c1">// start at line 10
</span> <span class="mi">10</span> <span class="c1">// iterate 10 lines
</span><span class="p">);</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$linesTenToTwentyIterator</span> <span class="k">as</span> <span class="nv">$line</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="nv">$line</span><span class="p">;</span> <span class="c1">// outputs line 10 to 20
</span><span class="p">}</span>
</pre></td></tr></tbody></table>
</div>
</div>
<p><code class="highlighter-rouge">SplFileObject</code> is complemented by <code class="highlighter-rouge">SplTempFileObject</code> and <code class="highlighter-rouge">SplFileInfo</code>. The first offers an object oriented interface for a temporary file, including in-memory files. As such it is similar to file pointers opened with <code class="highlighter-rouge">php://temp</code> or <code class="highlighter-rouge">php://memory</code> as file descriptors.</p>
<p><code class="highlighter-rouge">SplFileInfo</code> offers a high-level object oriented interface to information for an individual file. This includes methods for getting the realpath, basename and so on. <code class="highlighter-rouge">SplFileInfo</code> is actually the parent class of the other two.</p>
<p>So next time you’re going to whip out another file pointer, remember there is a nice OO alternative.</p>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="http://php.net/manual/en/class.splfileobject.php">The SplFileObject class</a></li>
<li><a href="http://php.net/manual/en/class.spltempfileobject.php">The SplTempFileObject class</a></li>
<li><a href="http://php.net/manual/en/class.splfileinfo.php">The SplFileInfo class</a></li>
<li><a href="http://php.net/manual/en/class.seekableiterator.php">The SeekableIterator interface</a></li>
<li><a href="http://php.net/manual/en/class.iterator.php">The Iterator Interface</a></li>
<li><a href="http://php.net/manual/en/class.limititerator.php">The LimitIterator Class</a></li>
</ul>
Announcing PHPUnit Schema2011-04-05T00:00:00+00:00http://blog.gordon-oheim.biz/Announcing-PHPUnit-Schema<p>When working with <a href="http://www.phpunit.de/manual/current/en/appendixes.configuration.html">PHPUnit’s XML Config file</a>, it can be somewhat tedious to remember all the possible configuration elements and how they should be written. For this purpose, I have assembled a PHPUnit Schema file to assist in authoring PHPUnit configuration files. And since I figured I am not the only one who could find that useful, I decided to share with you. <a href="https://github.com/gooh/phpunit-schema">The PHPUnit-Schema is available on GitHub</a>. Contributions and corrections are welcome. If you want to participate in maintaining and/or improving the file, feel free to fork at will. Pull requests are always welcome.</p>
<h2 id="usage">Usage</h2>
<p>To apply the Schema to a configuration file, you have to declare the Schema Namespace and the location of the Schema file in the phpunit.xml file. Since PHPUnit does not use a dedicated namespace for the configuration file, the following two lines are all that is required:</p>
<div class="prettyprint linenums lang-xml highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="err"><</span>?xml version="1.0" encoding="UTF-8">
<span class="nt"><phpunit</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span class="na">xsi:noNamespaceSchemaLocation=</span><span class="s">"location of xsd file"</span>
<span class="err">…</span>
</pre></td></tr></tbody></table>
</div>
</div>
<p>Assuming you are working with a Schema-aware editor (like Eclipse) you should get Content Assist and limited Code Completion then:</p>
<p><img src="/assets/posts/2011-04-05/ContentAssist.png" alt="PHPUnit Code Completion in Zend Studio" /></p>
<h2 id="notes">Notes</h2>
<p>The Schema file is currently split into multiple smaller files. This eases maintaining the Schema file during development for me. But it’s somewhat inconvenient, if you just want the Schema file for Content Assist. For this purpose, you can create a single phpunit.xsd with the PHP script given in the tools folder:</p>
<div class="highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>$ php generate-schema.php
Created new validated Schema file at:
F:\Work\code\PHPUnit-Schema\tools\phpunit.xsd.1301999633
</pre></td></tr></tbody></table>
</div>
</div>
The DOM Goodie in PHP 5.3.62011-03-17T00:00:00+00:00http://blog.gordon-oheim.biz/The-DOM-Goodie-in-PHP-5.3.6<p>PHP 5.3.6 has been released today. There is a lot of improvement and bugfixes that are worth mentioning. But the one that made me particularly excited was this one:</p>
<blockquote>
<p>Implemented <a href="http://bugs.php.net/bug.php?id=39771">FR #39771</a> (Made DOMDocument::saveHTML accept an optional DOMNode like DOMDocument::saveXML). (Gustavo)</p>
</blockquote>
<p>If you have worked with <a href="http://www.php.net/manual/en/book.dom.php">DOM</a> before, you know that this will ease working with broken HTML a lot, because now you can do</p>
<div class="prettyprint linenums lang-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>$dom = new DOMDocument;
$dom->loadHtml('<div id="content"><p>Some<br>HTML Fragment</p></div>');
echo $dom->saveHTML($dom->getElementById('content'));
</pre></td></tr></tbody></table>
</div>
</div>
<p>and get</p>
<div class="prettyprint linenums lang-html highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre><div id="content"><p>Some<br>HTML Fragment</p></div>
</pre></td></tr></tbody></table>
</div>
</div>
<h2 id="why-is-it-cool">Why is it cool?</h2>
<p>DOM is based on <a href="http://www.xmlsoft.org/">libxml</a>. So it is primarily intended for working with XML. HTML isn’t XML at all, but is based on SGML. Different rules. Unfortunately, even after years of advocating web standards, most of the web is still broken HTML. Pick a random site on the web and run it through validator.w3.org. My guess is at least eight out of ten sites will not validate (including this blog - not my fault though). And just to make this clear: I don’t have any hopes that <a href="http://blog.whatwg.org/html-is-the-new-html5">TMFKAH</a> will improve the situation. A well formed web will forever be a Pipe Dream.</p>
<p>The good news is: despite common misbeliefs, DOM can also parse broken HTML. When you use <code class="highlighter-rouge">loadHTML()</code> or <code class="highlighter-rouge">loadHTMLFile()</code>, DOM will internally switch to it’s <a href="http://xmlsoft.org/html/libxml-HTMLparser.html">HTML Parser Module</a> and parse the markup as HTML4 Transitional.</p>
<p>The bad news is: when using the HTML Parser Module, libxml will also add a basic HTML skeleton to make sure it can parse the HTML somehow. This is a nasty unobvious side-effect, because when traversing the DOM with</p>
<div class="prettyprint linenums lang-php highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>echo $dom->documentElement->firstChild->nodeName;
</pre></td></tr></tbody></table>
</div>
</div>
<p>you would expect it to output ‘p’, but it will output ‘body’. Consequently, when we used <code class="highlighter-rouge">saveHTML()</code>, we would get the following output (shortened DocType for readability):</p>
<div class="prettyprint linenums lang-html highlighter-rouge"><div class="highlight"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="cp"><!DOCTYPE html PUBLIC "blah"></span>
<span class="nt"><html><body><div</span> <span class="na">id=</span><span class="s">"content"</span><span class="nt">><p></span>Some<span class="nt"><br></span>HTML Fragment<span class="nt"></p></div></body></html></span>
</pre></td></tr></tbody></table>
</div>
</div>
<p>To make matters worse: with <code class="highlighter-rouge">saveXML()</code> you can pass in a node to be dumped. With <code class="highlighter-rouge">saveHtml()</code> you couldn’t (until now). So when you were dealing with HTML fragments, you had no way to get just a particular node or fragment back from DOM. You could get all or nothing. The only two options you had was <a href="http://php.net/manual/en/domdocument.savehtml.php#85165">manually removing the HTML skeleton somehow</a> or dump the wanted nodes with saveXml instead. Using saveXml had the problem that it would format any markup according to XML rules as well, so <code class="highlighter-rouge"><br></code> would become <code class="highlighter-rouge"><br/></code>. If you didn’t intend your markup to be XHTML, this is unwanted.</p>
<p>But with PHP 5.3.6 we can finally pass a node to <code class="highlighter-rouge">saveHtml</code>. And that’s very cool!</p>
<p>Tweet a “Thank you” to <a href="https://twitter.com/cataphractpt">Gustavo</a> for implementing it.</p>
PHPUCEU and PHPDays in Manchester2011-02-16T00:00:00+00:00http://blog.gordon-oheim.biz/PHPUCEU-and-PHPDays-in-Manchester<p>I had the pleasure to attend the first <a href="http://www.phpuceu.org/phpuceu-2011" title="Official Website of the PHPUnconference EU">PHP Unconference Europe</a> and the <a href="http://www.phpuceu.org/2010/05/01/php-days-in-manchester" title="PHP Days Manchester">PHP Days in Manchester</a>. I knew there would be a couple of people I wanted to meet in person. Also, I’ve never been to Manchester before. So I decided I had to go. Happy I did, because I had a great time.</p>
<h3 id="warm-up">Warm-Up</h3>
<p>Before the actual conference, about 25 people met in a pub for the warm-up party. I was introduced to what the British consider beer (I’d rather call it Mock Beer or Beer Doubles) and quickly got into smalltalk with the other conference attendees. Since the Conf would start at 9am the next day, I left at about 11pm to get some sleep.</p>
<h3 id="day-1">Day 1</h3>
<p>The PHP Unconference in Manchester is the first spin-off of Hamburg’s PHP Unconference. So it was no suprise that a good quarter to half of the 100 attendees were german. Judith Andresen kicked off the conference with a short speech before she explained how the Session voting works: you got four votes per day, which you can use to vote for any available Sessions. The Sessions with the most votes wins. There is two Sessions in parallel.</p>
<p>The first talk I attended was <a href="http://www.lornajane.net/pages/about.html">Lorna “lornajane” Mitchell</a>’s <strong>“Speaking Tips for Developers”</strong>, which I liked very much. Lorna gave a highly enthusiastic talk with lots of useful advice for anyone who ever wants (or has) to speak in front of an audience.</p>
<p>I heard <strong>“Dealing with Errors”</strong> by James (last name?) then. I didnt agree on all the suggestions on how Error Handling should be used in PHP, but all in all, the Session was a good round-up of the various error handling mechanisms.</p>
<p>After that I saw <a href="http://joind.in/talk/view/2723" title="Volker Dusch as joind.in">Volker Dusch</a>’s talk <a href="http://www.slideshare.net/Edorian/php-unconference-europa-clean-code-stop-wasting-my-time" title="Session Slides"><strong>“Clean Code - Stop wasting my time”</strong></a>. The talk mainly focused on superfluous commenting in source code, doc blocks and commit messages. Again, quite interesting and also quite entertaining due to Volker’s ranting presentation style.</p>
<blockquote>
<p>It’s not so much about the talks than about the coffee breaks - Judith Andresen</p>
</blockquote>
<p>Along the lines of that quote I skipped the next session to meet <a href="20">Mark Baker</a> of PHPExcel then. I only knew Mark from StackOverflow so far and was happy to finally meet him in person. Was a pleasure.</p>
<p>The last session of the day was Arne Blankert’s talk <strong>“PHPDox – an alternative to PHPDocumentor”</strong>. PHPDox aims to finally supersede the aged PHPDocumentor tool. At the time of the conference, phpdox was nearing completion and looked quite promising already. It’s available on github.</p>
<p>After that it was socializing again. The conference venue, Pitcher and Piano, is a bar chain so we didnt have to relocate for the evening. The second floor was reserved for us. I spent quality time with good talking and a couple of free drinks sponsored by the conf organisers before heading back to the hotel at about 11pm again.</p>
<h3 id="day-2">Day 2</h3>
<p>When we arrived on the second day, they were still cleaning the room. So there was some delay before the voting and the sessions could start.</p>
<p>I attended <a href="http://www.slideshare.net/janosch007/20110218-janosch007-teambulildingkey" title="Session Slides"><strong>“Building a successful development team”</strong></a> held by Stefan Priebsch and Judith Andresen. This talk was an open discussion about the topic. Although there was some good points mentioned what makes a good team and what is hampering it, I felt the discussion was too superficial. But interesting nonetheless.</p>
<p>After that I saw the completely PHP-unrelated talk <strong>“HTML5 and Friends”</strong> by Patrick Lauke, Web Evangelist at Opera. This was a very thorough, professional and lengthy talk and Patrick had to continue it long into the lunch break to finish it. It couldn’t lessen my bias towards HTML5 though, as I don’t believe in “bling”.</p>
<p>> HTML5 is HTML4 with added bling - Patrick H. Lauke</p>
<p>Then I heard <strong>“Automated Release Procedures for the Web / DB Versioning and Deployment”</strong>. This was an open discussion again and I didn’t get too much out of it for myself. I like to leave a Session with at least one “I have to try that at home” thought.</p>
<p>The final session was <strong>“Setting up Jenkins CI for PHP Projects”</strong> held by Sebastian Bergmann and Volker Dusch (again). They introduced their <a href="http://jenkins-php.org/">PHP Template for Jenkins</a> and ran through setting up the Continuous Integration Server for usage with PHP QA Tools, like phpunit, pdepend, phpmd and so on. Very useful talk.</p>
<p>After that the organisers held a short closing speech and were (rightfully) applauded by the remaining attendees.</p>
<h3 id="venue">Venue</h3>
<p>Originally, another venue was considered. But because there wasn’t enough tickets sold when the venue was finalised, the choice was made for the Pitcher and Piano. So, next year, buy your tickets early and give the organizers some more financial room for planning.</p>
<p>Like already mentioned, Pitcher and Piano is a bar chain. Doing a conference in a bar works, as long as there is no other visitors. Unfortunately, the bar would allow other visitors into the bar though. Naturally, there noise level rose the later the day. This was somewhat annoying when attending talks upstairs, because music and talking from the main bar would disturb the speakers. Apart from that, the venue worked suprisingly well for me.</p>
<h3 id="catering">Catering</h3>
<p>Let’s admit it: the PHPUnconference in Hamburg spoiled me. You get breakfast, lunch, cake (not a lie) and unlimited coffee, tea and softdrinks for free. All very tasty and easily on par with the catering at a commerical conference, like IPC. If there was no talks at all, I’d still attend for the food alone.</p>
<p>I had expected a similar pampering in Manchester. I didn’t book breakfast at my hotel and I didn’t bring any drinks. Both mistakes, because there wasn’t any breakfast and no drinks during the day, except for coffee, tea and lemonade. All of these were made from tap water, which I wasn’t the only one who felt tasted odd, <a href="https://twitter.com/antz29/status/38943134884970496">quoting</a>:</p>
<p>> Wondering if they use canal water for the tea and coffee #phpuceu - antz29</p>
<p>Because of that I bought all my drinks at the bar instead (until we got our vouchers for the party).</p>
<p>The lunch on both days was solid. So was the dinner on the first day. I remember there was lasagna, chili, curry and assorted salads and side dishes. Vegetarians had their options, too. Some attendees told me they felt the food tasted rather bland. I felt it was okay (and there was salt and pepper available anyways). So, nothing to complain about here.</p>
<h2 id="php-days">PHP Days</h2>
<p>As part of their sponsoring, <a href="http://thephp.cc" title="Website of thePHPcc">thePHPcc</a> aka <a href="http://sebastian-bergmann.de" title="Website of Sebastian Bergmann">Sebastian Bergmann</a>, <a href="http://priebsch.de/about" title="Website of Stefan Priebsch">Stefan Priesch</a> and <a href="https://twitter.com/arneblankerts" title="Arne Blankerts on Twitter">Arne Blankerts</a> offered a two day training after the two days conference. All training fees would go directly to the Unconf, so they actually held the training for free. Because I had already attended both <a href="http://php-summit.de/" title="Website of the PHPSummit series of trainings (german)">PHPSummit’s</a> held by thePHPcc last year and found them very valuable, I was eager to participate in this training.</p>
<p>The PHP Days were held at the Manchester Conference Center with just eight attendees (five of them german). All of us already knew a fair share about PHP, so discussions were at an enjoyable intermediate to expert level. It’s also quite fun to see thePHPcc lecture together, as one of them will usually always play <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Devil%27s_advocate" title="Wikipedia on Devil's Advocate">Devil’s Advocate</a>. Plus, there will a good portion of <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Geek_humor" title="Wikipedia on Geek Humor">geek humor</a> involved.</p>
<p>Since we could decide where we wanted this training to be headed, we decided to build a <a href="https://github.com/thePHPcc/SplitOut" title="Joind.in clone on GitHub">joind.in clone</a> (we didn’t finish it though). So we discussed the problem domain while thePHPcc would write the code and the UnitTests for us. As the code evolved and domain knowledge got better, we would apply needed refactorings.</p>
<p>Inbetween there was lunch, tea, coffee and cookies.</p>
<p>On the second day, thePHPcc showed us how to create a minimal MVC framework around our new Domain classes. We also talked about how to use the Dependency Injection Principle to avoid tight coupling in our classes. And we talked about how to properly divide functionality into framework, application and domain classes to get the responsibilities right. This was very insightful, even for seasoned developers. The last two hours of the training, we talked about how to deploy our application.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Despite a few shortcomings, I really enjoyed PHP Unconference Manchester. It was a great event with great people and good talks. I am looking forward to attend next year.</p>
<p>The PHP Days training was fantastic and I can happily recommend it to any seasoned developer. Looking forward to attend this next year again as well (if it’s offered).</p>
<p>In short: thanks to everyone who made these four days possible and awesome.</p>
Becoming a Zend Certified Engineer 5.32011-01-20T00:00:00+00:00http://blog.gordon-oheim.biz/Becoming-a-Zend-Certified-Engineer<p>I took and passed the Zend Certified Engineer PHP 5.3 exam recently at my local Pearson Vue Test Center. I bought the certification bundle in early 2010 already. But due to a limited time budget, taking the exam had to wait until early January 2011. Now I can pride myself with … well, with having passed it. Or as the certificate puts it</p>
<blockquote>
<p>Has successfully completed the test requirements and demonstrated the knowledge and skills to be recognized as a Zend Certified Engineer PHP 5.3</p>
</blockquote>
<p><img src="/assets/posts/2011-01-20/zce-certificate.jpg" alt="My ZCE certificate" /></p>
<h2 id="what-does-it-mean-to-be-a-zce">What does it mean to be a ZCE?</h2>
<p>I think the text on the certificate is appropriate. In my opinion, passing the test requirements says very little about being able to successfully pass the real-world requirements on your next project. It wouldn’t be fair to expect that from a test like this anyway. Though the testimonials on Zend.com suggest different, I also wouldn’t expect the certificate to help too much with job offers either. If anything, it might give you a headstart. But it’s likely not enough to make you win the race. Or as someone on StackOverflow put it:</p>
<blockquote>
<p>The Value of an Zend Certified PHP Developer, for me personally, only lies in the fact that we can skip the “is he/she a complete moron that knows nothing about programming at all” - <a href="http://stackoverflow.com/questions/4277608/what-do-i-need-to-know-before-i-can-call-myself-a-php-programmer/4277696#4277696">edorian</a>.</p>
</blockquote>
<p>While that quote is a bit drastic, the author gives some valid points about professional PHP development later on. PHP has evolved a lot in recent years. So have the available frameworks, tools and methodologies. These are out of scope for the exam though. The exam only tests your working knowledge of PHP and it’s API. Passing it ensures you have a good and necessary foundation. Nothing more, nothing less.
Tell me more about the exam</p>
<p><a href="http://www.zend.com/en/services/certification/faq#faq15">Because I had to cross my heart and swear to die</a> not to tell anyone about the actual questions in the exam, I cannot write too detailed about it. I guess it’s okay to give a few hints as to what to expect from it though, since that is openly available in the <a href="http://www.zend.com/en/services/certification/faq#faq4">official ZCE FAQs</a> anyway.</p>
<p><a href="http://www.zend.com/en/services/certification/php-5-certification/">The exam is a collection of 70 questions, covering a good range of PHP and web-related topics</a>. The questions are either multiple choice or free input. Question tasks include analyzing code snippets for what they are doing. Or they might ask for appropriate functions, methods or interfaces applicable in a given scenario. There is also the occasional question about Design Patterns (at least in the Mock Exams).</p>
<p>Unfortunately, there is also a good portion of what I like to call “memo-questions”. These will ask you about argument order or which variation of a function name exists. Personally, I find those type of questions completely pointless. If I forgot whether the <code class="highlighter-rouge">$haystack</code> or the <code class="highlighter-rouge">$needle</code> comes first, I know where to look. Same for function names. Those questions should definitely be ditched.</p>
<p>You do not get penalized for wrong answers. If you don’t know an answer, guess. To my knowledge, the questions are picked randomly, so no test is alike. There is some logic that makes sure you get a certain amount of questions from certain areas. Somehow they have to make sure this is a PHP 5.3 exam, right?</p>
<p>You got 90 minutes for the exam, which is plenty. I finished 15 minutes earlier. You can mark questions during the exam, which makes reviewing your answers in the end quite easy. Once you are satisfied with your answers, you submit them. You’ll get the result immediately. If you pass, you’ll get listed with the <a href="http://www.zend.com/en/yellow-pages#show-ClientCandidateID=ZEND016055">Zend Yellow Pages</a> in a day or two. A few days later, you’ll receive your official certificate from Zend.
How did you prepare for the exam?</p>
<p>I bought the ZCE certification bundle. It contained the official Study Guide, ten Mock Exams and the voucher for the exam. The Study Guide and the Mock exams are for the ZCE PHP5 exam. Given that I had less than a dozen or so questions about PHP5.3 in the real exam, I consider both to be still well suited for preparation. I mostly ignored the Study Guide and only glanced through it to get an idea of what areas I should be knowledgable of.</p>
<p>Like their name suggests, the Mock Exams simulate the actual exam. I felt those are quite helpful to find out what to expect. I did two of the Mock Exams and passed them both with an “Excellent” grade immediately. You get a detailed report in the end, telling you how you fared in certain areas. Obviously you should improve your knowledge in those areas you scored low.</p>
<p>However, the best preparation is to actually read and write working code.
So the exam was easy?</p>
<p>No. Actually I was suprised when I took the exam. Maybe I was just unlucky but there was a number of questions where I was unsure or had no clue. Unlike in the Mock Exams you do not get a detailed report for the real exam, so I don’t know how I fared compared to the Mock Exams. But they definitely felt easier. I wouldn’t suggest to take the exam lightly or without passing the Mock Exams with high grades.
What others had to say</p>
<p>Find out how other developers think about the Zend Certified Engineer 5.3 exam and how they prepared for it:</p>
<ul>
<li><a href="http://www.dragonbe.com/2010/10/preparing-for-php-53-certification-exam.html">Michelangelo van Dam: Preparing for php 5.3 certification exam</a></li>
<li><a href="http://www.evilprofessor.co.uk/334-zend-certified-engineer-zce-5-3">Steven Lloyd Watkin: Zend Certified Engineer (ZCE) 5.3</a></li>
<li><a href="http://www.lornajane.net/posts/2010/Preparing-for-ZCE-5.3">Lorna “lornajane” Mitchell: Preparing for ZCE 5.3</a></li>
<li><a href="http://devzone.zend.com/article/12647-Passing-the-ZCE-PHP-5.3-certification-exam">DevZone: Passing the ZCE PHP 5.3 certification exam!</a></li>
<li><a href="http://www.sjoerdmaessen.be/2010/12/30/passing-the-php-5-3-zce-exam/">Sjoerd Maessen: Passing the PHP 5.3 ZCE exam</a></li>
</ul>
Why Singletons have no use in PHP2011-01-17T00:00:00+00:00http://blog.gordon-oheim.biz/Why-Singletons-have-no-use-in-PHP<p>I am pretty sure everyone working professionally or semi-professionally has heard, seen or worked with a <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Singleton_pattern">Singleton</a> before in one way or the other. For those of you who never heard of it, let me reiterate the purpose of that <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Design_pattern_%28computer_science%29">Design Pattern</a>:</p>
<ul>
<li>Make sure there can be only one instance of a class at any time.</li>
<li>Provide global access to that single instance from anywhere within your application.</li>
</ul>
<p>You’ll often find Singletons as wrappers around database adapters to limit the amount of connections. Another popular use is to make Front Controllers or a Registry into Singletons.</p>
<h2 id="implementing-singletons">Implementing Singletons</h2>
<p><img src="/assets/posts/2011-01-17/singleton-class-diagram.gif" alt="UML class diagram for a Singleton in PHP" /></p>
<p>Unlike some other patterns, creating a Singleton is easy.</p>
<ul>
<li>Add a static <code class="highlighter-rouge">getInstance()</code> method to allow global access.
<ul>
<li>Call the Singleton’s constructor on first call</li>
<li>Assign the newly created instance to the static <code class="highlighter-rouge">$instance</code> property.</li>
<li>Return <code class="highlighter-rouge">$instance</code> on subsequent calls.</li>
</ul>
</li>
<li>Make <code class="highlighter-rouge">__construct()</code> private to prevent direct instantiation from outside.</li>
<li>Make <code class="highlighter-rouge">__clone()</code> private to prevent cloning from outside.</li>
<li>Make <code class="highlighter-rouge">__wakeup()</code> private to prevent deserializing from outside.</li>
</ul>
<p>There used to be a similar sample implementation in the PHP Manual as well (now removed). <a href="https://secure.wikimedia.org/wikibooks/en/wiki/Computer_Science_Design_Patterns/Singleton">Variations of that implementation exist in other languages</a>. In PHP this one is the dominant variant though, mainly due to language constraints.</p>
<p>However, despite it’s apparent usefulness and wide adoption, the Singleton is also controversial. Many developers see it as an AntiPattern nowadays and I tend to agree with them.</p>
<h2 id="singletons-are-not-unique-snowflakes">Singletons are not unique snowflakes</h2>
<p>In languages where objects live in an application server, Singletons can be used to keep memory usage low. Instead of creating two objects, you reference an existing instance from the globally shared application memory. In PHP there is no such application memory. A Singleton created in one Request lives for exactly that request. A Singleton created in another Request done at the same time will still be a completely different instance. And it will occupy it’s own memory. Those instances are not linked to each other. They are completely isolated, because PHP is a Shared-Nothing architecture. You do not have one single unique instance, but many similar instances in parallel processes. Thus, one of the two main purposes of a Singleton is not applicable.</p>
<h2 id="dont-construct-twice-its-all-right">Don’t construct twice, it’s all right</h2>
<p>Advocates of the Singleton in PHP often argue it’s still useful to be able to limit an instance within a single request. The aforementioned database classes being the most prominent example. But the much easier solution would be simply not to instantiate a second instance. If anyone can make sure there is just one instance, it’s the developer. If you need to have the same instance in many classes, use <a href="http://fabien.potencier.org/article/11/what-is-dependency-injection">Dependency Injection</a>. <a href="http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne">Just create one</a>, inject everywhere. That will also save you the hassle of deconstructing your Singleton once you notice you need a second instance of it all of a sudden.</p>
<p>Another example where Singletons are often applied but don’t make sense is classes like <a href="http://martinfowler.com/eaaCatalog/frontController.html">FrontControllers</a>. While conceptually it makes sense to say “There may be only one FrontController”, it is superfluous to ensure it from an architectural viewpoint. A FrontController is usually instantiated only once in your application’s control flow anyway. If you don’t write a new Foo; anywhere else, you already made sure there is just one instance. So <a href="https://secure.wikimedia.org/wikipedia/en/wiki/You_ain%27t_gonna_need_it">you ain’t gonna need</a> the Singleton here. Don’t express concepts in your code that are never used.</p>
<h2 id="dont-shoot-yourself-in-the-foot">Don’t shoot yourself in the foot</h2>
<p>The Singleton’s other purpose (to have a global access point to the instance) is undesirable in PHP. The desire for that usually stems from having an architecture where objects pull in their dependencies. Like any globals and statics, the Singleton’s <code class="highlighter-rouge">getInstance()</code> method creates coupling to the global scope. <a href="http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html">This makes Unit-Testing harder</a>. There is ways to mitigate this, but in general, the cost to mitigate is higher than to simply avoid the Singleton in favor of Dependency Injection. This is especially true in those situations, where the Singleton is applied but never instantiated twice anyway.</p>
<h2 id="closing-notes">Closing Notes</h2>
<p>When working with PHP, Singletons cannot live up to their full potential due to PHP’s Shared Nothing architecture. They are also introducing a number of undesirable disadvantages that will make your application less maintainable and harder to change. And to add another sure sign that you should be wary of the Singleton: even <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Erich_Gamma">Erich Gamma</a>, one of the pattern’s inventors, <a href="http://www.informit.com/articles/printerfriendly.aspx?p=1404056">doubts the Singleton nowadays</a>:</p>
<blockquote>
<p>I’m in favor of dropping Singleton. Its use is almost always a design smell</p>
</blockquote>
<p>Hopefully this is enough to make you reconsider next time you think about using a Singleton. Should you still have trouble deciding, use the following cheatsheet:</p>
<p><img src="/assets/posts/2011-01-17/Singleton.png" alt="Helpful diagram in case you forget whether you need a Singleton" /></p>