I've been with my current company for about 16 months, and it's been quite an education in software development. This has been mainly because, since November last year, I've been the manager in charge of the development effort.
That effort has been split into three main areas:
1) Getting the tools right
2) Hiring the right people
3) Writing good code and improving our skillset
(leaving aside the management tasks, which I'm not generally all that fond of).
For now I'll just cover the tools, which can be split down into project techniques and equipment. Since we got the current development team in place, we've been working on a Scrum methodology, previously on a one month cycle and more recently on a two-week cycle. I mention this for now only as context; I'll go into more depth in a future post.
The development cycle we apply means we work very closely together in the team, and we have to be able to redirect our coding effort on a fairly regular basis. To help co-ordinate our effort we use the Subversion VCS. This was, in fact one of the first measures I took when I joined the company - even working with one other coder, or on my own, I've found version control invaluable.
To put it simply, every software project (or even documentation project) of any scale should use version control. It provides functionality in the core areas of backup, rollback, co-ordination, separation and accountability:
Version control with a client-server architecture (as with most such systems) provides an extremely easy way to keep a recent copy of (almost all) code - up to the last checkin at least. It's not the primary role of such software, but it's invaluable!
At some time in any project you'll wipe out some piece of essential code, or break something you were sure used to be working. Being able to look back a day, week or month means you can manually check what went wrong, or dig out the old code you'd wiped.
Of course, the preferred option is two be automatically warned of any code loss or changes, which we'll cover shortly.
Whenever a team works on a similar area of code, at some point two people will try and save over the same file with two different sets of changes. This can quite easily lose a day's changes or more, but the damage to team morale tends to have an even greater impact than the lost time. Re-writing code because of someone else's "error" is dispiriting at best.
Version control allows each developer to have his/her own sandbox, allowing testing and development of only that person's own changes. Each developer can then also have their own database and test area if required.
Some coders hate VCSs because of this - they think the tool's just there to "check up on them". Leaving aside the issue of whether you'd really want to work with someone who won't admit to their own code, being able to find "who changed what and when" is invaluable; not for reasons of blame, but to be able to ask why it was changed, with what intent, and how the desired changes can be made while preserving the old requirements.
The next essential (to my mind) is some sort of issue-tracking software. Call them bugs or tickets if you will, but being able to keep track of plans and problems in a controlled fashion helps immeasurably in keeping a sense of control and direction over the project code. Plenty of solutions exist, but the one I've found most useful is trac, which integrates smoothly with subversion, and also includes a closely-connected wiki for documentation.
So far we've got a way to control our code, and to track plans and issues. Some way of writing it would seem to be in order...
The choice of editors, or IDEs can be a contentious one - everyone tends to have a favourite, and it's a prime source of almost religious arguments. However, it's extremely useful to have everyone working on the same system, as it keeps input consistent and makes pair programming (or over-the-shoulder coding) more practical. The choice that I've found works particularly well for our team is ZDE (the Zend Development Environment). We work in a heterogeneous environment; one developer on OSX, one on Linux, and one on Windows XP (all, of course, with dual-monitor setups). ZDE handles all of these smoothly, and provides extremely good code/error highlighting, code hinting and contextual help. Perhaps most usefully it actively rewards good API documentation, as it uses PHPDOC comments internally to document class/function purpose, parameters and return types and values. As the code completion works on your own code by reading your PHPDOC comments, writing them saves more time than not doing so!
Advanced versions also include database, VCS and File transfer integration, but we've not currently found those necessary.
Evidently, as we code PHPDOC comments into our work as a matter of course, it would be silly not to build the documentation automatically, so we do this with a nightly cron script linked into our trac wiki.
So, now we can write version-controlled, documented, co-ordinated code. The next step (as alluded to above) is to ensure we only have to write it once! By this admittedly odd phrase I mean that we ensure that previously-written code doesn't fail unexpectedly and need some form of archaeological research to debug and repair. The solution to this - and possibly a slightly belated one in our team - is the use of unit testing, and a system setup that allows these tests to be run automatically and en masse. For this I've adopted the "simpletest" framework, on the basis that it's used and trusted by members of the PHP community that I know and trust! In fact the author, Marcus Baker, is a founder member of our local PHP group.