Top 15+ Best Practices for Writing Super Readable Code

Top 15+ Best Practices for Writing Super Readable Code

Tutorial Details
  • Topic: PHP Best Practices
  • Difficulty: Intermediate

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Nettuts+.

Code readability is a universal subject in the world of computer programming. It’s one of the first things we learn as developers. This article will detail the fifteen most important best practices when writing readable code.


1 - Commenting & Documentation

IDE’s (Integrated Development Environment) have come a long way in the past few years. This made commenting your code more useful than ever. Following certain standards in your comments allows IDE’s and other tools to utilize them in different ways.

Consider this example:

The comments I added at the function definition can be previewed whenever I use that function, even from other files.

Here is another example where I call a function from a third party library:

In these particular examples, the type of commenting (or documentation) used is based on PHPDoc, and the IDE is Aptana.


2 - Consistent Indentation

I assume you already know that you should indent your code. However, it’s also worth noting that it is a good idea to keep your indentation style consistent.

There are more than one way of indenting code.

Style 1:
function foo() {
	if ($maybe) {
		do_it_now();
		again();
	} else {
		abort_mission();
	}
	finalize();
}
Style 2:
function foo()
{
	if ($maybe)
	{
		do_it_now();
		again();
	}
	else
	{
		abort_mission();
	}
	finalize();
}
Style 3:
function foo()
{	if ($maybe)
	{	do_it_now();
		again();
	}
	else
	{	abort_mission();
	}
	finalize();
}

I used to code in style #2 but recently switched to #1. But that is only a matter of preference. There is no “best” style that everyone should be following. Actually, the best style, is a consistent style. If you are part of a team or if you are contributing code to a project, you should follow the existing style that is being used in that project.

The indentation styles are not always completely distinct from one another. Sometimes, they mix different rules. For example, in PEAR Coding Standards, the opening bracket "{" goes on the same line as control structures, but they go to the next line after function definitions.

PEAR Style:

function foo()
{                     // placed on the next line
    if ($maybe) {     // placed on the same line
        do_it_now();
        again();
    } else {
        abort_mission();
    }
    finalize();
}

Also note that they are using four spaces instead of tabs for indentations.

Here is a Wikipedia article with samples of different indent styles.


3 - Avoid Obvious Comments

Commenting your code is fantastic; however, it can be overdone or just be plain redundant. Take this example:

// get the country code
$country_code = get_country_code($_SERVER['REMOTE_ADDR']);

// if country code is US
if ($country_code == 'US') {

	// display the form input for state
	echo form_input_state();
}

When the text is that obvious, it’s really not productive to repeat it within comments.

If you must comment on that code, you can simply combine it to a single line instead:

// display state selection for US users
$country_code = get_country_code($_SERVER['REMOTE_ADDR']);
if ($country_code == 'US') {
	echo form_input_state();
}

4 - Code Grouping

More often than not, certain tasks require a few lines of code. It is a good idea to keep these tasks within separate blocks of code, with some spaces between them.

Here is a simplified example:


// get list of forums
$forums = array();
$r = mysql_query("SELECT id, name, description FROM forums");
while ($d = mysql_fetch_assoc($r)) {
	$forums []= $d;
}

// load the templates
load_template('header');
load_template('forum_list',$forums);
load_template('footer');

Adding a comment at the beginning of each block of code also emphasizes the visual separation.


5 - Consistent Naming Scheme

PHP itself is sometimes guilty of not following consistent naming schemes:

  • strpos() vs. str_split()
  • imagetypes() vs. image_type_to_extension()

First of all, the names should have word boundaries. There are two popular options:

  • camelCase: First letter of each word is capitalized, except the first word.
  • underscores: Underscores between words, like: mysql_real_escape_string().

Having different options creates a situation similar to the indent styles, as I mentioned earlier. If an existing project follows a certain convention, you should go with that. Also, some language platforms tend to use a certain naming scheme. For instance, in Java, most code uses camelCase names, while in PHP, the majority of uses underscores.

These can also be mixed. Some developers prefer to use underscores for procedural functions, and class names, but use camelCase for class method names:

class Foo_Bar {

