diff --git a/src/bindings/php/Tests/ChTest.php b/src/bindings/php/Tests/ChTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f18cdfb257272117ce7ffca25094a7ff5dfdb59b
--- /dev/null
+++ b/src/bindings/php/Tests/ChTest.php
@@ -0,0 +1,24 @@
+<?php
+
+include_once 'hammer.php';
+
+class ChTest extends PHPUnit_Framework_TestCase 
+{
+    protected $parser;
+
+    protected function setUp() 
+    {
+        $this->parser = h_ch("\xa2");
+    }
+    public function testSuccess() 
+    {
+        $result = h_parse($this->parser, "\xa2");
+        $this->assertEquals("\xa2", $result);
+    }     
+    public function testFailure()
+    {
+        $result = h_parse($this->parser, "95");
+        $this->assertEquals(NULL, $result);
+    }
+}
+?>
\ No newline at end of file
diff --git a/src/bindings/php/Tests/TokenTest.php b/src/bindings/php/Tests/TokenTest.php
index 720b74c221b00656854fe84c7f6b02d82184d6b2..492c17fbedb4bd9d7dff5e7a02ae2d4ac0be7a96 100644
--- a/src/bindings/php/Tests/TokenTest.php
+++ b/src/bindings/php/Tests/TokenTest.php
@@ -8,12 +8,11 @@ class TokenTest extends PHPUnit_Framework_TestCase
 
     protected function setUp() 
     {
-        $this->parser = hammer::h_token("95\xa2");
+        $this->parser = h_token("95\xa2");
     }
     public function testSuccess()
     {
-        $result = hammer::h_parse($this->parser, "95\xa2");
-        var_dump($result);
+        $result = h_parse($this->parser, "95\xa2");
         $this->assertEquals("95\xa2", $result); 
     }      
     public function testFailure()
diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i
index ccd5bf9ed538b96afd40b5f64e99f5d8e6420891..000b0c481cd71d31ba08f5dfd4ce146a583f4422 100644
--- a/src/bindings/swig/hammer.i
+++ b/src/bindings/swig/hammer.i
@@ -136,6 +136,23 @@
 
 #if defined(SWIGPHP)
 %ignore HCountedArray_;
+
+%inline %{
+  static int h_tt_php;
+  %}
+
+%init %{
+  h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php");
+  %}
+
+%inline {
+  struct HParsedToken_;
+  struct HParseResult_;
+  static zval* hpt_to_php(const struct HParsedToken_ *token);
+  
+  //static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data);
+ }
+
 %typemap(in) (const uint8_t* str, const size_t len) {
   $1 = (uint8_t*)(*$input)->value.str.val;
   $2 = (*$input)->value.str.len;
@@ -166,25 +183,42 @@
     // TODO: raise parse failure
     RETVAL_NULL();
   } else {
-    $result = hpt_to_php($1->ast);
-    printf("Being returned: %s\n", Z_STRVAL_P($result));
+    if ($1->ast == NULL) {
+      RETVAL_NULL();
+    } else {
+      switch($1->ast->token_type) {
+      case TT_NONE:
+	RETVAL_NULL();
+	break;
+      case TT_BYTES:
+	RETVAL_STRINGL((char*)$1->ast->token_data.bytes.token, $1->ast->token_data.bytes.len, 1);
+	break;
+      case TT_SINT:
+	RETVAL_LONG($1->ast->token_data.sint);
+	break;
+      case TT_UINT:
+	RETVAL_LONG($1->ast->token_data.uint);
+	break;
+      case TT_SEQUENCE:
+	array_init($result);
+	for (int i=0; i < $1->ast->token_data.seq->used; i++) {
+	  add_next_index_zval($result, hpt_to_php($1->ast->token_data.seq->elements[i]));
+	}
+	break;
+      default:
+	/* if (token->token_type == h_tt_php) { */
+	/* 	ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */
+	/* 	return return_value; */
+	/* } else { */
+	/* 	// I guess that's a python thing */
+	/* 	//return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */
+	/* 	// TODO: support registry */
+	/* } */
+	break;
+      }
+    }
   }
  }
-%inline %{
-  static int h_tt_php;
-  %}
-
-%init %{
-  h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php");
-  %}
-
-%inline {
-  struct HParsedToken_;
-  struct HParseResult_;
-  static zval* hpt_to_php(const struct HParsedToken_ *token);
-  
-  //static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data);
- }
 
 #else
   #warning no Hammer typemaps defined
@@ -420,6 +454,7 @@ def int64(): return _h_int64()
       return ret;
     case TT_BYTES:
       ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1);
+      printf("Being returned from hpt_to_php: %s\n", Z_STRVAL_P(ret));
       return ret;
     case TT_SINT:
       ZVAL_LONG(ret, token->token_data.sint);
@@ -430,21 +465,20 @@ def int64(): return _h_int64()
     case TT_SEQUENCE:
       array_init(ret);
       for (int i=0; i < token->token_data.seq->used; i++) {
-	add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i]));
+       add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i]));
       }
       return ret;
     default:
       /* if (token->token_type == h_tt_php) { */
-      /* 	ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */
-      /* 	return return_value; */
+      /*       ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, wh
+      /*       return return_value; */
       /* } else { */
-      /* 	// I guess that's a python thing */
-      /* 	//return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */
-      /* 	// TODO: support registry */
+      /*       // I guess that's a python thing */
+      /*       //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */
+      /*       // TODO: support registry */
       /* } */
       break;
     }
   }
  }
 #endif
-