Monthly Archive for March, 2009

Gradual Response

When designing an online server, some high-overhead operations (such as search) tend to decrease performance a lot.

One possibility is to ignore the issue. After all, you can only optimize search so much, and you only have so much money to go around for installing slave databases and extending web farms. The vast majority of small websites developed on a tight budget will tend to use this approach.

This opens the website to denial of service (DoS) attacks where an attacker can hit the server by sending large amounts of requests that take a lot of time to process. Imagine your one-database, one-server web site being hit by a hundred search requests per second—unless you have no content, the search operation will clog the tubes for every other visitor.

The solution is, of course, to limit repeat requests. No legitimate human user will submit ten search queries in ten seconds, so you may choose to detect such requests and prevent them from being executed. This can be done using the session data (very fast) if it’s available, and by persisting IP and timestamp data to the database for session-less visitors.

This creates a different issue: if you trigger the defense mechanism too easily, you can frustrate normal users. But making the trigger less sensitive is harder, because it cannot use the simple “if last request happened less than X seconds ago” approach. Case in point: go to www.magentocommerce.com and use the search box:

  • Enter a first search query, with a small typo.
  • Quickly correct the typo and re-submit the query.

If you did that in less than fifteen seconds (as most programmers certainly can) you will end up with a denial page.

A gradual response is always a good idea. If you get two queries in a row, it can still be a legitimate user. It might be a good idea to choose higher values of N in the “allow only N requests in T seconds” rule, so that it takes N requests to execute.

Another way is to delay the requests instead of simply refusing them. So that the second request in 15 seconds redirects to a “waiting page” for 15 seconds before resolving—it also helps the legitimate user determine when the query is available again, so that they do not search again one second too early and reset the 15-second timer again.

Published Articles

I have recently contributed two articles to two game development books.

These are:

Both are in the gamedev.net collection.

Value Consistency

Jeff Atwood hates PHP. So do I—despite working with it on a daily basis and leading several interesting PHP-based projects to successful completion, I do find PHP to be a disaster in terms of language design, and despite its gradual improvements over the course of its evolution.

And yet, my biggest issue with PHP is the same I have with C and C++ and, arguably, every single language in the C family with the exception of JavaScript.

Some Examples

Consider a simple get-day-name function:

function french_day_name($timestamp)
{
  return array(
    "Dimanche", "Lundi",    "Mardi",   "Mercredi",
    "Jeudi",    "Vendredi", "Samedi"
  ) [(int)date('w',$timestamp)];
}

You feed in a timestamp, and you get the day’s name in French. It relies on the fact that array() is an array literal, which is an expression (you can assign it to a variable or pass it as an argument to a function) and [] subscripting can be used to extract a certain index from an array. Except that this doesn’t work because the syntax does not allow subscripting into an array literal. Contrast this with JavaScript :

function french_day_name(timestamp)
{
  return [
    "Dimanche", "Lundi", "Mardi", "Mercredi",
    "Jeudi", "Vendredi", "Samedi"
  ] [(new Date(timestamp)).getDay()];
}

This is what I call value consistency: if your semantics allow writing array[subscript], then I expect to be able to use an array literal (or any other expression that evaluates to an array) in that expression. As a matter of fact, I don’t know what kinds of expressions support subscripting in PHP, and that makes me feel insecure so I always assign my array to a variable beforehand.

The same happens in other situations as well. For instance, don’t expect to write (new Date(timestamp)) -> getDay() in PHP: there are restrictions on what kind of expressions are allowed on the left-hand side of the object member operator, too.

Also, don’t expect to write:

$obj -> random = $good_random ? 'mt_rand' : 'rand' ;

// Later

$obj -> random(); // Sorry, not a member function

($obj -> random)(); // Sorry, bad syntax

$rand = $obj -> random();
$rand(); // Good programmer, you get a twinkie

That’s right, there are restrictions on what kind of expressions can be used to call functions as well! At least JavaScript is sane about this.

Value Consistency

For consistency, every operation that can operate on an arbitrary value should have a syntax that lets the programmer specify that value as an expression, whether that expression is a literal, an identifier, or any complex expression that ultimately evaluates to an appropriate value.

There are no circumstances under which syntax alone should prevent an expression to be used in a context where another semantically identical expression can be used.

Copy Protection

