The Secret Lives of Timer Objects

One of the better side-effects of working in memory-managed languages is that you don’t have to bother with manually cleaning up references. This removes a huge chunk of busywork for developers who have one less thing to get their heads around. Allocate an object, use it, and forget about it. The garbage collector will get around to it eventually and clean it out.

What could be simpler?

Great Power, Great Responsibility

However, with ActionScript 3, the bar has been raised substantially. This new incarnation adds a slew of APIs that increase its expressiveness and capabilities. Yes siree! ActionScript is no longer a toy language whose primary arsenal is gotoAndPlay(). There’s an extensive library of native classes that can do stuff like drawing on screen, playing audio, fetching text and binary data from all sorts of data sources, or even launching and communicating with other applications.

Take that, Java!

Several of these features mean that its legacy garbage collection techniques have to be replaced with less aggressive methods to identify unused memory. This in turn requires more developer intervention than before to identify which references are no longer required and which ones must be left untouched. The new AS3 garbage collector uses reference counting and mark sweeping (both techniques are covered by Grant Skinner here). And while things are still better than completely manual memory management, building complex or long-running applications requires that the developer have at least a passing understanding of how memory is allocated, references stored, passed around and cleared, and the potential for memory leaks in the midst of all this.

This is where the typical ActionScript programmer stumbles, mainly because people programming in AS3 often do not have a formal background in computer science or programming and have usually learned the language on their own through books or online tutorials. It is not uncommon to find ActionScript developers for whom this is their first taste of programming.

Our Subject for Today

One subtle pitfall is the Timer object which is used to run code on a specific time sequence. This class consolidates the setTimeout and setInterval methods. The API is pretty straightforward – create an instance of the class with its delay and repeat count properties, set up listeners which are triggered at the end of each delay or after the number of delays specified by the repeat count are completed, and finally, call the start() method to begin the countdown.

A Timer object is different from other types of objects because the garbage collector does not clear it unless it is stopped, even if there are no active references to it.

Let’s repeat that.

A Timer object is not cleared by the garbage collector as long as it is running, even when its references are set to null or the variable goes out of scope, and it continues to fire TIMER events as long as it is active.

The only way to clear the object from memory and stop events from being fired is to stop it using the stop() or reset() methods.

The following piece of code illustrates the permanence of Timer objects which haven’t been stopped.

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    public class Main extends Sprite 
    {
        public function Main():void 
        {
             var t:Timer; // Create timer as a local variable

             t = new Timer(1000);
             t.addEventListener(TimerEvent.TIMER, this.m_tick);
             t.start(); // Reference ends here; Timer continues to exist and trigger events
        }

        private function m_tick(e:TimerEvent):void
        {
             trace("tick");
        }
    }
}

This may look like a design flaw in the language to the casual passer-by and elicit a very obvious question.

“Everything else is cleared automatically. Why leave behind timers?”

Some thought on the subject will make you realize that the language designers at Adobe weren’t off their rockers after all. This behaviour is by design. In the example code shown above, ‘t’ is a local variable inside the constructor. When the function ends, the variable goes out of scope and there are no more references to the Timer. If the garbage collector cleared it out, it would not fire any events at all. This would essentially mean that a developer could only assign Timer objects to those variables that remain in scope for as long as it is supposed to run, such as member variables inside a class.

Conversely, a Timer instance which remains active with no way for it to be accessed and stopped is terrible. The object continues to maintain references to listeners and triggers events on them regularly. Listeners can never be garbage collected either because their reference count never goes down to zero. And finally, each active timer occupies a slice of CPU time, bringing the processor down to its knees gradually.

The Timer object always passes a reference to itself in the target property of the TimerEvents it triggers. The listener can use this reference to stop the Timer. When the listener function ends, the event object goes out of scope and is cleared, taking the reference to the Timer object along with it and in turn, making it available for garbage collection.

Here is an example that illustrates how this memory leak can inadvertently occur.

