<?xml version="1.0" encoding="UTF-8" ?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
			<title>Tagged with "web"</title>
			<link>http://www.addedbytes.com/feeds/tag-feed/</link>
			<description></description>
			<language>en</language>
			<copyright>Added Bytes - Brighton Web Application Development 2006</copyright>
			<ttl>120</ttl>
			<item>
				<title>Writing Secure PHP, Part 4</title>
				<link>http://www.addedbytes.com/writing-secure-php/writing-secure-php-4/</link>
				<description><![CDATA[ The fourth part of the <a href="http://www.addedbytes.com/writing-secure-php/">Writing Secure PHP</a> series, covering cross-site scripting, cross-site request forgery and character encoding security issues. <p>In <a href="http://www.addedbytes.com/php/writing-secure-php/">Writing Secure PHP</a>, <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a> and <a href="http://www.addedbytes.com/security/writing-secure-php-3/">Writing Secure PHP, Part 3</a> I covered many of the common mistakes PHP developers make, and how to avoid some potential security problems. This article covers some of the more advanced security problems common to PHP on the web.</p>

<h3>Cross-Site Scripting (XSS)</h3>

<p>Cross-site scripting (often abbreviated to XSS) is a form of injection, where an attacker finds a way to have the target site display code they control. In its most basic form, this can be as simple as a site that allows HTML characters in usernames, where someone can specify a username like:</p>

<pre class="php">DaveChild&lt;script type="text/javascript" src="http://www.example.com/my_script.js"&gt;&lt;/script&gt;</pre>

<p>Now, whenever someone sees my username on the target site, the script I've added to my username will run. I could potentially use this to grab the person's login information, log their keystrokes - any number of nefarious activities.</p>

<p>As a developer, you can combat this type of attack by encoding or removing HTML characters (watch out for character encoding issues, as outlined next). Even better than stripping out unwanted characters is to allow a whitelist of safe characters in usernames and other fields. Be especially careful with e-commerce sites where you are listing orders in a CMS - an XSS vulnerability may allow an attacker to gain administrative access to your CMS. It is also important to turn off TRACE and TRACK support on the server, as if there is a vulnerability (and always assume that despite your best efforts there will be) these potentially allow an attacker to steal a user's cookie.</p>

<p>As a user you are also vulnerable to this sort of attack, and it is very difficult, at the moment, to make yourself safe against it. Vigilance is key, and to that end I have released a <a href="http://www.addedbytes.com/tools/xss-alarm-userscript/">userscript that warns you about third party scripts</a> (for users of GreaseMonkey, Opera or Chrome).</p>

<h3>Cross-Site Request Forgery (CSRF)</h3>

<p>Despite the similar name, CSRF is unconnected to XSS. CSRF is a form of attack where an authenticated user performs an action on a site without knowing it.</p>

<p>Let's assume that Jack is logged in to his bank, and has a cookie stored on his computer. Each time he sends an HTTP request to the bank (i.e., views a page or an image on a page) his browser sends the cookie along with the request so that the bank knows that it's him making the request.</p>

<p>Jill, meanwhile, runs a different website and has managed to get Jack to visit it. One of the items on the page is in fact loaded from the bank, for example in an iframe. The URL of the iframe or request contains instructions to the bank to transfer money from Jack's account to Jill's. Because the request is coming from Jack's computer, and includes his cookie, the bank assumes it is a legitimate request and the money is transferred.</p>

<p>This type of attack is extremely dangerous and virtually untracable. As a developer, your job is to protect against it, and the best way to do that is to remember <a href="http://www.addedbytes.com/php/writing-secure-php/">Rule Number One: Never, Ever Trust Your Users</a>. No matter how authenticated they are, do not assume every request was intended.</p>

<p>In practical PHP terms, you can combat CSRF with several relatively simple coding habits. Never let the user do anything with a GET request - always use POST. Confirm actions before performing them with a confirmation dialog on a separate page - and make sure <em>both</em> the original action button or link <em>and</em> the confirmation were clicked. Even better, have the user enter information like letters from their password on the confirmation page.</p>

<p>Add a randomly generated token to forms and verify its presence when a request is made. Use <a href="http://javascript.internet.com/page-details/break-frames.html">frame-breaking JavaScript</a>. Time-out sessions with a short timespan (think minutes, not hours). Encourage the user to log out when they've finished. Check the HTTP_REFERER header (it can be hidden, but is still worth checking as if it is a different domain to that expected it is definitely a CSRF request).</p>

<h3>Character Encoding</h3>

<p>Character encoding in PHP and associated database systems is worthy of its own series. In any one request, there may be more different character encodings in use than you might think.</p>

<p>For example, a single request and response (uploading a file to a server and writing information to a database) may involve all of the following differently items with different character encodings: the HTTP request headers, post data, PHP's default encoding, the PHP MySQL module, MySQL's default set, the set of each table being used, a file being opened and read, a new file being created and written, the response headers and the response body.</p>

<p>English-speaking developers generally don't have much cause to get embroiled in character encoding issues, and that results in a lot of developers with a serious lack of understanding of how character encodings work and fit together. For those that do have a reason to look at character encodings, usually that interest ends with the setting of the response's character set.</p>

<p>However, character sets are a fundamental part of all web development. English alone can exist in any one of a wide variety of sets, and developers are usually familiar with the most common two: ISO-8859-1 and UTF-8. Fewer are familiar with UCS-2, UTF-16 or windows-1252. Still fewer are familiar with commonly used alternative language sets (e.g, GB2312 for Chinese).</p>

<p>Which, in a very roundabout way, brings me on to the security pitfalls of character encodings. Where data is processed by PHP using one character set, but a database server uses a different character set, a character (or series of characters) deemed safe by PHP may in fact allow SQL injection against the database.</p>

<p>PHP security expert Chris Shiflett <a href="http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string">has written about this issue</a> and included an example of how it can be exploited to allow SQL injection even where input is sanitized using addslashes().</p>

<p>The solution is to always <em>always</em> use mysql_real_escape_string() rather than addslashes() (or use prepared statements / stored procedures), and to explicitly state character sets at all stages of interaction. Ideally, use the same character set throughout your system (UTF-8 is recommended) and where PHP allows you to specify a character encoding for a function (e.g., htmlspecialchars() or htmlentities()), make use of it.</p>

<p>It's not just SQL that's vulnerable as a result of character encoding bugs. Cross-site scripting is possible even where HTML characters are escaped if character sets are not handled properly. Fortunately, once again that is simple to avoid by properly setting character encodings at all stages of the process and specifying character encoding for functions where possible.</p> <br><br>]]></description>
				<pubDate>Thu, 11 Sep 2008 12:11:14 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/writing-secure-php/writing-secure-php-4/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=coding&amp;start=0" class="ditto_tag" rel="tag">coding</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=mysql&amp;start=0" class="ditto_tag" rel="tag">mysql</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>RSS to iCal</title>
				<link>http://www.addedbytes.com/blog/rss-to-ical/</link>
				<description><![CDATA[ <p>I have been looking for a way to convert the BBC weather feed for my area to iCal, so I can subscribe to it. It's date-based, after all, and RSS never seemed to me to be an appropriate format for subscribing to weather information. iCal always struck me as being "better" for that purpose.</p> <p>I have been looking for a way to convert the BBC weather feed for my area to iCal, so I can subscribe to it. It's date-based, after all, and RSS never seemed to me to be an appropriate format for subscribing to weather information. iCal always struck me as being "better" for that purpose. Of course, the BBC only have an RSS feed for local weather. What I needed was a converter.</p>

<p>After some hunting, I discovered that Dean Sanvitale had written a PHP script to convert RSS feeds to iCal format. However, his site (codent.com) appears to be long since abandoned and the script is no longer available from there. Fortunately, the Wayback Machine did have a copy. Dean originally released the script under a <a href="http://creativecommons.org/licenses/by-sa/1.0/">Creative Commons License</a> which, fortunately, allows me to make the script available to download from this site (note: the script is available from this site under the same license).</p>

<p>So, if you're looking for a way to convert an RSS feed to iCal, this PHP script will do the job. Thanks Dean!</p>

<p>Source: <a href="http://www.addedbytes.com/rss2ical.txt">rss2ical.txt</a></p> <br><br>]]></description>
				<pubDate>Thu, 19 Oct 2006 11:14:16 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/rss-to-ical/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=bbc&amp;start=0" class="ditto_tag" rel="tag">bbc</a>,<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=convert&amp;start=0" class="ditto_tag" rel="tag">convert</a>,<a href="/feeds/tag-feed/?tags=ical&amp;start=0" class="ditto_tag" rel="tag">ical</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=rss&amp;start=0" class="ditto_tag" rel="tag">rss</a>,<a href="/feeds/tag-feed/?tags=rss2ical&amp;start=0" class="ditto_tag" rel="tag">rss2ical</a>,<a href="/feeds/tag-feed/?tags=tools&amp;start=0" class="ditto_tag" rel="tag">tools</a>,<a href="/feeds/tag-feed/?tags=weather&amp;start=0" class="ditto_tag" rel="tag">weather</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>Ten Ways To Improve Your Website Conversion Rate</title>
				<link>http://www.addedbytes.com/online-marketing/ten-ways-to-improve-your-website-conversion-rate/</link>
				<description><![CDATA[ Why worry about getting twice as many people to visit your site, when it can be far easier to double the number of sales from the people already visiting? Here are 10 ways to improve your website conversion rate. <h3>What is a Conversion Rate?</h3>

<p>Your conversion rate is a measure of the number of potential customers that go on to buy. In the context of a website, it is usually the percentage of visitors that make a purchase. Many websites concentrate solely on increasing the number of visitors they have, when often they have fairly simple problems with their site that, if solved, would have a huge effect on their conversion rate and improve their site's bottom line at minimal expense.</p>

<p>Improving a website conversion rate can be relatively simple. Here are 10 techniques for doing just that:</p>

<h3>10. Make The User's Life Easy</h3>

<p>Let's start with something that sounds simple, but apparently is too complex for many companies to get right. The more difficult you make your web site to use, the less people will buy from you.</p>

<p>A well designed website should aim to <em>prevent nobody from buying</em> - to allow 100% of the people who want to buy to do so. So where do they go wrong?</p>

<ul><li><strong>Accessibility</strong><br />Making a site accessible is a legal obligation in many countries. Despite that, inaccessible websites are still being created. That can affect your sales, depending on how inaccessible you are, as visitors find the site impossible to use and go elsewhere (and end up recommending one of your competitors to their friends as well). A fairly typical inaccessible site could be losing 5% of potential sales because of this. (A <em>really</em> inaccessible website could even prevent search engines indexing it, giving a far higher amount of potential lost sales.)
&nbsp;</li><li><strong>Browsers</strong><br />Many designers only pay attention to Internet Explorer. The justification for this is usually that 99% of the site's users use IE. It never seems to occur to the designers that perhaps the reason they have so few visitors with other browsers is that their site is fundamentally broken - it doesn't work in anything else. Percentages of people not using IE varies from site to site - over 60% of visitors to this site use an alternative browser, for example. The number most often quoted though, is that 80-85% of web users are using IE on Windows, which means that an average site that doesn't work in anything else could easily be losing 15-20% of sales.
&nbsp;</li><li><strong>Be Bold!</strong><br />What happens when a user decides to buy a product? They add it to a shopping basket. How do they add it? They click a button or link (usually a button). What happens when they can't see the button? They go elsewhere. There are some users who are <em>still</em> uncomfortable scrolling. Having things above the fold is still important. And yet there are still plenty of sites out there with buttons that are too subtle, or don't say the right thing, or are hidden away at the bottom of the page. "Add" is rubbish button text. "Buy" is ok. "Add xxx To Your Basket" is great. "Add xxx to Your Basket" in big letters on a big, bright button, near the top of the page, is even better. Calls to action, like this, don't have to be gaudy or tasteless, but they do have to be obvious and clear. Sites I have worked on where just the call to action was changed have reported anything from a 1% to 30% increase in sales as a result.
&nbsp;</li><li><strong>Usability</strong><br />If your potential customers want to find out more before they buy, can they? Is it obvious to the user where to go to find the technical specs on your products? Are they online at all? Are they in PDF format? Can users even find your products in the first place? This is probably the most common mistake I see on any website - a complete failure to think of what the user wants and needs, and how they might use a site. Plenty of sites have product pages with a photo and some sales patter - and nothing else. Anything from 1% to 99% of potential sales can be lost through poor usability.</li></ul>

<p>When you combine all of the problems above, it becomes fairly clear how easy it is to have a site perform poorly. Make your site accessible, make sure it is usable, make sure it works in common browsers, and make your calls to action clear and unambiguous, and you should be in a position to start converting the people who want to buy.</p>

<h3>9. Be Clear, Open and Honest</h3>

<p>If you have a product out of stock, say so. Few things annoy users as much as reading all about a product they are after, adding it to a cart, and starting the checkout process - only to find out the product isn't actually available.</p>

<p>The same applies to pricing - a user might spend $100 on a product, but when they find out the shipping is $100 on top of that, they are unlikely to continue the sale. Showing delivery pricing is tricky business, but not impossible. An <a href="http://ip-to-country.webhosting.info/node/view/6">Ip to Country</a> database will allow you to work out where a user is from and show them a likely delivery cost, for example. If you can't do that, show delivery prices for the countries most appropriate to you - where your products are most often delivered, or for major world regions.</p>

<h3>8. Don't Waste Time</h3>

<p>One of the biggest mistakes sites make is asking for too much information. Your conversion process may be sale, or it may be a request for information. Either way, don't waste the user's time asking for things you don't need to know. This is, of course, doubly important when it comes to asking for information the user deems private, and that they don't want to give out without good reason.</p>

<p>You don't need to demand the user's email address before letting them download a PDF. You don't need their phone number when they fill out an email enquiry form. A user may not want to buy from you twice - so why make them create an account so they can buy again later before processing their first order? You can give the user the option to do all of these things by all means, but make sure it's not compulsory.</p>

<h3>7. Help The User Trust You</h3>

<p>Most people are still cautious when buying online, and rightly so. There are plenty of people you really shouldn't give your credit card information to! It's important to give the potential customer every reason to trust you.</p>

<p>An address - bricks and mortar, not a P.O. Box - is a good start. A phone number, with people answering the phone, also helps. Showing a privacy policy and explaining shipping procedures clearly can also help the user to trust you. If you have a SSL certificate, show the "VeriSign Secured" logo to the user.</p>

<p>Design and content also play a part in trust. A poor design gives off an unprofessional feeling. If a company can't afford a decent website, or won't spend the money on it, how can a user be sure their order will be treated with the importance it deserves? If content is inaccurate or badly written, the same applies - show that you take pride in what you do.</p>

<h3>6. Have a Clear Returns Policy</h3>

<p>Returns on the web are, and are likely to remain, a major issue for consumers. With a bricks and mortar shop, the customer knows where the shop is and that to return the product they simply have to go back there and explain the problem. With the web, this is more of an issue. This is especially true for clothing (where people cannot try things on before buying).</p>

<p>Users are impressed with sites with a good returns policy and are more likely to buy from them. Have people phone for returns - they can then explain the problem to a real person, which is always a good first step. Free return shipping is usually a good option, if commercially viable. People don't like to pay to return things, especially if it is a mistake by the retailer. Finally, give the user plenty of time to return things. 28 days is fairly common, but if it takes you that long to deliver a product, what use is the return policy? 28 days from the date of delivery is better.</p>

<h3>5. Keep the User Informed</h3>

<p>When somebody buys something online, they want to know when it's going to arrive at their door. People are impatient, after all. Giving them an estimated delivery date during the checkout process is a good start. Emailing them when their product is dispatched is great. Giving them a tracking number if using a delivery service that supports online tracking is even better. Keep the user informed at every step of the process, before and after sale, about as much as you can.</p>

<p>How will this improve your conversion rate? Leaving the customer happy once they have made a sale means they are more likely to speak favourably about you later. They may even recommend you to their friends and within online communities. They are also far more likely to buy from you again.</p>

<p>Think about it like this - if a salesman is doing their absolute best to help you, and to make your life easy, and answering your questions, you might buy what they were selling. If they completely ignored you after you'd bought from them, how would you feel about them? They might well have undone all the good work they put in, because once you'd completed your purchase they see no immediate value in you. A company that shows it cares about their customers, even after they've finished shopping, will make a user far happier and far more likely to return.</p>

<h3>4. Offer Different Payment Options</h3>

<p>It might sound obvious, but you should offer the user a reasonable selection of methods of payment. Not everybody has a credit card, and those that do don't always want to use them. You don't have to accept cheques, but when deciding on payment methods, consider alternatives to the usual methods. Make the user's life easy and give them what they want.</p>

<h3>3. Improve the Value of Visitors</h3>

<p>People that buy from you are doing so because they like what it is they see. If a user adds a product to a basket, show them other things they might like as well. If they are viewing a product, the same applies - show them similar items. While they might not buy the product they first saw, other similar ones may not have issues that put them off the first. Upselling and cross-selling are tried and tested sales techniques, and there is no reason not to use them on the web.</p>

<h3>2. Be Memorable</h3>

<p>A good site will include information. A poor one is just an online catalogue. Information (articles, advice, reviews and so on) all help the user early in their buying process. Users start with research online, just as they do offline. If you can make contact with the user at that stage of their process, and give a favourable impression, there is a good chance that they will come back and buy from you when they finally decide to make a purchase.</p>

<p>Being memorable, and making sure you stick in the user's mind, is dependant on a lot of factors. You must have a USP (see the next point), and branding is important (no good if your visitors remember why you are great but don't remember your name), as well as the quality of your site and information.</p>

<h3>1. Know Your USP</h3>

<p>Finally, the most important point of all - your Unique Selling Point (USP). Your USP is what sets you apart from your competition. If a visitor goes to several sites looking for a product, why would they decide to buy from you instead of somewhere else?</p>

<p>Many companies do not know their USP. Almost all companies have one, but not all of them are aware of it. If you are a family run business, that's a potential USP. Great customer service, low prices, products that can't be bought elsewhere, free delivery, great support - all of these are USPs. Tell your users what yours is. Shout it from the proverbial rooftops.</p>

<h3>Part 2</h3>

<p>In March 2009, part 2 of this series was added: <a href="http://www.addedbytes.com/online-marketing/nine-more-ways-to-improve-your-website-conversion-rate/">Nine More Tips for Improving Your Website Conversion Rate</a>.</p>

<h3>Bonus!</h3>

<p>One excellent (and practical) way to increase your website conversion rate is to add consumer reviews to your store. They are a proven way to increase sales, and they have an excellent positive effect on your search engine optimisation work. A service like <a href="http://www.feedbackfair.com">FeedbackFair</a> will give your reviews extra credibility.</p> <br><br>]]></description>
				<pubDate>Mon, 12 Jun 2006 12:00:04 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/online-marketing/ten-ways-to-improve-your-website-conversion-rate/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=business&amp;start=0" class="ditto_tag" rel="tag">business</a>,<a href="/feeds/tag-feed/?tags=conversion&amp;start=0" class="ditto_tag" rel="tag">conversion</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=ecommerce&amp;start=0" class="ditto_tag" rel="tag">ecommerce</a>,<a href="/feeds/tag-feed/?tags=howto&amp;start=0" class="ditto_tag" rel="tag">howto</a>,<a href="/feeds/tag-feed/?tags=marketing&amp;start=0" class="ditto_tag" rel="tag">marketing</a>,<a href="/feeds/tag-feed/?tags=seo&amp;start=0" class="ditto_tag" rel="tag">seo</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorials&amp;start=0" class="ditto_tag" rel="tag">tutorials</a>,<a href="/feeds/tag-feed/?tags=usability&amp;start=0" class="ditto_tag" rel="tag">usability</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>
			</item>

			<item>
				<title>Online Marketing for Beginners</title>
				<link>http://www.addedbytes.com/for-beginners/online-marketing-for-beginners/</link>
				<description><![CDATA[ Wondering why you should hire someone to market your website and how they should go about doing it? Hopefully this article can help. <ul class="conversation"><li class="altrow"><span>Client:</span><div>'I want to be number 1 in Google.'</div></li><li><span>Me:</span><div>Sigh. 'Everyone does. Did you have any keywords in mind?'</div></li><li class="altrow"><span>Client:</span><div>'I was thinking of all these words.' (Client hands me a list of words including "sex", "poker", "loans" and so on.)</div></li><li><span>Me:</span><div>'Those have nothing to do with your business.'</div></li><li class="altrow"><span>Client:</span><div>'Yes, but lots of people search for them.'</div></li><li><span>Me (thinks):</span><div>'Did I travel back in time to 1996? Am I suddenly the Marty McFly of SEO? I wonder why DeLorean cars weren't more popular ...'</div></li><li class="altrow"><span>Client:</span><div>'Dave?'</div></li><li><span>Me:</span><div>'Sorry. Ok, we need to talk. Let me explain how search and online marketing actually work ...'</div></li></ul>

<p>It is amazing how many people hire online marketers without the faintest idea of what online marketers actually do. Search engine optimisation (SEO) is fairly simple - SEOs will try and improve your site's performance, usually by trying to leverage their knowledge of how search engines work and tricks they can use to make sites seem more relevant than they actually are to specific keywords.</p>

<p>Marketing online, though, need not have anything to do with search engines. Search engines are irrelevant - good positions and traffic are a by-product of effective online marketing.</p>

<p>Unfortunately, after educating a client on what online marketing is, they usually assume that if they pay you a few hundred pounds, you can make their site compete with the very best out there.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'Ok, I see. Great positions aren't necessarily worth much unless there are customers searching for those keywords.'</div></li><li><span>Me:</span><div>'Right. We want high traffic, but not if it's not going to be bad for your bottom line. Traffic that doesn't convert to sales just costs you money. Same applies for phrases people never search for. No point being number one for the phrase "fish banana druid" - it's likely to get you as many customers as peeing on people that walk past your shop will.'</div></li><li class="altrow"><span>Client:</span><div>'Ok, so if I pay you, say, £300, how long before I'm at number one for this list of relevant phrases?'</div></li><li><span>Me:</span><div>'You wouldn't get in a boxing ring with Joe Calzhaghe after jogging a couple of miles and doing a few push-ups, would you?'</div></li><li class="altrow"><span>Client:</span><div>'Well, no.'</div></li><li><span>Me:</span><div>'Exactly. To compete with the big dogs, you need to think bigger. Your site is a 10 stone weakling at the moment, and the aim is to turn it into a champion. It needs to be Rocky Balboa. You won't get the top spots quickly - this takes time and hard work. And it's not cheap.'</div></li></ul>

<p>People are obsessed with money. Absolutely obsessed. Even more so in a company environment. The chances are the most of the time, the person you are talking to at a client (or potential client) company is not the top dog. They have to justify their decisions, and they certainly have to justify what they spend.</p>

<p>The problem is that the way most people look at SEO (and they are thinking SEO, not marketing - it's up to you to show them the difference) is that they're going to pay a certain amount of money for the top spots for certain keywords. You can guarantee they've been told another company will guarantee 10 number 1 positions for $50.</p>

<p>This is where ROI comes into play. ROI stands for "Return on Investment". Paying $50 for a $0 return is a bad idea - but people do it all the time, because it's cheap. Paying $5,000 for a $50,000 return is a great idea - but people gasp at the very idea they could spend that much in the beginning, despite the potential.</p>

<p>In order to measure a return, you need to use tracking. If you're focussed on natural search, measure natural search traffic. See how many people come to the site, and where from. See where they go in the site. See if they view products, add them to a basket, and complete sales. See if they view products then come back weeks later to buy them. Measure that over time and you can tell a client exactly what effect your marketing campaign is having - and you will be able to show them what they are getting for their money. Usually, telling a client you are going to do this will also put their mind at ease - much easier to spend money on someone when that person tells you how they're going to measure their success. Most companies involved in SEO and online marketing focus on positions, not results.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'That's good to know. If I can see what's going on, I can give hard numbers to my boss. I'd rather tell him we have 10% more visitors and 20% more sales than tell him we're in top positions for our target phrases but traffic has gone down.'</div></li><li><span>Me:</span><div>'Woohoo! You've taken your first step into a larger world.'</div></li></ul>

<p>The other thing to bear in mind with money conversations is that most companies think of their site like a brochure. They think of it as a print-like cost, where they pay a fixed sum and that's it. They put the site up, leave it, and expect results. They should be thinking of a site like a salesman. A salesman that never sleeps, rarely gets ill, and can handle virtually unlimited enquiries. As such, they should be thinking of the money they spend more like a wage.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'We're spending $200 a month on our site now for hosting. Are you saying we should be spending a lot more?'</div></li><li><span>Me:</span><div>'What would you pay a salesman with the figures your site has, ignoring PPC?'</div></li><li class="altrow"><span>Client:</span><div>'Probably $3000 a month.'</div></li><li><span>Me:</span><div>'Then that's what you should be spending on the site. As the figures get better, spend a little more. Remember that that needs to include redesigns, hosting and other costs.'</div></li></ul>

<p>(Note: PPC is something of a difficult subject to bring in to a monthly spend on a site. You should have a monthly spend on PPC, but it should be managed as a separate entity.)</p>

<p>The same traffic you are monitoring to see where site visitors are coming from and what they are doing when they reach the site can also give you some good places to start making changes. Break the traffic down by area, by language, by time of day (user time of day, not server time of day), and track who converts to a sale and who doesn't. Track people through the sales process, and watch which links they click to navigate and buy products.</p>

<p>This will tell you a huge amount about the current users of the site. It will show you quick wins, opportunities, and highlight problems. Forget search - if on your first day marketing a website you can spot that there is a problem with the site checkout process and get it fixed, you could double sales from existing users. That's a good start to any campaign.</p>

<p>Look at language and area closely as well. If a site is getting traffic from the US, but only sells to the UK, look at similar companies only serving the US and strike a deal with them. You direct US traffic to them, they direct UK traffic to you, and you both do slightly better.</p>

<p>Check browser usage stats, especially if the site is a tables-based dinosaur. The chances are that it is an inaccessible mess. Get it cleaned up! Semantic markup is key - it allows user agents (browsers, search engine spiders, screen readers) to attach specific meaning to different areas of a page. Unlike with tables, semantic markup allows you to differentiate between a header and normal content, or to identify an address. Accessible coding is likely to draw attention, and should help you retain a higher percentage of your visitors, and should help reduce the running costs of your website (lower bandwidth bills and quicker turnarounds on redesigns, for example, both save you money).</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'I don't care about different browsers though - they only make up 1% of my traffic. Everyone else uses Internet Explorer'</div></li><li><span>Me:</span><div>'Perhaps it is because your site doesn't work in other browsers that that number is so low. Even if you do have 99% of users on the same system, the other 1% is still important. Techies use different browsers and operating systems. Techies are also often the people who are asked by their families if they know a good site to buy something from. Many directory editors are in the same boat, and techies can create links to your site.'</div></li><li class="altrow"><span>Client:</span><div>'Ok, techies are important. But do I need to care about blind users and all that accessibility stuff?'</div></li><li><span>Me:</span><div>'Yes, of course. It's a legal obligation for one thing, but users with sight problems make up a far larger proportion of your audience than you might think. They have a voice too - and it's far harder to undo the damage some adverse publicity can do than it is to make a site work properly in the first place. Finally, search engine spiders are blind users with no JavaScript support.'</div></li></ul>

<p>Dynamic sites are slightly trickier to improve. Most of the time, they are restricted, with the original authors not allowing access to the website code. Even if access to the code is allowed, changes may be overwritten later or worse cause immediate problems on the site. That said, making a site easier to use is important, and often dynamic sites are not easy to use.</p>

<p>Look at the pages users visit in the site, and how they get there. Look at the products they buy and spot themes. Use that information to make the important sections and products easier to find and organise. For example, if listing products, don't make people click through 4 levels of navigation to find them - improve the product navigation. Once they get there, allow them to reorder the page according to what they consider important, be that name, price, manufacturer - whatever is possible.</p>

<p>Remember also that people like to tell other people about things they find. If a user likes something on your site, they may email the address of the page they are on to a friend. Most people use forms to set the ordering criteria of a page. That means that the user will be sending a friend a URL that will show that friend something different to what the user currently sees. Make life easy for your users - use URLs, not forms, wherever possible in a site.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'I am curious about one thing. We're already really well ranked for the name of our main product, and lots of people search for it. The people that visit our site tend to buy the product. But I can't help feeling that there should be more people coming from the engines. Any ideas?'</div></li><li><span>Me:</span><div>'Yes. The <a href="http://inventory.overture.com/d/searchinventory/suggestion/">Overture Search Term Suggestion Tool</a>', capitalising my speech for no good reason, 'shows that millions of people search for that phrase. I can see you have a top spot. And your traffic is surprisingly low, but converting well.'</div></li><li class="altrow"><span>Client:</span><div>'So I'm not imagining it then - we have a problem?'</div></li><li><span>Me:</span><div>'Yes, we do. When a user looks at search results, they scan the first two or three words of each link. Your link says "Arthur Jackson Ltd. Sheds and other garden products." That comes from your page title.'</div></li><li class="altrow"><span>Client:</span><div>'And that's bad?'</div></li><li><span>Me:</span><div>'Most people will only glance at "Arthur Jackson Ltd". You need to show them, in the first two or three words of your page title, that you have what they are looking for. And you're not doing that. The user has no reason to click on your link ahead of all the others they see.'</div></li></ul>

<p>Titles are tricky. They're important to the user, they provide the text for bookmarks, they appear in search results, and search engines use them as part of ranking algorithms. You need for fit branding into a title, and describe a product, ideally also incorporating a call to action. Tricky stuff. But not impossible.</p>

<p>First, consider the brand. Most companies think their company name should be the first thing in a page title, even if the rest is unique for each page (as it should be). However, unless the company has a household brand name, the company name is irrelevant to the searcher. They're looking for a product (or the answer to a question), so show them you have it.</p>

<p>Next, remember that as titles are used as the text for bookmarks, links and appear in search engines, they should, when taken out of context, by themselves, leave no doubt what a page is about.</p>

<p>A good example of a title is:</p>

<ul class="conversation"><li class="altrow">"Norwegian Blue Parrot - Buy Norwegian Blue Parrots from Mr. Praline's Pet Shop".</li></ul>

<p>You've included the all-important product name twice in the title, along with a call to action, a hefty dose of branding, and not added irrelevant information. It's a title that tells the user straight away what the page is about. No messing around.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'Ok, the titles need sorting, but what about the content of the site? I keep hearing that "Content is King".'</div></li><li><span>Me:</span><div>'Content is, ultimately, King. Sites with lots of great content will, over a decent time period, far outperform sites with no original content. But content doesn't just have to be on site ...'</div></li></ul>

<p>Product is important. The object you sell though is only half of the picture. A user will want support from you. They will want information. They may want news. All of this is part and parcel of the package a company offers. Your site needs good, visible support (including a phone number), as well as plenty of good, original information. Guides to products, online manuals, FAQs, advice - there are always areas, in any industry, where content can be added.</p>

<p>Content need not be solely posted on the website either. Big news should be released as a press release, and there are plenty of services that will distribute press releases for you. These will be reproduced all over the web, allowing more and more people to hear of the company. Most press release services will allow you to embed a link to a site in a press release, generating more direct traffic as well.</p>

<p>When writing content, or advising on the writing of content, remember that it is not about keywords. Sure, keywords are important, but there is more to it than simply stuffing as many keywords into text as possible. Content needs to answer questions - to provide information. It needs to give a user what they are looking for, and they need to feel that it has done that. Content that is written for SEO can read very badly with too many keywords in, and can mean that although more people see an article, most of them leave the site straight away to find a better one.</p>

<p>A good way to add content to a site is a blog, or a news section. Aside from adding plenty of information, this gives a great opportunity to connect with the user. Consumers are constantly being targeted, from every angle, by companies anxious to take their money. Sometimes they get trodden on. When adding content to your site, stay on the side of the average consumer. Recently, in the UK, the energy companies all raised their prices dramatically. Sites that allow users to compare fuel prices almost all missed a great opportunity to have themselves noticed - not one of them posted a decent news item denouncing the changes as unnecessary or over the top. They all simply commented on the change factually.</p>

<p>While on the one hand, some of these companies may be unable to comment in this fashion (and many companies have strict policies regarding neutrality and customer perception), at least one should have been able to stand out by taking a clear, customer-supporting position on the issue. That is the kind of thing that gets companies noticed and remembered, and spotting opportunities like that is key to a good marketing strategy.</p>

<p>Not all content need be inflammatory of course. It does need to be unique in some way, however. It can be controversial, but it could also be definitive - the ultimate and complete guide to a topic. Controversial content is interesting to the user, and definitive content is just plain useful - either makes for good content for any website.</p>

<p>Users go through different stages when buying products, and one of the early ones is a research stage. There is always a good chance that a user will come back to the same place that helped them or impressed them when they were doing research to buy what they were looking for. This is branding - associating specific ideas and feelings with your company. You want your users, when they revisit the web to make a purchase, to think of your company first.</p>

<p>Which brings us nicely to our last, and most important point. Why would a customer think of any company first, ahead of any other. Content will help, yes. A nice design might even make a difference. More than anything else, though, customers pay attention to the company that stands out from the crowd - the company that is <em>different</em>, that offers them something nobody else does. Often known as a Unique Selling Point, or USP, this is the thing that makes you memorable, or if ignored helps you blend into the crowd.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'But we don't have a USP. How do we get one?'</div></li><li><span>Me:</span><div>'Well, hang on one minute. You say you don't have a USP, but is there nothing about your product that makes it better than the alternatives?'</div></li><li class="altrow"><span>Client:</span><div>'Well, we sell Norwegian Blue Parrots. They're all the same, really. Although a rather large proportion of our competitors appear to sell mostly dead ones.'</div></li><li><span>Me:</span><div>'There you go then. Your USP is that your product is, in fact, not dead.'</div></li><li class="altrow"><span>Client:</span><div>'By that reasoning, a USP could be almost anything, when put in the right light. And when did we turn into a Monty Python sketch?'</div></li><li><span>Me:</span><div>'Be quiet about the Monty Python thing. Yes, though, a USP can be virtually anything. It can be quicker delivery than competitors, better products, better customer service, a freephone enquiries number, or simply the people that run the business. Almost every business has a USP - although most of them don't know what it is.'</div></li></ul>

<p>Many businesses don't know their own USP. They can't tell you, when you ask, what makes them different. Many of them will just say "because we're better than the others", but can't explain why. Usually, however, a quick chat will reveal what makes them stand out. Whatever the USP is, it needs to be clear and obvious on the website. The customer can't miss it, because if they don't know what makes one business different from another, they're not going to remember it.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'What about search? You've not told me how to get my site to the top of the search engines!'</div></li><li><span>Me:</span><div>'Let's review, shall we. You've changed your site substantially, so that it meets current standards and you can sell to more of your users. You're showing your clients why you are better than your competition. You've started releasing press releases, and adding content to your site. You're championing the cause of the common man, increasing link numbers and getting people talking about your business. And you know how your users find your site, and what they do when they get there.'</div></li><li class="altrow"><span>Client:</span><div>'And?'</div></li><li><span>Me:</span><div>'You're positioning yourself as a great resource for your market. Your search engine rankings will come as a direct result of everything else you are doing. You're going to perform well in search, as a direct result of good marketing.'</div></li><li class="altrow"><span>Client:</span><div>'I'll get my chequebook.' (Hah. As if.)</div></li></ul> <br><br>]]></description>
				<pubDate>Fri, 19 May 2006 07:34:00 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/for-beginners/online-marketing-for-beginners/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=article&amp;start=0" class="ditto_tag" rel="tag">article</a>,<a href="/feeds/tag-feed/?tags=blog&amp;start=0" class="ditto_tag" rel="tag">blog</a>,<a href="/feeds/tag-feed/?tags=business&amp;start=0" class="ditto_tag" rel="tag">business</a>,<a href="/feeds/tag-feed/?tags=guide&amp;start=0" class="ditto_tag" rel="tag">guide</a>,<a href="/feeds/tag-feed/?tags=howto&amp;start=0" class="ditto_tag" rel="tag">howto</a>,<a href="/feeds/tag-feed/?tags=marketing&amp;start=0" class="ditto_tag" rel="tag">marketing</a>,<a href="/feeds/tag-feed/?tags=optimization&amp;start=0" class="ditto_tag" rel="tag">optimization</a>,<a href="/feeds/tag-feed/?tags=search&amp;start=0" class="ditto_tag" rel="tag">search</a>,<a href="/feeds/tag-feed/?tags=seo&amp;start=0" class="ditto_tag" rel="tag">seo</a>,<a href="/feeds/tag-feed/?tags=toread&amp;start=0" class="ditto_tag" rel="tag">toread</a>,<a href="/feeds/tag-feed/?tags=tutorials&amp;start=0" class="ditto_tag" rel="tag">tutorials</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>
			</item>

			<item>
				<title>Jargon Explained</title>
				<link>http://www.addedbytes.com/online-marketing/jargon-explained/</link>
				<description><![CDATA[ Many of my clients have worked previously consultants and SEOs that inundated them with jargon, especially where proposals and sales calls are concerned. I find myself sometimes using too much jargon - easily done when you spend so much time working in any field. This jargon guide explains the industry terms in simple language. <h3 id="anchortext">Anchor Text</h3>

<p>Anchor text is the text used to link to another site. In this example - <a href="http://www.google.com">Google Web Search</a> - the anchor text is "Google Web Search".</p>

<h3 id="atom">Atom</h3>

<p>Atom is a file format used for web <a href="http://www.addedbytes.com/seo/jargon-explained/#feeds">feeds</a>. It is a type of <a href="http://www.addedbytes.com/seo/jargon-explained/#xml">XML</a> document, and is used in <a href="http://www.addedbytes.com/seo/jargon-explained/#syndication">syndication</a>.</p>

<h3 id="blackhat">Black Hat</h3>

<p>Black Hat is the term used to describe techniques used by some search marketers to promote websites. These techniques are those that go against guidelines published by search engines, and in many cases their use <em>can</em> result in a site being penalised or removed from search engine listings. Black Hat is the opposite of <a href="http://www.addedbytes.com/seo/jargon-explained/#whitehat">White Hat</a>.</p>

<h3 id="cctld">ccTLD</h3>

<p>A ccTLD is a country-code <a href="http://www.addedbytes.com/seo/jargon-explained/#tld">top level domain</a>. .uk, for example, is a ccTLD, as are .au (Australia), .de (Germany), .fr (France), .ca (Canada) and .nz (New Zealand).</p>

<h3 id="clickthroughrate">Click-through Rate</h3>

<p>See <a href="http://www.addedbytes.com/seo/jargon-explained/#ctr">CTR</a>.</p>

<h3 id="cloaking">Cloaking</h3>

<p>Cloaking is a technique used to show content to a search engine and different content to a user. The content shown to the engine is usually designed to help a page rank very well for a certain phrase or word, and the content shown to the user usually designed to maximise the <a href="http://www.addedbytes.com/seo/jargon-explained/#conversion">conversions</a> from that page. Search engines dislike this technique and many sites are banned for using it. It is a <a href="#blackhat">Black Hat</a> technique.</p>

<h3 id="conversion">Conversion</h3>

<p>A conversion is when a website user completes a specific goal. With some sites that can be to complete a sale; with others, to sign up to a newsletter; and with others to make an enquiry.</p>

<h3 id="cookie">Cookie</h3>

<p>A cookie is a small text file stored on a website user's computer. It identifies a repeat visitor to a site, often with a unique code, allowing people to shop online and removing the need to log in to sites repeatedly. Cookies are often considered dangerous by less experienced web users. You can find out more about cookies in <a href="http://www.addedbytes.com/development/are-cookies-dangerous/">Are Cookies Dangerous?</a></p>

<h3 id="cpa">CPA</h3>

<p>CPA stands for "Cost-Per-Action", and is a form of advertising model. The idea is that an advertiser pays a specific amount for each successful <a href="http://www.addedbytes.com/seo/jargon-explained/#conversion">conversion</a>, be that a sale or a signup.</p>

<h3 id="cpc">CPC</h3>

<p>CPC stands for "Cost-Per-Click", and is a form of advertising model. The idea is that an advertiser pays a specific amount for each visitor referred to their website, regardless of whether that user converts to a sale or not.</p>

<h3 id="cpm">CPM</h3>

<p>CPM stands for "Cost-Per-Mille", and is a form of advertising model. The idea is that an advertiser pays a specific amount for every thousand times his advert is seen on a site, regardless of how many of the users who see the advert click on it and visit the advertiser's site.</p>

<h3 id="crawler">Crawler</h3>

<p>See <a href="http://www.addedbytes.com/seo/jargon-explained/#spider">Spider</a>.</p>

<h3 id="ctr">CTR</h3>

<p>CTR stands for "Click-through Rate". It is an indicator of the percentage of people who see an advert who actually click on it. For example, if one out of every hundred people who view an advert click on it, the advert with have a CTR of 1%.</p>

<h3 id="directory">Directory</h3>

<p>A directory is different to a search engine in that it organises the sites it lists in categories. Sites are usually added by hand, rather than found using a <a href="http://www.addedbytes.com/seo/jargon-explained/#spider">spider</a>, and often a small fee is charged for this addition.</p>

<h3 id="datacenter">Data Center</h3>

<p>A data center is a large collection of computers that hold information for a search engine. Major search engines have several of these around the world. Their purposes is to process search queries.</p>

<h3 id="doorway">Doorway Page</h3>

<p>A doorway page is a page designed specifically to rank well in search engines. Often a visitor to a doorway page will not notice they have visited one, as they will be sent straight on to the target page instantly. Use of doorways is a <a href="http://www.addedbytes.com/seo/jargon-explained/#blackhat">Black Hat</a> technique.</p>

<h3 id="feed">Feed</h3>

<p>A feed is a file that users can download that contains information about recent updates and additions to a website. Often these feeds are used for <a href="http://www.addedbytes.com/seo/jargon-explained/#syndication">syndication</a> purposes. Using feeds and programs designed to use feeds, users can often keep up to date with many hundreds of websites.</p>

<h3 id="ffa">FFA</h3>

<p>FFA stands for "Free-For All". It is usually used in conjunction with links pages that allow anyone and everyone to add a link to the page.</p>

<h3 id="googledance">Google Dance</h3>

<p>The Google Dance is the name for the process Google used to go through very regularly when it updated an algorithm. As various <a href="http://www.addedbytes.com/seo/jargon-explained/#datacenter">data centres</a> around the world were progrssively updated, people would be able to make the same search several times in succession and see different results each time. The Google Dance does not happen as often now, but can still be seen when major changes are made to the Google infrastructure or algorithms.</p>

<h3 id="hit">Hit</h3>

<p>A "hit" can mean one of two things.</p>

<ul><li>When searching the web, a hit can be a result found by a search engines that matches the search criteria.</li><li>In analytics, a hit is when a file is requested by a server. Some people have used hits as a measure of website traffic, however hits to a server include images and repeat visitors, and are a poor indicator of traffic. One thousand hits very rarely equals one thousand visits.</li></ul>

<h3 id="ibl">IBL</h3>

<p>IBL stands for "Inbound Link", and refers to a link pointing to a website from a separate website (unlike an internal link, which refers to a link within one website pointing to somewhere else within the same site).</p>

<h3 id="impression">Impression</h3>

<p>Impression is the word used to describe a single viewing of something. A page impression would mean a single view of a web page. In advertising, one impression is a single view of the advert.</p>

<h3 id="keyword">Keyword</h3>

<p>A keyword is simply a word used to describe a page. It can also be a word used by someone trying to find a site, entered into a search engine.</p>

<h3 id="keyphrase">Keyphrase</h3>

<p>A keyphrase is very similar to a <a href="http://www.addedbytes.com/seo/jargon-explained/#keywords">keyword</a>, except that it is a phrase made up of several words.</p>

<h3 id="keywordstuffing">Keyword Stuffing</h3>

<p>Keyword stuffing is the practice of repeating a keyword (or keywords) far too many times throughout a page. It may be that the keyword is repeated so many times in the text that as a result the text reads badly. It may be that it is repeated lots of times in meta tags, or elsewhere in code, or it may be a combination of these things. Common practice in the late 90s, this is now considered a technique that may harm a site more than help it.</p>

<h3 id="linkbuilding">Link Building</h3>

<p>Link Building is the process used to increase the number of links to a website. This can include submitting a website to directories, creating more content for a website, link rental, and many more techniques. Most search engines now use link data extensively in their algorithms, and so link building has become far more common.</p>

<h3 id="metadata">Meta Data / Meta Tag</h3>

<p>Meta Data is information held about a page or document. It is usually held invisibly within the page, and may include a description of the page, a list of relevant keywords, or the name of the author. For a full explanation of common meta tags, and how to work out which ones are worth using, please read <a href="http://www.addedbytes.com/seo/meta-tags/">Meta Tags</a>.</p>

<h3 id="pagetitle">Page Title</h3>

<p>A page title is an important part of a page - it is usually the part of the page that appears as a link in search results. It is usually visible in the title bar of your browser while you are viewing a page.</p>

<h3 id="pr">PageRank / PR</h3>

<p>PageRank is an algorithm, developer by Larry Page and Sergey Brin, founders of Google. It allows you to find the "best" pages of a group of pages by looking at how the pages link to each other. The more links a page has, the better it is considered, and the more important its links, in turn, are considered. PageRank is named after Larry Page.</p>

<h3 id="payperaction">Pay Per Action</h3>

<p>Pay Per Action advertising is the same advertising model as <a href="http://www.addedbytes.com/seo/jargon-explained/#cpa">CPA</a>, in that an advertiser will pay every time a user completes a specific action.</p>

<h3 id="paypercall">Pay Per Call</h3>

<p>Pay Per Call advertising is a subset of <a href="http://www.addedbytes.com/seo/jargon-explained/#payperaction">Pay Per Action</a>, and is the same advertising model as <a href="http://www.addedbytes.com/seo/jargon-explained/#cpa">CPA</a>, in that an advertiser will pay every time a user calls a specific number.</p>

<h3 id="payperclick">Pay Per Click</h3>

<p>Pay Per Click advertising is the same advertising model as <a href="http://www.addedbytes.com/seo/jargon-explained/#cpc">CPC</a>, in that an advertiser will pay every time a user clicks on their advert.</p>

<h3 id="pfi">PFI</h3>

<p>PFI stands for "Pay For Inclusion". Some engines will charge sites to be listed at all in their results (notably Yahoo for many years). Prices vary greatly, and some engines charge annually, where others charge a one-off fee. This is a far more common feature of directories than search engines.</p>

<h3 id="ppc">PPC</h3>

<p>See <a href="payperclick">Pay Per Click</a>.</p>

<h3 id="robots">Robots.txt</h3>

<p>A robots.txt file is a simple text file that contains instructions for search engine <a href="http://www.addedbytes.com/seo/jargon-explained/#spider">spiders</a>. It can tell specific spiders to slow down, or not to index specific area of a site. For more information, please read <a href="http://www.addedbytes.com/development/robots-txt-file/">robots.txt</a>.</p>

<h3 id="roi">ROI</h3>

<p>ROI stands for "Return on Investment". It is a measure of the success of any marketing campaign. A marketing campaign that cost ?10,000 but made ?3,000 would obviously have a low ROI. A marketing campaign that cost ?10,000 but made ?100,000 would have a high ROI.</p>

<h3 id="rss">RSS</h3>

<p>RSS is a type of <a href="http://www.addedbytes.com/seo/jargon-explained/#xml">XML</a> file, and is the most commonly used file format for website <a href="http://www.addedbytes.com/seo/jargon-explained/#feed">feeds</a>.</p>

<h3 id="sem">SEM</h3>

<p>SEM is an acronym of "Search Engine Marketing". SEM is a broader topic than <a href="http://www.addedbytes.com/seo/jargon-explained/#seo">SEO</a>, and can include, for example, an online PR campaign or <a href="http://www.addedbytes.com/seo/jargon-explained/#ppc">PPC</a> (and other forms of) advertising.</p>

<h3 id="seo">SEO</h3>

<p>SEO is an acronym of "Search Engine Optimisation", and is the art of altering a website to improve a site's performance in search engines (note: an improvement in performance does not equal an increase in traffic!).</p>

<h3 id="serps">SERPs</h3>

<p>SERPs is an acronym for "Search Engine Result Pages".</p>

<h3 id="ses">SEs</h3>

<p>SE is an abbreviation of "Search Engine".</p>

<h3 id="sitemaps">Site Map</h3>

<p>A site map is a page, or set of pages, on a website, designed to help users and search engines find their way around a site.</p>

<h3 id="spam">Spam</h3>

<p>Spam has many different meanings on the web. The most common meaning is related to email, where spam describes unwanted email, often commercial in nature, and often sent out indiscriminately to millions of people at once. In a search engine context, spam refers to pages that are listed out of place. This can mean pages that are found for keywords unrelated to their content. It can also mean pages appearing unnaturally high in search engines. These pages are often promoted using <a href="http://www.addedbytes.com/seo/jargon-explained/#blackhat">Black Hat</a> techniques, especially <a href="http://www.addedbytes.com/seo/jargon-explained/#cloaking">cloaking</a> and <a href="http://www.addedbytes.com/seo/jargon-explained/#doorway">doorway pages</a>.</p>

<h3 id="spider">Spider</h3>

<p>A spider, also often called a "crawler", is a program created by a search engine to index pages on the web. It visits pages on the web, collects their content, and finds links within that page. It then adds the links found on that page to those it intends to crawl.</p>

<h3 id="splashpage">Splash Page</h3>

<p>A splash page is an introduction page to a website, often created using flash. They are much derided, as they slow down access to a website and often provide no useful information to the user.</p>

<h3 id="stopword">Stop Word</h3>

<p>A stop word is a word that is ignored by the search engines. It is a word that appears so often on the web as to be useless to a search engine. Examples include "a", "and", "I", "you" and "it".</p>

<h3 id="syndication">Syndication</h3>

<p>Syndication is where a website makes information available for others to use. In the majority of cases, the information available is a list of the content most recently added to the site (a <a href="http://www.addedbytes.com/seo/jargon-explained/#feed">feed</a>), to allows visitors to keep up to date easily with new content added to many sites.</p>

<h3 id="textlinkad">Text Link Ad</h3>

<p>A text link ad is a type of advert on a website, placed in return for a simple monthly fee. These types of advert can have a positive effect on a website's SEO campaign, and can directly generate traffic to websites.</p>

<h3 id="tld">TLD</h3>

<p>A TLD is an acronym for "Top Level Domain". .com, .org, .net, .biz, .info, .name and .pro are all examples of TLDs. They are usually global TLDs, unlike <a href="http://www.addedbytes.com/seo/jargon-explained/#cctld">ccTLDs</a>, which are country-code domains.</p>

<h3 id="url">URL / URI</h3>

<p>A URL (Uniform Resource Locator), sometimes (more correctly) referred to as a URI (Uniform Resource Identifier), is in basic terms a web address. For example, "http://www.addedbytes.com" is a URI.</p>

<h3 id="visits">Visit</h3>

<p>A visit is different from a <a href="http://www.addedbytes.com/seo/jargon-explained/#hit">Hit</a> or an <a href="http://www.addedbytes.com/seo/jargon-explained/#impression">Impression</a>, in that it indicates a single person's visit to a website. A visit may include many page impressions, and many hits.</p>

<h3 id="whitehat">White Hat</h3>

<p>White Hat is the term used to describe techniques used by some search marketers to promote websites. These techniques are those that adhere to the guidelines published by search engines. White Hat is the opposite of <a href="http://www.addedbytes.com/seo/jargon-explained/#blackhat">Black Hat</a>.</p>

<h3 id="xml">XML</h3>

<p>XML is a file format designed to create files that are easy to share and understand.</p> <br><br>]]></description>
				<pubDate>Wed, 03 May 2006 12:17:00 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/online-marketing/jargon-explained/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=article&amp;start=0" class="ditto_tag" rel="tag">article</a>,<a href="/feeds/tag-feed/?tags=blog&amp;start=0" class="ditto_tag" rel="tag">blog</a>,<a href="/feeds/tag-feed/?tags=google&amp;start=0" class="ditto_tag" rel="tag">google</a>,<a href="/feeds/tag-feed/?tags=jargon&amp;start=0" class="ditto_tag" rel="tag">jargon</a>,<a href="/feeds/tag-feed/?tags=reference&amp;start=0" class="ditto_tag" rel="tag">reference</a>,<a href="/feeds/tag-feed/?tags=search&amp;start=0" class="ditto_tag" rel="tag">search</a>,<a href="/feeds/tag-feed/?tags=seo&amp;start=0" class="ditto_tag" rel="tag">seo</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 3</title>
				<link>http://www.addedbytes.com/writing-secure-php/writing-secure-php-3/</link>
				<description><![CDATA[ The third part of the Writing Secure PHP series, covering weak passwords, clients and more advanced topics. <p>In <a href="http://www.addedbytes.com/php/writing-secure-php/">Writing Secure PHP</a> and <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a> I covered many of the basic mistakes PHP developers make, and how to avoid common security problems. It is time to get a little deeper into security though, and begin to tackle some more advanced issues.</p>

<p>[Writing Secure PHP is a series. <a href="http://www.addedbytes.com/php/writing-secure-php/">Part 1</a>, <a href="http://www.addedbytes.com/php/writing-secure-php-2/">Part 2</a> and <a href="http://www.addedbytes.com/php/writing-secure-php-4/">Part 4</a> are currently also available.]</p>

<h3>Context</h3>

<p>Before I start, it is worth mentioning at this point in this series that much of what is to come is highly dependant on context. If you are running a small personal site and are regularly backing it up, the chances are that there is no real benefit to you spending weeks on advanced security issues. If an attacker can gain nothing (and cause no harm) by compromising your site, and it would only take you ten minutes to restore it, should something go wrong, then it would be a waste to spend too long on security concerns. At the other end of the scale, if you are managing an ecommerce site that processes thousands of credit cards a day, then it is negligent not to spend a lot of time researching and improving your site's security.</p>

<h3>Database Field Lengths</h3>

<p>Database (we're going to talk about <a href="http://www.mysql.com">MySQL</a> here, but this is applicable to any database) fields are always of a specific type, and every type has its limits. You can as well, in MySQL, limit field lengths further than they are already limited by their types.</p>

<p>However, to the inexperienced developer, this can present problems. If you are allowing users to post an article on your site, and adding that to a database field with type "blob", then the longest article you can store in the database is 65,535 characters. For most articles that will be fine, but what is going to happen when a user posts an article of 100,000 characters? At best, if you have set up your site so errors are not displayed, their article will simply vanish without being added to the site.</p>

<p>Remember that for an attacker to be able to compromise your system, they need information about it. They need to find weaknesses. Error messages are a very powerful part of that and if you are displaying errors, then an attacker can make use of this to find out information about your database.</p>

<p>To fix this, simply check the lengths of data input through forms and querystrings and ensure that before you launch a site you check forms will not cause errors to be displayed when too many characters are entered.</p>

<h3>Weak Passwords</h3>

<p>Dictionaries are a useful tool for an attacker. If you have a site with a login system and your database were compromised (and there is no harm in assuming that at some point it will be), an attacker can grab a list of hashed passwords. It is difficult (practically impossible) to directly translate a hash back into a password.</p>

<p>However, most attackers will have databases containing lists of words and their matching hashes in common formats (eg a database with all words in English and their MD5 hashes). It is fairly easy, should someone gain access to your database, for them to compare a hashed password to this list of pre-hashed passwords. If a match is found in the list, the attacker then knows what the un-hashed password is.</p>

<p>There are ways to avoid this problem, and the best of those is to ensure that only strong passwords are ever used. Some people find guaging the strength of passwords tricky, but the general rule of thumb is: a password like "password", "admin", "god", "sex", "qwerty", "123456" or similar (i.e. easily guessable) is extremely weak; a password made up only of a word in the dictionary is weak; a password made of letters, numbers and making use of upper and lower case is strong (there is a strong usability case to be made for not using case-sensitive passwords - if you wish to use case-insensitve ones, simply perform checks to ensure people do not pick passwords like "password12345").</p>

<h3>Clients</h3>

<p>Clients are a huge security risk, believe it or not. Some will hire a cheaper developer to make small changes six months after you're finished. Some will give out FTP details to anyone who phones and asks for them. [Out of curiosity, I decided to see how easy it is to get FTP details over the phone. I visited the site of a local company (who shall remain nameless) and found the name of their design company (who shall also remain nameless). I then phoned the local company and told them I was with the design company and needed them to send me the site's FTP details. They agreed without question or hesitation. Scary. (I told them what I was doing before they sent any sensitive data to me and they are now better educated and suitably paranoid about people asking for details over the phone).]</p>

<p>Some will ignore emails from people pointing out security problems (in the process of writing the previous article in this series, I found a large selection of sites with publically available database connection scripts. I emailed the owners explaining why they are at risk, and only one has replied and had the problem fixed at the time of writing). Admitedly, many of the emails and calls they receive will be misinformation or sales pitches, but it is still worth them having someone check this out - they do not know enough to distinguish a genuine problem from the rest.</p>

<p>Unfortunately, this is one security problem that cannot be solved with code. This one requires education. For this reason, I have created an unbranded copy of the sheet I give to my clients, with a selection of security tips on. When we launch the site, I sit down with them and tell them how they need to treat their site, and what to consider when making decisions regarding it.</p>

<p><a href="content/writing-secure-php-3/client_security.png">Client Security Handout</a> (PNG, 74KB)</p>

<h3>Code Injection (a.k.a. "Cross-Site Scripting")</h3>

<p>Unlike SQL Injection, which relies on the use of delimiters in user-input text to take control of database queries, code injection relies on mistakes in the treatment of text before it is output. Or, to put it in simpler terms, code injection is where a malicious user uses a text box to add HTML that they've written to your webpage.</p>

<p>Let's say you have a system that allows users to register as members to your site and that they are allowed to create their own username. They fill out a form, and you insert the data they enter, once you've made it safe to use in a SQL query, into a database. Your members listing page fetches all the usernames from the database and lists them, outputting exactly what is in the database to anyone that views that page.</p>

<p>Now, let's say you've not added a limit to username lengths. Someone could, if they wanted, create a user with the following username:</p>

<pre class="php">Username&lt;script type="text/javascript" src="http://www.website.com/malicious.js"&gt;&lt;/script&gt;</pre>

<p>Anyone that then views a page with that username on it will see a normal username, but a JavaScript has been loaded from another site invisibly to the user.</p>

<p>There are plenty of uses for this. First and foremost, it allows attackers to add keyloggers, tracking scripts or porn banners on your site, or just stop your site working altogether. There are several ways to ensure this doesn't happen. First, you could encode HTML in usernames. If you wanted to allow people to use greater-then and less-than signs in their usernames, that is. If not, you can strip these characters out, or strip out HTML tags altogether.</p>

<p>Another, better way to approach this is to limit the character set that can be used in usernames. If you only allow letters and numbers, for example, you could simply use a regular expression in the signup process to validate the username and force the user to pick another if they have disallowed characters in their username. Obviously the problem is not just applicable to usernames - however, as with most other security concerns, being quite paranoid will ensure that you always check data coming from a user before outputting it, and sanitising it in an appropriate way.</p>

<h3>Aftermath</h3>

<p>Part of a good security strategy is the assumption that at some point everything (and I mean everything) will be deleted or destroyed. It is wise to assume that at some point any security measure you have in place will be compromised. All data may be taken (which is one reason why it is important to encrypt things like passwords and credit card numbers in databases), all files deleted and so on.</p>

<p>One part of PHP development, though perhaps not directly about PHP security, is ensuring that after a catastrophic failure a site can be brought back online quickly. While downtime of four hours maybe acceptable with a low-traffic point-of-presence site, any ecommerce retailer is going to erupt with fury at the thought of that much lost revenue.</p>

<p>Dealing with the client under these circumstances is the first step. Often, your first inkling of a problem with a site may actually come from the client. They may have phoned you and could be angry, worried, or a myriad of other emotions. At moments like this, you would be very glad to have a clear contigency plan in place. Many developers panic when the client phones saying their front page has been defaced. Stick to your action plan and to your client you will seem confident and unphased. That will relax them. The plan will also allow you to resolve the problem far faster.</p>

<p>First, find out what happened. Are you dealing with a security breach or has someone at the host company tripped over a power lead? Was the database compromised, or deleted, as a result of an attack or was your server simply unable to cope with too much traffic? You need to know what has happened in order to deal with it - a site going offline could be down to too many factors to just assume it is a security problem.</p>

<p>Assuming this is a security problem, the next step is to reassure the client. Let them know what has happened. If someone got into the database, no problem - all sensitive data is encrypted. If they've uploaded files to your server (quite possible), you'll have to delete all files and restore from a backup.</p>

<p>You've got to find out how the attacker broke into your system. Check log files, if you have access to them. Also, have a look at hacker and cracker web sites - many of them will list successful attacks against servers by various groups (these are often what are sometimes known as "script kiddies" - not hackers as such, but usually exploiting vulnerabilities found by others). You may well find your site listed and that listing will give you invaluable information. Look at other sites brought down by the same group at around the same time - you will often spot a theme (e.g. all sites that have been attacked were running the same version of <a href="http://www.microsoft.com/WindowsServer2003/iis/default.mspx">IIS</a> or <a href="http://www.apache.org">Apache</a>, were all running <a href="http://www.phpbb.com">phpBB</a>, or all are file repositories running on <a href="http://www.macromedia.com/v1/cfdocs/cfml_language_reference/contents.htm">CFML</a>).</p>

<p>If you are running any third party software on the site, check the distribution site and if necessary get in touch with them, especially if other sites running the same software appear to have been compromised.</p>

<p>It is very important that you fix any hole there may be before you restore the site. It would be wise to add a "We are currently undergoing essential maintenance" page, but do not fully restore the site before you have found out and fixed whatever the problem was - you'll be wasting your time.</p>

<h3>Shared Hosting</h3>

<p>Shared hosting is much cheaper than dedicated hosting, and is where several sites are all hosted on the same server. Most sites are hosted this way, and this brings with it its own set of security issues.</p>

<p>First and foremost, the security of your site is, in these circumstances, almost entirely out of your hands. It is dependant on the hosting company you are with. They may be excellent, or they may be crooks. Check reviews of a company before you select them, as they will have access to all the data you store with them. There is no harm in being automatically suspicious of your hosting company.</p>

<p>If they are completely above board (and most are), you are still not necessarily secure with shared hosting. The security measures they put in place are generally pretty simple. Shared hosting servers should always use PHP's safe mode (which disables many of the more advanced and dangerous features of PHP). That is what it is there for. However, many don't.</p>

<p>Vulnerabilities associated with shared hosting are, for the most part, out of your hands. A badly set up server will allow any site on that server to access files like /etc/passwd and httpd.conf, often giving them access to all other sites on the same server. It is possible to secure yourself to some degree against the effects of this vulnerability. Storing information in a database is recommended. Of course, if you then store your database login in a file, an attacked could access this information. In order to make this inaccessible to others on the same server, you could set database login information within the httpd.conf file, using environmental variables (you will need to ask your host company to add the lines to the httpd.conf file).</p>

<p>Better yet is to ensure that your host, if shared, uses safe mode. While this is still not 100% secure (nothing is), it does help make these attacks more difficult. A dedicated server is another, far better, option, but the expense may be prohibitive.</p>

<p><em>Ready for more? Try <a href="http://www.addedbytes.com/security/writing-secure-php-4/">Writing Secure PHP, Part 4</a>.</em></p> <br><br>]]></description>
				<pubDate>Wed, 27 Jul 2005 08:58:00 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/writing-secure-php/writing-secure-php-3/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=guide&amp;start=0" class="ditto_tag" rel="tag">guide</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>,<a href="/feeds/tag-feed/?tags=work&amp;start=0" class="ditto_tag" rel="tag">work</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 2</title>
				<link>http://www.addedbytes.com/writing-secure-php/writing-secure-php-2/</link>
				<description><![CDATA[ Learn how to improve your security a little further with the second part of this PHP tutorial. <p>In <a href="http://www.addedbytes.com/php/writing-secure-php/">Writing Secure PHP</a>, I covered a few of the most common security holes in websites. It's time to move on, though, to a few more advanced techniques for securing a website. As techniques for 'breaking into' a site or crashing a site become more advanced, so must the methods used to stop those attacks.</p>

<p>[Writing Secure PHP is a series. <a href="http://www.addedbytes.com/php/writing-secure-php/">Part 1</a>, <a href="http://www.addedbytes.com/php/writing-secure-php-3/">Part 3</a> and <a href="http://www.addedbytes.com/php/writing-secure-php-4/">Part 4</a> are currently also available.]</p>

<h3>File Systems</h3>

<p>Most hosting environments are very similar, and rather predictable. Many web developers are also very predictable. It doesn't take a genius to guess that a site's includes (and most dynamic sites use an includes directory for common files) is an www.website.com/includes/. If the site owner has allowed directory listing on the server, anyone can navigate to that folder and browse files.</p>

<p>Imagine for a second that you have a database connection script, and you want to connect to the database from every page on your site. You might well place that in your includes folder, and call it something like connect.inc. However, this is very predictable - many people do exactly this. Worst of all, a file with the extension ".inc" is usually rendered as text and output to the browser, rather than processed as a PHP script - meaning if someone were to visit that file in a browser, they'll be given your database login information.</p>

<p>Placing important files in predictable places with predictable names is a recipe for disaster. Placing them outside the web root can help to lessen the risk, but is not a foolproof solution. The best way to protect your important files from vulnerabilities is to place them outside the web root, in an unusually-named folder, and to make sure that error reporting is set to off (which should make life difficult for anyone hoping to find out where your important files are kept). You should also make sure directory listing is not allowed, and that all folders have a file named "index.html" in (at least), so that nobody can ever see the contents of a folder.</p>

<p>Never, ever, give a file the extension ".inc". If you must have ".inc" in the extension, use the extension ".inc.php", as that will ensure the file is processed by the PHP engine (meaning that anything like a username and password is not sent to the user). Always make sure your includes folder is outside your web root, and not named something obvious. Always make sure you add a blank file named "index.html" to all folders like include or image folders - even if you deny directory listing yourself, you may one day change hosts, or someone else may alter your server configuration - if directory listing is allowed, then your index.html file will make sure the user always receives a blank page rather than the directory listing. As well, always make sure directory listing is denied on your web server (easily done with .htaccess or httpd.conf).</p>

<p>------</p>

<p>Out of sheer curiosity, shortly after writing this section of this tutorial, I decided to see how many sites I could find in a few minutes vulnerable to this type of attack. Using <a href="http://www.google.com">Google</a> and a few obvious search phrases, I found about 30 database connection scripts, complete with usernames and passwords. A little more hunting turned up plenty more open include directories, with plenty more database connections and even FTP details. All in, it took about ten minutes to find enough information to cause serious damage to around 50 sites, without even using these vulnerabilities to see if it were possible to cause problems for other sites sharing the same server.</p>

<p>-----</p>

<h3>Login Systems</h3>

<p>Most site owners now require an online administration area or CMS (content management system), so that they can make changes to their site without needing to know how to use an <a href="http://filezilla.sourceforge.net/">FTP client</a>. Often, these are placed in predictable locations (as covered in the last article), however placing an administration area in a hard-to-find location isn't enough to protect it.</p>

<p>Most CMSes allow users to change their password to anything they choose. Many users will pick an easy-to-remember word, often the name of a loved one or something similar with special significance to them. Attackers will use something called a "dictionary attack" (or "brute force attack") to break this kind of protection. A dictionary attack involves entering each word from the dictionary in turn as the password until the correct one is found.</p>

<p>The best way to protect against this is threefold. First, you should add a turing test to a login page. Have a randomly generated series of letters and numbers on the page that the user must enter to login. Make sure this series changes each time the user tries to login, that it is an image (rather than simple text), and that it cannot be identified by an optical character recognition script.</p>

<p>Second, add in a simple counter. If you detect a certain number of failed logins in a row, disable logging in to the administration area until it is reactivated by someone responsible. If you only allow each potential attacker a small number of attempts to guess a password, they will have to be very lucky indeed to gain access to the protected area. This might be inconvenient for authentic users, however is usually a price worth paying.</p>

<p>Finally, make sure you track IP addresses of both those users who successfully login and those who don't. If you spot repeated attempts from a single IP address to access the site, you may consider blocking access from that IP address altogether.</p>

<h3>Database Users</h3>

<p>One excellent way to make sure that even if you have a problem with someone accessing your database who shouldn't be able to, you can limit the damage they can cause. Modern databases like MySQL and SQL Server allow you to control what a user can and cannot do. You can give users (or not) permission to create data, edit, delete, and more using these permissions. Usually, I try and ensure that I only allow users to add and edit data.</p>

<p>If a site requires an item be deleted, I will usually set the front end of the site to only appear to delete the item. For example, you could have a numeric field called "item_deleted", and set it to 1 when an item is deleted. You can then use that to prevent users seeing these items. You can then purge these later if required, yourself, while not giving your users "delete" permissions for the database. If a user cannot delete or drop tables, neither can someone who finds out the user login to the database (though obviously they can still do damage).</p>

<h3>Powerful Commands</h3>

<p>PHP contains a variety of commands with access to the operating system of the server, and that can interact with other programs. Unless you need access to these specific commands, it is highly recommended that you disable them entirely.</p>

<p>For example, the <a href="http://www.php.net/eval">eval()</a> function allows you to treat a string as PHP code and execute it. This can be a useful tool on occasion. However, if using the <a href="http://www.php.net/eval">eval()</a> function on any input from the user, the user could cause all sorts of problems. You could be, without careful input validation, giving the user free reign to execute whatever commands he or she wants.</p>

<p>There are ways to get around this. Not using <a href="http://www.php.net/eval">eval()</a> is a good start. However, the php.ini file gives you a way to completely disable certain functions in PHP - "disable_functions". This directive of the php.ini file takes a comma-separated list of function names, and will completely disable these in PHP. Commonly disabled functions include <a href="http://www.php.net/ini_set">ini_set()</a>, <a href="http://www.php.net/exec">exec()</a>, <a href="http://www.php.net/fopen">fopen()</a>, <a href="http://www.php.net/popen">popen()</a>, <a href="http://www.php.net/passthru">passthru()</a>, <a href="http://www.php.net/readfile">readfile()</a>, <a href="http://www.php.net/file">file()</a>, <a href="http://www.php.net/shell_exec">shell_exec()</a> and <a href="http://www.php.net/system">system()</a>.</p>

<p>It may be (it usually is) worth enabling safe_mode on your server. This instructs PHP to limit the use of functions and operators that can be used to cause problems. If it is possible to enable safe_mode and still have your scripts function, it is usually best to do so.</p>

<h3>Finally, Be Completely and Utterly Paranoid</h3>

<p>Much as I hate to bring this point up again, it still holds true (and always will). Most of the above problems can be avoided through careful input validation. Some become obvious points to address when you assume everyone is out to destroy your site. If you are prepared for the worst, you should be able to deal with anything.</p>

<p><em>Ready for more? Try <a href="http://www.addedbytes.com/security/writing-secure-php-3/">Writing Secure PHP, Part 3</a>.</em></p> <br><br>]]></description>
				<pubDate>Tue, 22 Mar 2005 16:53:00 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/writing-secure-php/writing-secure-php-2/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=imported&amp;start=0" class="ditto_tag" rel="tag">imported</a>,<a href="/feeds/tag-feed/?tags=mysql&amp;start=0" class="ditto_tag" rel="tag">mysql</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>,<a href="/feeds/tag-feed/?tags=work&amp;start=0" class="ditto_tag" rel="tag">work</a>
			</item>

			<item>
				<title>Are Cookies Dangerous?</title>
				<link>http://www.addedbytes.com/blog/are-cookies-dangerous/</link>
				<description><![CDATA[ Many inexperienced web users are terrified of cookies, convinced that they are being used to send all their private information (and money) to some sinister group of internet scum. Here is a simple guide to what cookies are and how to make sure you maintain your privacy. <p>The web has been around for many years, and since the early days, websites have been requested by users and delivered to them using HTTP - the HyperText Transfer Protocol. HTTP is the means by which web browsers and web servers communicate. Unfortunately, HTTP is what we call a "stateless" protocol - meaning, effectively, that when you visit a page on a website, and then another page, the website you are visiting has no way of knowing it is the same person that visited the two pages.</p>

<p>This makes things like user login systems difficult to manage. You can't use IP addresses to track users for a variety of reasons, most notably proxy servers that might be used by several people (many hundreds in the case of AOL) to access the web. This is where cookies come in handy.</p>

<p>A cookie is a simple, tiny, text file. It is stored on your PC, and is incapable of performing any tasks or functions. It is simply a text file containing data in text form, just like this (an example cookie from Google):</p>

<code>en_GB
www&#46;google&#46;com/
1425
2053574882
29726548
4298754968
23581292
*</code>

<p>Cookies, once stored on your PC, are tied to a specific web address. That can be a domain (eg google&#46;com), a sub-domain (eg www&#46;google&#46;com), or even a folder (eg www&#46;google&#46;com/folder/). When you revisit a web page, your browser checks to see if any cookies that are stored on your PC are valid ones for the page you are visiting. If they are, the information contained within them is sent back to the server. </p>

<p>Which means, essentially, that a website can only get from a cookie information it put there in the first place. Not all that dangerous in the vast majority of cases. With the above cookie on my PC, any time I visit a page within the "www.google.com" subdomain my browser will send the contents of the text file above to Google.</p>

<p>However, in some circumstances this tool can be put to work in a wider context. Companies like "DoubleClick", that provide advertising (just for example), place data (usually images and links) on web pages. When you see an advert (or any image, or iframe, or even JavaScript), that item may not necessarily be sent from the same server as the rest of the web page. It may be sent from another server. This is perfectly normal in the case of advertising providers. However, along with the image, or text file, many advertisers also usually send a cookie set to use their main domain (eg "DoubleClick.com"). </p>

<p>The next time you request an advert from DoubleClick (i.e. the next time you visit a web page with advertising provided by DoubleClick, or whoever the advertising provider is), your browser may send back data you received in a cookie from a previous time you viewed a DoubleClick advert. One advertiser cannot read cookies from another, as web servers will only send cookie data out when you request a page from within the domain of the cookie.  </p>

<p>What this allows the advertising provider to do is to identify that someone who visited one page also visited another page. It can't identify you personally, but it can tell that someone who viewed a review of "Smokey and the Bandit" on one site then went on to order 6 cases of Jack Daniels on another. Assuming both sites carry advertising from the same provider (increasingly rare). They provide basic thematic profiling - the above example, if repeated by thousands of people, would tell them that people with excellent taste in movies also have excellent taste in drinks. They might use that information to help provide more accurate advertising - Jack Daniels ads on the "Smokey and the Bandit" review, for example.</p>

<p>Can cookies ever contain private information? Yes, they can. A web site can only place information in a cookie that it already has, and only that web site will be able to retrieve that information, so if you have given that web site personal information about yourself, they could store that in a cookie. Is that dangerous? Not in the slightest.</p>

<p>If you want to avoid being tracked by advertisers (and remember, any tracking they do is not personally identifiable to you), there are measures you can take. Most competent browsers allow cookie control (at the end of this article is a guide to preventing your browser from accepting third party cookies). Some allow you to accept and reject cookies individually, or based upon domain. Some will allow you to reject "third party cookies" (the above, cookies sent with advertising, would count as third party cookies), or all cookies altogether. </p>

<p>Personally, I have my version of [url=http://www.opera.com/]Opera[/url] set to reject third party cookies without notifying me. I've had no problems at all using the web since, and running ad-aware every few months turns up no more than one or two tracking cookies, usually ones that have turned up when I've used Internet Explorer for brief testing purposes.</p>

<p>Many people call cookies "Bugs", which makes them sound rather insidious. Misunderstanding and paranoia have made cookies an issue, but for no valid reasons. Most sites have privacy policies now, and I recommend you read a site's privacy policy if you are worried about any cookies they might use. More and more people are just refusing to accept cookies altogether now, but remember - if you reject every single cookie, out of hand, it is ultimately only you that will suffer, as you are just making it harder for the average site to improve your user experience.</p>

<h3>How to prevent your browser from accepting third party cookies.</h3>

<p><strong>Internet Explorer</strong></p>

<ol><li>Click in Tools &gt; Internet Options.</li><li>Select the "Privacy" tab.</li><li>Click "Advanced".</li><li>Select "Override automatic cookie handling".</li><li>Check that you are set to "Accept" (or "Prompt") First Party Cookies, and to "Block" Third Party Cookies.</li><li>Though it is up to you, I recommend you also make sure "Always allow session cookies" is checked.</li><li>Click "ok" to close the "Advanced Privacy Settings" Window.</li><li>Click "ok" to close the Internet Options pop-up.</li></ol>

<p><strong>Opera</strong></p>

<ol><li>Press "ALT-P" or click Tools > Preferences.</li><li>Select "Privacy" on the left.</li><li>Make sure "Enable Cookies" is ticked.</li><li>Next to "Normal cookies", check that "Accept all cookies" is checked.</li><li>Next to "Third party cookies", check that "Refuse all cookies" is checked.</li><li>Click "ok".</li><li>(There are other settings in there you may wish to experiment with until you are happy with your cookie setup).</li></ol>

<p><strong>Mozilla Firefox</strong></p>

<ol><li>Click on Tools > Options.</li><li>Select "Privacy".</li><li>Expand the "Cookies" section.</li><li>Check that, of the four boxes, only the top two, "Enable cookies" and "for the originating web site only" are both ticked.</li><li>Click "ok".</li></ol> <br><br>]]></description>
				<pubDate>Wed, 18 Aug 2004 08:08:00 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/are-cookies-dangerous/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=cookies&amp;start=0" class="ditto_tag" rel="tag">cookies</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 1</title>
				<link>http://www.addedbytes.com/writing-secure-php/writing-secure-php-1/</link>
				<description><![CDATA[ Learn how to avoid some of the most common mistakes in PHP, and so make your sites more secure. <p><a href="http://www.php.net">PHP</a> is a very easy language to learn, and many people without any sort of background in programming learn it as a way to add interactivity to their web sites. Unfortunately, that often means PHP programmers, especially those newer to web development, are unaware of the potential security risks their web applications can contain. Here are a few of the more common security problems and how to avoid them.</p>

<p>[Writing Secure PHP is a series. <a href="http://www.addedbytes.com/php/writing-secure-php-2/">Part 2</a>, <a href="http://www.addedbytes.com/php/writing-secure-php-3/">Part 3</a> and <a href="http://www.addedbytes.com/php/writing-secure-php-4/">Part 4</a> are currently also available.]</p>

<h3>Rule Number One: Never, Ever, Trust Your Users</h3>

<p>It can never be said enough times, you should never, ever, ever trust your users to send you the data you expect. I have heard many people respond to that with something like "Oh, nobody malicious would be interested in my site". Leaving aside that that could not be more wrong, it is not always a malicious user who can exploit a security hole - problems can just as easily arise because of a user unintentionally doing something wrong.</p>

<p>So the cardinal rule of all web development, and I can't stress it enough, is: <strong>Never, Ever, Trust Your Users</strong>. Assume every single piece of data your site collects from a user contains malicious code. Always. That includes data you think you have checked with client-side validation, for example using JavaScript. If you can manage that, you'll be off to a good start. If PHP security is important to you, this single point is the most important to learn. Personally, I have a "PHP Security" sheet next to my desk with major points on, and this is in large bold text, right at the top.</p>

<h3>Global Variables</h3>

<p>In many languages you must explicitly create a variable in order to use it. In PHP, there is an option, "register_globals", that you can set in php.ini that allows you to use global variables, ones you do not need to explicitly create. </p>

<p>Consider the following code:</p>

<pre class="php">if ($password == "my_password") {
    $authorized = 1;
}

if ($authorized == 1) {
    echo "Lots of important stuff.";
}</pre>

<p>To many that may look fine, and in fact this exact type of code is in use all over the web. However, if a server has "register_globals" set to on, then simply adding "?authorized=1" to the URL will give anyone free access to exactly what you do not want everyone to see. This is one of the most common PHP security problems.</p>

<p>Fortunately, this has a couple of possible simple solutions. The first, and perhaps the best, is to set "register_globals" to off. The second is to ensure that you only use variables that you have explicitly set yourself. In the above example, that would mean adding "$authorized = 0;" at the beginning of the script:</p>

<pre class="php">$authorized = 0;
if ($password == "my_password") {
    $authorized = 1;
}

if ($authorized == 1) {
    echo "Lots of important stuff.";
}</pre>

<h3>Error Messages</h3>

<p>Errors are a very useful tool for both programmer and hacker. A developer needs them in order to fix bugs. A hacker can use them to find out all sorts of information about a site, from the directory structure of the server to database login information. If possible, it is best to turn off all error reporting in a live application. PHP can be told to do this through .htaccess or php.ini, by setting "error_reporting" to "0". If you have a development environment, you can set a different error reporting level for that.</p>

<h3>SQL Injection</h3>

<p>One of PHP's greatest strengths is the ease with which it can communicate with databases, most notably <a href="http://www.mysql.com">MySQL</a>. Many people make extensive use of this, and a great many sites, including this one, rely on databases to function.</p>

<p>However, as you would expect, with that much power there are potentially huge security problems you can face. Fortunately, there are plenty of solutions. The most common security hazard faced when interacting with a database is that of SQL Injection - when a user uses a security glitch to run SQL queries on your database.</p>

<p>Let's use a common example. Many login systems feature a line that looks a lot like this when checking the username and password entered into a form by a user against a database of valid username and password combinations, for example to control access to an administration area:</p>

<pre class="php">$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$_POST['username']."' and Password = '".$_POST['password']."'");</pre>

<p>Look familiar? It may well do. And on the face of it, the above does not look like it could do much damage. But let's say for a moment that I enter the following into the "username" input box in the form and submit it:</p>

<pre class="php">' OR 1=1 #</pre>

<p>The query that is going to be executed will now look like this:</p>

<pre class="sql">SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''</pre>

<p>The hash symbol (#) tells MySQL that everything following it is a comment and to ignore it. So it will actually only execute the SQL up to that point. As 1 always equals 1, the SQL will return all of the usernames and passwords from the database. And as the first username and password combination in most user login databases is the admin user, the person who simply entered a few symbols in a username box is now logged in as your website administrator, with the same powers they would have if they actually knew the username and password.</p>

<p>With a little creativity, the above can be exploited further, allowing a user to create their own login account, read credit card numbers or even wipe a database clean.</p>

<p>Fortunately, this type of vulnerability is easy enough to work around. By checking for apostrophes in the items we enter into the database, and removing or neutralising them, we can prevent anyone from running their own SQL code on our database. The function below would do the trick:</p>

<pre class="php">function make_safe($variable) {
    $variable = mysql_real_escape_string(trim($variable));
    return $variable;
}</pre>

<p>Now, to modify our query. Instead of using _POST variables as in the query above, we now run all user data through the make_safe function, resulting in the following code:</p>

<pre class="php">$username = make_safe($_POST['username']);
$password = make_safe($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$username."' and Password = '".$password."'");</pre>

<p>Now, if a user entered the malicious data above, the query will look like the following, which is perfectly harmless. The following query will select from a database where the username is equal to "\' OR 1=1 #".</p>

<pre class="sql">SELECT Username, Password, UserLevel FROM Users WHERE Username = '\' OR 1=1 #' and Password = ''</pre>

<p>Now, unless you happen to have a user with a very unusual username and a blank password, your malicious attacker will not be able to do any damage at all. It is important to check all data passed to your database like this, however secure you think it is. HTTP Headers sent from the user can be faked. Their referral address can be faked. Their browsers User Agent string can be faked. Do not trust a single piece of data sent by the user, though, and you will be fine.</p>

<h3>File Manipulation</h3>

<p>Some sites currently running on the web today have URLs that look like this:</p>

<pre class="php">index.php?page=contactus.html</pre>

<p>The "index.php" file then simply includes the "contactus.html" file, and the site appears to work. However, the user can very easily change the "contactus.html" bit to anything they like. For example, if you are using <a href="http://www.apache.org/">Apache</a>'s mod_auth to protect files and have saved your password in a file named ".htpasswd" (the conventional name), then if a user were to visit the following address, the script would output your username and password:</p>

<pre class="php">index.php?page=.htpasswd</pre>

<p>By changing the URL, on some systems, to reference a file on another server, they could even run PHP that they have written on your site. Scared? You should be. Fortunately, again, this is reasonably easy to protect against. First, make sure you have correctly set "open_basedir" in your php.ini file, and have set "allow_url_fopen" to "off". That will prevent most of these kinds of attacks by preventing the inclusion of remote files and system files. Next, if you can, check the file requested against a list of valid files. If you limit the files that can be accessed using this script, you will save yourself a lot of aggravation later.</p>

<h3>Using Defaults</h3>

<p>When MySQL is installed, it uses a default username of "root" and blank password. SQL Server uses "sa" as the default user with a blank password. If someone finds the address of your database server and wants to try to log in, these are the first combinations they will try. If you have not set a different password (and ideally username as well) than the default, then you may well wake up one morning to find your database has been wiped and all your customers' credit card numbers stolen. The same applies to all software you use - if software comes with default username or password, change them.</p>

<h3>Leaving Installation Files Online</h3>

<p>Many PHP programs come with installation files. Many of these are self-deleting once run, and many applications will refuse to run until you delete the installation files. Many however, will not pay the blindest bit of attention if the install files are still online. If they are still online, they may still be usable, and someone may be able to use them to overwrite your entire site.</p>

<h3>Predictability</h3>

<p>Let us imagine for a second that your site has attracted the attention of a Bad Person. This Bad Person wants to break in to your administration area, and change all of your product descriptions to "This Product Sucks". I would hazard a guess that their first step will be to go to http://www.yoursite.com/admin/ - just in case it exists. Placing your sensitive files and folders somewhere predictable like that makes life for potential hackers that little bit easier.</p>

<p>With this in mind, make sure you name your sensitive files and folders so that they are tough to guess. Placing your admin area at http://www.yoursite.com/jsfh8sfsifuhsi8392/ might make it harder to just type in quickly, but it adds an extra layer of security to your site. Pick something memorable by all means if you need an address you can remember quickly, but don't pick "admin" or "administration" (or your username or password). Pick something unusual.</p>

<p>The same applies to usernames and passwords. If you have an admin area, do not use "admin" as the username and "password" as the password. Pick something unusual, ideally with both letters and numbers (some hackers use something called a "dictionary attack", trying every word in a dictionary as a password until they find a word that works - adding a couple of digits to the end of a password renders this type of attack useless). It is also wise to change your password fairly regularly (every month or two).</p>

<p>Finally, make sure that your error messages give nothing away. If your admin area gives an error message saying "Unknown Username" when a bad username is entered and "Wrong Password" when the wrong password is entered, a malicious user will know when they've managed to guess a valid username. Using a generic "Login Error" error message for both of the above means that a malicious user will have no idea if it is the username or password he has entered that is wrong.</p>

<h3>Finally, Be Completely and Utterly Paranoid</h3>

<p>If you assume your site will never come under attack, or face any problems of any sort, then when something eventually does go wrong, you will be in massive amounts of trouble. If, on the other hand, you assume every single visitor to your site is out to get you and you are permanently at war, you will help yourself to keep your site secure, and be prepared in case things should go wrong.</p>

<p><em>Ready for more? Try <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a>.</em></p> <br><br>]]></description>
				<pubDate>Fri, 16 Jul 2004 09:07:15 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/writing-secure-php/writing-secure-php-1/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=coding&amp;start=0" class="ditto_tag" rel="tag">coding</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=mysql&amp;start=0" class="ditto_tag" rel="tag">mysql</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>Output Caching for Beginners</title>
				<link>http://www.addedbytes.com/for-beginners/output-caching-for-beginners/</link>
				<description><![CDATA[ High-traffic sites can often benefit from caching of pages, to save processing of the same data over and over again. This caching tutorial runs through the basics of file caching in PHP. <p>Caching of output in PHP is made easier by the use of the output buffering functions built in to PHP 4 and above.</p>

<p>You'll need to use two files to set up a caching system for your site. The first, "begin_caching.php" in this case, will run before any other PHP on your site. The second, "end_caching.php" in this case, runs after normal scripts have run. The two scripts effectively wrap around your current site.</p>

<p>You can achieve this wrapping effect one of two ways. The first way is to simply use the include() function and add them manually to every script you run. Unfortunately, this method can take some time, but is arguably more portable than the alternative.</p>

<p>The alternative relies on adding the following two lines of code (modified to reflect the correct path to the two PHP files needed) to your htaccess file. This is my preferred method, just because it requires no modification to existing scripts, and can very easily and quickly be turned off (just by commenting out the relevant lines in the htaccess file).</p>

<pre class="php">php_value auto_prepend_file /full/path/to/begin_caching.php
php_value auto_append_file /full/path/to/end_caching.php</pre>

<p>Next, we move on to the scripts that do the work. There are several stages to caching a document:</p>

<ol><li>Receive request for page</li><li>Check for the existence of a cached version of that page</li><li>Check the cached copy is still valid<ul><li>If it is, send the cached copy</li><li>If not, create a new cached copy and send it</li></ul></li></ol>

<p>To begin with, the script below contains a few basic settings. Here, you can set the directory you want to save cached files to (I would recommend keeping that directory outside your web root directory or at least protecting it from view through a normal browser). This script will need to be able to create files in this directory, and you need to allow this by setting the permissions of the directory. The permissions depend upon your server set up, so you may want to start by setting them to 777 while testing the script, and then reduce them to the lowest levels possible once the script is working.</p>

<p>You can also set the time, in seconds, a cached file should be considered valid for after creation, and set the file extension for saved files. It would be wise to not name them ".php", just for safety's sake.</p>

<pre class="php">&lt;?php

    // Settings
    $cachedir = '../cache/'; // Directory to cache files in (keep outside web root)
    $cachetime = 600; // Seconds to cache files for
    $cacheext = 'cache'; // Extension to give cached files (usually cache, htm, txt)

    // Ignore List
    $ignore_list = array(
        'addedbytes.com/rss.php',
        'addedbytes.com/search/'
    );

    // Script
    $page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // Requested page
    $cachefile = $cachedir . md5($page) . '.' . $cacheext; // Cache file to either load or create

    $ignore_page = false;
    for ($i = 0; $i &lt; count($ignore_list); $i++) {
        $ignore_page = (strpos($page, $ignore_list[$i]) !== false) ? true : $ignore_page;
    }

    $cachefile_created = ((@file_exists($cachefile)) and ($ignore_page === false)) ? @filemtime($cachefile) : 0;
    @clearstatcache();

    // Show file from cache if still valid
    if (time() - $cachetime &lt; $cachefile_created) {

        <em>//ob_start('ob_gzhandler');</em>
        @readfile($cachefile);
        <em>//ob_end_flush();</em>
        exit();

    }

    // If we're still here, we need to generate a cache file

    ob_start();

?&gt;</pre>

<p>The file starts by generating an MD5 hash of the page that has been requested. It will use the complete requested URL, and the MD5 hash will be a 32 digit number, unique for each file. It then checks for the existence of this file.</p>

<p>If the file exists, it checks to see when it was last updated. If the file is older than the allowed time, it acts as though no cache existed (carrying on and generating a new file). If the file is still valid, it simply displays it.</p>

<p>There is also, in the settings, a list of pages to ignore when caching. This can be search results, comments pages, a news page or news feed - anything that should always be up to date. Simply add anything you do not want cached into here, and it will not be cached. You can add directories, or parts of URLs - the above simply searches for a text string. In the example above, I have left out the "http://www" portion of the URL, as this can be missed out by some visitors.</p>

<p>Finally, the two lines in italics above are both commented out. You can, if you like, uncomment these, and that will use outbut buffering to gzip your content before sending it to users, making your site even faster for them. Please note, though, that output buffering with gz encoding is not available in versions of PHP previous to 4.0.5.</p>

<p>Which brings us to the second file, "end_caching.php". At the end of the first file, if no cache exists, we start output buffering. This means that rather than send the page to the user, we are saving it for use later. In the second script below, we take the contents of the output buffer, and write it to a file.</p>

<pre class="php">&lt;?php

    // Now the script has run, generate a new cache file
    $fp = @fopen($cachefile, 'w'); 

    // save the contents of output buffer to the file
    @fwrite($fp, ob_get_contents());
    @fclose($fp); 

    ob_end_flush(); 

?&gt;</pre>

<p><strong>Important:</strong> If you do not have "register_globals" set to off in php.ini, make sure you add the following to the beginning of "end_caching.php" (straight after the "&lt;?php" line) to aid security. This will ensure that an attacker cannot visit "end_caching.php" directly and overwrite an important file on your site (or read its contents).</p>

<pre class="php">    $cachedir = '../cache/'; // Directory to cache files in (keep outside web root)
    $cacheext = 'cache'; // Extension to give cached files (usually cache, htm, txt)
    $page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // Requested page
    $cachefile = $cachedir . md5($page) . '.' . $cacheext; // Cache file to either load or create</pre>

<p>And there we have it. If a cached document exists, it is shown to the user, and if not, one is created.</p>

<p>Finally, you need to make sure the cache remains reasonably clean. Over time, out of date or redundant files could build up, and these should be removed regularly. For this reason, I usually set up an automated script to delete all cache files once a week (or less often, depending on the traffic of the site), but this will depend greatly upon the server software you are using.</p>

<p>The script below is one example of a script to delete all cache files. You will need to set the cache directory at the beginning before running the script. You can either use this manually, visiting the page through your browser whenever you want to empty the cache, or run it automatically. An example of a CRON job used to run this script automatically is below the script (the " &gt;/dev/null 2&gt;&amp;1" bit at the end of the crontab prevents the server emailing me every time the script runs). Please note that this last script will be cached too, unless you specify otherwise!</p>

<pre class="php">&lt;?php

    // Settings
    $cachedir = '../cache/'; // Directory to cache files in (keep outside web root)

    if ($handle = @opendir($cachedir)) {
        while (false !== ($file = @readdir($handle))) {
            if ($file != '.' and $file != '..') {
                echo $file . ' deleted.&lt;br&gt;';
                @unlink($cachedir . '/' . $file);
            }
        }
        @closedir($handle);
    }

?&gt;</pre>

<pre class="php">curl http://www.your_domain.com/empty_caching.php &gt;/dev/null 2&gt;&amp;1</pre> <br><br>]]></description>
				<pubDate>Wed, 09 Jun 2004 15:13:00 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/for-beginners/output-caching-for-beginners/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=article&amp;start=0" class="ditto_tag" rel="tag">article</a>,<a href="/feeds/tag-feed/?tags=cache&amp;start=0" class="ditto_tag" rel="tag">cache</a>,<a href="/feeds/tag-feed/?tags=caching&amp;start=0" class="ditto_tag" rel="tag">caching</a>,<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=performance&amp;start=0" class="ditto_tag" rel="tag">performance</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>
	</channel>
</rss>