You’re a software developer, and you’ve just developed a new piece of software that you now want to sell. But there’s the problem: your customers are greedy schemers out to get you. You’ll get one paid download from them, and then they’ll make the software available online for free and you won’t get another cent from it ever.

Never mind, you say, I can always include copy protection in my software!

Arr! Here be bytes and checksums!

Arr! Here be bytes and checksums!

No protection is cracker-proof

Any software that runs on the user’s computer is vulnerable. What you have just given your customer is a complete description of how the program works, and any dedicated cracker can alter that description so that the copy protection behavior is disabled. No amount of skill or cleverness is going to save you here: you can not stop the cracking process, you may only slow it down.

In fact, the objective of the copy protection of most games is just that: to slow down the crackers long enough for the game to make a profit (since most sales for games occur right after its release).

So, you will be looking for the optimal amount of copy protection to include in your game: too much, and you will be spending more money than you’ll ever earn, too little and hundreds of people will be seeding a torrent for your program within one day.

No protection is harmless

The problem with copy-protection is that it needs to determine whether the program is being used in a legitimate way. This is extremely hard to do correctly (even if you ignore the issue of crackers for a moment), because the very definition of legitimate use is complex.

See, an user can use a program if they bought it from the developer. The problem is that your average computer has no biological identification features that could be used to identify the user, so you must rely on other ways of gathering that information such as:

  • Requiring that the user inserts the original CD, connects an USB dongle or enters a key.
  • Using an internet connection for verification.
  • Locking the software to a single machine.

All of these are annoying to the user if they work correctly (can you backup your Wii games, or play single player Portal without an internet connection?), and can be downright damaging to your reputation if you push things too far. In fact, customers have regularly managed to pressure the copy protection away.

What else?

One solution increasingly used by many developers is to go online. You cannot crack World of Warcraft, because the code that runs the game servers … runs on the game servers! If you have no access to code, you cannot make it act differently. So, short of knowing the login/password to an account that was paid for, you cannot connect to the game servers. And, best of all, this kind of protection doesn’t even feel like protection to users: it’s perfectly normal to have to provide a login/password to connect to a multiplayer game (otherwise, how would the game know who you are and who your characters are?) and no one would give away their login/password online because their account might be stolen by others.

So, if you can move any significant part of your operation online, you can have your customers pay for that part (whether this means anti-virus updates, video game servers or content) and it will both feel natural and be immune to cracking.

If we were to broaden these definitions, we could say that anything you can offer which makes the software more valuable is something you can sell. A lot of open source software work this way: you can download our program for free, and if you have any trouble using it or extending it, we’ll be happy to provide help for a fee!

But there’s something else. Something that has to do with how people cheat and steal when they think they can get away with it, unless you remind them that stealing is bad.

A three-step approach

Suppose that your program does not have anything to offer online: updates happen few and far between, there’s no online content and no support. It’s just a simple, ten-dollar tool. You’re not going through a retailer either: you’re small, so you sell your software online, and you cannot rely on any physical security (such as a dongle or a CD).You have three objectives:

  1. To create and amplify the incentives to buy.
  2. To prevent the customers from redistributing their software.
  3. To prevent  the prospects from downloading a free version.

What kind of copy protection do you include?

I would say, none, and make this statement on the sales website:

No Copy Protection

We decided not to include any kind of copy protection in FooBar™. Copy protection always ends up causing trouble to legitimate customers : we don’t want you to remember a registration key, keep your computer connected to the internet or give us a call when you buy a new computer.

We strongly believe that if you paid for it, then you should be able to use it : restricting what you can do with your software is just as bad as downloading paying software for free.

Unlimited Downloads

Once you buy FooBar™, you can download it as many times as you want, and install it on any number of computers you own: just connect to your online account and you will have unlimited access to the latest version of FooBar™.

Warning: revealing your account number and password or giving out your copy of FooBar™ may let other people connect to your control panel and steal the account by changing the password.

