16th march 2007 - trauma-ptsd · basics of maintainable code (what you should already know) php...

38
Writing Maintainable PHP Laura Thomson, OmniTI PHP Quebec Conference 16th March 2007

Upload: others

Post on 05-Aug-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

Writing Maintainable PHP

Laura Thomson, OmniTI

PHP Quebec Conference

16th March 2007

Page 2: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 2

Overview

• Defining the problem

• Basics of maintainable code

• Scaling the code base

• Maintaining legacy code

Page 3: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

What is Maintainability?

Page 4: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 4

Maintainability

• Can somebody else understand your code enough to change and update it?

• Can you understand your own code enough to change and update it?

• Can the code be extended and adapted easily?

Page 5: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 5

How do maintainability problems arise?

• Lack of foresight about: – Size of the project

– Time frame/future direction

• Developer ignorance (a big one)

Page 6: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 6

Sizing the project

• For small problems write small code and be willing to write throwaway code

• For big problems design before you start

• The issue arises when projects grow organically

• Classic problem of being unable to redevelop a prototype

Page 7: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 7

Developer ignorance

• Self taught and junior developers

• Lack of experience with working in teams

• Lack of experience with developing significant code bases

• Lack of experience with other people’s horrible code

• Have not yet been forced to revisit their own old code

• How are they going to improve?

Page 8: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

Basics of maintainable code

(What you should already know)

Page 9: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 9

Basics of maintainable code

• Common errors

• Coding standards

• Version control

• Developer education

Page 10: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 10

Common errors

• Obfuscated code (the big one)

• Failure to comment appropriately

• Inline functions

• Side effects

• Failure to read and fit in with existing code

• Ignoring security (or planning to retrofit)

Page 11: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 11

Obfuscated code

• The worst of all common errors: – Poor naming

– Seventeen layers of handoff

– Misuse of define()

– Reimplementation of built in functions

– Failure to do the simplest thing that could possibly work

– Premature optimization (and it’s virtually always premature)

Page 12: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 12

Poor naming

