<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Fruits of my Labour &#187; Web Programming and Admin</title>
	<atom:link href="http://www.toao.net/web-programming/feed" rel="self" type="application/rss+xml" />
	<link>http://www.toao.net</link>
	<description>by Mango</description>
	<lastBuildDate>Sun, 18 Jul 2010 21:44:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Seamless Email Server Migration</title>
		<link>http://www.toao.net/438-seamless-email-server-migration</link>
		<comments>http://www.toao.net/438-seamless-email-server-migration#comments</comments>
		<pubDate>Sat, 13 Mar 2010 19:17:24 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Web Programming and Admin]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=438</guid>
		<description><![CDATA[Those of you who run your own email servers will likely need to move from server to server from time to time.&#160; It would be nice if you could just change an MX record and have all email instantly arrive at the new server.&#160; Unfortunately, for various reasons, not everyone obeys TTL, and may cache [...]]]></description>
			<content:encoded><![CDATA[<br />Those of you who run your own email servers will likely need to move from server to server from time to time.&nbsp; It would be nice if you could just change an MX record and have all email instantly arrive at the new server.&nbsp; Unfortunately, for various reasons, not everyone obeys TTL, and may cache the old MX record for an unknown period of time.&nbsp; Here's a list of basic instructions for how to migrate your email from one server to another, guaranteeing that no email will fall through the cracks.<br />
<br  />
<span id="more-438"></span><br   />
<br />

<ol><li>Before you start, be sure the new email server is configured exactly as you please.&nbsp; Make sure that your SPF records are correct and DomainKeys is working.</li>
<li>Change the TTL of your mail server's DNS record to something short like five minutes.&nbsp; Do this at least the length of your previous TTL before the migration.</li>
<li>Several hours before the migration, disable "Leave mail on server" for any users that use POP3.&nbsp; (The POP3 clients will download multiple copies of mail left on the server.)</li>
<li>Create all your email accounts on the new server, exactly as they are on the old server.</li>
<li>Create a subdomain on the new server, something like tempmail.example.com.</li>
<li>Create an alias (forwarder) for each mail account on the new server.&nbsp; If you have an account murphy@example.com, create an alias murphy@tempmail.example.com that forwards to murphy@example.com.</li>
<li>Create an alias (forwarder) for each mail account on the old server.&nbsp; If you have an account murphy@example.com, create an alias murphy@example.com that forwards to murphy@tempmail.example.com.&nbsp; This way, any mail sent to the old server during the migration will be forwarded to the new server.&nbsp; Send an email to murphy@example.com and be sure it arrives in Murphy's account on BOTH servers.<br />
<br />
The next few steps should be done as quickly as possible so that users notice little to no downtime:<br /><br /></li>
<li>Change everyone's email passwords on the old server to something random so that they are no longer able to log in to the old server.</li>
<li>Use rsync or a similar tool to synchronize the mail folders from the old server to the new one.</li>
<li>Change the MX record for example.com so that it points to the new server.</li>
<li>Change any DNS records or redirects to webmail so that they point to the new server.</li>
<li>Change any DNS records for the POP3/SMTP/IMAP servers so that they point to the new server.</li>
<li>Reinstate "Leave mail on server" for POP3 clients, if appropriate.</li></ol>
<br />
Congratulations!&nbsp; If all went according to plan, nobody noticed.]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/438-seamless-email-server-migration/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Which Email Providers are the Most Popular?</title>
		<link>http://www.toao.net/431-most-popular-email-providers</link>
		<comments>http://www.toao.net/431-most-popular-email-providers#comments</comments>
		<pubDate>Wed, 10 Feb 2010 01:37:02 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Web Programming and Admin]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=431</guid>
		<description><![CDATA[At Mango's day job, he operates a mailing list for his customers.&#160; Approximately 2,000 customers have subscribed to it.&#160; He wanted to set up test email accounts with various webmail providers to be sure his emails arrived as intended.&#160; But which webmail providers should he choose?&#160; The most popular email providers were easily found with [...]]]></description>
			<content:encoded><![CDATA[<br />At Mango's day job, he operates a mailing list for his customers.&nbsp; Approximately 2,000 customers have subscribed to it.&nbsp; He wanted to set up test email accounts with various webmail providers to be sure his emails arrived as intended.&nbsp; But which webmail providers should he choose?&nbsp; The most popular email providers were easily found with this MySQL query:<br />


<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span>
<span style="color: #000099;">SUBSTRING</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`email`</span><span style="color: #000033;">,</span> <span style="color: #000099;">LOCATE</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">'@'</span><span style="color: #000033;">,</span> <span style="color: #008000;">`email`</span><span style="color: #FF00FF;">&#41;</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">AS</span> <span style="color: #008000;">`domain`</span><span style="color: #000033;">,</span>
<span style="color: #000099;">COUNT</span><span style="color: #FF00FF;">&#40;</span><span style="color: #CC0099;">*</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">AS</span> <span style="color: #008000;">`count`</span>
<span style="color: #990099; font-weight: bold;">FROM</span> <span style="color: #008000;">`table`</span>
<span style="color: #990099; font-weight: bold;">GROUP BY</span> <span style="color: #008000;">`domain`</span>
<span style="color: #990099; font-weight: bold;">ORDER BY</span> <span style="color: #008000;">`count`</span> <span style="color: #990099; font-weight: bold;">DESC</span></pre></div></div>
For our list, the results were:<br />
<br />
Major regional ISPs - 39%<br />
Hotmail - 14%<br />
Yahoo - 9%<br />
Gmail - 8%<br />
AOL - 1%<br />
<br />
The remaining 29% consisted of small ISPs and insignificant webmail providers, each less than 1% of the total.]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/431-most-popular-email-providers/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatic Read More in Joomla</title>
		<link>http://www.toao.net/182-automatic-read-more-in-joomla</link>
		<comments>http://www.toao.net/182-automatic-read-more-in-joomla#comments</comments>
		<pubDate>Sun, 07 Feb 2010 15:40:22 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Joomla]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=182</guid>
		<description><![CDATA[We've always wanted to be able to set up Joomla to automatically add a "Read More" link for articles in Category Blog or Section Blog Layouts so that the articles would all be the same length and they would line up just as pretty as you please.&#160; Google revealed a handful of other people attempting [...]]]></description>
			<content:encoded><![CDATA[<br />We've always wanted to be able to set up Joomla to automatically add a "Read More" link for articles in Category Blog or Section Blog Layouts so that the articles would all be the same length and they would line up just as pretty as you please.&nbsp; Google revealed a handful of other people attempting the same thing, but having no solution.&nbsp; So Mango wrote a plugin for it.<br />
<br  />
<span id="more-182"></span><br  />
<b>By popular request, we have added the following new features in the new <a href='/pub/plg_AutoReadMore.zip'>Version 1.1 Beta 3</a>:</b><br  />
<ul>
<li>Thumbnails are linked to the full version of the article.</li>
<li>Portuguese and Spanish language files are included.&nbsp; Thanks to the volunteers who translated these!</li>
<li>FJ Related Articles is tentatively supported.</li>
<li>"Developer mode" feature to assist PHP coders in making Auto Read More compatible with other modules.</li>
<li>Bug where special characters were not displayed correctly has been fixed.</li>
<li>Bug where multiple thumbnails were sometimes not displayed correctly has been fixed.</li></ul><br  />
<strong>Features:</strong><br  />
<ul>
<li>Automatically adds "Read more..." link after a configurable number of characters.</li>
<li>Articles with shorter intro text display their intro text only.</li>
<li>Works on the Front Page, Category Blog, or Section Blog.</li>
<li>Will not break HTML or break the article in the middle of a word.</li>
<li>Configurable to ignore specific categories, sections, articles, or the Front Page.</li>
<li>Commented so that you may read through the code and add your own features if you like.</li>
</ul>Latest version (1.1 Beta 3): <a href='/pub/plg_AutoReadMore.zip'>Download Plugin to insert Read More links automatically in Joomla articles</a><br   />
<br  />
<b>Note:</b> If you already use a different version of Auto Read More, <b>you must uninstall it first.</b><br   />
<br />
Old versions: <a href='/pub/plg_AutoReadMore1.0.zip'>1.0</a>, <a href='/pub/plg_AutoReadMore1.1Beta.zip'>1.1 Beta</a>, <a href='/pub/plg_AutoReadMore1.1Beta2.zip'>1.1 Beta 2</a><br   />
<br />
Feature requests, bug reports, and general comments welcome!]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/182-automatic-read-more-in-joomla/feed</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>Easily Check HTTP Headers with this tool</title>
		<link>http://www.toao.net/419-easily-check-http-headers-with-this-tool</link>
		<comments>http://www.toao.net/419-easily-check-http-headers-with-this-tool#comments</comments>
		<pubDate>Mon, 28 Dec 2009 21:30:09 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Web Programming and Admin]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=419</guid>
		<description><![CDATA[We were trying to solve an annoying bug in our mod_rewrite code today and couldn't quite figure out why our server was acting the way it was.&#160; Fortunately we discovered Web-Sniffer.net.&#160; Web-Sniffer.net allows you to view the HTTP request and response headers for any URL you like.&#160; You can even choose between HTTP/1.1 and HTTP/1.0, [...]]]></description>
			<content:encoded><![CDATA[<br />We were trying to solve an annoying bug in our mod_rewrite code today and couldn't quite figure out why our server was acting the way it was.&nbsp; Fortunately we discovered Web-Sniffer.net.&nbsp; Web-Sniffer.net allows you to view the HTTP request and response headers for any URL you like.&nbsp; You can even choose between HTTP/1.1 and HTTP/1.0, with and without the Host header.<br />
<br  />
<a href="http://web-sniffer.net/" target="_blank">View HTTP Headers</a><br   />
<br />
The best part is that this is much easier than messing about with Telnet.exe!]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/419-easily-check-http-headers-with-this-tool/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Six Notify Sounds</title>
		<link>http://www.toao.net/403-six-notify-sounds</link>
		<comments>http://www.toao.net/403-six-notify-sounds#comments</comments>
		<pubDate>Thu, 10 Sep 2009 20:08:45 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Web Programming and Admin]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=403</guid>
		<description><![CDATA[Here are six "notify" sound effects that Mango made for use in an application, free for the download.]]></description>
			<content:encoded><![CDATA[<br />Here are six <a href='/pub/six_notify_sounds.zip'>"notify" sound effects</a> that Mango made for use in an application, free for the download.]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/403-six-notify-sounds/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>12 Things Mango Wishes He&#039;d Known When He Was a PHP N00b.</title>
		<link>http://www.toao.net/266-essential-php-tips</link>
		<comments>http://www.toao.net/266-essential-php-tips#comments</comments>
		<pubDate>Mon, 29 Jun 2009 16:32:15 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=266</guid>
		<description><![CDATA[Never use Register Globals.&#160; Ever.&#160; And if you ever even THINK of using Register Globals, and we find out, Mango is going to send someone over to your house to kick your ass.&#160; Are we clear? As much as we love working with PHP, Register Globals is something that should be filed under "Monumentally Bad [...]]]></description>
			<content:encoded><![CDATA[<br /><ol style='font-weight:bold;'>
<li>Never use Register Globals.&nbsp; Ever.&nbsp; And if you ever even THINK of using Register Globals, and we find out, Mango is going to send someone over to your house to kick your ass.&nbsp; Are we clear?
<div style='font-weight:normal;'>
As much as we love working with PHP, Register Globals is something that should be filed under "Monumentally Bad Ideas".&nbsp; And unfortunately, it's something that, at first glance, appears convenient.&nbsp; If a user submits a form to a PHP script with Register Globals enabled, the script will create a variable for each form element.&nbsp; However, keep in mind that this allows your end users to set any variable in your script that they like.&nbsp; Here is a common mistake that we see:<br />


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$logged_in</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> secret_functions_allow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span></pre></div></div>
In a situation like this, the author has first run some code to see if the user is logged in or not.&nbsp; If so, the script will have defined the $logged_in variable.&nbsp; When the above line of code fires, it will provide the user with some functions only availble to authenticated users.&nbsp; Innocent enough, yes?&nbsp; However, to "hack" this, all that a malicious user would need to do is form a URL like http://www.example.com/?logged_in=1.&nbsp; To turn off Register Globals, add <b>php_flag register_globals off</b> to .htaccess or <b>register_globals = Off</b> to php.ini.&nbsp; Many administrators ban use of Register Globals entirely, so by developing without it, your script will be more portable.&nbsp; This is a good thing.</div></li>
</ol><br  />
<span id="more-266"></span><br   />

<ol start='2' style='font-weight:bold;'>
<li>Turn notices on when developing code.
<div style='font-weight:normal;'>
Yes, we know they're annoying.&nbsp; However, notices provide you with some valuable information you can use both to improve your script and improve your skills as a programmer.&nbsp; One thing that notices will alert you to is undefined variables.&nbsp; Continuing with the above example, the fictitous script assumes that the $logged_in variable will be defined if the user is logged in.&nbsp; Proper programming practice would be a scenario more like $logged_in==1 if the user is logged in and $logged_in==0 if not.&nbsp; If notices are turned on, PHP will alert you to this.&nbsp; To turn notices on, add <b>php_value display_errors on</b> and <b>php_value error_reporting 2147483647</b> to .htaccess or <b>display_errors = On</b> and <b>error_reporting = E_ALL</b> to php.ini.&nbsp; You can also use <b>ini_set('display_errors', 1); error_reporting(E_ALL);</b> in your PHP script however this will not display parse errors such as a missing quote or bracket.<br  />
<b>Security note:</b> you should turn display_errors off for a production server.&nbsp; It's best to use it only when developing code.</div>
</li>

<li>Don't rely on Magic Quotes.
<div style='font-weight:normal;'>
Magic Quotes is a feature of PHP before (but not including) version 6.&nbsp; It was originally created to help prevent <a href='http://php.net/manual/en/security.database.sql-injection.php' target='_blank'>SQL Injection</a> however new thinking is that programmers should write secure code (!) rather than rely on Magic Quotes.&nbsp; Here is an example of a function that you may pass $_GET, $_POST, and $_COOKIE to.&nbsp; It will work whether or not Magic Quotes is enabled.<br />


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> mysql_real_escape_array<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$name</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #990000;">unset</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">get_magic_quotes_gpc</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> mysql_real_escape_array<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #990000;">unset</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">get_magic_quotes_gpc</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
   <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
 <span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></div></div>
</div>

</li>
<li>Do not use the path to your files in your script.
<div style='font-weight:normal;'>
There's nothing worse than having to move servers in a hurry, realizing that you now have a new path to your home directory, and having to change a hardcoded path in dozens of files.&nbsp; Instead of hardcoding paths, use $_SERVER['DOCUMENT_ROOT'] to have your script discover your document root.&nbsp; Or, use dirname(__FILE__) to find the directory that the script is located in.&nbsp; (Note that this is literally dirname(__FILE__) - you don't replace __FILE__ with anything.)  Or, use the <a href='http://php.net/getcwd' target='_blank'>getcwd</a> function.</div>

</li>
<li>Avoid having the same or even similar code in different parts of your script.
<div style='font-weight:normal;'>
You want to do this simply because it's more efficient.&nbsp; It's faster to write code when you don't have to write the same code over and over, it's faster to modify code when you don't have to modify it in multiple places, and it's easier for other people to read the finished product when the code is short.&nbsp; If you have to do the same thing more than once in your script, use functions or loops.&nbsp; If you have to do the same thing in multiple scripts, use include files.</div>

</li>
<li>Don't do <i>for ($i = 0; $i < count($array); $i++) {</i><br   />
<div style='font-weight:normal;'>
Yes, this will run and will often produce the desired results.&nbsp; However, the <a href='http://php.net/count' target='_blank'>count</a> function will run at every single iteration.&nbsp; Instead, it's faster to do:<br />


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$count</span><span style="color: #339933;">=</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$count</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>
</div>

</li>
<li>Come up with a naming scheme for functions, variables, and column names.
<div style='font-weight:normal;'>
Someone once told us that functions and variables should all be named with as much care as one names their first child.&nbsp; We agree.&nbsp; If your naming scheme is effective, one should be able to <b>guess</b> names by looking at other names.&nbsp; The <a href='http://php.net/manual/en/book.mailparse.php' target='_blank'>Mailparse Extension</a> is a good example of effective naming schemes.&nbsp; Additionally, take care when defining the order of parameters in a function.&nbsp; One example of why this is a good idea is the <a href='http://php.net/strpos' target='_blank'>strpos</a> function and the <a href='http://php.net/str_replace' target='_blank'>str_replace</a> function.&nbsp; These functions have two strikes against them.&nbsp; By looking at str_replace, I would assume strpos would be named str_pos.&nbsp; Additionally, the parameters are in different orders: strpos requires the subject first and str_replace requires the subject last.<br />
<br />
For naming functions, we separate words with underscores.&nbsp; The first word in the name is a word that defines the general group of functions that we're writing, (for ease of identifying what the function is for, and also for ease of sorting when writing documentation) and then use more words as necessary to describe the function.&nbsp; Similar functions should have parameters in the same order, with parameters that have default values at the end.&nbsp; For naming database column names, we often use the actual human readable phrase, converted to lower case, with underscores instead of spaces.&nbsp; This occasionally makes for a slightly long column name, but the advantage is that we can later use str_replace and <a href='http://php.net/ucwords' target='_blank'>ucwords</a> to display the name and not need to cross-reference a list of human-readable column names.</div>

</li>
<li>Use UTF-8
<div style='font-weight:normal;'>
There's a great article about <a href='http://developer.loftdigital.com/blog/php-utf-8-cheatsheet' target='_blank'>using UTF-8 with PHP and MySQL</a> at developer.loftdigital.com.</div>

</li>
<li>Use SELECT * only when necessary.
<div style='font-weight:normal;'>
This is a MySQL tip, however we include it here because a great deal of PHP students also wish to learn MySQL.&nbsp; SELECT * is not inherently a bad thing to do, however it's often misused.&nbsp; The only time that it should be used is when you need to select <i>every single column</i> in a table <b>and</b> <i>you do not know in advance what columns the table will have.</i>  We see many people selecting all columns in the table but only actually using one or two.&nbsp; In this case, it's better to do something such as <b>SELECT `first_name`,`last_name`</b>.&nbsp; This makes for a longer query, however since the entire row is not loaded, your script uses less memory.<br />
<br />
Here's an example of where you DO want to use SELECT *.&nbsp; Let's say you have a program that displays information about customers from a database.&nbsp; Perhaps one day you decide that you want to keep track of customers' birthdays.&nbsp; So you add a column to your MySQL table named `birthday`.&nbsp; When your program displays the information about the customer, it is necessary to see all of the information.&nbsp; Because in this case columns such as the `birthday` column may be added in the future and we do not yet know what columns may be added, we have satisfied both of the requirements for using SELECT *.</div>

</li>
<li>Make a wrapper for MySQL queries.
<div style='font-weight:normal;'>
This might not be necessary for quick scripts but it's something we like to do for large projects.&nbsp; The simplest wrapper is as such:<br />


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> mysql_mangos_query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #b1b100;">return</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span></pre></div></div>
There are many advantages to this technique.&nbsp; For example, one may want to use the mysql_error() function to see if the query returned an error, and if so, write the error to a log.&nbsp; Or, if one is working on a large project with multiple tables, one might want to prefix the tables with something like projectname1_ so that multiple instances of the project may run with different data.&nbsp; One example of this is the content management system Joomla.&nbsp; All of Joomla's queries look like <b>SELECT [columns] FROM #__content WHERE...</b>  Joomla removes #__ and replaces it with the appropriate table prefix.</div>

</li>
<li>Learn how to use regular expressions.
<div style='font-weight:normal;'>
Regular expressions are by far the most powerful underused feature of PHP that we see.&nbsp; Students often avoid using them because they look intimidating.&nbsp; We agree, however they're easy to get to know in 15 or 20 minutes.&nbsp; They're often a very simple and efficient solution to data manipulation problems.&nbsp; If you're a programming student, one can easily impress friends (well, fellow programming students anyway) by being able to read and write complex regular expressions.</div>

</li>
<li>Finally, know where to go for documentation.
<div style='font-weight:normal;'>
It's always a good idea to have documentation at your fingertips.&nbsp; We certainly don't claim to know every PHP function there is to know (although that would be really cool).&nbsp; To find documentation on any function, simply go to http://php.net/functionname.&nbsp; If you don't know the name of the function you need, look up a similar function and see if the one you want is listed as a related function.&nbsp; Often, you will also find examples and tips on usage.&nbsp; These are very helpful.&nbsp; For example, someone wanting to find out if a string is contained within a string might look up preg_match.&nbsp; However, this operation does not actually require regular expressions, and as the manual will tell you, it is faster in this situation to use strpos instead.</div></li>
</ol>
Happy coding!]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/266-essential-php-tips/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mango&#039;s PHP PostScript Functions</title>
		<link>http://www.toao.net/244-mangos-php-postscript-functions</link>
		<comments>http://www.toao.net/244-mangos-php-postscript-functions#comments</comments>
		<pubDate>Thu, 18 Jun 2009 04:59:45 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=244</guid>
		<description><![CDATA[The latest techniques we've been playing with involve using a PHP script on our server in Michigan to print to a remote printer at our office in Vancouver.&#160; In the past we've done this by generating an XHTML document with high-resolution images and simply prompting the user to print it.&#160; This worked, but if any [...]]]></description>
			<content:encoded><![CDATA[<br />The latest techniques we've been playing with involve using a PHP script on our server in Michigan to print to a remote printer at our office in Vancouver.&nbsp; In the past we've done this by generating an <a href='/10-600dpi-on-a-website-yes-its-possible'>XHTML document with high-resolution images</a> and simply prompting the user to print it.&nbsp; This worked, but if any sort of precision was required, the user had to configure their browser's page setup just so, and to make things even more difficult, different browsers required different settings.<br />
<br />
Enter PostScript, a language understood by many laser printers.&nbsp; With PostScript, we can go directly from our script to the printer, (pipe the finished PostScript document to the printer on port 9100) eliminating the stop off at the browser.&nbsp; And, we can position things on our page with as much precision as necessary.<br />
<br  />
<span id="more-244"></span><br   />
<br />
PHP has a basic set of functions for creating PostScript documents - and we're very grateful for this because it meant we didn't have to learn PostScript itself - but it lacks advanced text handling features such as vertical alignment and automatic resizing of text.&nbsp; And, while it can do justified text, it does it in very mysterious ways.&nbsp; Fortunately, these issues were not a problem for Mango, and Mango's PostScript Functions were born.<br />
<br />
Here's the source to <a href='/pub/PostScript/mangos_ps_functions.txt'>Mango's PostScript Functions including ps_super_boxed</a>, a <a href='/pub/PostScript/mangos_ps_demo.txt'>demo of how to vertically align and dynamically resize text with PHP and pslib</a>, and the <a href='/pub/PostScript/mangos_ps_demo.pdf'>results of the demo</a>, converted to PDF for easy viewing.&nbsp; (One note: the demo requires the font file Helvetica.afm and we're not sure if we're allowed to distribute that, but it's very easy to find with Google.)<br />
<br />
Enjoy!]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/244-mangos-php-postscript-functions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converters for Webmasters</title>
		<link>http://www.toao.net/227-converters-for-webmasters</link>
		<comments>http://www.toao.net/227-converters-for-webmasters#comments</comments>
		<pubDate>Mon, 08 Jun 2009 04:15:47 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Bookmarklets]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=227</guid>
		<description><![CDATA[When we're writing software, we always seem to use a few functions for quick conversions.&#160; We've got a series of converters bookmarked, but today we were thinking it would be even more handy to have everything all in one place.&#160; So we developed the Converters for Webmasters bookmarklet. Feel free to bookmark this page for [...]]]></description>
			<content:encoded><![CDATA[<br />When we're writing software, we always seem to use a few functions for quick conversions.&nbsp; We've got a series of converters bookmarked, but today we were thinking it would be even more handy to have everything all in one place.&nbsp; So we developed the Converters for Webmasters bookmarklet.<br />
<br  />
<span id="more-227"></span><br   />

<iframe src='/pub/bookmarklets/converter.html' width='100%' height='225'></iframe>
Feel free to bookmark this page for any time you want to use it, or check out our <a href='/pub/bookmarklets/converter_bookmarklet.php'>Converter Bookmarklets</a> for Firefox and Opera.]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/227-converters-for-webmasters/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replacing smart quotes, em-dashes, and ellipses with MySQL or PHP</title>
		<link>http://www.toao.net/48-replacing-smart-quotes-and-em-dashes-in-mysql</link>
		<comments>http://www.toao.net/48-replacing-smart-quotes-and-em-dashes-in-mysql#comments</comments>
		<pubDate>Thu, 05 Mar 2009 21:28:24 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Joomla]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.toao.net/48/replacing-smart-quotes-and-em-dashes-in-mysql/</guid>
		<description><![CDATA[Alternate title: "Help!&#160; My Quotes Appear as Question Marks or Other Strange Characters!" The "Smart quotes" feature in Microsoft Office transforms straight quotes into curly quotes.&#160; It also transforms hyphens into em-dashes and three periods into ellipses.&#160; While one might think, "How lovely!&#160; My document looks almost as if I'm educated!" readers of said document [...]]]></description>
			<content:encoded><![CDATA[<br />Alternate title: "Help!&nbsp; My Quotes Appear as Question Marks or Other Strange Characters!"<br />
<br />
The "Smart quotes" feature in Microsoft Office transforms straight quotes into curly quotes.&nbsp; It also transforms hyphens into em-dashes and three periods into ellipses.&nbsp; While one might think, "How lovely!&nbsp; My document looks almost as if I'm educated!" readers of said document may not.&nbsp; Microsoft, in its infinite wisdom, decided to assign special characters such as the ones I just mentioned to a range of codes above 128.&nbsp; Problem: these codes were already assigned to other characters, resulting in frustrating incompatibility with non-Microsoft systems.<br />
<br />
Keep reading for some PHP and MySQL code to help out with this issue, as well as a Joomla! plugin.<br />
<br  />
<span id="more-48"></span><br   />
<br />
Our introduction to this was in a situation where we had people using many different systems submitting articles to one of our programs.&nbsp; We decided that we wanted all our articles to use straight quotes, hyphens, and periods.&nbsp; This was partly for consistency, and partly because these characters are common to many character sets and won't cause incompatibilities.<br />
<br />
This article isn't really intended as a complete explanation of charsets, though we recommend <a href="http://www.joelonsoftware.com/articles/Unicode.html" target='_blank'>The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets</a> if you're interested in learning more.&nbsp; We will however show you some MySQL and PHP techniques for replacing all instances of smart quotes, plus the en dash, em dash, and ellipsis with straight quotes, one or two dashes, or three dots.&nbsp; This code should operate with both the Windows-1252 charset, and also UTF-8, an encoding with an extended character set that has made it the preferred encoding for email and websites.<br />
<br />
MySQL:<br />


<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># First, replace UTF-8 characters.</span>
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> 0xE28098<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;'&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> 0xE28099<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;'&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> 0xE2809C<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'&quot;'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> 0xE2809D<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'&quot;'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> 0xE28093<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'-'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> 0xE28094<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'--'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> 0xE280A6<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'...'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #808080; font-style: italic;"># Next, replace their Windows-1252 equivalents.</span>
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">145</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;'&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">146</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;'&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">147</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'&quot;'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">148</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'&quot;'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">150</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'-'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">151</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'--'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #ff0000;">`t`</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #ff0000;">`c`</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`c`</span><span style="color: #66cc66;">,</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">133</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'...'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>
PHP:<br />


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// First, replace UTF-8 characters.</span>
<span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span>
 <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\xe2</span><span style="color: #660099; font-weight: bold;">\x80</span><span style="color: #660099; font-weight: bold;">\x98</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\xe2</span><span style="color: #660099; font-weight: bold;">\x80</span><span style="color: #660099; font-weight: bold;">\x99</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\xe2</span><span style="color: #660099; font-weight: bold;">\x80</span><span style="color: #660099; font-weight: bold;">\x9c</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\xe2</span><span style="color: #660099; font-weight: bold;">\x80</span><span style="color: #660099; font-weight: bold;">\x9d</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\xe2</span><span style="color: #660099; font-weight: bold;">\x80</span><span style="color: #660099; font-weight: bold;">\x93</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\xe2</span><span style="color: #660099; font-weight: bold;">\x80</span><span style="color: #660099; font-weight: bold;">\x94</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\xe2</span><span style="color: #660099; font-weight: bold;">\x80</span><span style="color: #660099; font-weight: bold;">\xa6</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
 <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'-'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'--'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'...'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
 <span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Next, replace their Windows-1252 equivalents.</span>
 <span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span>
 <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">145</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">146</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">147</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">148</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">150</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">151</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">133</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
 <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'-'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'--'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'...'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
 <span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>
Joomla!:<br  />
<a href='/pub/plg_StripSmartQuotes.zip'>Joomla! plugin for removing smart/curly quotes, em-dashes and ellipses.</a><br   />
<br />
<br />
Additionally, here's a table of character codes that you may find useful:<br />

<table border="0" cellpadding="2" cellspacing="0" style='width:100%;'>
<tr>
<th>Character</th>
<th>HTML Code</th>
<th>Windows</th>
<th>UTF-8</th>
<th>name</th>
</tr>
<tr>
<td>&lsquo;</td>
<td>&amp;lsquo;</td>
<td>145</td>
<td>E28098</td>
<td>left single curly quote</td>
</tr>
<tr>
<td>&rsquo;</td>
<td>&amp;rsquo;</td>
<td>146</td>
<td>E28099</td>
<td>right single curly quote</td>
</tr>
<tr>
<td>&ldquo;</td>
<td>&amp;ldquo;</td>
<td>147</td>
<td>E2809C</td>
<td>left double curly quote</td>
</tr>
<tr>
<td>&rdquo;</td>
<td>&amp;rdquo;</td>
<td>148</td>
<td>E2809D</td>
<td>right double curly quote</td>
</tr>
<tr>
<td>&ndash;</td>
<td>&amp;ndash;</td>
<td>150</td>
<td>E28093</td>
<td>en dash</td>
</tr>
<tr>
<td>&mdash;</td>
<td>&amp;mdash;</td>
<td>151</td>
<td>E28094</td>
<td>em dash</td>
</tr>
<tr>
<td>&hellip;</td>
<td>&amp;hellip;</td>
<td>133</td>
<td>E280A6</td>
<td>ellipsis</td>
</tr>
</table>
<br />
Further reading from Wikipedia:<br  />
<a href="http://en.wikipedia.org/wiki/UTF-8" target='_blank'>UTF-8</a><br   />
<br  />
<a href="http://en.wikipedia.org/wiki/ISO/IEC_8859-1" target='_blank'>ISO/IEC 8859-1</a><br   />
<br  />
<a href="http://en.wikipedia.org/wiki/Windows-1252" target='_blank'>Windows-1252</a>]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/48-replacing-smart-quotes-and-em-dashes-in-mysql/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>reCAPTCHA is cool.</title>
		<link>http://www.toao.net/57-recaptcha-is-cool</link>
		<comments>http://www.toao.net/57-recaptcha-is-cool#comments</comments>
		<pubDate>Mon, 13 Oct 2008 21:22:59 +0000</pubDate>
		<dc:creator>Mango</dc:creator>
				<category><![CDATA[Web Programming and Admin]]></category>

		<guid isPermaLink="false">http://www.toao.net/?p=57</guid>
		<description><![CDATA[I wanted people to be able to leave comments to my articles without having to go through the hassle of signing up and waiting for an email confirmation.&#160; So, I looked for a CAPTCHA plugin for WordPress - one of those "enter the words you see in this picture" programs.&#160; I found reCAPTCHA, and let [...]]]></description>
			<content:encoded><![CDATA[<br />I wanted people to be able to leave comments to my articles without having to go through the hassle of signing up and waiting for an email confirmation.&nbsp; So, I looked for a CAPTCHA plugin for WordPress - one of those "enter the words you see in this picture" programs.&nbsp; I found reCAPTCHA, and let me tell you, reCAPTCHA has got to be one of the neatest ideas ever.&nbsp; According to the <a href='http://recaptcha.net/' target='_blank'>reCAPTCHA website</a>, "About 60 million CAPTCHAs are solved by humans around the world every day. In each case, roughly ten seconds of human time are being spent. Individually, that's not a lot of time, but in aggregate these little puzzles consume more than 150,000 hours of work each day."<br />
<br />
Amazing!&nbsp; Apparently, a brilliant group of people from the Carnegie Mellon University thought so too.&nbsp; Their next thought was, "How can we harness those 150,000 hours of work?"&nbsp; (Why can't I ever have thoughts like that?)  They got together with some people digitizing old books and newspapers.&nbsp; They had a problem.&nbsp; OCR, technology that is used to convert an image of printed text into digital format, is not perfect and occasionally can't read a word.&nbsp; reCAPTCHA was born.&nbsp; The program takes a known word, pairs it with an unknown word, and gives it to a user to enter.&nbsp; If the user solves the one for which the answer is already known, reCAPTCHA assumes the second is also solved correctly.&nbsp; Presto!&nbsp; Word by word, a book is eventually digitized.<br />
<br />
Here's an example.&nbsp; The word on the right was difficult to read.&nbsp; I assume it's "their".&nbsp; reCAPTCHA will show this word to a few other people as well, in case I'm wrong.<br />
<br  />
<img src="http://www.toao.net/pub/recaptcha2.gif" alt="" title="reCAPTCHA example" width="317" height="186"/>]]></content:encoded>
			<wfw:commentRss>http://www.toao.net/57-recaptcha-is-cool/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