What does this message achieve?

  • The absence of copy protection is used as a feature: if you do it, you might as well get a few sales from it. This part is a promise: you won’t be having these issues with our product. Obective 1.
  • The “we strongly believe” part creates a connection with the reader, and shows that we think about his satisfaction instead of our money. It also stealthily introduces the concept that “downloading software for free” is bad. So, if the reader was considering to look for a free torrent of the software, they will feel queasy because it’s “bad”, and because it feels like betraying us when we’ve done so much for them. Objective 3 (and, for a small part, 2).
  • It goes one step further and lets you download and install the software as many times as necessary with no restrictions. If this feature were presented on its own, it would probably feel out of place: people don’t need that. But by placing it right after our copy protection discourse, it actually feels like a natural consequence: “not only do we let you install your software as you wish, but we actually help you do so by providing you with a download”. Objective 1.
  • It warns against the consequences of redistributing FooBar not in terms of “you’re an evil cracker” (accusing prospects of anything is a bad way to turn them into customers), but rather in terms of “evil persons could steal the software from you”. We rely on loss aversion to have people avoid losing a service that, while useful, isn’t necessary for them to use the software, but we also espect smarter customers to infer that if evil thieves can determine the account number from the executable, so can we. Objective 2.

All you need to make this seem plausible is a watermarking process: when someone downloads the software, you give them a copy of the executable that contains the account number and the name of the buyer (readily available in, say, a “Licensed to:” subsection on the “About” menu). The crack in itself isn’t exceedingly difficult to perform: just get a legal version and either distribute it for free or remove the buyer’s name if you wish to protect him.

There’s another way to fight towards objective 3. Where do most people look for pirated software? Peer-to-peer networks, torrent search engines, and the classic search engines. So, if you manage to publish enough incorrect “free versions”, finding an actual free version might end up being too hard for people to find. If your software does cost $10, how long do you expect people to spend looking for a free version? Not much. $10 is what many people spend for lunch.

2D Transforms

A point in a 2D space is commonly identified as an (x,y) pair, representing its distance to the origin along the x-axis and the y-axis. Objects in 2D space have two additional properties that make no sense for mere points: scale and angle (I will ignore here shearing and anisotropic scaling).

A square, scaled and rotated.

A square, scaled and rotated.

An obvious question is, how to represent such transformations in a computer program, such as a video game? The simplest way one could think of is to use a structure that contains:

struct position
{
  float x;
  float y;
  float angle;
  float scale;
};

This works in most situations. Most simple 2D video games will be able to get away with this simple version without much difficulty. But there is one thing that it cannot do easily.

Relative Transforms

Suppose for a moment that the object we’re moving around is a spaceship. That spaceship has one gun at the end of each wing, which means positions (-2,0) and (2,0) relative to the center of the spaceship. Now, the ship is placed at a certain position, rotated and scaled. Where should the bullets be fired from?

What is the absolute position and angle of the guns?

What is the absolute position and angle of the guns?

On the one hand, we have an absolute position (where the ship is, its angle and its scale) and on the other hand we have a relative position (where the gun is, relative to the center of the ship). The objective is to determine the absolute position of the gun. Mathematically, if an object is at position (a,b) relative to an object that is at position (x,y) with scale s and angle θ, then its absolute position (a,’b) is:

a’ = x + s a cos θs b sin θ
b’ = y + s b
cos θ + s a sin θ

But what happens if the ship itself is part of a greater whole? Or what if the gun itself is in fact a turret that can rotate independently around a point on the wing?

To handle this, we define a transform as “something that moves an object from a certain position, angle and scale (the source) to another position, angle and scale (the destination)”. The ship has an absolute transform, which moves it from point (0,0), scale 100%, angle 0° to its actual position, scale and angle. The gun has a relative transform, which moves it from the ship’s position, scale and angle to its actual position, scale and angle.

So, the absolute transform of a gun is obtained by applying the absolute transform (move the ship to where it should be) then the relative transform (move the gun to where it should be based on the ship’s position). And once you have the absolute transform of the gun, you can deduce its position, scale and angle.

The problem is that using the above “position, scale, angle” representation for transforms is not handy, because applying two transforms one after another gets complicated very fast. One solution is to use a matrix, which is a commonly used tool for representing transforms. Another solution is using complex numbers.

Complex Numbers

A complex number is an object of the form a + ib, where a is the real part and b is the imaginary part. Complex number multiplication uses the property that i² = -1. From there, we deduce the rules for complex number addition and multiplication:

(a + ib) + (a’ + ib’) = (a + a’) + i(b + b’)

(a + ib) (a’ + ib’) = (aa’ – bb’) + i(ab’ + a’b)

