<?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>Illuminati Karate, Inc. &#187; PHP</title>
	<atom:link href="http://illuminatikarate.com/blog/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://illuminatikarate.com</link>
	<description>creative web design, development and marketing</description>
	<lastBuildDate>Fri, 03 Feb 2012 20:13:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Finding the Carrier of a Cell Phone Number in PHP</title>
		<link>http://illuminatikarate.com/blog/finding-the-carrier-of-a-cell-phone-number-in-php/</link>
		<comments>http://illuminatikarate.com/blog/finding-the-carrier-of-a-cell-phone-number-in-php/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 03:47:37 +0000</pubDate>
		<dc:creator>George Huger</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[cell phones]]></category>
		<category><![CDATA[cellular]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://illuminatikarate.com/?p=470</guid>
		<description><![CDATA[Often web apps need to send SMS messages to their users (for example: balance alerts, reminders, notifications). To send these text messages from within your app, you basically have 2 options: 1) Pay Twilio and Tropo for the use of their APIs, for roughly a penny per message. 2) [...]]]></description>
			<content:encoded><![CDATA[<p>Often web apps need to send SMS messages to their users (for example: balance alerts, reminders, notifications). To send these text messages from within your app, you basically have 2 options:</p>
<p>1) Pay <a title="Twilio" href="http://twilio.com">Twilio</a> and <a title="Tropo" href="http://tropo.com">Tropo</a> for the use of their APIs, for roughly a penny per message.</p>
<p>2) Send an email directly to their carrier&#8217;s mail-to-SMS gateway &#8211; a free service most carriers provide, which will translate your email into an SMS sent to their subscribers&#8217; phone</p>
<p>Twilio and Tropo are about as easy as it gets to integrate (REST-like APIs that return <a href="http://json.org">JSON</a>/<a href="http://en.wikipedia.org/wiki/Plain_Old_XML">POX</a>), but you pay for every single message and that can add up quickly. So #2 (mail-to-SMS gateways) starts to look pretty good.</p>
<p>But there&#8217;s some problems with mail-to-SMS gateways:<span id="more-470"></span></p>
<p>1) Each carrier has their own format. For example, T-Mobile&#8217;s gateway is <em>number</em>@tmomail.net (for the US), AT&amp;T&#8217;s is <em>number</em>@txt.att.net (for most of their customers), and Verizon is <em>number</em>@vtext.net (unless you used to be with Alltel &#8211; then its <em>number</em>@message.alltel.com). A big <a href="http://en.wikipedia.org/wiki/List_of_SMS_gateways">list of mail-to-SMS-gateways</a> is available on Wikipedia.</p>
<p>Bonus:some carriers want the international code prepended (the 1 in front of  the number, for the US), some carriers don&#8217;t. (e.g., T-Mobile does,  AT&amp;T doesn&#8217;t)</p>
<p>2) Some carriers require authentication (Sprint) or don&#8217;t have a mail-to-SMS gateway at all (Google Voice).</p>
<p>3) If the user ports their number to a different carrier you&#8217;ll have to detect it and react accordingly.</p>
<p>So you&#8217;ll have to figure out what carrier they&#8217;re using in order to direct the email and meet whatever requirements &#8211; which usually means asking the user to choose their carrier from a list.</p>
<p><strong>There is a better way!</strong> What if we could detect the carrier automatically?</p>
<p>It turns out you can. The lovely folks at <a href="http://cloudvox.com">CloudVox </a>made an API that does exactly that &#8211; you give it a phone number, and it tells you the carrier and if its a cell-phone or landline. Its 100% free, with no API keys/credentials required. </p>
<p>Its hosted at <a href="http://digits.cloudvox.com">digits.cloudvox.com</a>, along with example calls/responses (<a href="http://help.cloudvox.com/kb/digits/digits-phone-number-location-lookup-api">full docs are here</a>). It speaks JSON over HTTP.</p>
<p>This gives us a much better user experience:</p>
<p>1) User inputs their number, no carrier dropdown needed</p>
<p>2) We use CloudVox&#8217;s API to determine their carrier</p>
<p>3) Try to send them an SMS, and have them confirm ownership in the normal way (i.e., enter a confirmation code)</p>
<p>This will cover most people, and is free outside of the development time. If there was an error (i.e., we couldn&#8217;t find the number with CloudVox&#8217;s API, or we did but the carrier doesn&#8217;t support mail-to-SMS), we can fall back to Twilio or Tropo. We&#8217;re still paying a few cents here and there, but the default case is free.</p>
<p>Here&#8217;s some example code in PHP, for querying CloudVox&#8217;s API:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code2'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4702"><td class="code" id="p470code2"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
	<span style="color: #666666; font-style: italic;">/* Finds the carrier for the given phone number using CloudVox's API. Returns the carrier name as a string on success, or false if the carrier couldn't be determined */</span>
	<span style="color: #000000; font-weight: bold;">function</span> findCarrier<span style="color: #009900;">&#40;</span><span style="color: #000088;">$phoneNumber</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$carrier</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// will contain the carriers name as a string if we are able to look it up</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// attempt to lookup the number with the CloudVox API</span>
		<span style="color: #000088;">$requestUrl</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://digits.cloudvox.com/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$phoneNumber</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'.json'</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$apiResponse</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/file_get_contents"><span style="color: #990000;">file_get_contents</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$requestUrl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Note: needs code to handle the error case of file_get_contents</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$apiResponse</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$responseJson</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/json_decode"><span style="color: #990000;">json_decode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$apiResponse</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/isset"><span style="color: #990000;">isset</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$responseJson</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allocation</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <a href="http://www.php.net/isset"><span style="color: #990000;">isset</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$responseJson</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allocation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">carrier_name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$carrier</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$responseJson</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allocation</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">carrier_name</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;">$carrier</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// will be false or the name of the carrier</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/isset"><span style="color: #990000;">isset</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'phoneNumber'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// user has submitted a form via GET, containing a field called phoneNumber</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// collect the phoneNumber and remove any non-numeric chars</span>
		<span style="color: #000088;">$phoneNumber</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/preg_replace"><span style="color: #990000;">preg_replace</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#[^0-9]#'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><a href="http://www.php.net/strip_tags"><span style="color: #990000;">strip_tags</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'phoneNumber'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
		<span style="color: #000088;">$carrier</span> <span style="color: #339933;">=</span> findCarrier<span style="color: #009900;">&#40;</span><span style="color: #000088;">$phoneNumber</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$carrier</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><a href="http://www.php.net/stripos"><span style="color: #990000;">stripos</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$carrier</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'verizon'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				sendWithVerizon<span style="color: #009900;">&#40;</span><span style="color: #000088;">$phoneNumber</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: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/stripos"><span style="color: #990000;">stripos</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$carrier</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'at&amp;t'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				sendWithATT<span style="color: #009900;">&#40;</span><span style="color: #000088;">$phoneNumber</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: #666666; font-style: italic;">// other carrier. you'd really want to fall back to Twilio/Tropo here, and/or log the carrier so you can add it later</span>
				<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Unknown Carrier: <span style="color: #006699; font-weight: bold;">{$carrier}</span>&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">else</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// send SMS via Twilio or Tropo instead</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">else</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// show the form</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;form&gt;'</span> <span style="color: #339933;">.</span> 
			 <span style="color: #0000ff;">'&lt;label for=&quot;phoneNumber&quot;&gt;Phone Number&lt;/label&gt;'</span> <span style="color: #339933;">.</span>
			 <span style="color: #0000ff;">'&lt;input type=&quot;text&quot; name=&quot;phoneNumber&quot; /&gt;'</span> <span style="color: #339933;">.</span>
			 <span style="color: #0000ff;">'&lt;/form&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://illuminatikarate.com/blog/finding-the-carrier-of-a-cell-phone-number-in-php/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Facebook Graph API requires Access Token for Feed Access</title>
		<link>http://illuminatikarate.com/blog/facebook-graph-api-requires-access-token-for-feed-access/</link>
		<comments>http://illuminatikarate.com/blog/facebook-graph-api-requires-access-token-for-feed-access/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 18:49:58 +0000</pubDate>
		<dc:creator>Richard Gabriel</dc:creator>
				<category><![CDATA[Facebook]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://illuminatikarate.com/?p=442</guid>
		<description><![CDATA[On June 3rd, Facebook updated the Graph API to require an access token to pull wall post data from public Facebook pages. This change can cause scripts to stop working, so here is a quick solution to pull wall post data from public Facebook pages with an access token. [...]]]></description>
			<content:encoded><![CDATA[<p>On June 3rd, Facebook <a href="http://developers.facebook.com/blog/post/510/">updated the Graph API</a> to require an access token to pull wall post data from public Facebook pages.  This change can cause scripts to stop working, so here is a quick solution to pull wall post data from public Facebook pages with an access token.<span id="more-442"></span></p>
<p>Consider the following code:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p442code6'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4426"><td class="code" id="p442code6"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> fetchUrl<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #000088;">$ch</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/curl_init"><span style="color: #990000;">curl_init</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_URL<span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_TIMEOUT<span style="color: #339933;">,</span> <span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
     <span style="color: #000088;">$retData</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/curl_exec"><span style="color: #990000;">curl_exec</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <a href="http://www.php.net/curl_close"><span style="color: #990000;">curl_close</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
     <span style="color: #b1b100;">return</span> <span style="color: #000088;">$retData</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p442code7'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4427"><td class="code" id="p442code7"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$profile_id</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;1234567890&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'feed_data'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> fetchUrl<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://graph.facebook.com/<span style="color: #006699; font-weight: bold;">{$profile_id}</span>/feed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Before the recent changes, this was all you needed to load a Facebook page&#8217;s feed.  You could load a public page&#8217;s feed by simply pulling from graph.facebook.com/{profile_id}/feed.  With the recent changes you just have to make a small modification and you&#8217;re good to go.</p>
<p>Here is the updated code:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p442code8'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4428"><td class="code" id="p442code8"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$profile_id</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;1234567890&quot;</span><span style="color: #339933;">;</span>		
&nbsp;
<span style="color: #666666; font-style: italic;">//App Info, needed for Auth</span>
<span style="color: #000088;">$app_id</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;0001234567890&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$app_secret</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;abc123ebf123f3g5g6j&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//retrieve auth token</span>
<span style="color: #000088;">$authToken</span> <span style="color: #339933;">=</span> fetchUrl<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;https://graph.facebook.com/oauth/access_token?type=client_cred&amp;client_id=<span style="color: #006699; font-weight: bold;">{$app_id}</span>&amp;client_secret=<span style="color: #006699; font-weight: bold;">{$app_secret}</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'feed_data'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> fetchUrl<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;https://graph.facebook.com/<span style="color: #006699; font-weight: bold;">{$profile_id}</span>/feed?<span style="color: #006699; font-weight: bold;">{$authToken}</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Be sure to use https instead of http, needed for OAuth.  You&#8217;ll also need to <a href="http://developers.facebook.com">create a simple Facebook app</a> to get an App ID and Secret key.  Once done, just swap out the variables in the above script for the proper values and you&#8217;re off to the races!</p>
]]></content:encoded>
			<wfw:commentRss>http://illuminatikarate.com/blog/facebook-graph-api-requires-access-token-for-feed-access/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free Webservice to Geocode IP Addresses Saves The Day</title>
		<link>http://illuminatikarate.com/blog/free-webservice-to-geocode-ip-addresses-saves-the-day/</link>
		<comments>http://illuminatikarate.com/blog/free-webservice-to-geocode-ip-addresses-saves-the-day/#comments</comments>
		<pubDate>Sat, 23 May 2009 06:03:06 +0000</pubDate>
		<dc:creator>George Huger</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Webservices]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://illuminatikarate.com/blog/?p=265</guid>
		<description><![CDATA[At Illuminati Karate we love a challenge. So when our client called needing two lists of 1500 IP addresses geocoded as quickly as possible, we rose to the occasion. With the help of PHP and a freely available web service we were able to complete the task in just [...]]]></description>
			<content:encoded><![CDATA[<p>At Illuminati Karate we love a challenge. So when our client called needing two lists of 1500 IP addresses geocoded as quickly as possible, we rose to the occasion. With the help of PHP and a freely available web service we were able to complete the task in just under an hour. Here&#8217;s how we did it.</p>
<p><span id="more-265"></span><br />
<h4>The Challenge</h4>
<p>Given 2 text files, each containing approximately 1500 anonymous IP addresses, we were to determine how many resolved to each US state. Separate counts were to be maintained for each list. The data was needed for a time sensitive report, and the clock was ticking.</p>
<h4>The Tools</h4>
<p>There are several freely available SQL databases which correlate IP addresses to their geographic location, such as <a href="http://www.iplocationtools.com/sql_database.php">this one</a> maintained by iplocationtools.com. If we&#8217;d been building a web app setting up a local instance would have made sense, but at 4.1 million rows it was going to take too long to get a local instance running.</p>
<p>What we needed was a web service to do the lookups for us. In the past, we&#8217;d been unable to find a free web service to fulfill this role, as most will not provide data beyond a country level. But today we were lucky, and Google quickly turned up the perfect solution: a free REST web service running the very same database from <a href="http://www.iplocationtools.com">iplocationtools.com</a>. Its exactly what it says on the tin: <a href="http://freegeoip.appspot.com/">a free IP geolocation webservice</a>. It gave us even more accuracy than we needed (cities and zipcodes!), and even better it was running on <a href="http://www.appspot.com" rel="nofollow">Google&#8217;s App Engine</a>, so we knew it could handle a heavy load.</p>
<p>With the primary problem solved, the only thing needed was a simple PHP script to read in the input files, query the web service for each IP, parse the JSON results, and maintain a total for each state.</p>
<h4>The Solution</h4>
<p>Thanks to PHP5&#8242;s excellent JSON support, the script to interact with the web service was trivial. I won&#8217;t bore you with the file I/O and tallying, but here&#8217;s the function which converts the IP address to its state.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p265code10'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p26510"><td class="code" id="p265code10"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
	<span style="color: #000000; font-weight: bold;">function</span> getStateFromIp<span style="color: #009900;">&#40;</span><span style="color: #000088;">$ip</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$resp</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/json_decode"><span style="color: #990000;">json_decode</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/file_get_contents"><span style="color: #990000;">file_get_contents</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://freegeoip.appspot.com/json/'</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/urlencode"><span style="color: #990000;">urlencode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ip</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</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: #339933;">!</span><span style="color: #000088;">$resp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">status</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// lookup failed</span>
			<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</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: #b1b100;">return</span> <span style="color: #000088;">$resp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">regioncode</span><span style="color: #339933;">;</span>		
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>      
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Take note of the the <a href="http://php.net/json_decode">json_decode</a> function. If you&#8217;re not already familiar with it I&#8217;d highly recommend taking a few minutes to familiarize yourself with <a href="http://php.net/manual/en/ref.json.php">PHP5&#8242;s JSON functions</a>. JSON is becoming a de facto standard for web services, so being able to painlessly convert to and from JSON in PHP is critical.</p>
<p>Finally, we simply used <a href="http://php.net/manual/en/function.print-r.php">print_r</a> to dump the array containing the per state totals, and used <a href="http://www.datawatch.com/_products/monarch_pro.php">Monarch</a> to pull the data into an Excel file which we then delivered to the customer. (<em>Note: under normal circumstances we would have reached a more elegant solution, but given the time constraints brute force was the name of the game.</em>)</p>
<h4>Conclusion</h4>
<p><a href="http://illuminatikarate.com/web-services/">On-demand web services</a> are fundamentally changing the way we interact with data. Projects which were formerly large, slow, and expensive can now be completed in a matter of hours or days for a fraction of the cost. Perhaps most importantly, anyone can get involved.</p>
<p>Its an exciting time, and we&#8217;re happy to be a part of it all. Thanks for reading!</p>
<p class="note"><em>If your company needs help with a custom dataset <a href="http://illuminatikarate.com/contact-us/" rel="nofollow">contact us</a> today. Even if you&#8217;re not sure exactly what to ask for, we can help fill in the blanks.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://illuminatikarate.com/blog/free-webservice-to-geocode-ip-addresses-saves-the-day/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