• Not just $foo, $bar function edit_item_name(itemID) {

var sItemID = "edit-item-" + itemID;

var oItemID = document.getElementById(sItemID);

• Imagine trying to find this error in the code define('ERROR_TAG_CATEGORY', 'ERR_TAG_CTGY::Please

provide a category name (or) select an existing one');

Page 13: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 13

Abusing define()

define('STR_NBSP', ' ');

define('STR_BR_TAG', '<BR/>');

define('STR_BEGIN_TD', '<TD>');

define('STR_END_TD', '</TD>');

Page 14: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 14

Reimplementation of built ins

function change_to_lowercase($item,$key)

{

global $changes;

$changes[$key] = strtolower($item);

}

Page 15: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 15

Simplicity

• First, try the simplest thing that could possibly work.

<?php

/** * Description: Changes the case of text within tags <> * Make sure the $argc and $argv variables are enabled. * Invoke this script on CLI as follows: * php <thisfilename.ext> file2Bparsed.ext * **/

if ($argc <= 1 || !isset($argv[1])) { die("\nPlease enter the file to be parsed\n");

}

$filename = $argv[1]; if (!file_exists($filename) || !is_readable($filename)) { die("\nEnter a valid file\n");

}

Page 16: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 16

Simplicity - 2

$changes = array(); $is_match = false; $fh = fopen($filename, "r"); $contents = fread($fh, filesize($filename)); fclose($fh);

$pattern = "/(<(\w+)>|<\/(\w+)>)/";

if (preg_match_all($pattern, $contents, $matches)) { $is_match = true; if (!empty($matches[0])) { //change the matched elements to all lowercase array_walk($matches[0], 'change_to_lowercase');

} }

if (!$is_match) { die("\nNo match found\n");

}

Page 17: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 17

Simplicity - 3

$fh = fopen($filename, "w"); if (!is_writable($filename)) { fclose($fh); die("\nFile is not writable\n");

}

$contents = str_replace($matches[0], $changes, $contents);

$success = fwrite($fh, $contents); if ($success) { print "\nSuccessfully matched and modified.\n";

} fclose($fh);

Page 18: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 18

Premature optimization

• Often obfuscates code, and often done without a good rational reason to do so

function foo(&$bar) {…

Page 19: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 19

Coding standards

• Have and use a coding standard

• Don’t need to write one from scratch: PHP standards exist for PEAR and for the Zend Framework. These can be used adhoc or serve as a basis for your own

• Greenfields vs legacy: virtually impossible

Page 20: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 20

How not to write a coding standard

• Make the rules awkward and difficult to remember

• Apps Hungarian – the most abused coding style ever

• Force millions of tiny files (performance hit)

• Force complete OO (why not just use Java?)

Page 21: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 21

Example coding standard

• (Excerpts)

• Formatting e.g. – Always use long form PHP tags <?php ?>

– Two space indents throughout, NO HARD TABS

– …

• Naming – Use camel caps for OO identifiers (classnames,

methods, member variables), like this: $theVarCalledFoo

– …

Page 22: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 22

Standard - 2

• Comments – Every file should have a header block

containing at a minimum…

– Single line comments are encouraged on non-obvious code. These can also be used to add "TODO", "DEBUG", and "FIXME" items

– …

Page 23: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 23

Standard - 3

Semantics

• Declare functions and classes in library files that do not have any execution side effects besides possibly instantiating variables or defining constants.

• All code should run clean with error reporting turned up to E_ALL

• Try to avoid use of the ternary operator for readability

• Avoid magic numbers, declare a constant

• Avoid embedding PHP logic in HTML and vice versa

• Use parentheses to reinforce unclear or complicated precedence.

• Avoid use of global keyword

• …

Page 24: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 24

Version control

• For any project that will take more than a week, more than one code file, or more than one developer .

• And most of the others as well.

• Frequent commits of conceptual changesets

• Detailed commit messages (trac, while it has shortcomings, is your friend)

Page 25: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 25

The code under the rug

• If nobody ever notices how awful your code is, but notices if it is late what happens?

• If the next guy only says “aaarrrgh” when you are working somewhere else, does it make a sound?

• You need somebody other than the original author doing QA anyway

• Peer review can be confronting, but valuable

• Somebody overseeing commits can pick up a lot of evil … and act as a deterrent

Page 26: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 26

Developer education

• Don’t underestimate the importance of training.

• How: – Provide code layout and design

– Provide sample code

– Explain what’s required

– Give frequent feedback

Page 27: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

Scaling the code base

Page 28: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 28

Frameworks and Architectures: use and abuse

• Frameworks are buzzy, and Rails doesn’t help.

• Having an architecture like MVC can be a really good thing, but: – Everybody has a different idea about how this ought to be

implemented

– Some of the ideas are really twisted

– Some make it hard to do very basic things simply

– Code bloats

– Which framework?

– No dominant paradigm yet, ergo little help with maintainability

Have a clear, simple, architecture that is easy to add to, easy to explain to new developers, and easy to remember now or in two or five years’ time.

Page 29: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 29

What do you gain from a framework?

• Standard code layout for that framework

• Often makes developing a prototype fast

Page 30: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 30

Downside

• Skills don’t transfer from one framework to another

• Rapidly prototyped code not necessarily appropriate for use in production

Page 31: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 31

Two kinds of frameworks

• MVC style (e.g. Cake)

• Component style (e.g. eZ)

• Both kinds of music (e.g. ZF)

Page 32: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 32

Database abstraction use and abuse

• Use PDO – it’s a defacto standard

• Standardize on use of prepared statements

Page 33: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 33

Security

• Needs to be part of the initial build

• Trying to retrofit it is very hard, but also what usually happens, and new exploits need to be accounted for

• Build into your architecture stages of input and output processing to encourage filtering and escaping in single locations

Page 34: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 34

Documentation

• For projects beyond a certain size, you start to need significant documentation

• If your plan says this code will grow large, document as you go, from the start. If it’s not done at the time, it will never be done.

• (Sometimes we can all be caught short) • Aim for consistent production of lightweight

documentation: – Takes less time to produce (and therefore has

some chance of actually happening) – Takes less time to read

Page 35: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

Maintaining Legacy Code (or, “The Ninth Circle of Hell”)

Page 36: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 36

Maintaining legacy code

• “Hell is other people’s code.” - Anonymous, late twentieth century

- Sad true facts: - You may never read all the legacy code - There will be parts of it that are broken or never

used - If the original author didn’t document it, chances

are you never will - If it needs a complete rewrite, chances are you

won’t have time - You will have to to deal with this at some stage if

you haven’t already.

Page 37: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 37

Strategies

• Worth spending some time to audit: – What you have in the way of documentation

– The basic architecture of the code

– Coding conventions if any

– What is used

– What is obviously broken or fragile and why

• Refactor as you go, to a lightweight plan

• Don’t get too ambitious.

Page 38: 16th March 2007 - TRAUMA-PTSD · Basics of maintainable code (What you should already know) PHP Quebec 2007 9 Basics of maintainable code ... • Make the rules awkward and difficult

PHP Quebec 2007 38

Questions?