So, how does this help us? Well, consider our original position/angle/scale approach, call these x, y, θ and s and build the complex number function:

t(z) = s (cos θ + i sin θ) z + (x + iy)

This function represents a relative transform. Calling it on a complex number (a + ib) will return a complex number (a’ + ib’) such that (a’,b’) will be the absolute position of a point that was at relative position (a,b) from the center of the transformed object:

a’ = x + s a cos θs b sin θ
b’ = y + s b
cos θ + s a sin θ

These are the exact formulas we discussed above!

So now, applying two transforms in a row is easy. If gun(z) is the he transform of the gun on the plane’s wing, and plane(z) is the transform of the plane in the world, then the transform of the gun in the world is plane(gun(z)). And since the functions are actually linear complex functions, composing them is exceedingly easy:

t(z) = a z + b
t’(z) = a
z + b’
t’(t(z)) = a’
(a z + b) + b’ = aa’ z + (a’b + b’)

Or, in terms of C++:

struct transform
{
  std::complex<double> a, b;

  transform(double x, double y, double angle = 0.0, double scale = 1.0)
    : a(scale * std::cos(angle), scale * std::sin(angle)), b(x, y)  {}

  transform &operator *=(const transform& o)
  {
    b += a * o.b;
    a *= o.a;
    return *this;
  }

  double x() const { return b.real(); }
  double y() const { return b.imag(); }
  double angle() const { return std::arg(a); }
  double scale() const { return std::abs(a); }
};

transform operator*(const transform &f, const transform &g)
{
  transform result(f);
  return f *= g;
}

Here, t’ * t represents the transform t’(t(z)).

Dear {IPADDR}

I wish to personally thank you for your meaningful contribution on my blog. While posting a link to a pornography site certainly showed one of my articles in a new way that would have certainly enlightened (no pun intended) most of my readers, there are some standards of decency I wish to enforce on this blog and, sadly, I will not be able to publish your comment.

The fact that you posted your comment as admin, with a coincidentally unusual website of nicollet.net and an incorrect yet default mail address of info@nicollet.net was only tangentially involved in my publishing decision.

However, I could not help but notice that your IP is running an unsecure internet-accessible XAMPP-based website. This, in itself, is a bad idea, because that would expose a lot of precious information to random internet users. Besides, I will only restate what phpMyAdmin has already told you:

Your configuration file contains settings (root with no password) that correspond to the default MySQL privileged account. Your MySQL server is running with this default, is open to intrusion, and you really should fix this security hole by setting a password for user ‘.root’.

I am a honest, law-abiding man. I fully understand your ability—nay, your right—to turn the computer at {IPADDR} into a blog-spamming zombie, and I do not wish to interfere with its operation, as that would be illegal in several countries including the one that I am currently living in.

But be aware that many people will not be as supportive as I am of your enterprise. An evil man, a weak-willed webmaster, a law-breaking vigilante, a bandit sans foi ni loi, who would happen to know an ounce of SQL, could easily connect and DROP your databases away. Or perhaps one of the many internet worms that target phpMyAdmin on random web servers might get you in turn?

I sincerely hope this outrageous loss of precious data will not happen to you.

Know what you mean

Bugs appear from one of two possible sources: either you mistakenly wrote something you didn’t mean to write, or you didn’t fully understand the consequences of what you meant to write.

Typical example, first situation:

double degrees_to_radians(double angle)
{
  return angle * 180.0 / PI;
}

The function actually performs a radian-to-degree conversion.

Typical example, second situation:

Posted on <?=date("F j, Y",$post -> date);?>

Although the programmer did mean to print the current date, he did not notice that printing the current date in the server’s time zone might be confusing to users.

Errors of the first kind

These errors are often easy to detect. If a programmer uses the wrong identifier or mistakenly swaps two function arguments, there’s a high probability that the type system will detect the error.

Even if it does not (as in the degrees-to-radians example above) the programmer can specify the expected behavior twice by using a unit test—the probability of an error of the first kind remaining undetected by a unit test with good coverage is slim indeed.

Besides it’s also possible to use the type system to construct error-proof interfaces at the cost of having to write explicit data type conversions manually in some cases.