package 
{
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    public class Slideshow
    {
        private var m_timer:Timer;

        private var m_isActive:Boolean;

        /**
         * Example how not to use a timer
         */
        public function Start():void
        {
             this.m_timer = new Timer(5000); // Create and start a new timer
             this.m_timer.addEventListener(TimerEvent.TIMER, this.m_next);
             this.m_timer.start();
        }

        private function Pause(e:TimerEvent):void
        {
             this.m_isActive = false;
        }

        private function m_next(e:TimerEvent):void
        {
             if (!this.m_isActive) return;

             // Code to move to next slide
        }
    }
}

In the example above, the programmer using this slideshow component is expected to call removeChild() to remove it from the stage. However, because the component does not stop the Timer when it is removed, it will continue to fire the TIMER event for as long as the application is run, and also prevent the memory used by the component from being garbage collected by holding a reference to its m_next method. If multiple instances of the slideshow object are created and disposed using removeChild(), their timers will continue to fire and none of the components will actually be cleared from memory.

Creating an Underwater Effect in ActionScript

ActionScript is very well suited to creating old-school demo effects due to its rich drawing API and absence of memory management. Speed would have been a concern a few years ago, but as long as you’re not replicating Heaven7, current releases of Flash player should still be able to handle complex animations with minimal performance problems.

Let me show you a simple wave effect, reminiscing of looking at an object through a wall of water.

Demo effects require a program structure that redraws the entire screen several times every second. The faster the screen refresh, the smoother the resulting animation, at a commensurately higher computation penalty. While traditional languages like C require some kind of a timer mechanism, Flash abstracts away the timers into a frame-rate. We can set up a handler to listen to the ENTER_FRAME event and refresh the screen every time it is triggered.

Demo effects implemented in C often use direct access to the display hardware for performance reasons. Since Flash does not provide direct access to physical devices, we must settle for using the BitmapData class as our drawing buffer and optimize our code within the bounds of its API.

But before we get around to simulating our effect, let us first spend some time understand the principles behind how it is created.

The Sine Wave

A sine wave is mathematical function that plots a smooth, repetitive oscillation and is represented in its simplest form as y(t) = A · sin(ωt + Φ) where A is the amplitude or peak deviation of the function from its centre position, ω is the frequency and specifies how many oscillations occur in a unit time interval in radians per second and Φ is the phase, which specifies where the oscillation cycle begins when t = 0.

With this information we can create a simple function to plot a sine wave.

public function Draw(e:Event):void 
{
    var x1:Number = -1;
    var x2:Number = -1;
    var y1:int = -1;
    var y2:int = -1;
    var amplitude:Number = 120;
    var frequency:Number = 1 * Math.PI / 180; // Convert degree to radians

    for (x1 = 0; x1 < 320; x1++)
    {
        y1 = Math.round(amplitude * Math.sin(frequency * x1)) + 120;
        DrawingUtils.lineBresenham2(this.m_bd, x1, y1, x2, y2, 0xFF000000);
        x2 = x1;
        y2 = y1;
    }
}

[swf]http://www.notadesigner.com/wp-content/uploads/2012/10/wave.swf, 320, 240[/swf]

We use the Bresenham line drawing algorithm instead of setPixel to plot the curve on the bitmap for better fidelity.

Image A: The image is taller than the red viewport

Creating Waves with Images

The same principles can be used to create a wave effect on an image. Instead of plotting points on a canvas, columns of an image are scaled up or down depending upon the shape of the wave. The image is scaled down at points where the wave forms a crest and scaled up wherever the wave forms a trough.

Image B: Extract a single vertical slice
Image C: Scale the extracted portion
Image D: Paste the slice back into the image

Because of the scaling required, the image we use is larger than the viewable area. Image A illustrates this. The red outline is the viewable area of our movie, whereas the image used is taller than that. If the image is not tall enough you will see white patches at the bottom of the movie when the animation begins.

Each time the screen is to be refreshed, the function cycles over all the columns in the image. The columns are 1 pixel wide in the movie, but for illustration, image B shows the columns as 40 pixels wide. Image C shows how the extracted image column is then scaled down.

