<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Ed Finkler</title>
    <link>http://virb.com/funkatron</link>
    <description><![CDATA[I'm a dad of the greatest kid in the whole wide world. I have an amazing partner. I'm a web developer, graphic designer and security "expert." I write in a vaguely journalistic sense on occasion, and used to do zines and such back in the day. I write music and put out a couple albums long ago, and somehow I need to sort out where to start again.

Some crap I do:
- <strong><a href="http://funkatron.com">My blog</a></strong> (I probably won't write posts here)
- <strong><a href="http://phpsecinfo.com">PHPSecInfo</a></strong> - A PHP environment auditing tool I created
- <strong><a href="http://funkatron.com/spaz">Spaz</a></strong> - A Twitter client I wrote for OS X, Windows and Linux
]]></description>
    <generator>Virb 2.0 (@funkatron)</generator>
    <language>en</language>
    <item>
      <title>Me.  Photo by George Schlossnagle</title>
      <link>http://virb.com/funkatron/photos/1176548</link>
      <description><![CDATA[<a href="http://virb.com/funkatron/photos/1176548"><img src="http://g.virbcdn.com/i/resize_575x575/Image-60482-247527-edfinkler.jpg" /></a>]]></description>
      <pubDate>Wed, 28 Mar 2007 01:34:13 -0700</pubDate>
      <guid>http://virb.com/funkatron/photos/1176548</guid>
    </item>
    <item>
      <title>PHP Advent 2008 Post: JSON is Everybody's Friend</title>
      <link>http://virb.com/funkatron/posts/text/1000243</link>
      <description><![CDATA[<p><a href="http://flickr.com/photos/thomashawk/268524287/" title="Security"><img src="http://farm1.static.flickr.com/113/268524287_6d0b9122f7.jpg" alt="Security"></a></p>

<p><em>Reposting something you wrote is a lot easier than coming up with original content. This article was <a href="http://phpadvent.org/2008/json-is-everybodys-friend-by-ed-finkler">originally posted</a> as part of the <a href="http://phpadvent.org/2008/">2008 PHP Advent Calendar</a></em></p>

<p>Last year I wrote some kind of feel-good, hippie crap for the PHP Advent
Calendar. This year I got a haircut, took a shower, and am ready to tell you
about something practical: working with <a href="http://json.org/">JavaScript Object Notation (JSON)</a>
in PHP.</p>

<p>"JSON?!" you cry. "But that's for JavaScript fruitcakes!" And you'd be right.
But JSON, while valid JavaScript code, is actually a very effective serialized
data format for exchanging data between applications written in a variety of
languages. And as of PHP 5.2, we have <a href="http://php.net/json"><em>native</em> support for JSON encoding and
decoding</a>.</p>

<h3>But I Love XML!</h3>

<p>Who doesn't? The thing is, for moving data around--not documents, but data--I
think JSON is superior to XML. This is mainly because JSON tends to map better
to the data models in most programming languages--arrays, objects, etc. JSON
<em>is</em> serialized JavaScript, so it's easy peasy representing these kinds of
things. Moving between JSON and your language's internal data models is
usually just a single function call. Smarter people than me can debate the
pros and cons of XML and JSON in various scenarios, but for a lot of what I
do, JSON does the same thing and requires less work.</p>

<h3>Get Your PHP Objects On</h3>

<p>In PHP 5.2+, there are two functions that handle JSON: <a href="http://us2.php.net/manual/en/function.json-encode.php">json_encode()</a>,
which takes a PHP data structure and returns a JSON string, and
<a href="http://php.net/manual/en/function.json-decode.php">json_decode()</a>, which takes a JSON string and converts it into a PHP
data structure. Let's take a look at json_encode() and how it handles
converting a PHP object into JSON:</p>

<pre>&amp;lt;?php
// make a simple object
$obj-&gt;body           = 'another post';
$obj-&gt;id             = 21;
$obj-&gt;approved       = true;
$obj-&gt;favorite_count = 1;
$obj-&gt;status         = NULL;

// convert into JSON
$json_obj = json_encode($obj);
echo $json_obj;
</pre>

<p>This will output the following JSON string:</p>

<pre>{"body":"another post","id":21,"approved":true,"favorite_count":1,"status":null}
</pre>

<p>Now, let's take that JSON and turn it back into PHP:</p>

<pre>// convert back into PHP
$new_obj = json_decode($json_obj);
var_dump($new_obj);
</pre>

<p>And we'll have the following PHP object:</p>

<pre>object(stdClass)#2 (5) {
  ["body"]=&gt;
  string(12) "another post"
  ["id"]=&gt;
  int(21)
  ["approved"]=&gt;
  bool(true)
  ["favorite_count"]=&gt;
  int(1)
  ["status"]=&gt;
  NULL
}
</pre>

<p>Notice that the data types are retained in the process. JSON supports strings,
numbers, objects, arrays (kinda), booleans and NULL. Things like methods,
constants, and non-public properties are dropped in the encoding process, as
shown in the example below:</p>

<pre>&amp;lt;?php
class Foo {
  const     ERROR_CODE = '404';
  public    $public_ex = 'this is public';
  private   $private_ex = 'this is private!';
  protected $protected_ex = 'this should be protected';

  public function getErrorCode() {
    return self::ERROR_CODE;
  }
}

$foo = new Foo
$foo_json = json_encode($foo
echo $foo_json
</pre>

<p>This outputs the following JSON:</p>

<pre>{"public_ex":"this is public"}
</pre>

<p>Also note that when you decode JSON into a PHP object, the object type is
always stdClass. If we use $foo_json from aboveâ¦</p>

<pre>$foo_new = json_decode($foo_json);
var_dump($foo_new);
</pre>

<p>â¦we'll get back the following object:</p>

<pre>object(stdClass)#4 (1) {
 ["public_ex"]=&gt;
 string(14) "this is public"
}
</pre>

<h3>Arrays, Indexed &amp; Associative</h3>

<p>Array support in JSON is limited to <em>indexed</em> arrays--those with sequential,
numeric keys. Associative arrays are converted into an object with
corresponding properties.</p>

<pre>&amp;lt;?php
// here's an indexed array. JSON natively handles these
$arr = array('orange', 'yellow', 'green', 122);
$json_arr = json_encode($arr);
echo $json_arr."\n";
</pre>

<p>That gives us this JSON:</p>

<pre>["orange","yellow","green",122]
</pre>

<p>And we can convert it back into PHPâ¦</p>

<pre>$new_arr = json_decode($json_arr);
var_dump($new_arr);
</pre>

<p>â¦without losing anything in the process.</p>

<pre>array(4) {
  [0]=&gt;
  string(6) "orange"
  [1]=&gt;
  string(6) "yellow"
  [2]=&gt;
  string(5) "green"
  [3]=&gt;
  int(122)
}
</pre>

<p>With associative arrays, the array is converted to an object. Also note that
all associative keys are converted into strings in the process:</p>

<pre>// associative PHP arrays are converted into objects
$assoc = array('orange'=&gt;'yellow', 'green'=&gt;122, 9=&gt;122);
$json_assoc = json_encode($assoc);
</pre>

<p>The encoded JSON will be {"orange":"yellow","green":122,"9":122}. Decoding
<em>that</em> gives us this PHP object:</p>

<pre>object(stdClass)#5 (3) {
  ["orange"]=&gt;
  string(6) "yellow"
  ["green"]=&gt;
  int(122)
  ["9"]=&gt;
  int(122)
}
</pre>

<p>You can, however, convert the JSON object back into a PHP associative array by passing TRUE as the second param to json_decode() (thanks Richard Orelup).</p>

<h3>Playing Well with Others</h3>

<p>That's all fine and good, but it might help to actually do something useful
with all this encodin' and decodin'. JSON is a really good choice for moving
data between client-side JavaScript applications and server-side applications,
because JSON <em>is</em> JavaScript code, and maps perfectly onto JavaScript's data
structures.</p>

<p>So, let's contrive a simple application that passes a "counter" object back
and forth between the client and server. The counter object stores information
on how often the PHP server application and the JavaScript client application
"touch" it. First, we'll make a PHP script to serve up some JSON code to our
JavaScript client. It will look for an action parameter in $_GET, perform
the requested action, and serve up some JSON in return.</p>

<pre>&amp;lt;?php
if ($_GET['action'] === "getinit") {

  // make the PHP object and add a PHP touch
  $counter-&gt;php_touches    = 1;
  $counter-&gt;js_touches    = 0;
  send_as_json($counter);

} elseif ($_GET['action'] === "updatedata") {
  // decode JSON
  $counter = json_decode($_POST['counter']);

  // increment php touch counter
  $counter-&gt;php_touches++;

  // serve up as JSON
  send_as_json($counter);

} else {
  send_as_json(false);
}


function send_as_json($obj) {

  // convert object to JSON
  $json = json_encode($obj);

  // set appropriate headers
  header('Content-Type: application/json');

  // output JSON string as body
  echo $json;
}
</pre>

<p>The getinit action will create a $counter object, initialize it with a
couple of variables to track "touches" by PHP and JSON, and serve up the
object as JSON via the send_as_json() function. The updatedata action will
take JSON from the $_POST array, decode it into the $counter object,
increment the php_touches property, and serve up the modified object as
JSON.</p>

<p>In the send_as_json() function, note the header() call that sets the
Content-Type to application/json. Setting the content type correctly is
good practice, and will sometimes avoid <a href="http://jibbering.com/blog/?p=514">unexpected security issues</a>.</p>

<p>On the client side, we'll make a short HTML page with some embedded JavaScript
to interact with our PHP service.</p>

<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
  &lt;title&gt;JSON PHP Example&lt;/title&gt;
  &lt;!-- Load the Google JS libs hosting API --&gt;
  &lt;script src="http://www.google.com/jsapi"&gt;&lt;/script&gt;
  &lt;!-- Load the newest jquery major version 1 from Google --&gt;
  &lt;script type="text/javascript" charset="utf-8"&gt;
    google.load("jquery", "1");
  &lt;/script&gt;
  &lt;!-- load the JSON2.js parser --&gt;
  &lt;script src="JSON2.js"&gt;&lt;/script&gt;

  &lt;script type="text/javascript" charset="utf-8"&gt;
    var counter;

    function processData(data, textStatus) {
      counter = JSON.parse(data);
      counter.js_touches++;
      $('#js-count').val( parseInt(counter.js_touches));
      $('#php-count').val( parseInt(counter.php_touches));
    }

    // when the DOM is ready, do this stuff
    $(document).ready( function() {
      $.get('jsonphp.php?action=getinit', processData, 'text');
      $('#increment-button').click( function() {
        counter.js_touches = parseInt( $('#js-count').val() );
        counter.php_touches = parseInt( $('#php-count').val() );
        var json = JSON.stringify(counter);
        $.post('jsonphp.php?action=updatedata', { 'counter':json }, processData, 'text');
      });
    });
  &lt;/script&gt;

  &lt;style type="text/css" media="screen"&gt;
    body, input {
      font-family: Baskerville, Georgia, "Times New Roman", serif;
    }
    table {
      border:1px solid #CCC;
      padding:.2em;
      margin: .2em;
    }
    td.label {
      text-align:right;
      font-weight:bold;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;table&gt;
    &lt;tr&gt;
      &lt;td class="label"&gt;JavaScript Touches:&lt;/td&gt;
      &lt;td&gt;&lt;input type="text" id="js-count" value="0" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td class="label"&gt;PHP Touches:&lt;/td&gt;
      &lt;td&gt;&lt;input type="text" id="php-count" value="0" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
  &lt;form&gt;
    &lt;input type="button" name="increment" value="Increment!" id="increment-button" /&gt;
  &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<p>Rendered in the browser, the page will look something like this:</p>

<p><img src="http://funkatron.com/content/jsonphp.html-screenshot.png" alt="Screenshot"></p>

<p>Note that we're using the jQuery library (loaded from the Google JavaScript
Libraries API) to handle DOM manipulation and Ajax calls. We're also using the
JSON2.js parser, available at <a href="http://json.org/json2.js">JSON.org</a>, to safely parse and create JSON.
The default method for decoding JSON into a JavaScript object or array is
eval(), but that leaves us open to <a href="http://funkatron.com/site/comments/safely-parsing-json-in-javascript/">all sorts of code injection issues</a>.</p>

<p>Jumping into our JavaScript code, the $().ready() is the most interesting
portion. The ready() method called on $(document) takes the anonymous
function passed into it, and executes the function as soon as the document is
"ready"--that is, when the DOM is completed and can be safely messed with. So,
when the DOM is ready, two things will happen:</p>

<ul>
<li><p>A GET request is made to jsonphp.php?action=getinit, and the results
are passed as text to the processData() function</p></li>
<li><p>An event listener is assigned to the click event for the button with the
id of increment-button. This listener will fire a function that:</p>

<ol>
<li><p>Grabs the values for the touch counts out of the form fields</p></li>
<li><p>Assigns them to the counter object</p></li>
<li><p>Encodes the counter object as JSON</p></li>
<li><p>POSTs counter to the server</p></li>
</ol></li>
</ul>

<p>So, each time we click the "Increment!" button, the object is sent from the
JavaScript application to the PHP application as JSON. Each side will
increment its own counter in the object, and the JavaScript application will
display those values to us in the page. If we want, we can even change the
values, and the JavaScript application will bind the new values to the object
before sending it to the server.</p>

<h3>What's It All Mean, Dave?</h3>

<p>Metaphysically, I have no idea. But practically, JSON support in PHP means
that our favorite server-side language is an even <em>better</em> glue language--
something it's been good at for a long time. Now, go forth and make the next
mega-ajax-crowdsourced-mashup masterpiece.</p>
<p><a href="http://feeds.feedburner.com/~a/funkablog?a=KE85ub"><img src="http://feeds.feedburner.com/~a/funkablog?i=KE85ub" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/funkablog?a=ubeLO"><img src="http://feeds.feedburner.com/~f/funkablog?i=ubeLO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=ydYxO"><img src="http://feeds.feedburner.com/~f/funkablog?i=ydYxO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=KPAFO"><img src="http://feeds.feedburner.com/~f/funkablog?i=KPAFO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=mrmvo"><img src="http://feeds.feedburner.com/~f/funkablog?i=mrmvo" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=v02Qo"><img src="http://feeds.feedburner.com/~f/funkablog?i=v02Qo" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=g16PO"><img src="http://feeds.feedburner.com/~f/funkablog?i=g16PO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=zuASO"><img src="http://feeds.feedburner.com/~f/funkablog?i=zuASO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/funkablog/~4/494424168" height="1" width="1" />]]></description>
      <pubDate>Thu, 25 Dec 2008 08:53:43 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/1000243</guid>
    </item>
    <item>
      <title>PHP Advent 2008 Post: JSON is Everybody's Friend</title>
      <link>http://virb.com/funkatron/posts/text/998029</link>
      <description><![CDATA[<p><a href="http://flickr.com/photos/thomashawk/268524287/" title="Security"><img src="http://farm1.static.flickr.com/113/268524287_6d0b9122f7.jpg" alt="Security"></a></p>

<p><em>Reposting something you wrote is a lot easier than coming up with original content. This article was <a href="http://phpadvent.org/2008/json-is-everybodys-friend-by-ed-finkler">originally posted</a> as part of the <a href="http://phpadvent.org/2008/">2008 PHP Advent Calendar</a></em></p>

<p>Last year I wrote some kind of feel-good, hippie crap for the PHP Advent
Calendar. This year I got a haircut, took a shower, and am ready to tell you
about something practical: working with <a href="http://json.org/">JavaScript Object Notation (JSON)</a>
in PHP.</p>

<p>"JSON?!" you cry. "But that's for JavaScript fruitcakes!" And you'd be right.
But JSON, while valid JavaScript code, is actually a very effective serialized
data format for exchanging data between applications written in a variety of
languages. And as of PHP 5.2, we have <a href="http://php.net/json"><em>native</em> support for JSON encoding and
decoding</a>.</p>

<h3>But I Love XML!</h3>

<p>Who doesn't? The thing is, for moving data around--not documents, but data--I
think JSON is superior to XML. This is mainly because JSON tends to map better
to the data models in most programming languages--arrays, objects, etc. JSON
<em>is</em> serialized JavaScript, so it's easy peasy representing these kinds of
things. Moving between JSON and your language's internal data models is
usually just a single function call. Smarter people than me can debate the
pros and cons of XML and JSON in various scenarios, but for a lot of what I
do, JSON does the same thing and requires less work.</p>

<h3>Get Your PHP Objects On</h3>

<p>In PHP 5.2+, there are two functions that handle JSON: <a href="http://us2.php.net/manual/en/function.json-encode.php">json_encode()</a>,
which takes a PHP data structure and returns a JSON string, and
<a href="http://php.net/manual/en/function.json-decode.php">json_decode()</a>, which takes a JSON string and converts it into a PHP
data structure. Let's take a look at json_encode() and how it handles
converting a PHP object into JSON:</p>

<pre>&amp;lt;?php
// make a simple object
$obj-&gt;body           = 'another post';
$obj-&gt;id             = 21;
$obj-&gt;approved       = true;
$obj-&gt;favorite_count = 1;
$obj-&gt;status         = NULL;

// convert into JSON
$json_obj = json_encode($obj);
echo $json_obj;
</pre>

<p>This will output the following JSON string:</p>

<pre>{"body":"another post","id":21,"approved":true,"favorite_count":1,"status":null}
</pre>

<p>Now, let's take that JSON and turn it back into PHP:</p>

<pre>// convert back into PHP
$new_obj = json_decode($json_obj);
var_dump($new_obj);
</pre>

<p>And we'll have the following PHP object:</p>

<pre>object(stdClass)#2 (5) {
  ["body"]=&gt;
  string(12) "another post"
  ["id"]=&gt;
  int(21)
  ["approved"]=&gt;
  bool(true)
  ["favorite_count"]=&gt;
  int(1)
  ["status"]=&gt;
  NULL
}
</pre>

<p>Notice that the data types are retained in the process. JSON supports strings,
numbers, objects, arrays (kinda), booleans and NULL. Things like methods,
constants, and non-public properties are dropped in the encoding process, as
shown in the example below:</p>

<pre>&amp;lt;?php
class Foo {
  const     ERROR_CODE = '404';
  public    $public_ex = 'this is public';
  private   $private_ex = 'this is private!';
  protected $protected_ex = 'this should be protected';

  public function getErrorCode() {
    return self::ERROR_CODE;
  }
}

$foo = new Foo
$foo_json = json_encode($foo
echo $foo_json
</pre>

<p>This outputs the following JSON:</p>

<pre>{"public_ex":"this is public"}
</pre>

<p>Also note that when you decode JSON into a PHP object, the object type is
always stdClass. If we use $foo_json from aboveâ¦</p>

<pre>$foo_new = json_decode($foo_json);
var_dump($foo_new);
</pre>

<p>â¦we'll get back the following object:</p>

<pre>object(stdClass)#4 (1) {
 ["public_ex"]=&gt;
 string(14) "this is public"
}
</pre>

<h3>Arrays, Indexed &amp; Associative</h3>

<p>Array support in JSON is limited to <em>indexed</em> arrays--those with sequential,
numeric keys. Associative arrays are converted into an object with
corresponding properties.</p>

<pre>&amp;lt;?php
// here's an indexed array. JSON natively handles these
$arr = array('orange', 'yellow', 'green', 122);
$json_arr = json_encode($arr);
echo $json_arr."\n";
</pre>

<p>That gives us this JSON:</p>

<pre>["orange","yellow","green",122]
</pre>

<p>And we can convert it back into PHPâ¦</p>

<pre>$new_arr = json_decode($json_arr);
var_dump($new_arr);
</pre>

<p>â¦without losing anything in the process.</p>

<pre>array(4) {
  [0]=&gt;
  string(6) "orange"
  [1]=&gt;
  string(6) "yellow"
  [2]=&gt;
  string(5) "green"
  [3]=&gt;
  int(122)
}
</pre>

<p>With associative arrays, the array is converted to an object. Also note that
all associative keys are converted into strings in the process:</p>

<pre>// associative PHP arrays are converted into objects
$assoc = array('orange'=&gt;'yellow', 'green'=&gt;122, 9=&gt;122);
$json_assoc = json_encode($assoc);
</pre>

<p>The encoded JSON will be {"orange":"yellow","green":122,"9":122}. Decoding
<em>that</em> gives us this PHP object:</p>

<pre>object(stdClass)#5 (3) {
  ["orange"]=&gt;
  string(6) "yellow"
  ["green"]=&gt;
  int(122)
  ["9"]=&gt;
  int(122)
}
</pre>

<h3>Playing Well with Others</h3>

<p>That's all fine and good, but it might help to actually do something useful
with all this encodin' and decodin'. JSON is a really good choice for moving
data between client-side JavaScript applications and server-side applications,
because JSON <em>is</em> JavaScript code, and maps perfectly onto JavaScript's data
structures.</p>

<p>So, let's contrive a simple application that passes a "counter" object back
and forth between the client and server. The counter object stores information
on how often the PHP server application and the JavaScript client application
"touch" it. First, we'll make a PHP script to serve up some JSON code to our
JavaScript client. It will look for an action parameter in $_GET, perform
the requested action, and serve up some JSON in return.</p>

<pre>&amp;lt;?php
if ($_GET['action'] === "getinit") {

  // make the PHP object and add a PHP touch
  $counter-&gt;php_touches    = 1;
  $counter-&gt;js_touches    = 0;
  send_as_json($counter);

} elseif ($_GET['action'] === "updatedata") {
  // decode JSON
  $counter = json_decode($_POST['counter']);

  // increment php touch counter
  $counter-&gt;php_touches++;

  // serve up as JSON
  send_as_json($counter);

} else {
  send_as_json(false);
}


function send_as_json($obj) {

  // convert object to JSON
  $json = json_encode($obj);

  // set appropriate headers
  header('Content-Type: application/json');

  // output JSON string as body
  echo $json;
}
</pre>

<p>The getinit action will create a $counter object, initialize it with a
couple of variables to track "touches" by PHP and JSON, and serve up the
object as JSON via the send_as_json() function. The updatedata action will
take JSON from the $_POST array, decode it into the $counter object,
increment the php_touches property, and serve up the modified object as
JSON.</p>

<p>In the send_as_json() function, note the header() call that sets the
Content-Type to application/json. Setting the content type correctly is
good practice, and will sometimes avoid <a href="http://jibbering.com/blog/?p=514">unexpected security issues</a>.</p>

<p>On the client side, we'll make a short HTML page with some embedded JavaScript
to interact with our PHP service.</p>

<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
  &lt;title&gt;JSON PHP Example&lt;/title&gt;
  &lt;!-- Load the Google JS libs hosting API --&gt;
  &lt;script src="http://www.google.com/jsapi"&gt;&lt;/script&gt;
  &lt;!-- Load the newest jquery major version 1 from Google --&gt;
  &lt;script type="text/javascript" charset="utf-8"&gt;
    google.load("jquery", "1");
  &lt;/script&gt;
  &lt;!-- load the JSON2.js parser --&gt;
  &lt;script src="JSON2.js"&gt;&lt;/script&gt;

  &lt;script type="text/javascript" charset="utf-8"&gt;
    var counter;

    function processData(data, textStatus) {
      counter = JSON.parse(data);
      counter.js_touches++;
      $('#js-count').val( parseInt(counter.js_touches));
      $('#php-count').val( parseInt(counter.php_touches));
    }

    // when the DOM is ready, do this stuff
    $(document).ready( function() {
      $.get('jsonphp.php?action=getinit', processData, 'text');
      $('#increment-button').click( function() {
        counter.js_touches = parseInt( $('#js-count').val() );
        counter.php_touches = parseInt( $('#php-count').val() );
        var json = JSON.stringify(counter);
        $.post('jsonphp.php?action=updatedata', { 'counter':json }, processData, 'text');
      });
    });
  &lt;/script&gt;

  &lt;style type="text/css" media="screen"&gt;
    body, input {
      font-family: Baskerville, Georgia, "Times New Roman", serif;
    }
    table {
      border:1px solid #CCC;
      padding:.2em;
      margin: .2em;
    }
    td.label {
      text-align:right;
      font-weight:bold;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;table&gt;
    &lt;tr&gt;
      &lt;td class="label"&gt;JavaScript Touches:&lt;/td&gt;
      &lt;td&gt;&lt;input type="text" id="js-count" value="0" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td class="label"&gt;PHP Touches:&lt;/td&gt;
      &lt;td&gt;&lt;input type="text" id="php-count" value="0" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
  &lt;form&gt;
    &lt;input type="button" name="increment" value="Increment!" id="increment-button" /&gt;
  &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<p>Rendered in the browser, the page will look something like this:</p>

<p><img src="http://funkatron.com/content/jsonphp.html-screenshot.png" alt="Screenshot"></p>

<p>Note that we're using the jQuery library (loaded from the Google JavaScript
Libraries API) to handle DOM manipulation and Ajax calls. We're also using the
JSON2.js parser, available at <a href="http://json.org/json2.js">JSON.org</a>, to safely parse and create JSON.
The default method for decoding JSON into a JavaScript object or array is
eval(), but that leaves us open to <a href="http://funkatron.com/site/comments/safely-parsing-json-in-javascript/">all sorts of code injection issues</a>.</p>

<p>Jumping into our JavaScript code, the $().ready() is the most interesting
portion. The ready() method called on $(document) takes the anonymous
function passed into it, and executes the function as soon as the document is
"ready"--that is, when the DOM is completed and can be safely messed with. So,
when the DOM is ready, two things will happen:</p>

<ul>
<li><p>A GET request is made to jsonphp.php?action=getinit, and the results
are passed as text to the processData() function</p></li>
<li><p>An event listener is assigned to the click event for the button with the
id of increment-button. This listener will fire a function that:</p>

<ol>
<li><p>Grabs the values for the touch counts out of the form fields</p></li>
<li><p>Assigns them to the counter object</p></li>
<li><p>Encodes the counter object as JSON</p></li>
<li><p>POSTs counter to the server</p></li>
</ol></li>
</ul>

<p>So, each time we click the "Increment!" button, the object is sent from the
JavaScript application to the PHP application as JSON. Each side will
increment its own counter in the object, and the JavaScript application will
display those values to us in the page. If we want, we can even change the
values, and the JavaScript application will bind the new values to the object
before sending it to the server.</p>

<h3>What's It All Mean, Dave?</h3>

<p>Metaphysically, I have no idea. But practically, JSON support in PHP means
that our favorite server-side language is an even <em>better</em> glue language--
something it's been good at for a long time. Now, go forth and make the next
mega-ajax-crowdsourced-mashup masterpiece.</p>
<p><a href="http://feeds.feedburner.com/~a/funkablog?a=DurXH7"><img src="http://feeds.feedburner.com/~a/funkablog?i=DurXH7" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/funkablog?a=A1CgO"><img src="http://feeds.feedburner.com/~f/funkablog?i=A1CgO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=rzk0O"><img src="http://feeds.feedburner.com/~f/funkablog?i=rzk0O" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=jJE9O"><img src="http://feeds.feedburner.com/~f/funkablog?i=jJE9O" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=0Uhqo"><img src="http://feeds.feedburner.com/~f/funkablog?i=0Uhqo" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=7z5mo"><img src="http://feeds.feedburner.com/~f/funkablog?i=7z5mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=2DUDO"><img src="http://feeds.feedburner.com/~f/funkablog?i=2DUDO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=et0JO"><img src="http://feeds.feedburner.com/~f/funkablog?i=et0JO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/funkablog/~4/493463760" height="1" width="1" />]]></description>
      <pubDate>Tue, 23 Dec 2008 23:58:26 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/998029</guid>
    </item>
    <item>
      <title>Links for 2008-12-21 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/994659</link>
      <description><![CDATA[<ul>
<li><a href="http://blog.experimentalworks.net/archives/98-DTracing-PHP.html">DTracing PHP</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/491954795" height="1" width="1" />]]></description>
      <pubDate>Mon, 22 Dec 2008 01:19:45 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/994659</guid>
    </item>
    <item>
      <title>Links for 2008-12-18 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/991240</link>
      <description><![CDATA[<ul>
<li><a href="http://gitcasts.com/posts/11">&ldquo;Git on Windows&rdquo; at GitCasts</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/489371750" height="1" width="1" />]]></description>
      <pubDate>Fri, 19 Dec 2008 14:21:12 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/991240</guid>
    </item>
    <item>
      <title>Links for 2008-12-16 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/987537</link>
      <description><![CDATA[<ul>
<li><a href="http://ditchnet.org/httpclient/">HTTP Client - Mac Developer Tool for HTTP Debugging</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/487320754" height="1" width="1" />]]></description>
      <pubDate>Wed, 17 Dec 2008 13:00:06 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/987537</guid>
    </item>
    <item>
      <title>Links for 2008-12-11 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/978800</link>
      <description><![CDATA[<ul>
<li><a href="http://blog.medryx.org/2008/10/03/codeigniter-rest/">CodeIgniter REST</a>
An interesting implementation of REST for CodeIgniter</li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/482383525" height="1" width="1" />]]></description>
      <pubDate>Fri, 12 Dec 2008 04:12:08 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/978800</guid>
    </item>
    <item>
      <title>Links for 2008-12-09 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/974744</link>
      <description><![CDATA[<ul>
<li><a href="http://al3x.net/2008/12/03/how-i-use-textmate.html">Alex Payne | How I Use TextMate</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/480262100" height="1" width="1" />]]></description>
      <pubDate>Wed, 10 Dec 2008 03:51:51 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/974744</guid>
    </item>
    <item>
      <title>Links for 2008-12-08 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/972897</link>
      <description><![CDATA[<ul>
<li><a href="http://www.alanwood.net/unicode/fontsbyrange.html">Unicode character ranges and the Unicode fonts that support them</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/479221454" height="1" width="1" />]]></description>
      <pubDate>Tue, 09 Dec 2008 05:14:16 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/972897</guid>
    </item>
    <item>
      <title>Links for 2008-12-04 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/966109</link>
      <description><![CDATA[<ul>
<li><a href="http://www.vimeo.com/2429555">PhoneGap iPhone Framework Demo on Vimeo</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/475400116" height="1" width="1" />]]></description>
      <pubDate>Fri, 05 Dec 2008 05:48:16 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/966109</guid>
    </item>
    <item>
      <title>Links for 2008-12-01 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/962372</link>
      <description><![CDATA[<ul>
<li><a href="http://www.nongnu.org/rdiff-backup/">rdiff-backup: Main</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/472117196" height="1" width="1" />]]></description>
      <pubDate>Wed, 03 Dec 2008 12:50:47 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/962372</guid>
    </item>
    <item>
      <title>Links for 2008-11-15 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/934283</link>
      <description><![CDATA[<ul>
<li><a href="http://www.evolt.org/article/A_Simple_Character_Entity_Chart/17/21234/">A Simple Character Entity Chart | evolt.org</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/454610408" height="1" width="1" />]]></description>
      <pubDate>Mon, 17 Nov 2008 06:02:47 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/934283</guid>
    </item>
    <item>
      <title>Links for 2008-11-10 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/924642</link>
      <description><![CDATA[<ul>
<li><a href="http://smalltalk.gnu.org/blog/bonzinip/using-git-without-feeling-stupid-part-1">Using git without feeling stupid (part 1) | GNU Smalltalk</a></li>
<li><a href="http://smalltalk.gnu.org/blog/bonzinip/using-git-without-feeling-stupid-part-2">Using git without feeling stupid (part 2) | GNU Smalltalk</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/449199954" height="1" width="1" />]]></description>
      <pubDate>Tue, 11 Nov 2008 20:09:36 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/924642</guid>
    </item>
    <item>
      <title>Links for 2008-11-07 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/917793</link>
      <description><![CDATA[<ul>
<li><a href="http://vectortuts.com/articles/web-roundups/60-free-vector-graphics-for-digital-art-pros/">60 Free Vector Graphics for Digital Art Pros - VECTORTUTS</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/446221919" height="1" width="1" />]]></description>
      <pubDate>Sat, 08 Nov 2008 02:36:51 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/917793</guid>
    </item>
    <item>
      <title>Links for 2008-11-05 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/916396</link>
      <description><![CDATA[<ul>
<li><a href="http://www.ibm.com/developerworks/edu/x-dw-x-xulintro.html">An introduction to XML User Interface Language (XUL) development</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/444030285" height="1" width="1" />]]></description>
      <pubDate>Fri, 07 Nov 2008 08:16:43 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/916396</guid>
    </item>
    <item>
      <title>The Funkatron.com PHPMAX 2008 US Tour</title>
      <link>http://virb.com/funkatron/posts/text/916395</link>
      <description><![CDATA[<p><img src="http://farm4.static.flickr.com/3199/3008316385_0803508286_o.png" alt="The Funkatron.com PHPMAX 2008 US Tour"></p>

<p>The coming weeks are gonna be a little hectic for me, as I fly to Atlanta on the 12th to attend <a href="http://phpworks.mtacon.com/">php|works / PyWorks 2008</a>. I'll be doing the following talks:</p>

<ul>
<li><a href="http://phpworks.mtacon.com/c/schedule/talk/d1s3/1">Building Desktop RIAs with PHP, HTML and Javascript in AIR</a></li>
<li><a href="http://phpworks.mtacon.com/c/schedule/talk/d1s7/1">The CodeIgniter Framework</a></li>
</ul>

<p>I'm pretty excited about <a href="http://phpworks.mtacon.com/">php|works / PyWorks 2008</a>, especially because we can interact with the Python community and learn more about each other's tech. Cross-pollination is a Good Thing.</p>

<p>I'm flying back to IND on the 15th, but then I'm leaving again on the 16th for San Francisco and the <a href="http://max.adobe.com/na">Adobe MAX 2008 conference</a>. I'm giving the following talk:</p>

<ul>
<li><a href="http://max.adobe.com/na/sessions/browser/#754">Developing Rich Applications with jQuery and Adobe AIR</a></li>
</ul>

<p>Originally this talk was going to be given by <a href="http://ejohn.org">John Resig</a>, creator of the <a href="http://jquery.com">jQuery</a> library, but he ran into some time constraints and thoughtfully suggested me. Of course, the description still mentions his name, which likely means I'll be tarred and feathered by the audience. This also looks like it may be the largest audience I've ever given a talk before: there are currently about 70 folks listed as attending, with ~300 capacity. So if I wet myself on stage, please forgive me.</p>
<p><a href="http://feeds.feedburner.com/~a/funkablog?a=CNDNv7"><img src="http://feeds.feedburner.com/~a/funkablog?i=CNDNv7" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/funkablog?a=ViLWN"><img src="http://feeds.feedburner.com/~f/funkablog?i=ViLWN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=VJxrN"><img src="http://feeds.feedburner.com/~f/funkablog?i=VJxrN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=oYGQN"><img src="http://feeds.feedburner.com/~f/funkablog?i=oYGQN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=zTfgn"><img src="http://feeds.feedburner.com/~f/funkablog?i=zTfgn" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=yGTgn"><img src="http://feeds.feedburner.com/~f/funkablog?i=yGTgn" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=v6mnN"><img src="http://feeds.feedburner.com/~f/funkablog?i=v6mnN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/funkablog?a=qngON"><img src="http://feeds.feedburner.com/~f/funkablog?i=qngON" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/funkablog/~4/444828056" height="1" width="1" />]]></description>
      <pubDate>Fri, 07 Nov 2008 08:16:42 -0800</pubDate>
      <guid>http://virb.com/funkatron/posts/text/916395</guid>
    </item>
    <item>
      <title>Links for 2008-10-30 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/902937</link>
      <description><![CDATA[<ul>
<li><a href="http://panmental.de/symbols/info.htm">Unicode Symbol Map Bookmarklet</a></li>
<li><a href="http://www.fileformat.info/info/unicode/char/a.htm">A to Z Index of Unicode Characters: starting with 'A'</a></li>
<li><a href="http://www.unicode.org/charts/symbols.html">Code Charts - Symbols</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/437686624" height="1" width="1" />]]></description>
      <pubDate>Fri, 31 Oct 2008 05:12:37 -0700</pubDate>
      <guid>http://virb.com/funkatron/posts/text/902937</guid>
    </item>
    <item>
      <title>Links for 2008-10-29 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/901576</link>
      <description><![CDATA[<ul>
<li><a href="http://www.smashingmagazine.com/2008/10/29/expressionengine-developers-toolbox/">ExpressionEngine Developer's Toolbox | Developer's Toolbox | Smashing Magazine</a>
Good stuff</li>
<li><a href="http://www.brandonballentine.com/?p=176">Building an iPhone Template for Expression Engine | brandonballentine.com</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/436557483" height="1" width="1" />]]></description>
      <pubDate>Thu, 30 Oct 2008 13:08:11 -0700</pubDate>
      <guid>http://virb.com/funkatron/posts/text/901576</guid>
    </item>
    <item>
      <title>Links for 2008-10-26 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/895098</link>
      <description><![CDATA[<ul>
<li><a href="http://www.train-ee.com/courseware/free-tutorials/category/building-a-church-site/">Building a Church Site | Train-ee ExpressionEngine Training | Free Tutorials</a>
&quot;Train-ee.com takes you through the implementation of a church website on ExpressionEngine - from start to finish.&quot; Great tutorial on EE.</li>
<li><a href="http://designshack.co.uk/tutorials/creating-a-virtual-jquery-keyboard">Creating a Virtual jQuery Keyboard | Design Shack</a></li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/433222768" height="1" width="1" />]]></description>
      <pubDate>Mon, 27 Oct 2008 08:39:41 -0700</pubDate>
      <guid>http://virb.com/funkatron/posts/text/895098</guid>
    </item>
    <item>
      <title>Links for 2008-10-24 [del.icio.us]</title>
      <link>http://virb.com/funkatron/posts/text/892226</link>
      <description><![CDATA[<ul>
<li><a href="http://www.presetsheaven.com/">PresetsHeaven | Your source to free Lightroom presets</a>
Wee I love presets</li>
</ul><img src="http://feeds.feedburner.com/~r/funkablog/~4/431400432" height="1" width="1" />]]></description>
      <pubDate>Sat, 25 Oct 2008 13:44:44 -0700</pubDate>
      <guid>http://virb.com/funkatron/posts/text/892226</guid>
    </item>
  </channel>
</rss>