Errors caused by forgetting to perform a required operation can be easily solved in many languages: a “you forgot to do A before B” error is prevented by having B require the return value of A  (and enforcing that with the type system)—you can’t fwrite() until you get a FILE* from fopen(); a “you forgot to do B after A” error is prevented by using RAII (in C++), using() directives in C#, and creating a function that calls a callback in-between operations A and B.

Errors of the second kind

These errors are much harder to detect, because by definition the programmer does not know and has no way of knowing that his design decisions will cause havoc down the road. You can always force the program to do what you mean by explaining enough times what you mean in excruciating detail, but you can never be sure that what you mean to do doesn’t have hidden flaws that will become glaring later on.

One way of defending against this is to write easily refactored code split up into units that each do one thing (and do it well). This way, when you do notice an error later on, you can reuse most of the smaller units to implement a new solution. Most people think in terms of “If things go wrong, I’ll rewrite the incorrect parts“, but the correct way to think about it is “If things go wrong, I’ll write a new solution using as many parts from the old solution as possible.

Another way of defending against this is to use libraries written by people who have experience with the domain. These people have often encountered many errors of the second kind while working on their projects.

  • Perhaps they thought they could make the database a singleton, only to discover two months later that many businesses do need you to accomodate two databases in your system.
  • Perhaps they thought all online stores share the same inventory, only to discover later on that B2B and B2C stores often have different inventory policies.
  • Perhaps they didn’t know there was a difference between a billing address and a delivery address.
  • Perhaps they learned the hard way that some languages are written right-to-left, or that some languages need UTF-8 to be rendered.
  • Perhaps they saw in the spec that XML uses namespaces, and thus XPath-based traversal needs namespace recognition context to work.
  • Perhaps they had to encounter performance problems before they thought about database master/slave configurations.

These libraries are exceedingly useful, and exceedingly unnerving to the programmer because they forcefully prevent him from making errors of the second type. The consequence is that the programmer first hates the library from preventing him from doing something exceedingly simple (Why the hell can’t I create a string from a byte array?) , then undergoes a painful paradigm shift that forces him to rethink his design before he even writes a single line of code (Oh, I see, I need to specify an encoding. But wait, what’s the input encoding in this function?).

The problem is that excellent libraries tend to make simple things very complicated, which gets them labeled as “enterprise-ish” and hated by the average programmer. Even though the problem they are solving is complicated, and they provide the simplest interface one could think of to that problem.

Stretched Thin

Lately, I have heard people refer to Object-Relational Mapping as being equivalent to the advent of compilers in the grand scheme of things, abstracting away relational semantics (which, like assembly, was the domain of expert hackers with overclocked brains and guru-like status that understood it) behind a nice and clean object interface that normal programmers could use. Think of the productivity gains!

And yet, a lot of non-technical people whose jobs include data mining will learn SQL at some point in their career. This includes many people in academia (you have to process that empirical data), librarians and various industry managers. And, from my experience, they have an easier time learning it than the average programmer—who is used to seeing the programming world in an imperative fashion.

The easiest way to explain SQL queries is to think in terms of merge and filter operations. The first step is to merge all the tables you need together. This happens as a cartesian product operation: if you merge two tables, you get a table that contains, as its lines, all pairs consisting in one line from the first table and one line from the second table. So, if you merge five tables with 100 records each, you get a nasty result set containing ten billion records. This is where filtering comes in: of all the records, you only need those who satisfy certain properties. One classic example is performing a join: you only keep the a record if its sub-records share the same key value, thereby turning your ten billion records back into a hundred. And, of course, the mathematical properties of relational algebra allow the database system to reorder certain merge and filter operations, so that you don’t first compute all ten billion rows and only then start filtering them.

As such, SQL is a very practical language: ‘FROM’ and ‘JOIN’ merge tables, ‘WHERE’ and ‘ON’ filter records, and the remaining ‘SELECT’, ‘ORDER BY’, ‘GROUP BY’ and ‘LIMIT’ further format the results returned to the user.

Besides, most database systems also provide features for defining functions and procedures within the database to run almost arbitrary code. This makes it possible to write an entire application that does nothing but parse user input and forward database output back to the user. The database would then take care of the business logic, data storage, and output formatting. Of course, having the database output formatted HTML based on its contents would be crazy. Or would it?

Layered Architectures