When all images are placed next to each other, they appear to make a wave, as shown in image D. While the effect looks very blocky in this illustration due to the wider column widths used, thinner columns used in the final movie give a smoother output.

Further fine-tuning can be done by changing the wavelength of the sine wave. A large value is used in the example below, causing all the columns in the image to shrink and expand at almost the same rate. A smaller value used in its place would have caused a broad discrepancy in the scaling values for each column. Having columns with both large and small values in the same frame would cause a wider range of distortion in the image, and speed up the motion. Effectively, frequency can be used to increase or decrease the speed of the animation, simulating choppy or calm waters as needed.

The function we use is as shown below.

public function Draw(e:Event):void
{
    var img:int;
    var wd:int;
    var y:Number;
    var mx:Matrix;

    for (y = 0; y < 240; y++)
    {
        img = 0; 
        wd = Math.round(Math.sin(aa) * 20) + 320;
        mx = new Matrix();
        mx.scale(1, wd / 320);

        this.m_bd.draw(this.m_rg[img], mx, null, null, new Rectangle(0, y, 320, 1), true);
        aa += 0.01;
    }

    aa = ab;
    ab += 1 * Math.PI / 180;
}

[swf]http://www.notadesigner.com/wp-content/uploads/2012/10/underwater.swf, 320, 240[/swf]

Underwater in Egypt used under CC from http://www.flickr.com/photos/ehole/ / CC BY 2.0

The only difference we need to make in our scaffolding code is to call the Draw effect repeatedly when trying to animate the wave effect, whereas drawing the sine wave can be done by calling the function just once on startup.

The entire codebase with both the effects and scaffolding code is available for download here. To change the effect shown, change the value of the m_fxName variable in Main.as to either SineWave or WaveEffect. New effects can be added by extending the BaseEffect class and changing the value of the m_fxName variable to the newly created class name.

Mathematical Elegance in Programming

Project Euler is a collection of mathematical problems for the programmer who enjoys taxing his brain cells once in a while. The problems are ordered to be successively difficult to solve, which explains why, as of today, 91,510 people have solved problem one, while problem 283 is solved only by 9 people. Not only are they successively more taxing, but going through so many problems itself is a tedious task that requires mental stamina even when taken in installments over several days.

Understanding the sum of numbers from 1 to N

Diagram A

Diagram A shows a square with each side 10 units long. A green diagonal cuts the square into two equal triangles. The number of squares making up the square equals 10 x 10 = 100.

Diagram B shows one half of the triangle, whose base and height are 10 units for a total of 55 cells. The number of cells can be calculated by adding the number of cells in each column, i.e. 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 55.

A similar blue triangle is placed above the red triangle in diagram C, in a way that both triangles are touching but do not overlap. Both triangles encompass 55 units and have sides of 10 units each. They combine to make a rectangle that is 10 units wide and 11 units tall. The total number of cells in the rectangle is 55 + 55 = 10 * 11 = 110.

Diagram B

Thus it can be seen how the total number of cells in one triangle (i.e. N + (N – 1) + (N – 2)…+ 1) can be computed by calculating the area encompassed by a rectangle that is N * (N + 1) and dividing the result by 2.

Thanks Reddit!

The good part is that solving a problem helps an individual build an insight that is useful while solving another one later down the line.

The first problem in Project Euler asks to add all the natural numbers below 1000 which are multiples of 3 or 5. The straightforward way to resolve this is to use a loop from 1 to 999 that uses a modulus operation to evaluate each integer between 1 and 1000 with 3 and 5, adding the ones that are perfectly divisible and discarding the rest.

Diagram C

Here’s an implementation of this code in ActionScript.

var sum:uint = 0;
for (var i:uint = 1; i < 1000; i++)
    if ((0 == i % 3) || (0 == x % 5)) sum += i;
trace(sum);