	public function someDummyMethod() {

	}

}

function procedural_function_name() {

}

So again, there is no obvious “best” style. Just being consistent.


6 - DRY Principle

DRY stands for Don’t Repeat Yourself. Also known as DIE: Duplication is Evil.

The principle states:

“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

The purpose for most applications (or computers in general) is to automate repetitive tasks. This principle should be maintained in all code, even web applications. The same piece of code should not be repeated over and over again.

For example, most web applications consist of many pages. It’s highly likely that these pages will contain common elements. Headers and footers are usually best candidates for this. It’s not a good idea to keep copy pasting these headers and footers into every page. Here is Jeffrey Way explaining how to create templates in CodeIgniter.

$this->load->view('includes/header');

$this->load->view($main_content);

$this->load->view('includes/footer');

7 - Avoid Deep Nesting

Too many levels of nesting can make code harder to read and follow.

function do_stuff() {

// ...

	if (is_writable($folder)) {

		if ($fp = fopen($file_path,'w')) {

			if ($stuff = get_some_stuff()) {

				if (fwrite($fp,$stuff)) {

					// ...

				} else {
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	} else {
		return false;
	}
}

For the sake of readability, it is usually possible to make changes to your code to reduce the level of nesting:

function do_stuff() {

// ...

	if (!is_writable($folder)) {
		return false;
	}

	if (!$fp = fopen($file_path,'w')) {
		return false;
	}

	if (!$stuff = get_some_stuff()) {
		return false;
	}

	if (fwrite($fp,$stuff)) {
		// ...
	} else {
		return false;
	}
}

8 - Limit Line Length

Our eyes are more comfortable when reading tall and narrow columns of text. This is precisely the reason why newspaper articles look like this:

It is a good practice to avoid writing horizontally long lines of code.


// bad
$my_email->set_from('test@email.com')->add_to('programming@gmail.com')->set_subject('Methods Chained')->set_body('Some long message')->send();

// good
$my_email
	->set_from('test@email.com')
	->add_to('programming@gmail.com')
	->set_subject('Methods Chained')
	->set_body('Some long message')
	->send();

// bad
$query = "SELECT id, username, first_name, last_name, status FROM users LEFT JOIN user_posts USING(users.id, user_posts.user_id) WHERE post_id = '123'";

// good
$query = "SELECT id, username, first_name, last_name, status
	FROM users
	LEFT JOIN user_posts USING(users.id, user_posts.user_id)
	WHERE post_id = '123'";

Also, if anyone intends to read the code from a terminal window, such as Vim users, it is a good idea to to limit the line length to around 80 characters.


9 - File and Folder Organization

Technically, you could write an entire application code within a single file. But that would prove to be a nightmare to read and maintain.

During my first programming projects, I knew about the idea of creating “include files.” However, I was not yet even remotely organized. I created an “inc” folder, with two files in it: db.php and functions.php. As the applications grew, the functions file also became huge and unmaintainable.

One of the best approaches is to either use a framework, or imitate their folder structure. Here is what CodeIgniter looks like:


10 - Consistent Temporary Names

Normally, the variables should be descriptive and contain one or more words. But, this doesn’t necessarily apply to temporary variables. They can be as short as a single character.

It is a good practice to use consistent names for your temporary variables that have the same kind of role. Here are a few examples that I tend use in my code:


// $i for loop counters
for ($i = 0; $i < 100; $i++) {

	// $j for the nested loop counters
	for ($j = 0; $j < 100; $j++) {

	}
}

// $ret for return variables
function foo() {
	$ret['bar'] = get_bar();
	$ret['stuff'] = get_stuff();

	return $ret;
}

// $k and $v in foreach
foreach ($some_array as $k => $v) {

}

// $q, $r and $d for mysql
$q = "SELECT * FROM table";
$r = mysql_query($q);
while ($d = mysql_fetch_assocr($r)) {

}

// $fp for file pointers
$fp = fopen('file.txt','w');

11 - Capitalize SQL Special Words

Database interaction is a big part of most web applications. If you are writing raw SQL queries, it is a good idea to keep them readable as well.

Even though SQL special words and function names are case insensitive, it is common practice to capitalize them to distinguish them from your table and column names.

SELECT id, username FROM user;

UPDATE user SET last_login = NOW()
WHERE id = '123'

SELECT id, username FROM user u
LEFT JOIN user_address ua ON(u.id = ua.user_id)
WHERE ua.state = 'NY'
GROUP BY u.id
ORDER BY u.username
LIMIT 0,20

12 - Separation of Code and Data

This is another principle that applies to almost all programming languages in all environments. In the case of web development, the “data” usually implies HTML output.

When PHP was first released many years ago, it was primarily seen as a template engine. It was common to have big HTML files with a few lines of PHP code in between. However, things have changed over the years and websites became more and more dynamic and functional. The code is now a huge part of web applications, and it is no longer a good practice to combine it with the HTML.

You can either apply the principle to your application by yourself, or you can use a third party tool (template engines, frameworks or CMS’s) and follow their conventions.

Popular PHP Frameworks:

Popular Template Engines:

Popular Content Management Systems


13 - Alternate Syntax Inside Templates

You may choose not to use a fancy template engine, and instead go with plain inline PHP in your template files. This does not necessarily violate the “Separation of Code and Data,” as long as the inline code is directly related to the output, and is readable. In this case you should consider using the alternate syntax for control structures.

Here is an example:

<div class="user_controls">
	<?php if ($user = Current_User::user()): ?>
		Hello, <em><?php echo $user->username; ?></em> <br/>
		<?php echo anchor('logout', 'Logout'); ?>
	<?php else: ?>
		<?php echo anchor('login','Login'); ?> |
		<?php echo anchor('signup', 'Register'); ?>
	<?php endif; ?>
</div>

<h1>My Message Board</h1>

<?php foreach($categories as $category): ?>

	<div class="category">

		<h2><?php echo $category->title; ?></h2>

		<?php foreach($category->Forums as $forum): ?>

			<div class="forum">

				<h3>
					<?php echo anchor('forums/'.$forum->id, $forum->title) ?>
					(<?php echo $forum->Threads->count(); ?> threads)
				</h3>

				<div class="description">
					<?php echo $forum->description; ?>
				</div>

			</div>

		<?php endforeach; ?>

	</div>

<?php endforeach; ?>

This lets you avoid lots of curly braces. Also, the code looks and feels similar to the way HTML is structured and indented.


14 - Object Oriented vs. Procedural

Object oriented programming can help you create well structured code. But that does not mean you need to abandon procedural programming completely. Actually creating a mix of both styles can be good.

Objects should be used for representing data, usually residing in a database.

class User {

	public $username;
	public $first_name;
	public $last_name;
	public $email;

	public function __construct() {
		// ...
	}

	public function create() {
		// ...
	}

	public function save() {
		// ...
	}

	public function delete() {
		// ...
	}

}

Procedural functions may be used for specific tasks that can be performed independently.

function capitalize($string) {

	$ret = strtoupper($string[0]);
	$ret .= strtolower(substr($string,1));
	return $ret;

}

15 - Read Open Source Code

Open Source projects are built with the input of many developers. These projects need to maintain a high level of code readability so that the team can work together as efficiently as possible. Therefore, it is a good idea to browse through the source code of these projects to observe what these developers are doing.


16 - Code Refactoring

When you “refactor,” you make changes to the code without changing any of its functionality. You can think of it like a “clean up,” for the sake of improving readability and quality.

This doesn’t include bug fixes or the addition of any new functionality. You might refactor code that you have written the day before, while it’s still fresh in your head, so that it is more readable and reusable when you may potentially look at it two months from now. As the motto says: “refactor early, refactor often.”

You may apply any of the “best practices” of code readability during the refactoring process.

I hope you enjoyed this article! Any that I missed? Let me know via the comments.

Tags: html
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.doctormalboro.net DoctorMalboro

    Except point 7, everything else I agree with.

    The deep nested should be used if the code is extensive and it has a large amount of conditionals or loops inside of it. Just to separate one conditional or loop.

  • http://www.xcellence-it.com/ Xcellence-IT

    excellent tips… it makes easy to maintain code, and especially when you’re working in team.. following this is the key.

  • Filip

    Nice

  • Pieter

    Nice article Burak, very usefull for starting developers!

  • http://doniz.net Donatas

    I don’t except that :

    <pre name=”code” class=”php”>
    <?php

    if ( $condition ) {
    // If that, then action block it is
    } else {
    // Action block
    }

    // For basic programming C, C++ and PHP say\s

    if ( $condition )
    // Just one action
    $my_one = $action;
    else {
    // More than one action
    $more = $than_one;
    $match = TRUE;
    }
    ?>
    </pre>

  • http://techbrij.com Brij

    Nice Post!!!
    I like ‘Read Open Source Code’ point.

  • http://www.webcoursesbangkok.com Carl – Web Courses Bangkok

    We always tell our students to do good clean readable code at Web Courses Bangkok cause we have had the pain of editing others code before so we want to send our new web designers out into the world making good quality code.

  • eeean

    The newspaper column line length (also known as line ‘measure’) is IMO not the best analogy to use for coding line length. It does point out a very important typographical consideration: readability, but the problem is that it takes it out of context.

    A newspaper has additional considerations, namely printable space and economy, that dictate this exaggeratedly short line length. Coding, and even to some extent the language used, is a unique context quite different from the line length considerations that apply to newspapers. Use your judgement appropriate to the context. I would recommend (*and so to does a certain widely regarded typographic bible) a more widely accepted line measure of between 40-75 characters. The ideal being around 66 characters, based on common convention and research. Again, use your own judgement.

    * http://webtypography.net/Rhythm_and_Proportion/Horizontal_Motion/2.1.2/

  • http://www.kevinbradwick.co.uk Kevin

    There are great tools out there to help you maintain readable and maintainable code. The ones I use regularly for this are PHP_CodeSniffer and PHP Mess Detector. If you use Eclipse IDE, then install the PHPsrc plugin to make the process automated: http://www.phpsrc.org/

  • http://designmodo.com Adrian

    Very clean and clear examples, but i think it is much more than 15+.

  • http://www.rcdmk.com RCDMK

    Great post.
    Its aways good to tell people how to write clean and reusable code.

    Nice job.

  • JD

    Why use everyone the $i and $j variables for for loops? I use all the time $x and $y. C64 german docs FTW!

    • edonovan

      $x, $y, and $z are generally used in relation to graphics and coordinates. $i, $j, and $k are used for indices or counters. $k, $v for key/value pairs.

      These rules are not set in stone, but it does help when they are used consistently, especially if you need all of them at the same time.

  • http://www.profilepicture.co.uk Phil

    Section 3 – avoid obvious comments…

    Section 4:

    // load the templates
    load_template(‘header’);
    load_template(‘forum_list’,$forums);
    load_template(‘footer’);

    Other than that a nice write up

    • Powerslave

      Score! :D

  • http://codehill.com/ Amgad

    Thanks, its good to be reminded of these best practices.

  • http://www.webdevelopersspot.com WebdevelopersSpot

    helping roundup for me as developer.

  • http://thinkdiff.net Mahmud Ahsan

    Awesome tutorial. Very helpful for beginner to intermediate level developer.

    • http://richardwillia.ms Richard Williams

      I agree, definitely useful for beginner and intermediate/advanced too. I think a lot of the points above make more and more sense as you become a more experienced developer. When you’re a beginner it can be quite hard to observe these good practises whilst getting your head round all the other things you’re doing, over time all this stuff clicks into place.

      Great Post.

  • The Insaint

    Damn, all those formatting are lost, event with this <pre name = "code" … stuff .. :(
    Please delete this.

  • http://www.anmsaiful.net A.N.M. Saiful Islam

    Hello Guzel, great tutorial. but i am not agree with the practice#7. nesting script prevents parser to avoid parsing unnecessary conditional checking. rest are awesome!

  • http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html Batman

    It is also good practice to use backticks ` to surround `column` names in SQL queries. Especially for those who don’t know about MySQL reserved words (http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html)

    Can save a beginner, even an intermediate, many hours of, “what the heeeeeell is going on here??”.

  • http://mokshasolutions.com Moksha

    very nice info about coding. thanks

  • http://www.modernooze.com sam – modernooze dorset

    very helpful thank you, i have enjoyed recapping on these techniques for more readable coee

  • http://pixelflo.net Pixelflo

    I have never seen style 3 code indentation before

  • http://brandonbuttars.com Buttars

    Thanks for the article. I’m always looking for better ways to improve my code.

  • http://ustaz-azhar.easyniaga.com Ustaz Azhar

    Excellent articles. I’ve always lost when taking over a project from a group of people who don’t appreciate code readability. The same problem also comes to mind when hiring a new programmer to maintain existing code base. Now what you’ve mentioned in the article here is really what I’ve been looking for. Thanks alot!

  • JC

    Using multiple “return” statements is _not_ an improvement over the nesting example.

    2 are allowed for short functions that do just simple comparisons.

    More than 2 return statements is a strong indication of poor style and probably poor software dev skills.

    Code execution should flow to the bottom, without gotos, breaks, continues, nested returns. It’s just bad, real bad, and a maintenance nightmare. The consequences are not as bad in JS land where all resources (i.e. memory) are managed by the browser, but it is still very bad style.

  • Tosin

    I’m Curious,
    How do you get your code snippets to look like that.

    Hello
    World

    Any answers would be greatly appreciated
    Is it CSS, soz am a newbie.

  • http://schlingel.soup.io schlingel

    This is only a beginners list. Readable code is much more then just good formatted code. As software engineer I think this list is only good for rookies but for everyone else it’s just a joke.

    Check this list: http://sourcemaking.com/refactoring

    It demonstrates patterns which can be applied to code not only the formatting of the code. Nice formatted code doesn’t help within a horrible architecture.

    Someone said:
    “Code execution should flow to the bottom, without gotos, breaks, continues, nested returns. It’s just bad, real bad, and a maintenance nightmare. The consequences are not as bad in JS land where all resources (i.e. memory) are managed by the browser, but it is still very bad style.”

    That’s true for C++ but in languages like C# or PHP it’s not recognized as bad style.

  • http://itcutives.com Jatin

    Nice tutorial.

    I personally favour DRY Principle, as most important thing in writing readable code.

  • http://www.cobbweb.me/ Andrew Cobby

    15 – Read Open Source Code
    …. the screenshot if from CodeIgniter which is PHP4….

  • a

    asd

  • http://gravitymad.com travis

    I’m going to start reading more open source code. I like that idea as well as everything noted here. Thanks :)

  • http://www.lk-webdesigns.co.uk LKenneth

    Excellent post! Some good points made here!

  • Gus

    <pre name="code" class="php"
    $my_email
    ->set_from('test@email.com')
    ->add_to('programming@gmail.com')
    ->set_subject('Methods Chained')
    ->set_body('Some long message')
    ->send();

    why is it when i make my own class and try something like this it doesnt work?

    class email {

    public $name;
    public $last;
    public $email;

    public function __construct() {

    }

    public function send() {

    echo $this->name . ” ” . $this->last . ” ” . $this->email;
    }

    public function setName($var) {

    $this->name = $var;

    }

    public function setLast($var) {

    $this->last = $var;

    }

    public function setEmail($var) {

    $this->email = $var;

    }

    }

    $my_email = new email();
    $my_email
    ->setName(‘Constantine’)
    ->setLast(‘Maroulis’)
    ->setEmail(‘constantine@maroulisdesigns.com’)
    ->send();

    the above does not work

    • JD Pace

      What you’re doing is called method chaining. In order for it to work, each method must return the object, as in:

      public function setName($var) {
      $this->name = $var;
      return $this;
      }

    • Powerslave

      Nah, don’t do that. You’re abusing the public keyword, mixing up several application layers and also making the class concerned not only with the data but with its presentation. Business logic should never echo/print/whatever.

      – Have an Email class with private members, setters/getters
      – Have a Controller for your base logic and have that controller retrieve data to display
      – Pass the resulting data to the View.

    • Powerslave

      Oh, and forgot to mention that even if chaining is a neat trick, it is better to avoid it.

  • http://www.sstudio.me Web dizajn Crna Gora

    This is really useful.

  • Henock

    Value added on me

  • http://www.flickr.com/people/64516246@N05/ Designer Drugs

    rush drug nz salvia divinorum incense jamaican ecstasy pill cheap highs list kronic in melbourne legal high shop usa diablo herbal potpourri buy legal designer amphetamines marijuana shops in maryland buy ivory wave online white diamond legal cocaine space trips ecstasy uk buying marijuana new york best legal speed powder puff legal high perth cocaine and poppers magic mushrooms dublin buy legal pills uk marijuana price amsterdam black gold legal bud legal highs holland buy kronic victoria best mood enhancing pills ecstasy like highs london underground highs

  • L.

    Nice article, I totally agree with most of it, just a few things :

    -> about the deep nesting, I remember reading someone talking about single return points – how do you consider that point of view – even though it can be combined with the no-deep-nesting option ?

    -> about the indentation style, style1 IS inherently better, it has just as much readability, less text to condense for the compiler (lol, talk about cheap optimization), but more importantly, I’ve read about bugs related to curly braces position (can’t quite remember in which language though, but it made the difference between crash and no-crash ;) )

    -> about the read opensource code : No . I mean reading code is good, but there’s a lot of bad code even in open source so it’s not really a good advice.

    Instead, I would add :

    -> read tdwtf
    -> read other serious coding blogs
    -> read postgresql-performance mailing lists and other expert-resources related to your coding language / dbms / whatever

    • Powerslave

      curly braces position bugs: JavaScript. In some cases it assumes the semicolon at EOL if not present.

      open source: Agree. Even the lots of the popular ones have awful code.

      tdwtf: I read (and love) that too :)

      add: NEVER EVER mix up procedural with OO code. That just smells.

  • http://www.thearkangelnetwork.com/ Andrew Skelland

    Excellent article great work!

  • Alonso

    Thanks for this! nice tutorial! :)

  • tendai

    Quite informative, Thanks for the tut.

  • http://www.jobs.ac.uk Guru

    Hi Burak Guzel,

    Fantastic tutorial and easy to understand

    Thanks
    Guru

  • Jose

    Each Developer MUST follow the next principle:


    Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.

  • http://www.quibblo.com/user/oriehigh1229 Thersa Selic

    I have to express appreciation to you just for bailing me out of this particular scenario. Because of surfing throughout the the web and coming across techniques which are not pleasant, I assumed my life was done. Living without the approaches to the problems you’ve solved as a result of this site is a crucial case, as well as the kind that would have adversely damaged my career if I had not noticed your web page. Your own knowledge and kindness in controlling the whole thing was very helpful. I am not sure what I would’ve done if I had not come across such a thing like this. It’s possible to at this point look forward to my future. Thanks so much for your reliable and effective guide. I won’t be reluctant to endorse the sites to anyone who wants and needs tips about this problem.

  • Subhan Ahmed

    Awesome tutorial really need to follow all the time.

  • http://www.jeremymorgan.com Jeremy

    Finally an article about clean code that mentions over-commenting. I see examples of this all the time, unfortunately it always seems the really obvious stuff is commented and the confusing parts have nothing.

    Great article!

    • rockidr4

      Usually that’s because the original programmer didn’t understand it either. The code you are looking at is a result of trial and error. Some where I read a quote about every program needing a comment over some block of code reading simply: “Do magic here”

  • http://www.empellex.com Don

    Nice Tips to help keep code clean, good practices for developers to follow, and its always good to state the obvious because sometimes the obvious get overlooked. Thanks.

  • http://www.10plustuts.com Robin

    I too really satisfy with these. Because a programmer becomes better only if he follows these tips :) Great listing

  • marketing

    I would like to
    appreciate your hard work you did write this post, Thanks for sharing this
    valuable post.
    articles

  • Rajinder

    good practice I was taught at Stanford was to have a PRE CONDITION and a POST CONDITION for loops (especially nested loops). It helps a 3rd party understand better the purpose of the whole function and improves readability and, if the option ever arose, edibility by a lot

  • http://www.imensosoftware.com/ Imenso Software