The average website is layered. There’s the dispatch layer, which receives the HTTP request and dispatches it to the appropriate controller based on the domain and URI. Then, there’s the controller layer, which parses the user input and initiates the business logic and uses view components to send data back to the user. Underneath, there’s the model, containing both business data and business logic. And below the model is the database itself.

Different architectures give each layer a different weight. Some may have heavy controllers that perform most of the logic, and very thing model and storage layers. Others may have a very thin controller, and rely on the model for everything save the most elementary output formatting.

What if we completely eliminated the model? All the business logic would be stored in the database as stored procedures and stored functions, and all the model would have to do is provide simple points of access to the procedures themselves: format arguments, run the stored procedure as a query, return the result set or success/failure. Oh, and of course, decide whether the query should be sent to the master database or to a slave.

There are a few advantages of doing things this way:

  • Performance benefits. Most of the time, the processing that has to be done by the system between the first request and the last request of a given session is very light (or, if it isn’t, proper architecture would demand that it be done asynchronously anyway). By performing everything on the database server, one wastes some time by having the database perform some processing that could have been done by the web script itself, but eliminates all the overhead related to serializing and sending data and the lock overhead for keeping a session locked too long, and allows the database to optimize queries ahead of time based on hints given when declaring the stored procedures and functions.
  • Abstraction benefits. When you need to make a database and a program communicate, you just have to create an abstraction that can serve as an interface between the two. If you decide that all operations on the database have to go through stored procedures, then you will end up with a flurry of stored procedures that completely hide the actual storage approach used by the database.
  • Interoperability. Any software that can connect to your database system can use the interface. This means that you can write asynchronous processing units in other languages that work with the database to perform costly computations (such as indexing). It also means that, if your software is intended to work on client computers, your client can develop extensions against the database.

There are, of course, downsides as well:

  • You need SQL developers and SQL architects. By definition, storing your model in the database means that you will have a relational design as opposed to an object-oriented design. Relational design is by no means inferior, but there are fewer people fluent enough with it than there are object-oriented designers, if only because it’s not encountered as often.
  • You might end up using non-portable SQL. By keeping your SQL simple (and hidden behind a Hibernate dialect) you guarantee that your system can be re-deployed to another database system if you need to improve performance, adjust to cost issues or adapt to the architecture of your customer.
  • It’s harder to deploy. Stored procedures are installed on the database by running SQL queries that create them. This is an order of magnitude harder than just zipping up a JAR or packing an assembly and uploading it to the server, and two orders of magnitude harder than just copying your PHP source directory to the server. Of course, there are tools that allow editing stored procedures on the server on-the-fly, but they often lose you the benefit of source control.

Choose wisely.

Painful Relatives

It’s hard to say which kind of path (relative, or absolute) was invented first. Did people first get the idea of a tree representation for information, where every node could be identified with a unique absolute path that started at the root? Or did they invent a nested dictionary structure where all data could be reached through a relative path from the currently active dictionary, and the root dictionary merely appeared because it had no parent?

Either way, relative paths are painful, because you don’t know what they will be relative to (if you include that information, you actually provide an absolute path). This leads to situations where the user expects a relative path to resolve to a certain absolute path, but it resolves to a different relative path instead—usually when you least expect it, because something changed the root path to something else.

PHP include paths are a classic: you have two files within the same directory, A.php and B.php, and you wish for A.php to include B.php while it runs. You might be tempted to include(”B.php”), which uses a relative path to refer to the file. That path is interpreted by PHP as being relative to its current list of include paths. So, if someone plays with the include paths, your code breaks. Even worse, include paths are per-execution, not per-file, meaning that if A.php is included from a somewhereelse/C.php, then it will go looking for somewhereelse/B.php insead of just B.php!

Words cannot describe how annoying it can be to include a PHP file, and see that file screw up its own inclusions because it assumes something about the include paths. This has led to three main approaches:

  • There’s an implicit ‘root’ from which all files must be included, which is defined in some simple way (for instance, in software that has a single root index.php file, the directory in which the file is found is the root). To use the PHP files in that program, you have to use that root yourself. Annoying.
  • Every file in the program computes the root itself based on the knowledge of its own path relative to the root (usually as by heavy use of dirname and __FILE__), then explicitely prepends that root to any files it includes, thereby using absolute paths.
  • Files don’t include other files. They rely to a central inclusion function (either explicitely or through class auto-loading) to seek and include files correctly). This can be very complicated if it relies on class auto-loading, since it will inevitably clash with your own use of that.