But the secondary goal of these problems is to have an implementation that can return an answer in less than one minute. Problem one is not all that taxing for a modern computer, making even a naïve implementation run well within the required time frame. But complexity for later problems increases exponentially, making the selection of a fast algorithm very essential.

Hence, it is required that one should understand the mathematical principle behind each problem in order to write an efficient solution.

A step-by-step breakdown of the complex, but more efficient solution goes as follows.

The smallest multiple of 3 greater than 1 is 3 itself.

The largest multiple of 3 less than 1000 can be computed easily.

multiples = (1000 - 1) / 3
multiples = 333.33
multiples = floor(remainder)
multiples = 333

The floor() function is used to discard the decimal part of the result by mapping the real number into the previous smallest integer.

The result, 333, is the number of multiples of 3 between 1 and 1000. So the sum of these values can be computed by adding the multiples together.

(1 * 3) + (2 * 3) + (3 * 3)...+ (333 * 3)
= 3 (1 + 2 + 3...333)

The sum of numbers between 1 and n is n (n + 1) / 2. So the sum of 1 to 333 is 333 (333 + 1) / 2, which is 55,611. Multiplying that by 3 gives you 166,833, which is the sum of all multiples of 3 between 1 and 1000.

The same method can be used to compute the sum of multiples of 5 between 1 and 1,000, to get a result of 99,500.

The problem asks to compute the sum of multiples of 3 or 5. What we have done so far is compute the sum of multiples of 3 and 5. To remove the overlap between the two sets, compute the least common multiple of the two numbers, which is 15, and calculate the sum of multiples of that number between 1 and 1000. Subtracting that set from the first two will result in a set which contains numbers which are either multiples of 3 or 5 but not both.

The same principle also applies when the sum of multiples of 15 is deducted from the sum of multiples of 3 plus the sum of multiples of 5.

So your final solution is sumOfMultiples(3) + sumOfMultiples(5) – sumOfMultiples(15).

The complete implementation of the program is as follows.

package 
{
    import flash.display.Sprite;

    /**
     * Project Euler solutions entry point
     */
    public class Main extends Sprite 
    {
        public function Main():void 
        {
            var p:IProblem = new Problem1();
            trace(p.solve());
        }
    }
}

package  
{
    /**
     * If we list all the natural numbers below 10 that are
     * multiples of 3 or 5, we get 3, 5, 6 and 9. The sum
     * of these multiples is 23.
     * 
     * Find the sum of all the multiples of 3 or 5 below 1000.
     */
    public class Problem1 implements IProblem
    {
        public function solve():uint
        {
            var limit:uint = 999;
            trace((sumOfMultiples(3, limit) + sumOfMultiples(5, limit)) - sumOfMultiples(15, limit));
        }

        private function sumOfMultiples(factor:uint, limit:uint):uint
        {
            return factor * sum1toN(limit / factor);
        }

        private function sum1toN(n:uint):uint
        {
            return Math.round((n * (n + 1)) / 2);
        }
    }
}

Director Done Right – Why Adobe Must Promote AIR

When I leapt headfirst into multimedia development a decade ago, there was just one go-to product for all interactive needs – Macromedia Director. With origins in the vastly successful MacroMind VideoWorks application, Director had a strong pedigree in multimedia production. Regular updates of the product over more than a decade had converted the original VideoWorks into a development environment with an object-oriented programming language of its own called Lingo. It also supported external plug-ins for added features, ran on Windows and Macintosh computers and supported all media formats of the day – plain text, images, sound and video. The greatest plus point of Director was its ability to create a projector out of the Director file, which was an executable file that bundled the player and the binary file along with any plugins that were used. The projector was guaranteed to work on any system without requiring any additional libraries (except maybe audio and video codecs).

A new age, a new champion

