For many developers, there are *at least* two versions out there for any particular web site you see: a development version and a production version. (Often, other versions exist as well, such as a testing / staging layer.) For many time-honored reasons, these are considered best practices in web development.
That said, there's no absolute rule about how one must approach web development. A lot of absolutely gigantic systems, believe it or not, are developed by sole coders out there and, in such lone-wolf environments, one can get away with practices simply not possible by larger development organizations or teams. Claim whatever you like about "agility" in development, but I don't think there's possibly anything more agile than coding on a live site.
The truth is this: One can sometimes exist fairly well with (gasp!) ONE version of a given web site. That's right: production only! (I'm not saying I recommend this always, or that it's better; I'm just saying that it's absolutely possible, and even preferable, much of the time, and probably more common than most developers realize.)
So this article, while considered blasphemy in the coding, design, and development world (and will surely earn me the disrespect of friends, colleagues, and strangers alike), nevertheless will offer a few examples of how one can sometimes get by with only a production site -- that is, working on a live, active web site instead of taking the site off to a development server.
Adding hooks or parameters and then coding for actions taken when these are seen
So, I had a site recently that has various parties working on various areas. All are generating content and making config changes to things in realtime. Yet, we also needed to do some pretty major design tweaks at the same time. Having a development version of the site, in this case, would have caused a good degree of confusuion and inconvenience for a lot of other people. So, in this case, I just added some code to the site to look for a "redesign=1" parameter added onto any site URL. If seen, the code would then load a new CSS file to supercede the existing one. Worked great... It told the client: You want to view the new site, just go to any page and add "?redesign=1" to the end of any URL.
Similarly, you can often just code various hooks into various scripts. For example, I might commonly have some configs atop a PHP script like "$isTesting = 0;". Then, when I'm working on that page, I might set that variable to 1, and account for such in the code for various things. For example, maybe it's a form that sends an email out, but I don't want to get 500 emails while I test things. So, I set that $isTesting to 1, run my tests (perhaps echoing out the form data to the screen instead of emailing it, based on that variable being "live"), and then set it back to 0 when I'm done. While this is a fairly standard coding methodology, it's also a handy thing for live sites.
A good argument against this sort of thing, of course, is that a web site is a live thing... so, what if someone sees your "under construction"-type page? Well, that's of course something you need to weigh into a decision about developing on a live site. How many might see your temporary unsightliness? There's usually some sort of common-sense threshhold there, and it's different for every site. If your site gets 10,000 hits per day on the home page, maybe this isn't such an appropriate tactic. But, if it's a deeper page, or simply just a less-busy site, then having a page possibly not function for a few minutes is absolutely immaterial. Clients and developers alike get *way* too concerned over such a thing. It does not matter if a page goes down for a few minutes. Naturally, you want to minimize this, but the world will go on, and no one will get hurt.
Such hooks can also be good for developing more primitive version-control type scenarios. For example, maybe you'd rather work up changes to your form.php script outside of any live page, but still on the live site. No worries... Maybe you use your $isTesting=1 to do things like change the form action. If $isTesting is set to 1, then instead of the form action being form.php (meaning the form sends data back to itself, a common practice), it changes to form_dev.php. Thus, you can develop your new scripts at form_dev.php, and they'll work, and when you decide to go live with them, you still only have to flip that switch off. So, what I'm getting at here is that you can build an entire *process* into your hooks if you like.
Adding var dumps, print_r, etc. within display:none areas
So, sometimes you just need to dump an object or array onto the screen to find a variable you're looking for, or to check the output of a script. True, that usually looks bad, and especially if you do a "die" there. But, you can also just embed that data within a div or textarea tag, and then style it with a display:none; So, dump your data on screen, but invisibly, and then go in with your inspector tool and make it visible again... then look for what you want and you're good! Similarly, you can also echo out data within normal HTML comment tags.
Building New Pages Outside of the Menu Structure
Quite often, new development is just that -- absolutely new material on a web site. So, there's no real need to have a development server for that. Just build out your pages on some URL that no one else knows about yet, and don't hook it into the main site until you're ready. There are many ways to go about this, of course, depending on what CMS you're running. But, all are fairly easy. Of course, you can do the same thing for any pure scripting you're doing. You may be working on a live web site, but there's little practical limit to how much work you can do away from any area visible to the public.
So, make yourself a "sandbox" directory, and use that for script testing. Why not? A lot of time, it's just some normal PHP code you're working out -- maybe a small chunk of code or something -- so you don't need a whole separate development site for just that; you simply need just a small corner of any web server to develop working code.
Basing New Code on User IDs
Similar to the $isTesting example, above, keep in mind that you can also code for specific users. So, sometimes, I'll do things like have the system look for who's looking. If it's me, it does X; if not, it does Y. Comes in handy in various situations.
Developing Additions to Function Libraries / Classes
So, maybe you have a library of functions you're including all over the place on your script... and, in your new script, you also need that. Yep, ok... but you also don't want to drop a semicolon in your included file, as you could bonk your whole site. Sure, no worries. Just develop your new functions in a separate file and/or on the same page as your new script. Work out all of the bugs there first, and then move it to your site- or component-wide library. Or... just be *really* careful if you're working with anything that could take down pages other than what you're working on. I know it sounds rather shocking, and yes even experienced programmers make typos, but one can often get away with making code changes within such an environment.
Purposeful Momentary Outages
Okay, here's a shocker... this method is basically out and out *breaking* the site -- on purpose! -- but just for a few seconds. I recommend this method for the quick-draw coders out there who can pull off speedy maneuvers. So, you might, for example do a print_r or something and a die... run the code, get the site to die and dump your data ... and then quick comment out the code & save again. Sounds bad, I know. But, statistically, even on a fairly busy web site, chances are you're the only one who sees the offending screen! Probably not a great candidate for home-page work, but we're talking about a page being shut down for maybe 5 seconds tops here. So, mathematically speaking, we're talking about an outage that accounts for 1 / 17280 of the day. That's immaterial -- unless you're Google, I suppose.
Planning Work During Low-Traffic Hours
Well, this isn't always practical. But, sometimes it's handy to plan work on a live site around other people -- be those visitors or site users -- most of whom usually visit a normal web site during the business day. So, if you do need to tolerate some ugliness on a live site, you sometimes can at least plan it for a time when fewer might see it. Heck, even today, there are still millions of sites where entire areas are live and have notes like "bear with us... we're doing some site construction!".
Taking the Whole Site Offline While You Work
For as much as many like and want a separate development site, it's notable that this functionality is still built into most CMSs. Joomla, which I use, is pretty great for this. You can simply mark the site as offline, and then you're able to still view it if you're signed in as an administrator. Very handy for some types of development -- although this sort of defeats the purpose a little, as your entire site is unavailable to all but you. Still, it's a tool in the toolbox, I suppose.
Similarly, you can always disable only the area of site you're working on. For example, if you have a menu item pointing to a form, maybe just disable that menu item while you work on that form. So, there are less drastic measures, for sure.
Summary and Best Practice Tips
Okay, yes, the above is potentially a lot to keep track of. And it would be especially so under a team approach. However, in the above scenario, it's all ONE person doing that, which also makes it a lot easier. I'm sure this goes against many developers' usual way of working, but who's to say what's better; it's just what suits you more, and I wanted to at least shed some light on this as a possibility.
The above is probably better suited for veteran programmers / developers, as it may be easier using this method to break a site for good if you're not careful. Also, as you're not doing advanced things like version control, rollbacks might be tougher to accomplish. So, be wary of that kind of thing. And, aside from the best practices and ideas noted above, normal development best practices apply as always; backup your sites before and after working on them, and test your new scripts thoroughly!!
Finally, just to point out the obvious... the above can't be recommended, nor is it realistically feasible in ALL cases. But, in some cases -- indeed, in *many* -- it's certainly a-okay. The world will not end, not even if a handful of visitors happen to see something odd in the works (something that should be very mitigated if the above practices are used).