Showing posts with label personal. Show all posts
Showing posts with label personal. Show all posts

Tuesday, September 14, 2010

Scalable Site Structure

If you've been developing web sites for a few years, you've probably developed a lot of sites with a structure similar to the following:

  • /css/
  • /images/
  • /scripts/
  • index.php
  • about.php
  • products.php

One of my colleagues likes to keep the root directory as clean as possible, so his site structures look like this:

  • /content/about.php
  • /content/products.php
  • /common/
  • /images/
  • index.php

Which I find slightly irritating because I prefer to keep my CSS separate from my JavaScript, and the /content/ folder is just taking the mess from one place and moving it to another.

Of course, the Holy Grail of site structures is to have clean URLs like this:

  • /about/
  • /css/
  • /images/
  • /products/
  • /scripts/
  • index.php

If you have a dynamic site, this is easily achieved using mod_rewrite, so /about/ becomes index.php?page=about, but sometimes the client doesn't want to pay for a dynamic site. In that case we use the Poor Man's Clean URLs™ wherein we actually create the /about/ and /products/ folders and put an index.php file in each with the static content. The PHP is then only really used to include a header, footer, navigation, etc.

As a site grows, performance and scalability become a (greater) concern. Popular site speed analysis tools often recommend using a content distribution network. Whether you outsource this or try to do it in-house, it sounds like a lot of work.

I hadn't had the privilege of working on a site that experienced enough traffic to be concerned about scalability until earlier this year. The company was running a national television commercial. They had hired another company to develop a micro-site on a separate server for the campaign, but viewers were being directed to the regular corporate site where a gigantic ad enticed them to visit the micro-site. If you're shaking your head right now, me too. The corporate web server was going down almost daily.

The web statistics package indicated that the most downloaded files were the product videos. I still don't know why they aren't using YouTube or Vimeo for this purpose. On a hunch, I copied the video files to the micro-site's web server and changed all the links. They experienced zero downtime after that.

This experience made me think about how to build scalability into a site from the beginning. Something in the back of my mind twigged a memory of reading something about serving static content from a cookieless domain. Cookies aside, it turns out that serving content from multiple subdomains has certain performance advantages.

Any discussion of clean URLs would not be complete without mentioning www.example.com vs. example.com. Dropping the www seems to be the "cool" thing to do, but my personal feeling is that www.example.com is more descriptive of what you will find there. The mail server is mail.example.com, so the web server should be www.example.com.

So here's the site structure I'm planning to use for future projects:

  • /css/ - css.example.com
  • /images/ - images.example.com
  • /images/logos/ - images.example.com/logos/
  • /images/products/ - images.example.com/products/
  • /js/ - js.example.com
  • /www/ - www.example.com
  • /www/about/ - www.example.com/about/
  • /www/products/ - www.example.com/products/
  • /www/index.php - the actual home page
  • /index.php - file which redirects to www.example.com

The subdomains can be hosted from the primary web server while traffic is small, and migrated to dedicated servers when the traffic increases. The URLs to the images, scripts, and stylesheets don't change, so the PHP files don't need to be updated. Use plenty of folders to keep things organized. You can see I made folders at images.example.com to keep the logos separate from product pictures. If there will be a lot of pictures for each product, I would make folders within the products folder to keep them segregated.

Saturday, June 6, 2009

Publishing schedule change

As I mentioned last week, I ran out of code samples that are suitable for publishing. All that remains is code in various states of partial completion. I was trying to avoid this, but have decided I need to change the publishing schedule of this blog from weekly to whenever I have something finished. I have some fairly large projects on the go right now that I need to focus on if I hope to complete them in my own lifetime. I'm not even sure that anyone is ever reading this besides myself as I type it, so I don't expect anyone will be upset by this.

Saturday, January 24, 2009

A year of reusable code

In just a few more days, it will be one year since I started this blog. Next week Saturday I plan to mark the occasion by sharing with you, one of my most favorite functions. In the weeks following that, I'll be bringing you some larger functions and function libraries which will hopefully make up for some of the less interesting things I've posted over the past year. Unfortunately I can't promise no more boring code, because eventually the good stuff will run out.


If I'm going to be completely honest, some of the functions I've posted here, I wrote specifically for here. The tag line of this blog purports "Practical examples for real-world progrmaming", and I feel that sometimes I wasn't really living up to that. However, I feel to a certain extent that I lived up to what I resolved not to do, which was post silly examples about animals and cars just to illustrate how code works.


Since this is Saturday, I owe you folks some source code. Since next week's code is going to super awesome, I'm going to shamefully post two quick snippets which might seem lackluster, but these were honestly written out of desire/need. Both are re-creations of PHP functions, requested by a PHP programmer that worked for me and had to code in ASP because that's what the existing code was written in.


First we have the echo() function. Our PHP programmer friends are spoiled with not having to type Response.Write every time they want to put something on the screen. Then again, are we not entitled to the same luxuries? Rather than merely aliasing Response.Write, you can also use \n instead of typing vbCrLf.


  1. sub echo(someText)
  2.     Response.Write Replace(someText, "\n", vbCrLf)
  3. end sub

Our second function for today was written for use with HTML's textarea element and SQL data types that contain text with line breaks.


  1. function nl2br(someText)
  2.     nl2br = Replace(someText, vbCrLf, "<br />")
  3. end function

Monday, May 19, 2008

Update

I've updated my Leap Years article with more elegant PHP solutions thanks to Jim Mayes.

I discovered his feedback via a web site called Snipplr, where I've been uploading all the code examples from this blog. All the previous code examples are still available here on the blog, but I'm considering posting future code examples on Snipplr only and linking to them from the blog, because it takes a ridiculous amount of time to format the code examples to display nicely on the blog. I think it will depend on the length of the example; I don't mind reformatting short examples, but I've got some longer ones that I'd rather not.

Anyways, you can view all my code snippets from my Snipplr profile. There are also some bonus things in there which are outside the scope of this blog (eg. Windows registry tweaks). I've also added this link to the sidebar so that it will be easy to find in the future when this post disappears off the front page.

Tuesday, January 29, 2008

A brief introduction

I thought it would be appropriate in my first post to talk a little bit about myself and why I started this blog. My name is Scott, and I used to be a web developer. I still dabble in code for fun, but professionally I've transitioned to the hardware side of things.

Sad to say, most of my experience has been with ASP, but I am in the process of learning PHP. There are a lot of things in PHP that are missing in ASP, and in some future posts we will bridge this gap a little bit. As I'm learning PHP, there are some things from ASP that I'm finding to be more difficult. Perhaps some reusable code can help to bridge that gap as well.

When I was working on my post-secondary education, the instructors in my programming classes often talked about how we would be writing lots of reusable code over our careers, but they never really offered any practical examples. It took a few years, but eventually I found myself needing to do certain things over and over in different places.

There seems to be a lack of high-quality reusable code available on the Internet, so I thought I would do my part to help change that. My goal is to provide working, practical examples that you can take and use in your own work, even commercially. It's my way of giving back a little bit for all the great blog posts that I learned from.