Then the whole web thing happened and Director could not keep pace any more. Macromedia shipped Xtras to support more media formats such as hypertext and Flash, and to make network requests. They also shipped the Shockwave browser plug-in to run a Director file in the browser. But it was no match for the Flash plug-in, which was a fraction of the download. This weighed heavily in the dial-up era back then. Chinks in the development environment began to take their toll. The biggest flaw of Director was that it bundled media and scripts in its working file into a single binary blob and saved it to disk. This meant that version control tools could not diff the scripts against previous revisions. Developers could not collaborate and work upon the same project without leaping through significant loops. The files would sometimes get damaged and become unreadable if there were power failures or other system breakdowns while the file was being saved. There was no easy way to create and reuse libraries. And the eccentric syntax of the Lingo language was a black mark on its developers, who could never gain any repute among people who used “real” programming languages with curly braces.

When Flash began to gain a foothold in the market because of its reach and ease of use, multimedia developers began to move on to the new platform in a steady trickle over the years, until Director became a niche production environment. The situation gave Macromedia a chance to right the problems of Director on a new platform, blank as a clean slate. And they capitalized upon it in a stellar manner. ActionScript quickly morphed from a simple scripting language with a handful of constructs, to a full-blown development environment that supported complex object hierarchies, most OOP principles, a rich API for various tasks ranging from media control to network access, all packaged inside a runtime that was tiny and already available on most of the internet-enabled computers. And it had curly braces.

A web of entanglement

Yet, the biggest drawback of Flash was its sandbox that prevented developers from doing anything beyond the boundaries of the browser. Local file system access was out. Native nested windows were out. Drag and drop was not available. Launching native processes was out. Projector files were slightly more forgiving and allowed read-only local file access and limited spawning of new processes. But this was nowhere close to the unrestricted freedom offered by Director projectors. This in itself was not bad most of the time. But when more serious functionality was needed, ActionScript developers had to depend upon another programming language to get the job done. To be fair, Macromedia, and now Adobe have always done their best to make cross-language interop as easy as possible. We have come a long way from the getURL() calls required in ActionScript 1 to today’s ExternalInterface API. But a dependency meant having to support yet another codebase.

Breaking free

It was heartening then to hear of the Adobe AIR announcement some years ago. Finally, Flash applications could be written to take advantage of local facilities of the system along with the existing media and internet APIs. It was now possible to read and write local files in a meaningful manner. Network utilities could be a lot more proactive and efficient. Applications could update themselves transparently and could support richer desktop paradigms such as taskbar icons and drag-and-drop interactions.

There still isn’t complete unfettered access to the system, the way Director projectors could. But this limitation will remain due to the different security scenario today. Being able to sell AIR as a secure replacement for web applications is highly desirable for Adobe in the face of HTML 5 and the advancing capabilities of browsers. But combined with all the other benefits that Flash offers, along with the reduced development time over other desktop development environments, and instant cross-platform compatibility, this is an insignificant bump.

The only drawback that AIR has over Director is that it requires a separate download of the AIR runtime. At 11 MB, it does not add a significant cost in today’s age. But it is a deal breaker for users without administrative rights. There really should be a way to package the runtime and the application package into a single executable.

HTML is not the only future

There still are naysayers who predict that the Flash platform is dead. All that is needed is wider acceptance and support for HTML 5. But with support for HTML and JavaScript built into AIR (with WebKit, no less), Adobe already has that base covered. And the web is not the do-all and end-all of computing. While having a social networking application online makes sense, personal accounting or mail applications are better kept locally for security and accessibility reasons. And desktop applications have the unique ability to morph into hybrids that work locally as well as with remote services, which is better in some cases than having a web-only application. Most people already use a hybrid application – their mail client. New mails can be downloaded and read when connected online, while still being able to access downloaded emails when working offline.

Sure the W3C is working on writing specifications for similar functionality with HTML 5. But who said choice is bad? Given the sorry state of browser standardization even today, it is more likely that each browser publisher will implement the spec in some half-assed manner that causes subtle differences between them and require someone to invent a shim to fix those incompatibilities. And HTML 5 does not address all the features that AIR supports, including hardware accelerated 3D and filter effects, native menus, file extension registration, drag and drop, advanced sound and video APIs and windowing support beyond the most rudimentary.

