diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript
index 30391c261b0cdb6305af71f6157e449df53d4a02..919677bc830a7932f83a9b24e1f696cae69440b9 100644
--- a/src/bindings/php/SConscript
+++ b/src/bindings/php/SConscript
@@ -22,7 +22,7 @@ phpextprefix = os.popen("php-config --extension-dir").read().rstrip()
 phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_php, Copy("$TARGET", "$SOURCE"))
 AlwaysBuild(phplib)
 phpprefix = os.popen("php-config --prefix").read().rstrip()
-phpincl = phptestenv.Command(os.path.join(phpprefix, "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE"))
+phpincl = phptestenv.Command(os.path.join(os.path.join(phpprefix, "etc/conf.d"), "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE"))
 phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests")
 phptest = Alias("testphp", [phptestexec], phptestexec)
 AlwaysBuild(phptest)
diff --git a/src/bindings/php/Tests/TokenTest.php b/src/bindings/php/Tests/TokenTest.php
index 6a9cad5bae50baed1893adeb0c70d54349e90a05..720b74c221b00656854fe84c7f6b02d82184d6b2 100644
--- a/src/bindings/php/Tests/TokenTest.php
+++ b/src/bindings/php/Tests/TokenTest.php
@@ -1,6 +1,6 @@
 <?php
 
-include 'hammer.php';
+include_once 'hammer.php';
 
 class TokenTest extends PHPUnit_Framework_TestCase 
 {
@@ -8,24 +8,18 @@ class TokenTest extends PHPUnit_Framework_TestCase
 
     protected function setUp() 
     {
-        $this->parser = h_token("95\xa2");
+        $this->parser = hammer::h_token("95\xa2");
     }
-    public function testSuccess() 
+    public function testSuccess()
     {
-        $result = h_parse($this->parser, "95\xa2");
-        //var_dump($result);
-        $ast = hparseresult_ast_get($result);
-        //var_dump($ast);
-        $token_data = hparsedtoken_token_data_get($ast);
-        //var_dump($token_data);
-        $bytes = htokendata_bytes_get($token_data);
-        //var_dump($bytes);
-        $this->assertEquals($bytes, "95\xa2");
-    }     
+        $result = hammer::h_parse($this->parser, "95\xa2");
+        var_dump($result);
+        $this->assertEquals("95\xa2", $result); 
+    }      
     public function testFailure()
     {
         $result = h_parse($this->parser, "95");
-        $this->assertEquals($result, NULL);
+        $this->assertEquals(NULL, $result);
     }
 }
 ?>
\ No newline at end of file
diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i
index ead3c3fd274b0f0dd72686b8f8e12670e89adb07..ccd5bf9ed538b96afd40b5f64e99f5d8e6420891 100644
--- a/src/bindings/swig/hammer.i
+++ b/src/bindings/swig/hammer.i
@@ -140,22 +140,52 @@
   $1 = (uint8_t*)(*$input)->value.str.val;
   $2 = (*$input)->value.str.len;
  }
+
 //%typemap(out) (const uint8_t* str, const size_t len) {
 //  RETVAL_STRINGL((char*)$1, $2, 1);
 // }
 %apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) }
+
 %typemap(in) void*[] {
 
  }
+
 %typemap(in) uint8_t {
 
  }
+
 %typemap(out) HBytes* {
   RETVAL_STRINGL((char*)$1->token, $1->len, 1);
  }
+
 %typemap(out) struct HCountedArray_* {
 
  }
+%typemap(out) struct HParseResult_* {
+  if ($1 == NULL) {
+    // TODO: raise parse failure
+    RETVAL_NULL();
+  } else {
+    $result = hpt_to_php($1->ast);
+    printf("Being returned: %s\n", Z_STRVAL_P($result));
+  }
+ }
+%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
 #endif
@@ -375,4 +405,46 @@ def int64(): return _h_int64()
 #endif
 //%apply const char* { const uint8_t* }
 
+#if defined(SWIGPHP)
+%inline {
+  static zval* hpt_to_php(const HParsedToken *token) {
+    zval *ret;
+    ALLOC_INIT_ZVAL(ret);
+    if (token == NULL) {
+      ZVAL_NULL(ret);
+      return ret;
+    }
+    switch (token->token_type) {
+    case TT_NONE:
+      ZVAL_NULL(ret);
+      return ret;
+    case TT_BYTES:
+      ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1);
+      return ret;
+    case TT_SINT:
+      ZVAL_LONG(ret, token->token_data.sint);
+      return ret;
+    case TT_UINT:
+      ZVAL_LONG(ret, token->token_data.uint);
+      return ret;
+    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]));
+      }
+      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; */
+      /* } else { */
+      /* 	// I guess that's a python thing */
+      /* 	//return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */
+      /* 	// TODO: support registry */
+      /* } */
+      break;
+    }
+  }
+ }
+#endif