My take on the issue, both for PHP inclusion and as a general path-manipulation practice, is to always use absolute paths.

The only reason why relative paths are useful is that they allow you to specify a path that has a prefix that can be configured somewhere else, instead of having to specify that prefix along with the rest of the path. You don’t want to hard code ‘/home/nicollet/www’ in a hundred places in your code, do you?

Yet, I don’t need to have relative paths to do this. I can solve this redundant element the old-fashioned way by creating a constant that equals the prefix and refering to the prefix by its name, not by its value. You would get an include(ROOT . “/index.php”) instead of include(”/home/nicollet/www/index.php”), solving both issues.

Naming Conventions

Here’s a quick review of the naming conventions I’m using right now. I am not going to dive into silly cosmetic issues such as making some letters uppercase or using some underscores or prepending warts, because usually every project has their own writing conventions: if you use the Zend framework, you probably want to use the ZF conventions, if you use the C++ with boost, you probably want to use the SC++L/boost naming conventions, if you use C# and .NET you probably want to use the .NET naming scheme, and if you use Objective Caml you will be shoehorned into writing conventions as well.

But these conventions usually tell you how to place uppercase letters and underscores inside variable, function, class, label and module names. They do not tell you what words those variables should be made of. This is what my personal naming conventions bring to the table: a choice of words that’s reasonably standard. Here are some examples you can find in my code:

Basic Names

If the domain provides a simple and clear name for my variables and functions, I will use it. This happens very often in straight down-to-earth code that just does what is expected without any performance improvement attempts. It will be using names such as “username“, “page“, “reply“, “target” or “missile“.

And if your choice of type names is equally sane, you will end up with variables looking like “Missile missile“. There’s nothing inherently wrong with this—as long as the context gives enough information about why this missile is important.

The technical names that match required knowledge are also fair game. For instance, if your code uses a MySQL database, then it’s acceptable to assume that the reader will have to know about MySQL-related concepts and thus the corresponding names can be used. This makes “row“, “field” and “query” acceptable names in that context.

Be aware of collisions! If your program manipulates both domain-level queries (such as a query from a user) and implementation-level queries (such as a query for the database), the default interpretation whenever both contexts are possible is the domain-level one, because this is the one that readers will have in mind most of the time.

Context

Depending on where the name is used, its meaning can be different.

Class members usually have an implicit “of” meaning: “user.Name” is the user’s name without a shadow of a doubt. This is why, for instance, I would never hesitate to use a variable with the same name as its type as a member variable: the fact that it’s a member variable adds some information about it. Plus, in languages without type annotations (OCaml and PHP, for instance), it gives the reader some information about the type.

The same happens with function parameters, which have an implicit “to be processed” meaning. A function which computes the balance of an account can certainly have a self-explanatory parameter of type “Account” named “account“.

And, of course, loop variables in for-each loops also have an implicit “in the collection” meaning.

Modifiers

  • fooCount : the number of “foo” elements within the context where the name appears. This is always an unsigned integer (or as close to an unsigned integer the language allows). For example, article # visitor_count would return the number of visitors of an article, and $errorCount would be the number of errors encountered by a function so far.
  • fooBarRatio : the proportion of “bar” objects within the context that have the “foo” property. This is always a floating-point number, and is usually equivalent to dividing fooBarCount by barCount. For example, TaskManager::FailedTaskRatio() returns the proportion of failed tasks among the tasks handled by the task manager.
  • foos : a sequence of “foo” elements. This is usually the language’s simplest representation of a sequence, such as an array or list. For example, article # authors is a sequence of authors.
  • fooIsBar : a boolean indicating whether the “foo” has the property “bar“. The “foo” may be implicit. For example, errorIsFatal indicates whether an error is fatal, and article # is_visible indicates whether an article is visible. I do not use “has”, because if an object may optionally have a certain something, that something should be an optional property using language support for optional values.
  • fooByBar : an associative container which allows retrieving a “foo” value associated to a “bar” valule, or a function which performs as an associative container retrieval. The “foo” may be implicit in exceptional situations. There’s no guarantee, of course, that a key has an associated value. For example, User::ByName finds and returns a user by its name.