In spite of all the advantages that it has, AIR has failed to make major inroads into desktop development. Blame lies squarely on Adobe for failing to promote it well enough. Other than ActionScript developer circles, there rarely is any mention or knowledge of the platform. They really ought to pick up some steam on that front and corner the market the way Director and Flash have done in their time.

How to Write Unmaintainable Code – PHP Redux

How to Write Unmaintainable Code is a satirical piece of programming advice written by Roedy Green a long time ago. That it remains his most popular essay till date speaks volumes about the programming skills of human society as a whole. Collectively, we are either a massive bunch of shit-chucking apes who take this essay seriously, or a small bunch of highly skilled developers seeking relief from daily disillusionment in our work behind its biting humour.

I hope to hell that it’s the latter.

Green’s essay is written with Java and C programmers in mind, but many of the techniques described can be applied to any programming language. Consider this essay as a “lite” version of Green’s to keep us script kiddies from feeling left out.

Write code. Or markup. Or both. Together.

PHP has a very unique ability of allowing the programmer to intersperse program code with HTML markup in the same file by using special PHP tags to identify code blocks. And as with all things PHP, there is more than one way to skin a cat.

<? echo "Hello, World!"; > // What is referred to as the "old style".

<? echo "Hello, World!"; ?> // What is referred to as the "first new style". Note the added question mark in the end tag.

<?php echo "Hello, World!"; ?> // The "second new style" is similar to the first new style and most recommended

<script language="php">
    echo "Hello, World!"; > // What else? The "third new style" of tags
</script>

<% echo "Hello, World!"; %> // And finally, a fourth way that uses ASP-style tags

This in itself opens whole new avenues for abuse for a programmer used to the sharper separation of code and presentation enforced in a more serious language. What’s worse is that the tag rules can be changed on individual systems through the php.ini file. Develop with all style flags enabled. Tell your colleagues that you’re doing it in the interest of maximum compatibility with third-party libraries. For added fun, find (or write your own) library that liberally switches between all five types of tags and make it an indispensable part of your project. Or keep switching coding standards every few weeks until there’s a healthy mix of all types of PHP tags scattered throughout your code. Refuse to replace previously used styles with the current favourite because it’s better to leave well enough alone.

Do not document this anywhere.

This is in the interest of avoiding single-step deployments on a stock (or sane) PHP installation. Force system administrators to find the problem in your code and then comb through the php.ini file for the appropriate settings. Always say that you have security in mind, which is encouraged by having the system administrator read each line of the settings file.

But the ability of the language to intersperse HTML markup even inside if…else or loop blocks evidences the sheer the heinousness that must have enveloped the language designers when they wrote that bit of the specification.

There are so many ways to abuse this “feature”.

A tamer way would be –

<?php if (foo == null): ?>
    <p> Invalid foo</p>
<? elseif (foo == 1): ?>
    <p>Foo is too small.</p>
<? else ?>
    <p>Correct foo entered</p>
<?php endif ?>

A more advanced programmer might use something like this –

<div class="query_output">
    <?
        $sql="select * from names";
        if (db_connect()): ?>
            <p>Error!</p>
        <?php else: ?>
            <p><strong>Names</strong></p>
        <?
            $res = db_query($sql);
            $names = db_result($res);
            foreach ($names as $names): ?>
                <!--span><?php echo $name ?></span-->
                <li class="name"><? echo $name ?></li>
        <? endforeach; ?>
    <? endif; ?>
</div>

By closely coupling the business logic with the presentation layer, your manager will have to assign a qualified programmer to make even innocuous changes to the front-end code rather than assign them to a design trainee. Male lions in the wild mark their territory by pissing on trees. Programmers should mark theirs by pissing all over the front-end markup.

Reinvent the wheel. Poorly

