diff --git a/lib/php/src/Thrift.php b/lib/php/src/Thrift.php
new file mode 100644
index 0000000..ef6ab8a
--- /dev/null
+++ b/lib/php/src/Thrift.php
@@ -0,0 +1,787 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift
+ */
+
+
+/**
+ * Data types that can be sent via Thrift
+ */
+class TType {
+  const STOP   = 0;
+  const VOID   = 1;
+  const BOOL   = 2;
+  const BYTE   = 3;
+  const I08    = 3;
+  const DOUBLE = 4;
+  const I16    = 6;
+  const I32    = 8;
+  const I64    = 10;
+  const STRING = 11;
+  const UTF7   = 11;
+  const STRUCT = 12;
+  const MAP    = 13;
+  const SET    = 14;
+  const LST    = 15;    // N.B. cannot use LIST keyword in PHP!
+  const UTF8   = 16;
+  const UTF16  = 17;
+}
+
+/**
+ * Message types for RPC
+ */
+class TMessageType {
+  const CALL  = 1;
+  const REPLY = 2;
+  const EXCEPTION = 3;
+  const ONEWAY = 4;
+}
+
+/**
+ * NOTE(mcslee): This currently contains a ton of duplicated code from TBase
+ * because we need to save CPU cycles and this is not yet in an extension.
+ * Ideally we'd multiply-inherit TException from both Exception and Base, but
+ * that's not possible in PHP and there are no modules either, so for now we
+ * apologetically take a trip to HackTown.
+ *
+ * Can be called with standard Exception constructor (message, code) or with
+ * Thrift Base object constructor (spec, vals).
+ *
+ * @param mixed $p1 Message (string) or type-spec (array)
+ * @param mixed $p2 Code (integer) or values (array)
+ */
+class TException extends Exception {
+  function __construct($p1=null, $p2=0) {
+    if (is_array($p1) && is_array($p2)) {
+      $spec = $p1;
+      $vals = $p2;
+      foreach ($spec as $fid => $fspec) {
+        $var = $fspec['var'];
+        if (isset($vals[$var])) {
+          $this->$var = $vals[$var];
+        }
+      }
+    } else {
+      parent::__construct($p1, $p2);
+    }
+  }
+
+  static $tmethod = array(TType::BOOL   => 'Bool',
+                          TType::BYTE   => 'Byte',
+                          TType::I16    => 'I16',
+                          TType::I32    => 'I32',
+                          TType::I64    => 'I64',
+                          TType::DOUBLE => 'Double',
+                          TType::STRING => 'String');
+
+  private function _readMap(&$var, $spec, $input) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kread = $vread = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kread = 'read'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vread = 'read'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $var = array();
+    $_ktype = $_vtype = $size = 0;
+    $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
+    for ($i = 0; $i < $size; ++$i) {
+      $key = $val = null;
+      if ($kread !== null) {
+        $xfer += $input->$kread($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $class = $kspec['class'];
+          $key = new $class();
+          $xfer += $key->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($key, $kspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($key, $kspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($key, $kspec, $input, true);
+          break;
+        }
+      }
+      if ($vread !== null) {
+        $xfer += $input->$vread($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $class = $vspec['class'];
+          $val = new $class();
+          $xfer += $val->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($val, $vspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($val, $vspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($val, $vspec, $input, true);
+          break;
+        }
+      }
+      $var[$key] = $val;
+    }
+    $xfer += $input->readMapEnd();
+    return $xfer;
+  }
+
+  private function _readList(&$var, $spec, $input, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $eread = $vread = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $eread = 'read'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    $var = array();
+    $_etype = $size = 0;
+    if ($set) {
+      $xfer += $input->readSetBegin($_etype, $size);
+    } else {
+      $xfer += $input->readListBegin($_etype, $size);
+    }
+    for ($i = 0; $i < $size; ++$i) {
+      $elem = null;
+      if ($eread !== null) {
+        $xfer += $input->$eread($elem);
+      } else {
+        $espec = $spec['elem'];
+        switch ($etype) {
+        case TType::STRUCT:
+          $class = $espec['class'];
+          $elem = new $class();
+          $xfer += $elem->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($elem, $espec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($elem, $espec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($elem, $espec, $input, true);
+          break;
+        }
+      }
+      if ($set) {
+        $var[$elem] = true;
+      } else {
+        $var []= $elem;
+      }
+    }
+    if ($set) {
+      $xfer += $input->readSetEnd();
+    } else {
+      $xfer += $input->readListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _read($class, $spec, $input) {
+    $xfer = 0;
+    $fname = null;
+    $ftype = 0;
+    $fid = 0;
+    $xfer += $input->readStructBegin($fname);
+    while (true) {
+      $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+      if ($ftype == TType::STOP) {
+        break;
+      }
+      if (isset($spec[$fid])) {
+        $fspec = $spec[$fid];
+        $var = $fspec['var'];
+        if ($ftype == $fspec['type']) {
+          $xfer = 0;
+          if (isset(TBase::$tmethod[$ftype])) {
+            $func = 'read'.TBase::$tmethod[$ftype];
+            $xfer += $input->$func($this->$var);
+          } else {
+            switch ($ftype) {
+            case TType::STRUCT:
+              $class = $fspec['class'];
+              $this->$var = new $class();
+              $xfer += $this->$var->read($input);
+              break;
+            case TType::MAP:
+              $xfer += $this->_readMap($this->$var, $fspec, $input);
+              break;
+            case TType::LST:
+              $xfer += $this->_readList($this->$var, $fspec, $input, false);
+              break;
+            case TType::SET:
+              $xfer += $this->_readList($this->$var, $fspec, $input, true);
+              break;
+            }
+          }
+        } else {
+          $xfer += $input->skip($ftype);
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      $xfer += $input->readFieldEnd();
+    }
+    $xfer += $input->readStructEnd();
+    return $xfer;
+  }
+
+  private function _writeMap($var, $spec, $output) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kwrite = $vwrite = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kwrite = 'write'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vwrite = 'write'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
+    foreach ($var as $key => $val) {
+      if (isset($kwrite)) {
+        $xfer += $output->$kwrite($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $xfer += $key->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($key, $kspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($key, $kspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($key, $kspec, $output, true);
+          break;
+        }
+      }
+      if (isset($vwrite)) {
+        $xfer += $output->$vwrite($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $xfer += $val->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($val, $vspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($val, $vspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($val, $vspec, $output, true);
+          break;
+        }
+      }
+    }
+    $xfer += $output->writeMapEnd();
+    return $xfer;
+  }
+
+  private function _writeList($var, $spec, $output, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $ewrite = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $ewrite = 'write'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    if ($set) {
+      $xfer += $output->writeSetBegin($etype, count($var));
+    } else {
+      $xfer += $output->writeListBegin($etype, count($var));
+    }
+    foreach ($var as $key => $val) {
+      $elem = $set ? $key : $val;
+      if (isset($ewrite)) {
+        $xfer += $output->$ewrite($elem);
+      } else {
+        switch ($etype) {
+        case TType::STRUCT:
+          $xfer += $elem->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($elem, $espec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($elem, $espec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($elem, $espec, $output, true);
+          break;
+        }
+      }
+    }
+    if ($set) {
+      $xfer += $output->writeSetEnd();
+    } else {
+      $xfer += $output->writeListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _write($class, $spec, $output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin($class);
+    foreach ($spec as $fid => $fspec) {
+      $var = $fspec['var'];
+      if ($this->$var !== null) {
+        $ftype = $fspec['type'];
+        $xfer += $output->writeFieldBegin($var, $ftype, $fid);
+        if (isset(TBase::$tmethod[$ftype])) {
+          $func = 'write'.TBase::$tmethod[$ftype];
+          $xfer += $output->$func($this->$var);
+        } else {
+          switch ($ftype) {
+          case TType::STRUCT:
+            $xfer += $this->$var->write($output);
+            break;
+          case TType::MAP:
+            $xfer += $this->_writeMap($this->$var, $fspec, $output);
+            break;
+          case TType::LST:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, false);
+            break;
+          case TType::SET:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, true);
+            break;
+          }
+        }
+        $xfer += $output->writeFieldEnd();
+      }
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+
+}
+
+/**
+ * Base class from which other Thrift structs extend. This is so that we can
+ * cut back on the size of the generated code which is turning out to have a
+ * nontrivial cost just to load thanks to the wondrously abysmal implementation
+ * of PHP. Note that code is intentionally duplicated in here to avoid making
+ * function calls for every field or member of a container..
+ */
+abstract class TBase {
+
+  static $tmethod = array(TType::BOOL   => 'Bool',
+                          TType::BYTE   => 'Byte',
+                          TType::I16    => 'I16',
+                          TType::I32    => 'I32',
+                          TType::I64    => 'I64',
+                          TType::DOUBLE => 'Double',
+                          TType::STRING => 'String');
+
+  abstract function read($input);
+
+  abstract function write($output);
+
+  public function __construct($spec=null, $vals=null) {
+    if (is_array($spec) && is_array($vals)) {
+      foreach ($spec as $fid => $fspec) {
+        $var = $fspec['var'];
+        if (isset($vals[$var])) {
+          $this->$var = $vals[$var];
+        }
+      }
+    }
+  }
+
+  private function _readMap(&$var, $spec, $input) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kread = $vread = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kread = 'read'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vread = 'read'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $var = array();
+    $_ktype = $_vtype = $size = 0;
+    $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
+    for ($i = 0; $i < $size; ++$i) {
+      $key = $val = null;
+      if ($kread !== null) {
+        $xfer += $input->$kread($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $class = $kspec['class'];
+          $key = new $class();
+          $xfer += $key->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($key, $kspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($key, $kspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($key, $kspec, $input, true);
+          break;
+        }
+      }
+      if ($vread !== null) {
+        $xfer += $input->$vread($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $class = $vspec['class'];
+          $val = new $class();
+          $xfer += $val->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($val, $vspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($val, $vspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($val, $vspec, $input, true);
+          break;
+        }
+      }
+      $var[$key] = $val;
+    }
+    $xfer += $input->readMapEnd();
+    return $xfer;
+  }
+
+  private function _readList(&$var, $spec, $input, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $eread = $vread = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $eread = 'read'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    $var = array();
+    $_etype = $size = 0;
+    if ($set) {
+      $xfer += $input->readSetBegin($_etype, $size);
+    } else {
+      $xfer += $input->readListBegin($_etype, $size);
+    }
+    for ($i = 0; $i < $size; ++$i) {
+      $elem = null;
+      if ($eread !== null) {
+        $xfer += $input->$eread($elem);
+      } else {
+        $espec = $spec['elem'];
+        switch ($etype) {
+        case TType::STRUCT:
+          $class = $espec['class'];
+          $elem = new $class();
+          $xfer += $elem->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($elem, $espec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($elem, $espec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($elem, $espec, $input, true);
+          break;
+        }
+      }
+      if ($set) {
+        $var[$elem] = true;
+      } else {
+        $var []= $elem;
+      }
+    }
+    if ($set) {
+      $xfer += $input->readSetEnd();
+    } else {
+      $xfer += $input->readListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _read($class, $spec, $input) {
+    $xfer = 0;
+    $fname = null;
+    $ftype = 0;
+    $fid = 0;
+    $xfer += $input->readStructBegin($fname);
+    while (true) {
+      $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+      if ($ftype == TType::STOP) {
+        break;
+      }
+      if (isset($spec[$fid])) {
+        $fspec = $spec[$fid];
+        $var = $fspec['var'];
+        if ($ftype == $fspec['type']) {
+          $xfer = 0;
+          if (isset(TBase::$tmethod[$ftype])) {
+            $func = 'read'.TBase::$tmethod[$ftype];
+            $xfer += $input->$func($this->$var);
+          } else {
+            switch ($ftype) {
+            case TType::STRUCT:
+              $class = $fspec['class'];
+              $this->$var = new $class();
+              $xfer += $this->$var->read($input);
+              break;
+            case TType::MAP:
+              $xfer += $this->_readMap($this->$var, $fspec, $input);
+              break;
+            case TType::LST:
+              $xfer += $this->_readList($this->$var, $fspec, $input, false);
+              break;
+            case TType::SET:
+              $xfer += $this->_readList($this->$var, $fspec, $input, true);
+              break;
+            }
+          }
+        } else {
+          $xfer += $input->skip($ftype);
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      $xfer += $input->readFieldEnd();
+    }
+    $xfer += $input->readStructEnd();
+    return $xfer;
+  }
+
+  private function _writeMap($var, $spec, $output) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kwrite = $vwrite = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kwrite = 'write'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vwrite = 'write'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
+    foreach ($var as $key => $val) {
+      if (isset($kwrite)) {
+        $xfer += $output->$kwrite($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $xfer += $key->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($key, $kspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($key, $kspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($key, $kspec, $output, true);
+          break;
+        }
+      }
+      if (isset($vwrite)) {
+        $xfer += $output->$vwrite($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $xfer += $val->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($val, $vspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($val, $vspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($val, $vspec, $output, true);
+          break;
+        }
+      }
+    }
+    $xfer += $output->writeMapEnd();
+    return $xfer;
+  }
+
+  private function _writeList($var, $spec, $output, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $ewrite = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $ewrite = 'write'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    if ($set) {
+      $xfer += $output->writeSetBegin($etype, count($var));
+    } else {
+      $xfer += $output->writeListBegin($etype, count($var));
+    }
+    foreach ($var as $key => $val) {
+      $elem = $set ? $key : $val;
+      if (isset($ewrite)) {
+        $xfer += $output->$ewrite($elem);
+      } else {
+        switch ($etype) {
+        case TType::STRUCT:
+          $xfer += $elem->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($elem, $espec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($elem, $espec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($elem, $espec, $output, true);
+          break;
+        }
+      }
+    }
+    if ($set) {
+      $xfer += $output->writeSetEnd();
+    } else {
+      $xfer += $output->writeListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _write($class, $spec, $output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin($class);
+    foreach ($spec as $fid => $fspec) {
+      $var = $fspec['var'];
+      if ($this->$var !== null) {
+        $ftype = $fspec['type'];
+        $xfer += $output->writeFieldBegin($var, $ftype, $fid);
+        if (isset(TBase::$tmethod[$ftype])) {
+          $func = 'write'.TBase::$tmethod[$ftype];
+          $xfer += $output->$func($this->$var);
+        } else {
+          switch ($ftype) {
+          case TType::STRUCT:
+            $xfer += $this->$var->write($output);
+            break;
+          case TType::MAP:
+            $xfer += $this->_writeMap($this->$var, $fspec, $output);
+            break;
+          case TType::LST:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, false);
+            break;
+          case TType::SET:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, true);
+            break;
+          }
+        }
+        $xfer += $output->writeFieldEnd();
+      }
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+}
+
+class TApplicationException extends TException {
+  static $_TSPEC =
+    array(1 => array('var' => 'message',
+                     'type' => TType::STRING),
+          2 => array('var' => 'code',
+                     'type' => TType::I32));
+
+  const UNKNOWN = 0;
+  const UNKNOWN_METHOD = 1;
+  const INVALID_MESSAGE_TYPE = 2;
+  const WRONG_METHOD_NAME = 3;
+  const BAD_SEQUENCE_ID = 4;
+  const MISSING_RESULT = 5;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+
+  public function read($output) {
+    return $this->_read('TApplicationException', self::$_TSPEC, $output);
+  }
+
+  public function write($output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin('TApplicationException');
+    if ($message = $this->getMessage()) {
+      $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
+      $xfer += $output->writeString($message);
+      $xfer += $output->writeFieldEnd();
+    }
+    if ($code = $this->getCode()) {
+      $xfer += $output->writeFieldBegin('type', TType::I32, 2);
+      $xfer += $output->writeI32($code);
+      $xfer += $output->writeFieldEnd();
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+}
+
+/**
+ * Set global THRIFT ROOT automatically via inclusion here
+ */
+if (!isset($GLOBALS['THRIFT_ROOT'])) {
+  $GLOBALS['THRIFT_ROOT'] = dirname(__FILE__);
+}
+include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TProtocol.php';
+include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php';
+
+?>
diff --git a/lib/php/src/autoload.php b/lib/php/src/autoload.php
new file mode 100644
index 0000000..3a35545
--- /dev/null
+++ b/lib/php/src/autoload.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift
+ */
+
+
+/**
+ * Include this file if you wish to use autoload with your PHP generated Thrift
+ * code. The generated code will *not* include any defined Thrift classes by
+ * default, except for the service interfaces. The generated code will populate
+ * values into $GLOBALS['THRIFT_AUTOLOAD'] which can be used by the autoload
+ * method below. If you have your own autoload system already in place, rename your
+ * __autoload function to something else and then do:
+ * $GLOBALS['AUTOLOAD_HOOKS'][] = 'my_autoload_func';
+ *
+ * Generate this code using the --gen php:autoload Thrift generator flag.
+ */
+
+$GLOBALS['THRIFT_AUTOLOAD'] = array();
+$GLOBALS['AUTOLOAD_HOOKS'] = array();
+
+if (!function_exists('__autoload')) {
+  function __autoload($class) {
+    global $THRIFT_AUTOLOAD;
+    $classl = strtolower($class);
+    if (isset($THRIFT_AUTOLOAD[$classl])) {
+      include_once $GLOBALS['THRIFT_ROOT'].'/packages/'.$THRIFT_AUTOLOAD[$classl];
+    } else if (!empty($GLOBALS['AUTOLOAD_HOOKS'])) {
+      foreach ($GLOBALS['AUTOLOAD_HOOKS'] as $hook) {
+        $hook($class);
+      }
+    }
+  }
+}
diff --git a/lib/php/src/ext/thrift_protocol/config.m4 b/lib/php/src/ext/thrift_protocol/config.m4
new file mode 100644
index 0000000..8cfb37d
--- /dev/null
+++ b/lib/php/src/ext/thrift_protocol/config.m4
@@ -0,0 +1,13 @@
+dnl Copyright (C) 2009 Facebook
+dnl Copying and distribution of this file, with or without modification,
+dnl are permitted in any medium without royalty provided the copyright
+dnl notice and this notice are preserved.
+
+PHP_ARG_ENABLE(thrift_protocol, whether to enable the thrift_protocol extension,
+[  --enable-thrift_protocol	Enable the fbthrift_protocol extension])
+
+if test "$PHP_THRIFT_PROTOCOL" != "no"; then
+  PHP_REQUIRE_CXX()
+  PHP_NEW_EXTENSION(thrift_protocol, php_thrift_protocol.cpp, $ext_shared)
+fi
+
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
new file mode 100644
index 0000000..399cbe6
--- /dev/null
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
@@ -0,0 +1,999 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <stdexcept>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htonll(x) bswap_64(x)
+#define ntohll(x) bswap_64(x)
+#else
+#define htonll(x) x
+#define ntohll(x) x
+#endif
+
+enum TType {
+  T_STOP       = 0,
+  T_VOID       = 1,
+  T_BOOL       = 2,
+  T_BYTE       = 3,
+  T_I08        = 3,
+  T_I16        = 6,
+  T_I32        = 8,
+  T_U64        = 9,
+  T_I64        = 10,
+  T_DOUBLE     = 4,
+  T_STRING     = 11,
+  T_UTF7       = 11,
+  T_STRUCT     = 12,
+  T_MAP        = 13,
+  T_SET        = 14,
+  T_LIST       = 15,
+  T_UTF8       = 16,
+  T_UTF16      = 17
+};
+
+const int32_t VERSION_MASK = 0xffff0000;
+const int32_t VERSION_1 = 0x80010000;
+const int8_t T_CALL = 1;
+const int8_t T_REPLY = 2;
+const int8_t T_EXCEPTION = 3;
+// tprotocolexception
+const int INVALID_DATA = 1;
+const int BAD_VERSION = 4;
+
+#include "php.h"
+#include "zend_interfaces.h"
+#include "zend_exceptions.h"
+#include "php_thrift_protocol.h"
+
+static function_entry thrift_protocol_functions[] = {
+  PHP_FE(thrift_protocol_write_binary, NULL)
+  PHP_FE(thrift_protocol_read_binary, NULL)
+  {NULL, NULL, NULL}
+} ;
+
+zend_module_entry thrift_protocol_module_entry = {
+  STANDARD_MODULE_HEADER,
+  "thrift_protocol",
+  thrift_protocol_functions,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  "1.0",
+  STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_THRIFT_PROTOCOL
+ZEND_GET_MODULE(thrift_protocol)
+#endif
+
+class PHPExceptionWrapper : public std::exception {
+public:
+  PHPExceptionWrapper(zval* _ex) throw() : ex(_ex) {
+    snprintf(_what, 40, "PHP exception zval=%p", ex);
+  }
+  const char* what() const throw() { return _what; }
+  ~PHPExceptionWrapper() throw() {}
+  operator zval*() const throw() { return const_cast<zval*>(ex); } // Zend API doesn't do 'const'...
+protected:
+  zval* ex;
+  char _what[40];
+} ;
+
+class PHPTransport {
+public:
+  zval* protocol() { return p; }
+  zval* transport() { return t; }
+protected:
+  PHPTransport() {}
+
+  void construct_with_zval(zval* _p, size_t _buffer_size) {
+    buffer = reinterpret_cast<char*>(emalloc(_buffer_size));
+    buffer_ptr = buffer;
+    buffer_used = 0;
+    buffer_size = _buffer_size;
+    p = _p;
+
+    // Get the transport for the passed protocol
+    zval gettransport;
+    ZVAL_STRING(&gettransport, "getTransport", 0);
+    MAKE_STD_ZVAL(t);
+    ZVAL_NULL(t);
+    TSRMLS_FETCH();
+    call_user_function(EG(function_table), &p, &gettransport, t, 0, NULL TSRMLS_CC);
+  }
+  ~PHPTransport() {
+    efree(buffer);
+    zval_ptr_dtor(&t);
+  }
+
+  char* buffer;
+  char* buffer_ptr;
+  size_t buffer_used;
+  size_t buffer_size;
+
+  zval* p;
+  zval* t;
+};
+
+
+class PHPOutputTransport : public PHPTransport {
+public:
+  PHPOutputTransport(zval* _p, size_t _buffer_size = 8192) {
+    construct_with_zval(_p, _buffer_size);
+  }
+
+  ~PHPOutputTransport() {
+    flush();
+    directFlush();
+  }
+
+  void write(const char* data, size_t len) {
+    if ((len + buffer_used) > buffer_size) {
+      flush();
+    }
+    if (len > buffer_size) {
+      directWrite(data, len);
+    } else {
+      memcpy(buffer_ptr, data, len);
+      buffer_used += len;
+      buffer_ptr += len;
+    }
+  }
+
+  void writeI64(int64_t i) {
+    i = htonll(i);
+    write((const char*)&i, 8);
+  }
+
+  void writeU32(uint32_t i) {
+    i = htonl(i);
+    write((const char*)&i, 4);
+  }
+
+  void writeI32(int32_t i) {
+    i = htonl(i);
+    write((const char*)&i, 4);
+  }
+
+  void writeI16(int16_t i) {
+    i = htons(i);
+    write((const char*)&i, 2);
+  }
+
+  void writeI8(int8_t i) {
+    write((const char*)&i, 1);
+  }
+
+  void writeString(const char* str, size_t len) {
+    writeU32(len);
+    write(str, len);
+  }
+
+  void flush() {
+    if (buffer_used) {
+      directWrite(buffer, buffer_used);
+      buffer_ptr = buffer;
+      buffer_used = 0;
+    }
+  }
+
+protected:
+  void directFlush() {
+    zval ret;
+    ZVAL_NULL(&ret);
+    zval flushfn;
+    ZVAL_STRING(&flushfn, "flush", 0);
+    TSRMLS_FETCH();
+    call_user_function(EG(function_table), &t, &flushfn, &ret, 0, NULL TSRMLS_CC);
+    zval_dtor(&ret);
+  }
+  void directWrite(const char* data, size_t len) {
+    zval writefn;
+    ZVAL_STRING(&writefn, "write", 0);
+    char* newbuf = (char*)emalloc(buffer_used + 1);
+    memcpy(newbuf, buffer, buffer_used);
+    newbuf[buffer_used] = '\0';
+    zval *args[1];
+    MAKE_STD_ZVAL(args[0]);
+    ZVAL_STRINGL(args[0], newbuf, buffer_used, 0);
+    TSRMLS_FETCH();
+    zval ret;
+    ZVAL_NULL(&ret);
+    call_user_function(EG(function_table), &t, &writefn, &ret, 1, args TSRMLS_CC);
+    zval_ptr_dtor(args);
+    zval_dtor(&ret);
+    if (EG(exception)) {
+      zval* ex = EG(exception);
+      EG(exception) = NULL;
+      throw PHPExceptionWrapper(ex);
+    }
+  }
+};
+
+class PHPInputTransport : public PHPTransport {
+public:
+  PHPInputTransport(zval* _p, size_t _buffer_size = 8192) {
+    construct_with_zval(_p, _buffer_size);
+  }
+
+  ~PHPInputTransport() {
+    put_back();
+  }
+
+  void put_back() {
+    if (buffer_used) {
+      zval putbackfn;
+      ZVAL_STRING(&putbackfn, "putBack", 0);
+
+      char* newbuf = (char*)emalloc(buffer_used + 1);
+      memcpy(newbuf, buffer_ptr, buffer_used);
+      newbuf[buffer_used] = '\0';
+
+      zval *args[1];
+      MAKE_STD_ZVAL(args[0]);
+      ZVAL_STRINGL(args[0], newbuf, buffer_used, 0);
+
+      TSRMLS_FETCH();
+
+      zval ret;
+      ZVAL_NULL(&ret);
+      call_user_function(EG(function_table), &t, &putbackfn, &ret, 1, args TSRMLS_CC);
+      zval_ptr_dtor(args);
+      zval_dtor(&ret);
+    }
+    buffer_used = 0;
+    buffer_ptr = buffer;
+  }
+
+  void skip(size_t len) {
+    while (len) {
+      size_t chunk_size = MIN(len, buffer_used);
+      if (chunk_size) {
+        buffer_ptr = reinterpret_cast<char*>(buffer_ptr) + chunk_size;
+        buffer_used -= chunk_size;
+        len -= chunk_size;
+      }
+      if (! len) break;
+      refill();
+    }
+  }
+
+  void readBytes(void* buf, size_t len) {
+    while (len) {
+      size_t chunk_size = MIN(len, buffer_used);
+      if (chunk_size) {
+        memcpy(buf, buffer_ptr, chunk_size);
+        buffer_ptr = reinterpret_cast<char*>(buffer_ptr) + chunk_size;
+        buffer_used -= chunk_size;
+        buf = reinterpret_cast<char*>(buf) + chunk_size;
+        len -= chunk_size;
+      }
+      if (! len) break;
+      refill();
+    }
+  }
+
+  int8_t readI8() {
+    int8_t c;
+    readBytes(&c, 1);
+    return c;
+  }
+
+  int16_t readI16() {
+    int16_t c;
+    readBytes(&c, 2);
+    return (int16_t)ntohs(c);
+  }
+
+  uint32_t readU32() {
+    uint32_t c;
+    readBytes(&c, 4);
+    return (uint32_t)ntohl(c);
+  }
+
+  int32_t readI32() {
+    int32_t c;
+    readBytes(&c, 4);
+    return (int32_t)ntohl(c);
+  }
+
+protected:
+  void refill() {
+    assert(buffer_used == 0);
+    zval retval;
+    ZVAL_NULL(&retval);
+
+    zval *args[1];
+    MAKE_STD_ZVAL(args[0]);
+    ZVAL_LONG(args[0], buffer_size);
+
+    TSRMLS_FETCH();
+
+    zval funcname;
+    ZVAL_STRING(&funcname, "read", 0);
+
+    call_user_function(EG(function_table), &t, &funcname, &retval, 1, args TSRMLS_CC);
+    zval_ptr_dtor(args);
+
+    if (EG(exception)) {
+      zval_dtor(&retval);
+      zval* ex = EG(exception);
+      EG(exception) = NULL;
+      throw PHPExceptionWrapper(ex);
+    }
+
+    buffer_used = Z_STRLEN(retval);
+    memcpy(buffer, Z_STRVAL(retval), buffer_used);
+    zval_dtor(&retval);
+
+    buffer_ptr = buffer;
+  }
+
+};
+
+void binary_deserialize_spec(zval* zthis, PHPInputTransport& transport, HashTable* spec);
+void binary_serialize_spec(zval* zthis, PHPOutputTransport& transport, HashTable* spec);
+void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval** value, HashTable* fieldspec);
+void skip_element(long thrift_typeID, PHPInputTransport& transport);
+
+// Create a PHP object given a typename and call the ctor, optionally passing up to 2 arguments
+void createObject(char* obj_typename, zval* return_value, int nargs = 0, zval* arg1 = NULL, zval* arg2 = NULL) {
+  TSRMLS_FETCH();
+  size_t obj_typename_len = strlen(obj_typename);
+  zend_class_entry* ce = zend_fetch_class(obj_typename, obj_typename_len, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
+  if (! ce) {
+    php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", obj_typename);
+    RETURN_NULL();
+  }
+
+  object_and_properties_init(return_value, ce, NULL);
+  zend_function* constructor = zend_std_get_constructor(return_value TSRMLS_CC);
+  zval* ctor_rv = NULL;
+  zend_call_method(&return_value, ce, &constructor, NULL, 0, &ctor_rv, nargs, arg1, arg2 TSRMLS_CC);
+  zval_ptr_dtor(&ctor_rv);
+}
+
+void throw_tprotocolexception(char* what, long errorcode) {
+  TSRMLS_FETCH();
+
+  zval *zwhat, *zerrorcode;
+  MAKE_STD_ZVAL(zwhat);
+  MAKE_STD_ZVAL(zerrorcode);
+
+  ZVAL_STRING(zwhat, what, 1);
+  ZVAL_LONG(zerrorcode, errorcode);
+
+  zval* ex;
+  MAKE_STD_ZVAL(ex);
+  createObject("TProtocolException", ex, 2, zwhat, zerrorcode);
+  zval_ptr_dtor(&zwhat);
+  zval_ptr_dtor(&zerrorcode);
+  throw PHPExceptionWrapper(ex);
+}
+
+void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval* return_value, HashTable* fieldspec) {
+  zval** val_ptr;
+  Z_TYPE_P(return_value) = IS_NULL; // just in case
+
+  switch (thrift_typeID) {
+    case T_STOP:
+    case T_VOID:
+      RETURN_NULL();
+      return;
+    case T_STRUCT: {
+      if (zend_hash_find(fieldspec, "class", 6, (void**)&val_ptr) != SUCCESS) {
+        throw_tprotocolexception("no class type in spec", INVALID_DATA);
+        skip_element(T_STRUCT, transport);
+        RETURN_NULL();
+      }
+      char* structType = Z_STRVAL_PP(val_ptr);
+      createObject(structType, return_value);
+      if (Z_TYPE_P(return_value) == IS_NULL) {
+        // unable to create class entry
+        skip_element(T_STRUCT, transport);
+        RETURN_NULL();
+      }
+      TSRMLS_FETCH();
+      zval* spec = zend_read_static_property(zend_get_class_entry(return_value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
+      if (Z_TYPE_P(spec) != IS_ARRAY) {
+        char errbuf[128];
+        snprintf(errbuf, 128, "spec for %s is wrong type: %d\n", structType, Z_TYPE_P(spec));
+        throw_tprotocolexception(errbuf, INVALID_DATA);
+        RETURN_NULL();
+      }
+      binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec));
+      return;
+    } break;
+    case T_BOOL: {
+      uint8_t c;
+      transport.readBytes(&c, 1);
+      RETURN_BOOL(c != 0);
+    }
+  //case T_I08: // same numeric value as T_BYTE
+    case T_BYTE: {
+      uint8_t c;
+      transport.readBytes(&c, 1);
+      RETURN_LONG(c);
+    }
+    case T_I16: {
+      uint16_t c;
+      transport.readBytes(&c, 2);
+      RETURN_LONG(ntohs(c));
+    }
+    case T_I32: {
+      uint32_t c;
+      transport.readBytes(&c, 4);
+      RETURN_LONG(ntohl(c));
+    }
+    case T_U64:
+    case T_I64: {
+      uint64_t c;
+      transport.readBytes(&c, 8);
+      RETURN_LONG(ntohll(c));
+    }
+    case T_DOUBLE: {
+      union {
+        uint64_t c;
+        double d;
+      } a;
+      transport.readBytes(&(a.c), 8);
+      a.c = ntohll(a.c);
+      RETURN_DOUBLE(a.d);
+    }
+    //case T_UTF7: // aliases T_STRING
+    case T_UTF8:
+    case T_UTF16:
+    case T_STRING: {
+      uint32_t size = transport.readU32();
+      if (size) {
+        char* strbuf = (char*) emalloc(size + 1);
+        transport.readBytes(strbuf, size);
+        strbuf[size] = '\0';
+        ZVAL_STRINGL(return_value, strbuf, size, 0);
+      } else {
+        ZVAL_EMPTY_STRING(return_value);
+      }
+      return;
+    }
+    case T_MAP: { // array of key -> value
+      uint8_t types[2];
+      transport.readBytes(types, 2);
+      uint32_t size = transport.readU32();
+      array_init(return_value);
+
+      zend_hash_find(fieldspec, "key", 4, (void**)&val_ptr);
+      HashTable* keyspec = Z_ARRVAL_PP(val_ptr);
+      zend_hash_find(fieldspec, "val", 4, (void**)&val_ptr);
+      HashTable* valspec = Z_ARRVAL_PP(val_ptr);
+
+      for (uint32_t s = 0; s < size; ++s) {
+        zval *value;
+        MAKE_STD_ZVAL(value);
+
+        zval* key;
+        MAKE_STD_ZVAL(key);
+
+        binary_deserialize(types[0], transport, key, keyspec);
+        binary_deserialize(types[1], transport, value, valspec);
+        if (Z_TYPE_P(key) == IS_LONG) {
+          zend_hash_index_update(return_value->value.ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL);
+        }
+        else {
+          if (Z_TYPE_P(key) != IS_STRING) convert_to_string(key);
+          zend_hash_update(return_value->value.ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
+        }
+        zval_ptr_dtor(&key);
+      }
+      return; // return_value already populated
+    }
+    case T_LIST: { // array with autogenerated numeric keys
+      int8_t type = transport.readI8();
+      uint32_t size = transport.readU32();
+      zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
+      HashTable* elemspec = Z_ARRVAL_PP(val_ptr);
+
+      array_init(return_value);
+      for (uint32_t s = 0; s < size; ++s) {
+        zval *value;
+        MAKE_STD_ZVAL(value);
+        binary_deserialize(type, transport, value, elemspec);
+        zend_hash_next_index_insert(return_value->value.ht, &value, sizeof(zval *), NULL);
+      }
+      return;
+    }
+    case T_SET: { // array of key -> TRUE
+      uint8_t type;
+      uint32_t size;
+      transport.readBytes(&type, 1);
+      transport.readBytes(&size, 4);
+      size = ntohl(size);
+      zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
+      HashTable* elemspec = Z_ARRVAL_PP(val_ptr);
+
+      array_init(return_value);
+
+      for (uint32_t s = 0; s < size; ++s) {
+        zval* key;
+        zval* value;
+        MAKE_STD_ZVAL(key);
+        MAKE_STD_ZVAL(value);
+        ZVAL_TRUE(value);
+
+        binary_deserialize(type, transport, key, elemspec);
+
+        if (Z_TYPE_P(key) == IS_LONG) {
+          zend_hash_index_update(return_value->value.ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL);
+        }
+        else {
+          if (Z_TYPE_P(key) != IS_STRING) convert_to_string(key);
+          zend_hash_update(return_value->value.ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
+        }
+        zval_ptr_dtor(&key);
+      }
+      return;
+    }
+  };
+
+  char errbuf[128];
+  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
+  throw_tprotocolexception(errbuf, INVALID_DATA);
+}
+
+void skip_element(long thrift_typeID, PHPInputTransport& transport) {
+  switch (thrift_typeID) {
+    case T_STOP:
+    case T_VOID:
+      return;
+    case T_STRUCT:
+      while (true) {
+        int8_t ttype = transport.readI8(); // get field type
+        if (ttype == T_STOP) break;
+        transport.skip(2); // skip field number, I16
+        skip_element(ttype, transport); // skip field payload
+      }
+      return;
+    case T_BOOL:
+    case T_BYTE:
+      transport.skip(1);
+      return;
+    case T_I16:
+      transport.skip(2);
+      return;
+    case T_I32:
+      transport.skip(4);
+      return;
+    case T_U64:
+    case T_I64:
+    case T_DOUBLE:
+      transport.skip(8);
+      return;
+    //case T_UTF7: // aliases T_STRING
+    case T_UTF8:
+    case T_UTF16:
+    case T_STRING: {
+      uint32_t len = transport.readU32();
+      transport.skip(len);
+      } return;
+    case T_MAP: {
+      int8_t keytype = transport.readI8();
+      int8_t valtype = transport.readI8();
+      uint32_t size = transport.readU32();
+      for (uint32_t i = 0; i < size; ++i) {
+        skip_element(keytype, transport);
+        skip_element(valtype, transport);
+      }
+    } return;
+    case T_LIST:
+    case T_SET: {
+      int8_t valtype = transport.readI8();
+      uint32_t size = transport.readU32();
+      for (uint32_t i = 0; i < size; ++i) {
+        skip_element(valtype, transport);
+      }
+    } return;
+  };
+
+  char errbuf[128];
+  sprintf(errbuf, "Unknown thrift typeID %ld", thrift_typeID);
+  throw_tprotocolexception(errbuf, INVALID_DATA);
+}
+
+void binary_serialize_hashtable_key(int8_t keytype, PHPOutputTransport& transport, HashTable* ht, HashPosition& ht_pos) {
+  bool keytype_is_numeric = (!((keytype == T_STRING) || (keytype == T_UTF8) || (keytype == T_UTF16)));
+
+  char* key;
+  uint key_len;
+  long index = 0;
+
+  zval* z;
+  MAKE_STD_ZVAL(z);
+
+  int res = zend_hash_get_current_key_ex(ht, &key, &key_len, (ulong*)&index, 0, &ht_pos);
+  if (keytype_is_numeric) {
+    if (res == HASH_KEY_IS_STRING) {
+      index = strtol(key, NULL, 10);
+    }
+    ZVAL_LONG(z, index);
+  } else {
+    char buf[64];
+    if (res == HASH_KEY_IS_STRING) {
+      key_len -= 1; // skip the null terminator
+    } else {
+      sprintf(buf, "%ld", index);
+      key = buf; key_len = strlen(buf);
+    }
+    ZVAL_STRINGL(z, key, key_len, 1);
+  }
+  binary_serialize(keytype, transport, &z, NULL);
+  zval_ptr_dtor(&z);
+}
+
+inline bool ttype_is_int(int8_t t) {
+  return ((t == T_BYTE) || ((t >= T_I16)  && (t <= T_I64)));
+}
+
+inline bool ttypes_are_compatible(int8_t t1, int8_t t2) {
+  // Integer types of different widths are considered compatible;
+  // otherwise the typeID must match.
+  return ((t1 == t2) || (ttype_is_int(t1) && ttype_is_int(t2)));
+}
+
+void binary_deserialize_spec(zval* zthis, PHPInputTransport& transport, HashTable* spec) {
+  // SET and LIST have 'elem' => array('type', [optional] 'class')
+  // MAP has 'val' => array('type', [optiona] 'class')
+  TSRMLS_FETCH();
+  zend_class_entry* ce = zend_get_class_entry(zthis TSRMLS_CC);
+  while (true) {
+    zval** val_ptr = NULL;
+
+    int8_t ttype = transport.readI8();
+    if (ttype == T_STOP) return;
+    int16_t fieldno = transport.readI16();
+    if (zend_hash_index_find(spec, fieldno, (void**)&val_ptr) == SUCCESS) {
+      HashTable* fieldspec = Z_ARRVAL_PP(val_ptr);
+      // pull the field name
+      // zend hash tables use the null at the end in the length... so strlen(hash key) + 1.
+      zend_hash_find(fieldspec, "var", 4, (void**)&val_ptr);
+      char* varname = Z_STRVAL_PP(val_ptr);
+
+      // and the type
+      zend_hash_find(fieldspec, "type", 5, (void**)&val_ptr);
+      if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
+      int8_t expected_ttype = Z_LVAL_PP(val_ptr);
+
+      if (ttypes_are_compatible(ttype, expected_ttype)) {
+        zval* rv = NULL;
+        MAKE_STD_ZVAL(rv);
+        binary_deserialize(ttype, transport, rv, fieldspec);
+        zend_update_property(ce, zthis, varname, strlen(varname), rv TSRMLS_CC);
+        zval_ptr_dtor(&rv);
+      } else {
+        skip_element(ttype, transport);
+      }
+    } else {
+      skip_element(ttype, transport);
+    }
+  }
+}
+
+void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval** value, HashTable* fieldspec) {
+  // At this point the typeID (and field num, if applicable) should've already been written to the output so all we need to do is write the payload.
+  switch (thrift_typeID) {
+    case T_STOP:
+    case T_VOID:
+      return;
+    case T_STRUCT: {
+      TSRMLS_FETCH();
+      if (Z_TYPE_PP(value) != IS_OBJECT) {
+        throw_tprotocolexception("Attempt to send non-object type as a T_STRUCT", INVALID_DATA);
+      }
+      zval* spec = zend_read_static_property(zend_get_class_entry(*value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
+      binary_serialize_spec(*value, transport, Z_ARRVAL_P(spec));
+    } return;
+    case T_BOOL:
+      if (Z_TYPE_PP(value) != IS_BOOL) convert_to_boolean(*value);
+      transport.writeI8(Z_BVAL_PP(value) ? 1 : 0);
+      return;
+    case T_BYTE:
+      if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
+      transport.writeI8(Z_LVAL_PP(value));
+      return;
+    case T_I16:
+      if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
+      transport.writeI16(Z_LVAL_PP(value));
+      return;
+    case T_I32:
+      if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
+      transport.writeI32(Z_LVAL_PP(value));
+      return;
+    case T_I64:
+    case T_U64:
+      if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
+      transport.writeI64(Z_LVAL_PP(value));
+      return;
+    case T_DOUBLE: {
+      union {
+        int64_t c;
+        double d;
+      } a;
+      if (Z_TYPE_PP(value) != IS_DOUBLE) convert_to_double(*value);
+      a.d = Z_DVAL_PP(value);
+      transport.writeI64(a.c);
+    } return;
+    //case T_UTF7:
+    case T_UTF8:
+    case T_UTF16:
+    case T_STRING:
+      if (Z_TYPE_PP(value) != IS_STRING) convert_to_string(*value);
+      transport.writeString(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
+      return;
+    case T_MAP: {
+      if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
+      if (Z_TYPE_PP(value) != IS_ARRAY) {
+        throw_tprotocolexception("Attempt to send an incompatible type as an array (T_MAP)", INVALID_DATA);
+      }
+      HashTable* ht = Z_ARRVAL_PP(value);
+      zval** val_ptr;
+
+      zend_hash_find(fieldspec, "ktype", 6, (void**)&val_ptr);
+      if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
+      uint8_t keytype = Z_LVAL_PP(val_ptr);
+      transport.writeI8(keytype);
+      zend_hash_find(fieldspec, "vtype", 6, (void**)&val_ptr);
+      if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
+      uint8_t valtype = Z_LVAL_PP(val_ptr);
+      transport.writeI8(valtype);
+
+      zend_hash_find(fieldspec, "val", 4, (void**)&val_ptr);
+      HashTable* valspec = Z_ARRVAL_PP(val_ptr);
+
+      transport.writeI32(zend_hash_num_elements(ht));
+      HashPosition key_ptr;
+      for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
+        binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
+        binary_serialize(valtype, transport, val_ptr, valspec);
+      }
+    } return;
+    case T_LIST: {
+      if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
+      if (Z_TYPE_PP(value) != IS_ARRAY) {
+        throw_tprotocolexception("Attempt to send an incompatible type as an array (T_LIST)", INVALID_DATA);
+      }
+      HashTable* ht = Z_ARRVAL_PP(value);
+      zval** val_ptr;
+
+      zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
+      if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
+      uint8_t valtype = Z_LVAL_PP(val_ptr);
+      transport.writeI8(valtype);
+
+      zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
+      HashTable* valspec = Z_ARRVAL_PP(val_ptr);
+
+      transport.writeI32(zend_hash_num_elements(ht));
+      HashPosition key_ptr;
+      for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
+        binary_serialize(valtype, transport, val_ptr, valspec);
+      }
+    } return;
+    case T_SET: {
+      if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
+      if (Z_TYPE_PP(value) != IS_ARRAY) {
+        throw_tprotocolexception("Attempt to send an incompatible type as an array (T_SET)", INVALID_DATA);
+      }
+      HashTable* ht = Z_ARRVAL_PP(value);
+      zval** val_ptr;
+
+      zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
+      if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
+      uint8_t keytype = Z_LVAL_PP(val_ptr);
+      transport.writeI8(keytype);
+
+      transport.writeI32(zend_hash_num_elements(ht));
+      HashPosition key_ptr;
+      for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
+        binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
+      }
+    } return;
+  };
+  char errbuf[128];
+  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
+  throw_tprotocolexception(errbuf, INVALID_DATA);
+}
+
+
+void binary_serialize_spec(zval* zthis, PHPOutputTransport& transport, HashTable* spec) {
+  HashPosition key_ptr;
+  zval** val_ptr;
+
+  TSRMLS_FETCH();
+  zend_class_entry* ce = zend_get_class_entry(zthis TSRMLS_CC);
+
+  for (zend_hash_internal_pointer_reset_ex(spec, &key_ptr); zend_hash_get_current_data_ex(spec, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(spec, &key_ptr)) {
+    ulong fieldno;
+    if (zend_hash_get_current_key_ex(spec, NULL, NULL, &fieldno, 0, &key_ptr) != HASH_KEY_IS_LONG) {
+      throw_tprotocolexception("Bad keytype in TSPEC (expected 'long')", INVALID_DATA);
+      return;
+    }
+    HashTable* fieldspec = Z_ARRVAL_PP(val_ptr);
+
+    // field name
+    zend_hash_find(fieldspec, "var", 4, (void**)&val_ptr);
+    char* varname = Z_STRVAL_PP(val_ptr);
+
+    // thrift type
+    zend_hash_find(fieldspec, "type", 5, (void**)&val_ptr);
+    if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
+    int8_t ttype = Z_LVAL_PP(val_ptr);
+
+    zval* prop = zend_read_property(ce, zthis, varname, strlen(varname), false TSRMLS_CC);
+    if (Z_TYPE_P(prop) != IS_NULL) {
+      transport.writeI8(ttype);
+      transport.writeI16(fieldno);
+      binary_serialize(ttype, transport, &prop, fieldspec);
+    }
+  }
+  transport.writeI8(T_STOP); // struct end
+}
+
+// 6 params: $transport $method_name $ttype $request_struct $seqID $strict_write
+PHP_FUNCTION(thrift_protocol_write_binary) {
+  int argc = ZEND_NUM_ARGS();
+  if (argc < 6) {
+    WRONG_PARAM_COUNT;
+  }
+
+  zval ***args = (zval***) emalloc(argc * sizeof(zval**));
+  zend_get_parameters_array_ex(argc, args);
+
+  if (Z_TYPE_PP(args[0]) != IS_OBJECT) {
+    php_error_docref(NULL TSRMLS_CC, E_ERROR, "1st parameter is not an object (transport)");
+    efree(args);
+    RETURN_NULL();
+  }
+
+  if (Z_TYPE_PP(args[1]) != IS_STRING) {
+    php_error_docref(NULL TSRMLS_CC, E_ERROR, "2nd parameter is not a string (method name)");
+    efree(args);
+    RETURN_NULL();
+  }
+
+  if (Z_TYPE_PP(args[3]) != IS_OBJECT) {
+    php_error_docref(NULL TSRMLS_CC, E_ERROR, "4th parameter is not an object (request struct)");
+    efree(args);
+    RETURN_NULL();
+  }
+
+  PHPOutputTransport transport(*args[0]);
+  const char* method_name = Z_STRVAL_PP(args[1]);
+  convert_to_long(*args[2]);
+  int32_t msgtype = Z_LVAL_PP(args[2]);
+  zval* request_struct = *args[3];
+  convert_to_long(*args[4]);
+  int32_t seqID = Z_LVAL_PP(args[4]);
+  convert_to_boolean(*args[5]);
+  bool strictWrite = Z_BVAL_PP(args[5]);
+  efree(args);
+  args = NULL;
+
+  try {
+    if (strictWrite) {
+      int32_t version = VERSION_1 | msgtype;
+      transport.writeI32(version);
+      transport.writeString(method_name, strlen(method_name));
+      transport.writeI32(seqID);
+    } else {
+      transport.writeString(method_name, strlen(method_name));
+      transport.writeI8(msgtype);
+      transport.writeI32(seqID);
+    }
+
+    zval* spec = zend_read_static_property(zend_get_class_entry(request_struct TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
+    binary_serialize_spec(request_struct, transport, Z_ARRVAL_P(spec));
+  } catch (const PHPExceptionWrapper& ex) {
+    zend_throw_exception_object(ex TSRMLS_CC);
+    RETURN_NULL();
+  }
+}
+
+// 3 params: $transport $response_Typename $strict_read
+PHP_FUNCTION(thrift_protocol_read_binary) {
+  int argc = ZEND_NUM_ARGS();
+
+  if (argc < 3) {
+    WRONG_PARAM_COUNT;
+  }
+
+  zval ***args = (zval***) emalloc(argc * sizeof(zval**));
+  zend_get_parameters_array_ex(argc, args);
+
+  if (Z_TYPE_PP(args[0]) != IS_OBJECT) {
+    php_error_docref(NULL TSRMLS_CC, E_ERROR, "1st parameter is not an object (transport)");
+    efree(args);
+    RETURN_NULL();
+  }
+
+  if (Z_TYPE_PP(args[1]) != IS_STRING) {
+    php_error_docref(NULL TSRMLS_CC, E_ERROR, "2nd parameter is not a string (typename of expected response struct)");
+    efree(args);
+    RETURN_NULL();
+  }
+
+  PHPInputTransport transport(*args[0]);
+  char* obj_typename = Z_STRVAL_PP(args[1]);
+  convert_to_boolean(*args[2]);
+  bool strict_read = Z_BVAL_PP(args[2]);
+  efree(args);
+  args = NULL;
+
+  try {
+    int8_t messageType = 0;
+    int32_t sz = transport.readI32();
+
+    if (sz < 0) {
+      // Check for correct version number
+      int32_t version = sz & VERSION_MASK;
+      if (version != VERSION_1) {
+        throw_tprotocolexception("Bad version identifier", BAD_VERSION);
+      }
+      messageType = (sz & 0x000000ff);
+      int32_t namelen = transport.readI32();
+      // skip the name string and the sequence ID, we don't care about those
+      transport.skip(namelen + 4);
+    } else {
+      if (strict_read) {
+        throw_tprotocolexception("No version identifier... old protocol client in strict mode?", BAD_VERSION);
+      } else {
+        // Handle pre-versioned input
+        transport.skip(sz); // skip string body
+        messageType = transport.readI8();
+        transport.skip(4); // skip sequence number
+      }
+    }
+
+    if (messageType == T_EXCEPTION) {
+      zval* ex;
+      MAKE_STD_ZVAL(ex);
+      createObject("TApplicationException", ex);
+      zval* spec = zend_read_static_property(zend_get_class_entry(ex TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
+      binary_deserialize_spec(ex, transport, Z_ARRVAL_P(spec));
+      throw PHPExceptionWrapper(ex);
+    }
+
+    createObject(obj_typename, return_value);
+    zval* spec = zend_read_static_property(zend_get_class_entry(return_value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
+    binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec));
+  } catch (const PHPExceptionWrapper& ex) {
+    zend_throw_exception_object(ex TSRMLS_CC);
+    RETURN_NULL();
+  }
+}
+
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h
new file mode 100644
index 0000000..c9a3e00
--- /dev/null
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#pragma once
+
+PHP_FUNCTION(thrift_protocol_write_binary);
+PHP_FUNCTION(thrift_protocol_read_binary);
+
+extern zend_module_entry thrift_protocole_module_entry;
+
diff --git a/lib/php/src/protocol/TBinaryProtocol.php b/lib/php/src/protocol/TBinaryProtocol.php
new file mode 100644
index 0000000..31bbbf9
--- /dev/null
+++ b/lib/php/src/protocol/TBinaryProtocol.php
@@ -0,0 +1,431 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.protocol
+ */
+
+include_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
+
+/**
+ * Binary implementation of the Thrift protocol.
+ *
+ */
+class TBinaryProtocol extends TProtocol {
+
+  const VERSION_MASK = 0xffff0000;
+  const VERSION_1 = 0x80010000;
+
+  protected $strictRead_ = false;
+  protected $strictWrite_ = true;
+
+  public function __construct($trans, $strictRead=false, $strictWrite=true) {
+    parent::__construct($trans);
+    $this->strictRead_ = $strictRead;
+    $this->strictWrite_ = $strictWrite;
+  }
+
+  public function writeMessageBegin($name, $type, $seqid) {
+    if ($this->strictWrite_) {
+      $version = self::VERSION_1 | $type;
+      return
+        $this->writeI32($version) +
+        $this->writeString($name) +
+        $this->writeI32($seqid);
+    } else {
+      return
+        $this->writeString($name) +
+        $this->writeByte($type) +
+        $this->writeI32($seqid);
+    }
+  }
+
+  public function writeMessageEnd() {
+    return 0;
+  }
+
+  public function writeStructBegin($name) {
+    return 0;
+  }
+
+  public function writeStructEnd() {
+    return 0;
+  }
+
+  public function writeFieldBegin($fieldName, $fieldType, $fieldId) {
+    return
+      $this->writeByte($fieldType) +
+      $this->writeI16($fieldId);
+  }
+
+  public function writeFieldEnd() {
+    return 0;
+  }
+
+  public function writeFieldStop() {
+    return
+      $this->writeByte(TType::STOP);
+  }
+
+  public function writeMapBegin($keyType, $valType, $size) {
+    return
+      $this->writeByte($keyType) +
+      $this->writeByte($valType) +
+      $this->writeI32($size);
+  }
+
+  public function writeMapEnd() {
+    return 0;
+  }
+
+  public function writeListBegin($elemType, $size) {
+    return
+      $this->writeByte($elemType) +
+      $this->writeI32($size);
+  }
+
+  public function writeListEnd() {
+    return 0;
+  }
+
+  public function writeSetBegin($elemType, $size) {
+    return
+      $this->writeByte($elemType) +
+      $this->writeI32($size);
+  }
+
+  public function writeSetEnd() {
+    return 0;
+  }
+
+  public function writeBool($value) {
+    $data = pack('c', $value ? 1 : 0);
+    $this->trans_->write($data, 1);
+    return 1;
+  }
+
+  public function writeByte($value) {
+    $data = pack('c', $value);
+    $this->trans_->write($data, 1);
+    return 1;
+  }
+
+  public function writeI16($value) {
+    $data = pack('n', $value);
+    $this->trans_->write($data, 2);
+    return 2;
+  }
+
+  public function writeI32($value) {
+    $data = pack('N', $value);
+    $this->trans_->write($data, 4);
+    return 4;
+  }
+
+  public function writeI64($value) {
+    // If we are on a 32bit architecture we have to explicitly deal with
+    // 64-bit twos-complement arithmetic since PHP wants to treat all ints
+    // as signed and any int over 2^31 - 1 as a float
+    if (PHP_INT_SIZE == 4) {
+      $neg = $value < 0;
+
+      if ($neg) {
+        $value *= -1;
+      }
+
+      $hi = (int)($value / 4294967296);
+      $lo = (int)$value;
+
+      if ($neg) {
+        $hi = ~$hi;
+        $lo = ~$lo;
+        if (($lo & (int)0xffffffff) == (int)0xffffffff) {
+          $lo = 0;
+          $hi++;
+        } else {
+          $lo++;
+        }
+      }
+      $data = pack('N2', $hi, $lo);
+
+    } else {
+      $hi = $value >> 32;
+      $lo = $value & 0xFFFFFFFF;
+      $data = pack('N2', $hi, $lo);
+    }
+
+    $this->trans_->write($data, 8);
+    return 8;
+  }
+
+  public function writeDouble($value) {
+    $data = pack('d', $value);
+    $this->trans_->write(strrev($data), 8);
+    return 8;
+  }
+
+  public function writeString($value) {
+    $len = strlen($value);
+    $result = $this->writeI32($len);
+    if ($len) {
+      $this->trans_->write($value, $len);
+    }
+    return $result + $len;
+  }
+
+  public function readMessageBegin(&$name, &$type, &$seqid) {
+    $result = $this->readI32($sz);
+    if ($sz < 0) {
+      $version = (int) ($sz & self::VERSION_MASK);
+      if ($version != (int) self::VERSION_1) {
+        throw new TProtocolException('Bad version identifier: '.$sz, TProtocolException::BAD_VERSION);
+      }
+      $type = $sz & 0x000000ff;
+      $result +=
+        $this->readString($name) +
+        $this->readI32($seqid);
+    } else {
+      if ($this->strictRead_) {
+        throw new TProtocolException('No version identifier, old protocol client?', TProtocolException::BAD_VERSION);
+      } else {
+        // Handle pre-versioned input
+        $name = $this->trans_->readAll($sz);
+        $result +=
+          $sz +
+          $this->readByte($type) +
+          $this->readI32($seqid);
+      }
+    }
+    return $result;
+  }
+
+  public function readMessageEnd() {
+    return 0;
+  }
+
+  public function readStructBegin(&$name) {
+    $name = '';
+    return 0;
+  }
+
+  public function readStructEnd() {
+    return 0;
+  }
+
+  public function readFieldBegin(&$name, &$fieldType, &$fieldId) {
+    $result = $this->readByte($fieldType);
+    if ($fieldType == TType::STOP) {
+      $fieldId = 0;
+      return $result;
+    }
+    $result += $this->readI16($fieldId);
+    return $result;
+  }
+
+  public function readFieldEnd() {
+    return 0;
+  }
+
+  public function readMapBegin(&$keyType, &$valType, &$size) {
+    return
+      $this->readByte($keyType) +
+      $this->readByte($valType) +
+      $this->readI32($size);
+  }
+
+  public function readMapEnd() {
+    return 0;
+  }
+
+  public function readListBegin(&$elemType, &$size) {
+    return
+      $this->readByte($elemType) +
+      $this->readI32($size);
+  }
+
+  public function readListEnd() {
+    return 0;
+  }
+
+  public function readSetBegin(&$elemType, &$size) {
+    return
+      $this->readByte($elemType) +
+      $this->readI32($size);
+  }
+
+  public function readSetEnd() {
+    return 0;
+  }
+
+  public function readBool(&$value) {
+    $data = $this->trans_->readAll(1);
+    $arr = unpack('c', $data);
+    $value = $arr[1] == 1;
+    return 1;
+  }
+
+  public function readByte(&$value) {
+    $data = $this->trans_->readAll(1);
+    $arr = unpack('c', $data);
+    $value = $arr[1];
+    return 1;
+  }
+
+  public function readI16(&$value) {
+    $data = $this->trans_->readAll(2);
+    $arr = unpack('n', $data);
+    $value = $arr[1];
+    if ($value > 0x7fff) {
+      $value = 0 - (($value - 1) ^ 0xffff);
+    }
+    return 2;
+  }
+
+  public function readI32(&$value) {
+    $data = $this->trans_->readAll(4);
+    $arr = unpack('N', $data);
+    $value = $arr[1];
+    if ($value > 0x7fffffff) {
+      $value = 0 - (($value - 1) ^ 0xffffffff);
+    }
+    return 4;
+  }
+
+  public function readI64(&$value) {
+    $data = $this->trans_->readAll(8);
+
+    $arr = unpack('N2', $data);
+
+    // If we are on a 32bit architecture we have to explicitly deal with
+    // 64-bit twos-complement arithmetic since PHP wants to treat all ints
+    // as signed and any int over 2^31 - 1 as a float
+    if (PHP_INT_SIZE == 4) {
+
+      $hi = $arr[1];
+      $lo = $arr[2];
+      $isNeg = $hi  < 0;
+
+      // Check for a negative
+      if ($isNeg) {
+        $hi = ~$hi & (int)0xffffffff;
+        $lo = ~$lo & (int)0xffffffff;
+
+        if ($lo == (int)0xffffffff) {
+          $hi++;
+          $lo = 0;
+        } else {
+          $lo++;
+        }
+      }
+
+      // Force 32bit words in excess of 2G to pe positive - we deal wigh sign
+      // explicitly below
+
+      if ($hi & (int)0x80000000) {
+        $hi &= (int)0x7fffffff;
+        $hi += 0x80000000;
+      }
+
+      if ($lo & (int)0x80000000) {
+        $lo &= (int)0x7fffffff;
+        $lo += 0x80000000;
+      }
+
+      $value = $hi * 4294967296 + $lo;
+
+      if ($isNeg) {
+        $value = 0 - $value;
+      }
+    } else {
+
+      // Upcast negatives in LSB bit
+      if ($arr[2] & 0x80000000) {
+        $arr[2] = $arr[2] & 0xffffffff;
+      }
+
+      // Check for a negative
+      if ($arr[1] & 0x80000000) {
+        $arr[1] = $arr[1] & 0xffffffff;
+        $arr[1] = $arr[1] ^ 0xffffffff;
+        $arr[2] = $arr[2] ^ 0xffffffff;
+        $value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
+      } else {
+        $value = $arr[1]*4294967296 + $arr[2];
+      }
+    }
+
+    return 8;
+  }
+
+  public function readDouble(&$value) {
+    $data = strrev($this->trans_->readAll(8));
+    $arr = unpack('d', $data);
+    $value = $arr[1];
+    return 8;
+  }
+
+  public function readString(&$value) {
+    $result = $this->readI32($len);
+    if ($len) {
+      $value = $this->trans_->readAll($len);
+    } else {
+      $value = '';
+    }
+    return $result + $len;
+  }
+}
+
+/**
+ * Binary Protocol Factory
+ */
+class TBinaryProtocolFactory implements TProtocolFactory {
+  private $strictRead_ = false;
+  private $strictWrite_ = false;
+
+  public function __construct($strictRead=false, $strictWrite=false) {
+    $this->strictRead_ = $strictRead;
+    $this->strictWrite_ = $strictWrite;
+  }
+
+  public function getProtocol($trans) {
+    return new TBinaryProtocol($trans, $this->strictRead, $this->strictWrite);
+  }
+}
+
+/**
+ * Accelerated binary protocol: used in conjunction with the thrift_protocol
+ * extension for faster deserialization
+ */
+class TBinaryProtocolAccelerated extends TBinaryProtocol {
+  public function __construct($trans, $strictRead=false, $strictWrite=true) {
+    // If the transport doesn't implement putBack, wrap it in a
+    // TBufferedTransport (which does)
+    if (!method_exists($trans, 'putBack')) {
+      $trans = new TBufferedTransport($trans);
+    }
+    parent::__construct($trans, $strictRead, $strictWrite);
+  }
+  public function isStrictRead() {
+    return $this->strictRead_;
+  }
+  public function isStrictWrite() {
+    return $this->strictWrite_;
+  }
+}
+
+?>
diff --git a/lib/php/src/protocol/TProtocol.php b/lib/php/src/protocol/TProtocol.php
new file mode 100644
index 0000000..e9ff41a
--- /dev/null
+++ b/lib/php/src/protocol/TProtocol.php
@@ -0,0 +1,377 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.protocol
+ */
+
+
+/**
+ * Protocol module. Contains all the types and definitions needed to implement
+ * a protocol encoder/decoder.
+ *
+ * @package thrift.protocol
+ */
+
+/**
+ * Protocol exceptions
+ */
+class TProtocolException extends TException {
+  const UNKNOWN = 0;
+  const INVALID_DATA = 1;
+  const NEGATIVE_SIZE = 2;
+  const SIZE_LIMIT = 3;
+  const BAD_VERSION = 4;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+}
+
+/**
+ * Protocol base class module.
+ */
+abstract class TProtocol {
+  // The below may seem silly, but it is to get around the problem that the
+  // "instanceof" operator can only take in a T_VARIABLE and not a T_STRING
+  // or T_CONSTANT_ENCAPSED_STRING. Using "is_a()" instead of "instanceof" is
+  // a workaround but is deprecated in PHP5. This is used in the generated
+  // deserialization code.
+  static $TBINARYPROTOCOLACCELERATED = 'TBinaryProtocolAccelerated';
+
+  /**
+   * Underlying transport
+   *
+   * @var TTransport
+   */
+  protected $trans_;
+
+  /**
+   * Constructor
+   */
+  protected function __construct($trans) {
+    $this->trans_ = $trans;
+  }
+
+  /**
+   * Accessor for transport
+   *
+   * @return TTransport
+   */
+  public function getTransport() {
+    return $this->trans_;
+  }
+
+  /**
+   * Writes the message header
+   *
+   * @param string $name Function name
+   * @param int $type message type TMessageType::CALL or TMessageType::REPLY
+   * @param int $seqid The sequence id of this message
+   */
+  public abstract function writeMessageBegin($name, $type, $seqid);
+
+  /**
+   * Close the message
+   */
+  public abstract function writeMessageEnd();
+
+  /**
+   * Writes a struct header.
+   *
+   * @param string     $name Struct name
+   * @throws TException on write error
+   * @return int How many bytes written
+   */
+  public abstract function writeStructBegin($name);
+
+  /**
+   * Close a struct.
+   *
+   * @throws TException on write error
+   * @return int How many bytes written
+   */
+  public abstract function writeStructEnd();
+
+  /*
+   * Starts a field.
+   *
+   * @param string     $name Field name
+   * @param int        $type Field type
+   * @param int        $fid  Field id
+   * @throws TException on write error
+   * @return int How many bytes written
+   */
+  public abstract function writeFieldBegin($fieldName, $fieldType, $fieldId);
+
+  public abstract function writeFieldEnd();
+
+  public abstract function writeFieldStop();
+
+  public abstract function writeMapBegin($keyType, $valType, $size);
+
+  public abstract function writeMapEnd();
+
+  public abstract function writeListBegin($elemType, $size);
+
+  public abstract function writeListEnd();
+
+  public abstract function writeSetBegin($elemType, $size);
+
+  public abstract function writeSetEnd();
+
+  public abstract function writeBool($bool);
+
+  public abstract function writeByte($byte);
+
+  public abstract function writeI16($i16);
+
+  public abstract function writeI32($i32);
+
+  public abstract function writeI64($i64);
+
+  public abstract function writeDouble($dub);
+
+  public abstract function writeString($str);
+
+  /**
+   * Reads the message header
+   *
+   * @param string $name Function name
+   * @param int $type message type TMessageType::CALL or TMessageType::REPLY
+   * @parem int $seqid The sequence id of this message
+   */
+  public abstract function readMessageBegin(&$name, &$type, &$seqid);
+
+  /**
+   * Read the close of message
+   */
+  public abstract function readMessageEnd();
+
+  public abstract function readStructBegin(&$name);
+
+  public abstract function readStructEnd();
+
+  public abstract function readFieldBegin(&$name, &$fieldType, &$fieldId);
+
+  public abstract function readFieldEnd();
+
+  public abstract function readMapBegin(&$keyType, &$valType, &$size);
+
+  public abstract function readMapEnd();
+
+  public abstract function readListBegin(&$elemType, &$size);
+
+  public abstract function readListEnd();
+
+  public abstract function readSetBegin(&$elemType, &$size);
+
+  public abstract function readSetEnd();
+
+  public abstract function readBool(&$bool);
+
+  public abstract function readByte(&$byte);
+
+  public abstract function readI16(&$i16);
+
+  public abstract function readI32(&$i32);
+
+  public abstract function readI64(&$i64);
+
+  public abstract function readDouble(&$dub);
+
+  public abstract function readString(&$str);
+
+  /**
+   * The skip function is a utility to parse over unrecognized date without
+   * causing corruption.
+   *
+   * @param TType $type What type is it
+   */
+  public function skip($type) {
+    switch ($type) {
+    case TType::BOOL:
+      return $this->readBool($bool);
+    case TType::BYTE:
+      return $this->readByte($byte);
+    case TType::I16:
+      return $this->readI16($i16);
+    case TType::I32:
+      return $this->readI32($i32);
+    case TType::I64:
+      return $this->readI64($i64);
+    case TType::DOUBLE:
+      return $this->readDouble($dub);
+    case TType::STRING:
+      return $this->readString($str);
+    case TType::STRUCT:
+      {
+        $result = $this->readStructBegin($name);
+        while (true) {
+          $result += $this->readFieldBegin($name, $ftype, $fid);
+          if ($ftype == TType::STOP) {
+            break;
+          }
+          $result += $this->skip($ftype);
+          $result += $this->readFieldEnd();
+        }
+        $result += $this->readStructEnd();
+        return $result;
+      }
+    case TType::MAP:
+      {
+        $result = $this->readMapBegin($keyType, $valType, $size);
+        for ($i = 0; $i < $size; $i++) {
+          $result += $this->skip($keyType);
+          $result += $this->skip($valType);
+        }
+        $result += $this->readMapEnd();
+        return $result;
+      }
+    case TType::SET:
+      {
+        $result = $this->readSetBegin($elemType, $size);
+        for ($i = 0; $i < $size; $i++) {
+          $result += $this->skip($elemType);
+        }
+        $result += $this->readSetEnd();
+        return $result;
+      }
+    case TType::LST:
+      {
+        $result = $this->readListBegin($elemType, $size);
+        for ($i = 0; $i < $size; $i++) {
+          $result += $this->skip($elemType);
+        }
+        $result += $this->readListEnd();
+        return $result;
+      }
+    default:
+      return 0;
+    }
+  }
+
+  /**
+   * Utility for skipping binary data
+   *
+   * @param TTransport $itrans TTransport object
+   * @param int        $type   Field type
+   */
+  public static function skipBinary($itrans, $type) {
+    switch ($type) {
+    case TType::BOOL:
+      return $itrans->readAll(1);
+    case TType::BYTE:
+      return $itrans->readAll(1);
+    case TType::I16:
+      return $itrans->readAll(2);
+    case TType::I32:
+      return $itrans->readAll(4);
+    case TType::I64:
+      return $itrans->readAll(8);
+    case TType::DOUBLE:
+      return $itrans->readAll(8);
+    case TType::STRING:
+      $len = unpack('N', $itrans->readAll(4));
+      $len = $len[1];
+      if ($len > 0x7fffffff) {
+        $len = 0 - (($len - 1) ^ 0xffffffff);
+      }
+      return 4 + $itrans->readAll($len);
+    case TType::STRUCT:
+      {
+        $result = 0;
+        while (true) {
+          $ftype = 0;
+          $fid = 0;
+          $data = $itrans->readAll(1);
+          $arr = unpack('c', $data);
+          $ftype = $arr[1];
+          if ($ftype == TType::STOP) {
+            break;
+          }
+          // I16 field id
+          $result += $itrans->readAll(2);
+          $result += self::skipBinary($itrans, $ftype);
+        }
+        return $result;
+      }
+    case TType::MAP:
+      {
+        // Ktype
+        $data = $itrans->readAll(1);
+        $arr = unpack('c', $data);
+        $ktype = $arr[1];
+        // Vtype
+        $data = $itrans->readAll(1);
+        $arr = unpack('c', $data);
+        $vtype = $arr[1];
+        // Size
+        $data = $itrans->readAll(4);
+        $arr = unpack('N', $data);
+        $size = $arr[1];
+        if ($size > 0x7fffffff) {
+          $size = 0 - (($size - 1) ^ 0xffffffff);
+        }
+        $result = 6;
+        for ($i = 0; $i < $size; $i++) {
+          $result += self::skipBinary($itrans, $ktype);
+          $result += self::skipBinary($itrans, $vtype);
+        }
+        return $result;
+      }
+    case TType::SET:
+    case TType::LST:
+      {
+        // Vtype
+        $data = $itrans->readAll(1);
+        $arr = unpack('c', $data);
+        $vtype = $arr[1];
+        // Size
+        $data = $itrans->readAll(4);
+        $arr = unpack('N', $data);
+        $size = $arr[1];
+        if ($size > 0x7fffffff) {
+          $size = 0 - (($size - 1) ^ 0xffffffff);
+        }
+        $result = 5;
+        for ($i = 0; $i < $size; $i++) {
+          $result += self::skipBinary($itrans, $vtype);
+        }
+        return $result;
+      }
+    default:
+      return 0;
+    }
+  }
+}
+
+/**
+ * Protocol factory creates protocol objects from transports
+ */
+interface TProtocolFactory {
+  /**
+   * Build a protocol from the base transport
+   *
+   * @return TProtcol protocol
+   */
+  public function getProtocol($trans);
+}
+
+
+?>
diff --git a/lib/php/src/transport/TBufferedTransport.php b/lib/php/src/transport/TBufferedTransport.php
new file mode 100644
index 0000000..cfae767
--- /dev/null
+++ b/lib/php/src/transport/TBufferedTransport.php
@@ -0,0 +1,163 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * Buffered transport. Stores data to an internal buffer that it doesn't
+ * actually write out until flush is called. For reading, we do a greedy
+ * read and then serve data out of the internal buffer.
+ *
+ * @package thrift.transport
+ */
+class TBufferedTransport extends TTransport {
+
+  /**
+   * Constructor. Creates a buffered transport around an underlying transport
+   */
+  public function __construct($transport=null, $rBufSize=512, $wBufSize=512) {
+    $this->transport_ = $transport;
+    $this->rBufSize_ = $rBufSize;
+    $this->wBufSize_ = $wBufSize;
+  }
+
+  /**
+   * The underlying transport
+   *
+   * @var TTransport
+   */
+  protected $transport_ = null;
+
+  /**
+   * The receive buffer size
+   *
+   * @var int
+   */
+  protected $rBufSize_ = 512;
+
+  /**
+   * The write buffer size
+   *
+   * @var int
+   */
+  protected $wBufSize_ = 512;
+
+  /**
+   * The write buffer.
+   *
+   * @var string
+   */
+  protected $wBuf_ = '';
+
+  /**
+   * The read buffer.
+   *
+   * @var string
+   */
+  protected $rBuf_ = '';
+
+  public function isOpen() {
+    return $this->transport_->isOpen();
+  }
+
+  public function open() {
+    $this->transport_->open();
+  }
+
+  public function close() {
+    $this->transport_->close();
+  }
+
+  public function putBack($data) {
+    if (strlen($this->rBuf_) === 0) {
+      $this->rBuf_ = $data;
+    } else {
+      $this->rBuf_ = ($data . $this->rBuf_);
+    }
+  }
+
+  /**
+   * The reason that we customize readAll here is that the majority of PHP
+   * streams are already internally buffered by PHP. The socket stream, for
+   * example, buffers internally and blocks if you call read with $len greater
+   * than the amount of data available, unlike recv() in C.
+   *
+   * Therefore, use the readAll method of the wrapped transport inside
+   * the buffered readAll.
+   */
+  public function readAll($len) {
+    $have = strlen($this->rBuf_);
+    if ($have == 0) {
+      $data = $this->transport_->readAll($len);
+    } else if ($have < $len) {
+      $data = $this->rBuf_;
+      $this->rBuf_ = '';
+      $data .= $this->transport_->readAll($len - $have);
+    } else if ($have == $len) {
+      $data = $this->rBuf_;
+      $this->rBuf_ = '';
+    } else if ($have > $len) {
+      $data = substr($this->rBuf_, 0, $len);
+      $this->rBuf_ = substr($this->rBuf_, $len);
+    }
+    return $data;
+  }
+
+  public function read($len) {
+    if (strlen($this->rBuf_) === 0) {
+      $this->rBuf_ = $this->transport_->read($this->rBufSize_);
+    }
+
+    if (strlen($this->rBuf_) <= $len) {
+      $ret = $this->rBuf_;
+      $this->rBuf_ = '';
+      return $ret;
+    }
+
+    $ret = substr($this->rBuf_, 0, $len);
+    $this->rBuf_ = substr($this->rBuf_, $len);
+    return $ret;
+  }
+
+  public function write($buf) {
+    $this->wBuf_ .= $buf;
+    if (strlen($this->wBuf_) >= $this->wBufSize_) {
+      $out = $this->wBuf_;
+
+      // Note that we clear the internal wBuf_ prior to the underlying write
+      // to ensure we're in a sane state (i.e. internal buffer cleaned)
+      // if the underlying write throws up an exception
+      $this->wBuf_ = '';
+      $this->transport_->write($out);
+    }
+  }
+
+  public function flush() {
+    if (strlen($this->wBuf_) > 0) {
+      $this->transport_->write($this->wBuf_);
+      $this->wBuf_ = '';
+    }
+    $this->transport_->flush();
+  }
+
+}
+
+?>
diff --git a/lib/php/src/transport/TFramedTransport.php b/lib/php/src/transport/TFramedTransport.php
new file mode 100644
index 0000000..dc57392
--- /dev/null
+++ b/lib/php/src/transport/TFramedTransport.php
@@ -0,0 +1,179 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * Framed transport. Writes and reads data in chunks that are stamped with
+ * their length.
+ *
+ * @package thrift.transport
+ */
+class TFramedTransport extends TTransport {
+
+  /**
+   * Underlying transport object.
+   *
+   * @var TTransport
+   */
+  private $transport_;
+
+  /**
+   * Buffer for read data.
+   *
+   * @var string
+   */
+  private $rBuf_;
+
+  /**
+   * Buffer for queued output data
+   *
+   * @var string
+   */
+  private $wBuf_;
+
+  /**
+   * Whether to frame reads
+   *
+   * @var bool
+   */
+  private $read_;
+
+  /**
+   * Whether to frame writes
+   *
+   * @var bool
+   */
+  private $write_;
+
+  /**
+   * Constructor.
+   *
+   * @param TTransport $transport Underlying transport
+   */
+  public function __construct($transport=null, $read=true, $write=true) {
+    $this->transport_ = $transport;
+    $this->read_ = $read;
+    $this->write_ = $write;
+  }
+
+  public function isOpen() {
+    return $this->transport_->isOpen();
+  }
+
+  public function open() {
+    $this->transport_->open();
+  }
+
+  public function close() {
+    $this->transport_->close();
+  }
+
+  /**
+   * Reads from the buffer. When more data is required reads another entire
+   * chunk and serves future reads out of that.
+   *
+   * @param int $len How much data
+   */
+  public function read($len) {
+    if (!$this->read_) {
+      return $this->transport_->read($len);
+    }
+
+    if (strlen($this->rBuf_) === 0) {
+      $this->readFrame();
+    }
+
+    // Just return full buff
+    if ($len >= strlen($this->rBuf_)) {
+      $out = $this->rBuf_;
+      $this->rBuf_ = null;
+      return $out;
+    }
+
+    // Return substr
+    $out = substr($this->rBuf_, 0, $len);
+    $this->rBuf_ = substr($this->rBuf_, $len);
+    return $out;
+  }
+
+  /**
+   * Put previously read data back into the buffer
+   *
+   * @param string $data data to return
+   */
+  public function putBack($data) {
+    if (strlen($this->rBuf_) === 0) {
+      $this->rBuf_ = $data;
+    } else {
+      $this->rBuf_ = ($data . $this->rBuf_);
+    }
+  }
+
+  /**
+   * Reads a chunk of data into the internal read buffer.
+   */
+  private function readFrame() {
+    $buf = $this->transport_->readAll(4);
+    $val = unpack('N', $buf);
+    $sz = $val[1];
+
+    $this->rBuf_ = $this->transport_->readAll($sz);
+  }
+
+  /**
+   * Writes some data to the pending output buffer.
+   *
+   * @param string $buf The data
+   * @param int    $len Limit of bytes to write
+   */
+  public function write($buf, $len=null) {
+    if (!$this->write_) {
+      return $this->transport_->write($buf, $len);
+    }
+
+    if ($len !== null && $len < strlen($buf)) {
+      $buf = substr($buf, 0, $len);
+    }
+    $this->wBuf_ .= $buf;
+  }
+
+  /**
+   * Writes the output buffer to the stream in the format of a 4-byte length
+   * followed by the actual data.
+   */
+  public function flush() {
+    if (!$this->write_) {
+      return $this->transport_->flush();
+    }
+
+    $out = pack('N', strlen($this->wBuf_));
+    $out .= $this->wBuf_;
+
+    // Note that we clear the internal wBuf_ prior to the underlying write
+    // to ensure we're in a sane state (i.e. internal buffer cleaned)
+    // if the underlying write throws up an exception
+    $this->wBuf_ = '';
+    $this->transport_->write($out);
+    $this->transport_->flush();
+  }
+
+}
diff --git a/lib/php/src/transport/THttpClient.php b/lib/php/src/transport/THttpClient.php
new file mode 100644
index 0000000..224d403
--- /dev/null
+++ b/lib/php/src/transport/THttpClient.php
@@ -0,0 +1,202 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * HTTP client for Thrift
+ *
+ * @package thrift.transport
+ */
+class THttpClient extends TTransport {
+
+  /**
+   * The host to connect to
+   *
+   * @var string
+   */
+  protected $host_;
+
+  /**
+   * The port to connect on
+   *
+   * @var int
+   */
+  protected $port_;
+
+  /**
+   * The URI to request
+   *
+   * @var string
+   */
+  protected $uri_;
+
+  /**
+   * The scheme to use for the request, i.e. http, https
+   *
+   * @var string
+   */
+  protected $scheme_;
+
+  /**
+   * Buffer for the HTTP request data
+   *
+   * @var string
+   */
+  protected $buf_;
+
+  /**
+   * Input socket stream.
+   *
+   * @var resource
+   */
+  protected $handle_;
+
+  /**
+   * Read timeout
+   *
+   * @var float
+   */
+  protected $timeout_;
+
+  /**
+   * Make a new HTTP client.
+   *
+   * @param string $host
+   * @param int    $port
+   * @param string $uri
+   */
+  public function __construct($host, $port=80, $uri='', $scheme = 'http') {
+    if ((strlen($uri) > 0) && ($uri{0} != '/')) {
+      $uri = '/'.$uri;
+    }
+    $this->scheme_ = $scheme;
+    $this->host_ = $host;
+    $this->port_ = $port;
+    $this->uri_ = $uri;
+    $this->buf_ = '';
+    $this->handle_ = null;
+    $this->timeout_ = null;
+  }
+
+  /**
+   * Set read timeout
+   *
+   * @param float $timeout
+   */
+  public function setTimeoutSecs($timeout) {
+    $this->timeout_ = $timeout;
+  }
+
+  /**
+   * Whether this transport is open.
+   *
+   * @return boolean true if open
+   */
+  public function isOpen() {
+    return true;
+  }
+
+  /**
+   * Open the transport for reading/writing
+   *
+   * @throws TTransportException if cannot open
+   */
+  public function open() {}
+
+  /**
+   * Close the transport.
+   */
+  public function close() {
+    if ($this->handle_) {
+      @fclose($this->handle_);
+      $this->handle_ = null;
+    }
+  }
+
+  /**
+   * Read some data into the array.
+   *
+   * @param int    $len How much to read
+   * @return string The data that has been read
+   * @throws TTransportException if cannot read any more data
+   */
+  public function read($len) {
+    $data = @fread($this->handle_, $len);
+    if ($data === FALSE || $data === '') {
+      $md = stream_get_meta_data($this->handle_);
+      if ($md['timed_out']) {
+        throw new TTransportException('THttpClient: timed out reading '.$len.' bytes from '.$this->host_.':'.$this->port_.'/'.$this->uri_, TTransportException::TIMED_OUT);
+      } else {
+        throw new TTransportException('THttpClient: Could not read '.$len.' bytes from '.$this->host_.':'.$this->port_.'/'.$this->uri_, TTransportException::UNKNOWN);
+      }
+    }
+    return $data;
+  }
+
+  /**
+   * Writes some data into the pending buffer
+   *
+   * @param string $buf  The data to write
+   * @throws TTransportException if writing fails
+   */
+  public function write($buf) {
+    $this->buf_ .= $buf;
+  }
+
+  /**
+   * Opens and sends the actual request over the HTTP connection
+   *
+   * @throws TTransportException if a writing error occurs
+   */
+  public function flush() {
+    // God, PHP really has some esoteric ways of doing simple things.
+    $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
+
+    $headers = array('Host: '.$host,
+                     'Accept: application/x-thrift',
+                     'User-Agent: PHP/THttpClient',
+                     'Content-Type: application/x-thrift',
+                     'Content-Length: '.strlen($this->buf_));
+
+    $options = array('method' => 'POST',
+                     'header' => implode("\r\n", $headers),
+                     'max_redirects' => 1,
+                     'content' => $this->buf_);
+    if ($this->timeout_ > 0) {
+      $options['timeout'] = $this->timeout_;
+    }
+    $this->buf_ = '';
+
+    $contextid = stream_context_create(array('http' => $options));
+    $this->handle_ = @fopen($this->scheme_.'://'.$host.$this->uri_, 'r', false, $contextid);
+
+    // Connect failed?
+    if ($this->handle_ === FALSE) {
+      $this->handle_ = null;
+      $error = 'THttpClient: Could not connect to '.$host.$this->uri_;
+      throw new TTransportException($error, TTransportException::NOT_OPEN);
+    }
+  }
+
+}
+
+?>
diff --git a/lib/php/src/transport/TMemoryBuffer.php b/lib/php/src/transport/TMemoryBuffer.php
new file mode 100644
index 0000000..01eb0f5
--- /dev/null
+++ b/lib/php/src/transport/TMemoryBuffer.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * A memory buffer is a tranpsort that simply reads from and writes to an
+ * in-memory string buffer. Anytime you call write on it, the data is simply
+ * placed into a buffer, and anytime you call read, data is read from that
+ * buffer.
+ *
+ * @package thrift.transport
+ */
+class TMemoryBuffer extends TTransport {
+
+  /**
+   * Constructor. Optionally pass an initial value
+   * for the buffer.
+   */
+  public function __construct($buf = '') {
+    $this->buf_ = $buf;
+  }
+
+  protected $buf_ = '';
+
+  public function isOpen() {
+    return true;
+  }
+
+  public function open() {}
+
+  public function close() {}
+
+  public function write($buf) {
+    $this->buf_ .= $buf;
+  }
+
+  public function read($len) {
+    if (strlen($this->buf_) === 0) {
+      throw new TTransportException('TMemoryBuffer: Could not read ' .
+                                    $len . ' bytes from buffer.',
+                                    TTransportException::UNKNOWN);
+    }
+
+    if (strlen($this->buf_) <= $len) {
+      $ret = $this->buf_;
+      $this->buf_ = '';
+      return $ret;
+    }
+
+    $ret = substr($this->buf_, 0, $len);
+    $this->buf_ = substr($this->buf_, $len);
+
+    return $ret;
+  }
+
+  function getBuffer() {
+    return $this->buf_;
+  }
+
+  public function available() {
+    return strlen($this->buf_);
+  }
+}
+
+?>
diff --git a/lib/php/src/transport/TNullTransport.php b/lib/php/src/transport/TNullTransport.php
new file mode 100644
index 0000000..bada5df
--- /dev/null
+++ b/lib/php/src/transport/TNullTransport.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * Transport that only accepts writes and ignores them.
+ * This is useful for measuring the serialized size of structures.
+ *
+ * @package thrift.transport
+ */
+class TNullTransport extends TTransport {
+
+  public function isOpen() {
+    return true;
+  }
+
+  public function open() {}
+
+  public function close() {}
+
+  public function read($len) {
+    throw new TTransportException("Can't read from TNullTransport.");
+  }
+
+  public function write($buf) {}
+
+}
+
+?>
diff --git a/lib/php/src/transport/TPhpStream.php b/lib/php/src/transport/TPhpStream.php
new file mode 100644
index 0000000..3a1c80b
--- /dev/null
+++ b/lib/php/src/transport/TPhpStream.php
@@ -0,0 +1,111 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * Php stream transport. Reads to and writes from the php standard streams
+ * php://input and php://output
+ *
+ * @package thrift.transport
+ */
+class TPhpStream extends TTransport {
+
+  const MODE_R = 1;
+  const MODE_W = 2;
+
+  private $inStream_ = null;
+
+  private $outStream_ = null;
+
+  private $read_ = false;
+
+  private $write_ = false;
+
+  public function __construct($mode) {
+    $this->read_ = $mode & self::MODE_R;
+    $this->write_ = $mode & self::MODE_W;
+  }
+
+  public function open() {
+    if ($this->read_) {
+      $this->inStream_ = @fopen(self::inStreamName(), 'r');
+      if (!is_resource($this->inStream_)) {
+        throw new TException('TPhpStream: Could not open php://input');
+      }
+    }
+    if ($this->write_) {
+      $this->outStream_ = @fopen('php://output', 'w');
+      if (!is_resource($this->outStream_)) {
+        throw new TException('TPhpStream: Could not open php://output');
+      }
+    }
+  }
+
+  public function close() {
+    if ($this->read_) {
+      @fclose($this->inStream_);
+      $this->inStream_ = null;
+    }
+    if ($this->write_) {
+      @fclose($this->outStream_);
+      $this->outStream_ = null;
+    }
+  }
+
+  public function isOpen() {
+    return
+      (!$this->read_ || is_resource($this->inStream_)) &&
+      (!$this->write_ || is_resource($this->outStream_));
+  }
+
+  public function read($len) {
+    $data = @fread($this->inStream_, $len);
+    if ($data === FALSE || $data === '') {
+      throw new TException('TPhpStream: Could not read '.$len.' bytes');
+    }
+    return $data;
+  }
+
+  public function write($buf) {
+    while (strlen($buf) > 0) {
+      $got = @fwrite($this->outStream_, $buf);
+      if ($got === 0 || $got === FALSE) {
+        throw new TException('TPhpStream: Could not write '.strlen($buf).' bytes');
+      }
+      $buf = substr($buf, $got);
+    }
+  }
+
+  public function flush() {
+    @fflush($this->outStream_);
+  }
+
+  private static function inStreamName() {
+    if (php_sapi_name() == 'cli') {
+      return 'php://stdin';
+    }
+    return 'php://input';
+  }
+
+}
+
+?>
diff --git a/lib/php/src/transport/TSocket.php b/lib/php/src/transport/TSocket.php
new file mode 100644
index 0000000..ba3a631
--- /dev/null
+++ b/lib/php/src/transport/TSocket.php
@@ -0,0 +1,312 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * Sockets implementation of the TTransport interface.
+ *
+ * @package thrift.transport
+ */
+class TSocket extends TTransport {
+
+  /**
+   * Handle to PHP socket
+   *
+   * @var resource
+   */
+  private $handle_ = null;
+
+  /**
+   * Remote hostname
+   *
+   * @var string
+   */
+  protected $host_ = 'localhost';
+
+  /**
+   * Remote port
+   *
+   * @var int
+   */
+  protected $port_ = '9090';
+
+  /**
+   * Send timeout in milliseconds
+   *
+   * @var int
+   */
+  private $sendTimeout_ = 100;
+
+  /**
+   * Recv timeout in milliseconds
+   *
+   * @var int
+   */
+  private $recvTimeout_ = 750;
+
+  /**
+   * Is send timeout set?
+   *
+   * @var bool
+   */
+  private $sendTimeoutSet_ = FALSE;
+
+  /**
+   * Persistent socket or plain?
+   *
+   * @var bool
+   */
+  private $persist_ = FALSE;
+
+  /**
+   * Debugging on?
+   *
+   * @var bool
+   */
+  protected $debug_ = FALSE;
+
+  /**
+   * Debug handler
+   *
+   * @var mixed
+   */
+  protected $debugHandler_ = null;
+
+  /**
+   * Socket constructor
+   *
+   * @param string $host         Remote hostname
+   * @param int    $port         Remote port
+   * @param bool   $persist      Whether to use a persistent socket
+   * @param string $debugHandler Function to call for error logging
+   */
+  public function __construct($host='localhost',
+                              $port=9090,
+                              $persist=FALSE,
+                              $debugHandler=null) {
+    $this->host_ = $host;
+    $this->port_ = $port;
+    $this->persist_ = $persist;
+    $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log';
+  }
+
+  /**
+   * Sets the send timeout.
+   *
+   * @param int $timeout  Timeout in milliseconds.
+   */
+  public function setSendTimeout($timeout) {
+    $this->sendTimeout_ = $timeout;
+  }
+
+  /**
+   * Sets the receive timeout.
+   *
+   * @param int $timeout  Timeout in milliseconds.
+   */
+  public function setRecvTimeout($timeout) {
+    $this->recvTimeout_ = $timeout;
+  }
+
+  /**
+   * Sets debugging output on or off
+   *
+   * @param bool $debug
+   */
+  public function setDebug($debug) {
+    $this->debug_ = $debug;
+  }
+
+  /**
+   * Get the host that this socket is connected to
+   *
+   * @return string host
+   */
+  public function getHost() {
+    return $this->host_;
+  }
+
+  /**
+   * Get the remote port that this socket is connected to
+   *
+   * @return int port
+   */
+  public function getPort() {
+    return $this->port_;
+  }
+
+  /**
+   * Tests whether this is open
+   *
+   * @return bool true if the socket is open
+   */
+  public function isOpen() {
+    return is_resource($this->handle_);
+  }
+
+  /**
+   * Connects the socket.
+   */
+  public function open() {
+
+    if ($this->persist_) {
+      $this->handle_ = @pfsockopen($this->host_,
+                                   $this->port_,
+                                   $errno,
+                                   $errstr,
+                                   $this->sendTimeout_/1000.0);
+    } else {
+      $this->handle_ = @fsockopen($this->host_,
+                                  $this->port_,
+                                  $errno,
+                                  $errstr,
+                                  $this->sendTimeout_/1000.0);
+    }
+
+    // Connect failed?
+    if ($this->handle_ === FALSE) {
+      $error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
+      if ($this->debug_) {
+        call_user_func($this->debugHandler_, $error);
+      }
+      throw new TException($error);
+    }
+
+    stream_set_timeout($this->handle_, 0, $this->sendTimeout_*1000);
+    $this->sendTimeoutSet_ = TRUE;
+  }
+
+  /**
+   * Closes the socket.
+   */
+  public function close() {
+    if (!$this->persist_) {
+      @fclose($this->handle_);
+      $this->handle_ = null;
+    }
+  }
+
+  /**
+   * Uses stream get contents to do the reading
+   *
+   * @param int $len How many bytes
+   * @return string Binary data
+   */
+  public function readAll($len) {
+    if ($this->sendTimeoutSet_) {
+      stream_set_timeout($this->handle_, 0, $this->recvTimeout_*1000);
+      $this->sendTimeoutSet_ = FALSE;
+    }
+    // This call does not obey stream_set_timeout values!
+    // $buf = @stream_get_contents($this->handle_, $len);
+
+    $pre = null;
+    while (TRUE) {
+      $buf = @fread($this->handle_, $len);
+      if ($buf === FALSE || $buf === '') {
+        $md = stream_get_meta_data($this->handle_);
+        if ($md['timed_out']) {
+          throw new TException('TSocket: timed out reading '.$len.' bytes from '.
+                               $this->host_.':'.$this->port_);
+        } else {
+          throw new TException('TSocket: Could not read '.$len.' bytes from '.
+                               $this->host_.':'.$this->port_);
+        }
+      } else if (($sz = strlen($buf)) < $len) {
+        $md = stream_get_meta_data($this->handle_);
+        if ($md['timed_out']) {
+          throw new TException('TSocket: timed out reading '.$len.' bytes from '.
+                               $this->host_.':'.$this->port_);
+        } else {
+          $pre .= $buf;
+          $len -= $sz;
+        }
+      } else {
+        return $pre.$buf;
+      }
+    }
+  }
+
+  /**
+   * Read from the socket
+   *
+   * @param int $len How many bytes
+   * @return string Binary data
+   */
+  public function read($len) {
+    if ($this->sendTimeoutSet_) {
+      stream_set_timeout($this->handle_, 0, $this->recvTimeout_*1000);
+      $this->sendTimeoutSet_ = FALSE;
+    }
+    $data = @fread($this->handle_, $len);
+    if ($data === FALSE || $data === '') {
+      $md = stream_get_meta_data($this->handle_);
+      if ($md['timed_out']) {
+        throw new TException('TSocket: timed out reading '.$len.' bytes from '.
+                             $this->host_.':'.$this->port_);
+      } else {
+        throw new TException('TSocket: Could not read '.$len.' bytes from '.
+                             $this->host_.':'.$this->port_);
+      }
+    }
+    return $data;
+  }
+
+  /**
+   * Write to the socket.
+   *
+   * @param string $buf The data to write
+   */
+  public function write($buf) {
+    if (!$this->sendTimeoutSet_) {
+      stream_set_timeout($this->handle_, 0, $this->sendTimeout_*1000);
+      $this->sendTimeoutSet_ = TRUE;
+    }
+    while (strlen($buf) > 0) {
+      $got = @fwrite($this->handle_, $buf);
+      if ($got === 0 || $got === FALSE) {
+        $md = stream_get_meta_data($this->handle_);
+        if ($md['timed_out']) {
+          throw new TException('TSocket: timed out writing '.strlen($buf).' bytes from '.
+                               $this->host_.':'.$this->port_);
+        } else {
+            throw new TException('TSocket: Could not write '.strlen($buf).' bytes '.
+                                 $this->host_.':'.$this->port_);
+        }
+      }
+      $buf = substr($buf, $got);
+    }
+  }
+
+  /**
+   * Flush output to the socket.
+   */
+  public function flush() {
+    $ret = fflush($this->handle_);
+    if ($ret === FALSE) {
+      throw new TException('TSocket: Could not flush: '.
+                           $this->host_.':'.$this->port_);
+    }
+  }
+}
+
+?>
diff --git a/lib/php/src/transport/TSocketPool.php b/lib/php/src/transport/TSocketPool.php
new file mode 100644
index 0000000..7f1157c
--- /dev/null
+++ b/lib/php/src/transport/TSocketPool.php
@@ -0,0 +1,296 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/** Inherits from Socket */
+include_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
+
+/**
+ * This library makes use of APC cache to make hosts as down in a web
+ * environment. If you are running from the CLI or on a system without APC
+ * installed, then these null functions will step in and act like cache
+ * misses.
+ */
+if (!function_exists('apc_fetch')) {
+  function apc_fetch($key) { return FALSE; }
+  function apc_store($key, $var, $ttl=0) { return FALSE; }
+}
+
+/**
+ * Sockets implementation of the TTransport interface that allows connection
+ * to a pool of servers.
+ *
+ * @package thrift.transport
+ */
+class TSocketPool extends TSocket {
+
+  /**
+   * Remote servers. Array of associative arrays with 'host' and 'port' keys
+   */
+  private $servers_ = array();
+
+  /**
+   * How many times to retry each host in connect
+   *
+   * @var int
+   */
+  private $numRetries_ = 1;
+
+  /**
+   * Retry interval in seconds, how long to not try a host if it has been
+   * marked as down.
+   *
+   * @var int
+   */
+  private $retryInterval_ = 60;
+
+  /**
+   * Max consecutive failures before marking a host down.
+   *
+   * @var int
+   */
+  private $maxConsecutiveFailures_ = 1;
+
+  /**
+   * Try hosts in order? or Randomized?
+   *
+   * @var bool
+   */
+  private $randomize_ = TRUE;
+
+  /**
+   * Always try last host, even if marked down?
+   *
+   * @var bool
+   */
+  private $alwaysTryLast_ = TRUE;
+
+  /**
+   * Socket pool constructor
+   *
+   * @param array  $hosts        List of remote hostnames
+   * @param mixed  $ports        Array of remote ports, or a single common port
+   * @param bool   $persist      Whether to use a persistent socket
+   * @param mixed  $debugHandler Function for error logging
+   */
+  public function __construct($hosts=array('localhost'),
+                              $ports=array(9090),
+                              $persist=FALSE,
+                              $debugHandler=null) {
+    parent::__construct(null, 0, $persist, $debugHandler);
+
+    if (!is_array($ports)) {
+      $port = $ports;
+      $ports = array();
+      foreach ($hosts as $key => $val) {
+        $ports[$key] = $port;
+      }
+    }
+
+    foreach ($hosts as $key => $host) {
+      $this->servers_ []= array('host' => $host,
+                                'port' => $ports[$key]);
+    }
+  }
+
+  /**
+   * Add a server to the pool
+   *
+   * This function does not prevent you from adding a duplicate server entry.
+   *
+   * @param string $host hostname or IP
+   * @param int $port port
+   */
+  public function addServer($host, $port) {
+    $this->servers_[] = array('host' => $host, 'port' => $port);
+  }
+
+  /**
+   * Sets how many time to keep retrying a host in the connect function.
+   *
+   * @param int $numRetries
+   */
+  public function setNumRetries($numRetries) {
+    $this->numRetries_ = $numRetries;
+  }
+
+  /**
+   * Sets how long to wait until retrying a host if it was marked down
+   *
+   * @param int $numRetries
+   */
+  public function setRetryInterval($retryInterval) {
+    $this->retryInterval_ = $retryInterval;
+  }
+
+  /**
+   * Sets how many time to keep retrying a host before marking it as down.
+   *
+   * @param int $numRetries
+   */
+  public function setMaxConsecutiveFailures($maxConsecutiveFailures) {
+    $this->maxConsecutiveFailures_ = $maxConsecutiveFailures;
+  }
+
+  /**
+   * Turns randomization in connect order on or off.
+   *
+   * @param bool $randomize
+   */
+  public function setRandomize($randomize) {
+    $this->randomize_ = $randomize;
+  }
+
+  /**
+   * Whether to always try the last server.
+   *
+   * @param bool $alwaysTryLast
+   */
+  public function setAlwaysTryLast($alwaysTryLast) {
+    $this->alwaysTryLast_ = $alwaysTryLast;
+  }
+
+
+  /**
+   * Connects the socket by iterating through all the servers in the pool
+   * and trying to find one that works.
+   */
+  public function open() {
+    // Check if we want order randomization
+    if ($this->randomize_) {
+      shuffle($this->servers_);
+    }
+
+    // Count servers to identify the "last" one
+    $numServers = count($this->servers_);
+
+    for ($i = 0; $i < $numServers; ++$i) {
+
+      // This extracts the $host and $port variables
+      extract($this->servers_[$i]);
+
+      // Check APC cache for a record of this server being down
+      $failtimeKey = 'thrift_failtime:'.$host.':'.$port.'~';
+
+      // Cache miss? Assume it's OK
+      $lastFailtime = apc_fetch($failtimeKey);
+      if ($lastFailtime === FALSE) {
+        $lastFailtime = 0;
+      }
+
+      $retryIntervalPassed = FALSE;
+
+      // Cache hit...make sure enough the retry interval has elapsed
+      if ($lastFailtime > 0) {
+        $elapsed = time() - $lastFailtime;
+        if ($elapsed > $this->retryInterval_) {
+          $retryIntervalPassed = TRUE;
+          if ($this->debug_) {
+            call_user_func($this->debugHandler_,
+                           'TSocketPool: retryInterval '.
+                           '('.$this->retryInterval_.') '.
+                           'has passed for host '.$host.':'.$port);
+          }
+        }
+      }
+
+      // Only connect if not in the middle of a fail interval, OR if this
+      // is the LAST server we are trying, just hammer away on it
+      $isLastServer = FALSE;
+      if ($this->alwaysTryLast_) {
+        $isLastServer = ($i == ($numServers - 1));
+      }
+
+      if (($lastFailtime === 0) ||
+          ($isLastServer) ||
+          ($lastFailtime > 0 && $retryIntervalPassed)) {
+
+        // Set underlying TSocket params to this one
+        $this->host_ = $host;
+        $this->port_ = $port;
+
+        // Try up to numRetries_ connections per server
+        for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) {
+          try {
+            // Use the underlying TSocket open function
+            parent::open();
+
+            // Only clear the failure counts if required to do so
+            if ($lastFailtime > 0) {
+              apc_store($failtimeKey, 0);
+            }
+
+            // Successful connection, return now
+            return;
+
+          } catch (TException $tx) {
+            // Connection failed
+          }
+        }
+
+        // Mark failure of this host in the cache
+        $consecfailsKey = 'thrift_consecfails:'.$host.':'.$port.'~';
+
+        // Ignore cache misses
+        $consecfails = apc_fetch($consecfailsKey);
+        if ($consecfails === FALSE) {
+          $consecfails = 0;
+        }
+
+        // Increment by one
+        $consecfails++;
+
+        // Log and cache this failure
+        if ($consecfails >= $this->maxConsecutiveFailures_) {
+          if ($this->debug_) {
+            call_user_func($this->debugHandler_,
+                           'TSocketPool: marking '.$host.':'.$port.
+                           ' as down for '.$this->retryInterval_.' secs '.
+                           'after '.$consecfails.' failed attempts.');
+          }
+          // Store the failure time
+          apc_store($failtimeKey, time());
+
+          // Clear the count of consecutive failures
+          apc_store($consecfailsKey, 0);
+        } else {
+          apc_store($consecfailsKey, $consecfails);
+        }
+      }
+    }
+
+    // Holy shit we failed them all. The system is totally ill!
+    $error = 'TSocketPool: All hosts in pool are down. ';
+    $hosts = array();
+    foreach ($this->servers_ as $server) {
+      $hosts []= $server['host'].':'.$server['port'];
+    }
+    $hostlist = implode(',', $hosts);
+    $error .= '('.$hostlist.')';
+    if ($this->debug_) {
+      call_user_func($this->debugHandler_, $error);
+    }
+    throw new TException($error);
+  }
+}
+
+?>
diff --git a/lib/php/src/transport/TTransport.php b/lib/php/src/transport/TTransport.php
new file mode 100644
index 0000000..e244525
--- /dev/null
+++ b/lib/php/src/transport/TTransport.php
@@ -0,0 +1,108 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+
+/**
+ * Transport exceptions
+ */
+class TTransportException extends TException {
+
+  const UNKNOWN = 0;
+  const NOT_OPEN = 1;
+  const ALREADY_OPEN = 2;
+  const TIMED_OUT = 3;
+  const END_OF_FILE = 4;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+}
+
+/**
+ * Base interface for a transport agent.
+ *
+ * @package thrift.transport
+ */
+abstract class TTransport {
+
+  /**
+   * Whether this transport is open.
+   *
+   * @return boolean true if open
+   */
+  public abstract function isOpen();
+
+  /**
+   * Open the transport for reading/writing
+   *
+   * @throws TTransportException if cannot open
+   */
+  public abstract function open();
+
+  /**
+   * Close the transport.
+   */
+  public abstract function close();
+
+  /**
+   * Read some data into the array.
+   *
+   * @param int    $len How much to read
+   * @return string The data that has been read
+   * @throws TTransportException if cannot read any more data
+   */
+  public abstract function read($len);
+
+  /**
+   * Guarantees that the full amount of data is read.
+   *
+   * @return string The data, of exact length
+   * @throws TTransportException if cannot read data
+   */
+  public function readAll($len) {
+    // return $this->read($len);
+
+    $data = '';
+    $got = 0;
+    while (($got = strlen($data)) < $len) {
+      $data .= $this->read($len - $got);
+    }
+    return $data;
+  }
+
+  /**
+   * Writes the given data out.
+   *
+   * @param string $buf  The data to write
+   * @throws TTransportException if writing fails
+   */
+  public abstract function write($buf);
+
+  /**
+   * Flushes any pending data out of a buffer
+   *
+   * @throws TTransportException if a writing error occurs
+   */
+  public function flush() {}
+}
+
+?>