If there’s one thing that PHP is famous for, it’s the rich selection of extremely useful, but badly named functions in its libraries and standard extensions. Make things worse by ignoring the in-built functions entirely and rolling your own instead. Feign ignorance, which is a pretty valid excuse when talking about PHP because it has extensions for everything you might dream about, and some things you might have never even heard of (can you spell Swish-e?).

Write your functions in the most naïve and inefficient manner possible. You get bonus points if it is error prone due to subtle variations in the input.

For example, PHP has an in-built strtotime() function that can convert “about any English textual datetime description into a Unix timestamp”. Ignore it. Take a date/time string and split it into its component values by using hard-coded delimiters. Don’t take regional differences into account. Everybody should just be using ISO 8601 anyways.

Naming is the key

Begin programming before the domain model is fully ready or understood. That way you get to create your own colourful terminology for objects which haven’t been named yet. For example, suppose you’re building a web-based interface for a controller in a bakery. Look up the thesaurus for the term “mould” and use an unrelated synonym such as “die” in place of the mould. Repeated instances of the word “die” will make the maintenance programmer wonder if you wanted to pass a subliminal message on to him through your code.

Take this to the next level by using different naming conventions for the same element. If your database field stores the machine operator’s name in a “username” field, store the value in a variable called “user_machine_op_curr”, “machine_operator_curuser”, “machop_current” and “machine_operator_current_user” in different places where you need the value.

For maximum effect, instead of encapsulating usage of this variable in a single module, apply the RYE principle to litter the code across all the files. Suppose you need a widget to display the active username at the top of the page. Write the query and code to do this on every page with subtle variations in field names and joining random bits of data from unrelated or unneeded tables. The maintenance programmer will have no idea whether the query really needs the other fields, which will dissuade him from refactoring the code into a single module.

Tell everyone who asks that you are caching data for later use in order to improve performance.

Code formatting is hard. Let’s go shopping.

Randomize whitespace rules in your project. Use tabs in some places, spaces in another, or you can even mix and match both on the same line. Aggressively prevent any kind of structure from appearing in the code through indentation. Nested if…else blocks or loops are best for this kind of camouflage. The unwary programmer will not notice a nested loop if it is not indented further than its parent. Compound this complexity with the ability to enter and exit PHP code blocks at random locations within the file.

Repeat Yourself Everywhere (RYE)

Functions and objects are for weenies. Duplicating large chunks of badly formatted code all over the project puts hair on your chest. Even if you are a girl.

This is the ultimate abuse of a maintenance programmer in any language. But by effectively combining the previous principles, PHP gives this technique the potential to become a lifelong nightmare of bugs which are hard to find, fix or test.

Putting on the Pounds

By diligently following all the pointers given above you can be sure to reach file sizes of magnanimous proportions. The ultimate goal is to make a file large enough to timeout the version control server while a network operation is in progress. Make enough of those and the maintenance programmer will be caught between a hard place and a rock. On one hand, there is the fragility of the code which requires frequent commits to keep from making too big a change. On the other there are constant network errors while trying to commit changes to version control.

Database Abuse

PHP’s ultimate utility is its excellent data-processing pedigree. Numerous extensions have been written to enable connecting PHP with different database servers. And the one common thing that all database publishers extol is to consolidate query operations through the use of joins for fewer disk operations and lower network transfer.

Ignore them.

Instead, run multiple queries – one to retrieve the master table and the rest while cycling through the result set to retrieve values from the secondary table, using the current record as the selection criteria. If you have enough values in the master table, this will slow your server down enough to frustrate the end user. Use the techniques mentioned above to obfuscate and entangle your queries with unrelated code to make it resistant to change.

For added joy, create a new connection at random places in your code to the same database server. This will confuse the casual maintenance programmer into thinking that you’re actually retrieving information from two databases, and hence justify you not using a join.

Summary

Perform enough of these activities in a single project and you can be assured of months of job security. The best part about working in a language like PHP is that you don’t have to worry about making it not look maintainable. Legions of bad programmers have given the language such a bad rep that people almost expect PHP code to look bad.

Which kind of makes this whole essay moot, though.