You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by jk...@apache.org on 2018/01/16 14:23:25 UTC
[3/8] thrift git commit: THRIFT-4459: reduce php library directory
depth Client: php
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TCurlClient.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TCurlClient.php b/lib/php/lib/Transport/TCurlClient.php
new file mode 100644
index 0000000..c761cd0
--- /dev/null
+++ b/lib/php/lib/Transport/TCurlClient.php
@@ -0,0 +1,249 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * HTTP client for Thrift
+ *
+ * @package thrift.transport
+ */
+class TCurlClient extends TTransport
+{
+ private static $curlHandle;
+
+ /**
+ * 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 $request_;
+
+ /**
+ * Buffer for the HTTP response data.
+ *
+ * @var binary string
+ */
+ protected $response_;
+
+ /**
+ * Read timeout
+ *
+ * @var float
+ */
+ protected $timeout_;
+
+ /**
+ * http headers
+ *
+ * @var array
+ */
+ protected $headers_;
+
+ /**
+ * Make a new HTTP client.
+ *
+ * @param string $host
+ * @param int $port
+ * @param string $uri
+ */
+ public function __construct($host, $port=80, $uri='', $scheme = 'http')
+ {
+ if ((TStringFuncFactory::create()->strlen($uri) > 0) && ($uri{0} != '/')) {
+ $uri = '/'.$uri;
+ }
+ $this->scheme_ = $scheme;
+ $this->host_ = $host;
+ $this->port_ = $port;
+ $this->uri_ = $uri;
+ $this->request_ = '';
+ $this->response_ = null;
+ $this->timeout_ = null;
+ $this->headers_ = array();
+ }
+
+ /**
+ * 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()
+ {
+ $this->request_ = '';
+ $this->response_ = 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)
+ {
+ if ($len >= strlen($this->response_)) {
+ return $this->response_;
+ } else {
+ $ret = substr($this->response_, 0, $len);
+ $this->response_ = substr($this->response_, $len);
+
+ return $ret;
+ }
+ }
+
+ /**
+ * Writes some data into the pending buffer
+ *
+ * @param string $buf The data to write
+ * @throws TTransportException if writing fails
+ */
+ public function write($buf)
+ {
+ $this->request_ .= $buf;
+ }
+
+ /**
+ * Opens and sends the actual request over the HTTP connection
+ *
+ * @throws TTransportException if a writing error occurs
+ */
+ public function flush()
+ {
+ if (!self::$curlHandle) {
+ register_shutdown_function(array('Thrift\\Transport\\TCurlClient', 'closeCurlHandle'));
+ self::$curlHandle = curl_init();
+ curl_setopt(self::$curlHandle, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt(self::$curlHandle, CURLOPT_BINARYTRANSFER, true);
+ curl_setopt(self::$curlHandle, CURLOPT_USERAGENT, 'PHP/TCurlClient');
+ curl_setopt(self::$curlHandle, CURLOPT_CUSTOMREQUEST, 'POST');
+ curl_setopt(self::$curlHandle, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt(self::$curlHandle, CURLOPT_MAXREDIRS, 1);
+ }
+ // God, PHP really has some esoteric ways of doing simple things.
+ $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
+ $fullUrl = $this->scheme_."://".$host.$this->uri_;
+
+ $headers = array();
+ $defaultHeaders = array('Accept' => 'application/x-thrift',
+ 'Content-Type' => 'application/x-thrift',
+ 'Content-Length' => TStringFuncFactory::create()->strlen($this->request_));
+ foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) {
+ $headers[] = "$key: $value";
+ }
+
+ curl_setopt(self::$curlHandle, CURLOPT_HTTPHEADER, $headers);
+
+ if ($this->timeout_ > 0) {
+ curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_);
+ }
+ curl_setopt(self::$curlHandle, CURLOPT_POSTFIELDS, $this->request_);
+ $this->request_ = '';
+
+ curl_setopt(self::$curlHandle, CURLOPT_URL, $fullUrl);
+ $this->response_ = curl_exec(self::$curlHandle);
+
+ // Connect failed?
+ if (!$this->response_) {
+ curl_close(self::$curlHandle);
+ self::$curlHandle = null;
+ $error = 'TCurlClient: Could not connect to '.$fullUrl;
+ throw new TTransportException($error, TTransportException::NOT_OPEN);
+ }
+ }
+
+ public static function closeCurlHandle()
+ {
+ try {
+ if (self::$curlHandle) {
+ curl_close(self::$curlHandle);
+ self::$curlHandle = null;
+ }
+ } catch (\Exception $x) {
+ error_log('There was an error closing the curl handle: ' . $x->getMessage());
+ }
+ }
+
+ public function addHeaders($headers)
+ {
+ $this->headers_ = array_merge($this->headers_, $headers);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TFramedTransport.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TFramedTransport.php b/lib/php/lib/Transport/TFramedTransport.php
new file mode 100644
index 0000000..b8a64a9
--- /dev/null
+++ b/lib/php/lib/Transport/TFramedTransport.php
@@ -0,0 +1,193 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * 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 (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
+ $this->readFrame();
+ }
+
+ // Just return full buff
+ if ($len >= TStringFuncFactory::create()->strlen($this->rBuf_)) {
+ $out = $this->rBuf_;
+ $this->rBuf_ = null;
+
+ return $out;
+ }
+
+ // Return TStringFuncFactory::create()->substr
+ $out = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
+ $this->rBuf_ = TStringFuncFactory::create()->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 (TStringFuncFactory::create()->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 < TStringFuncFactory::create()->strlen($buf)) {
+ $buf = TStringFuncFactory::create()->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_ || TStringFuncFactory::create()->strlen($this->wBuf_) == 0) {
+ return $this->transport_->flush();
+ }
+
+ $out = pack('N', TStringFuncFactory::create()->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();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/THttpClient.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/THttpClient.php b/lib/php/lib/Transport/THttpClient.php
new file mode 100644
index 0000000..b372ab7
--- /dev/null
+++ b/lib/php/lib/Transport/THttpClient.php
@@ -0,0 +1,229 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * 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_;
+
+ /**
+ * http headers
+ *
+ * @var array
+ */
+ protected $headers_;
+
+ /**
+ * Make a new HTTP client.
+ *
+ * @param string $host
+ * @param int $port
+ * @param string $uri
+ */
+ public function __construct($host, $port=80, $uri='', $scheme = 'http')
+ {
+ if ((TStringFuncFactory::create()->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;
+ $this->headers_ = array();
+ }
+
+ /**
+ * 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();
+ $defaultHeaders = array('Host' => $host,
+ 'Accept' => 'application/x-thrift',
+ 'User-Agent' => 'PHP/THttpClient',
+ 'Content-Type' => 'application/x-thrift',
+ 'Content-Length' => TStringFuncFactory::create()->strlen($this->buf_));
+ foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) {
+ $headers[] = "$key: $value";
+ }
+
+ $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);
+ }
+ }
+
+ public function addHeaders($headers)
+ {
+ $this->headers_ = array_merge($this->headers_, $headers);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TMemoryBuffer.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TMemoryBuffer.php b/lib/php/lib/Transport/TMemoryBuffer.php
new file mode 100644
index 0000000..ca31c57
--- /dev/null
+++ b/lib/php/lib/Transport/TMemoryBuffer.php
@@ -0,0 +1,100 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * 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)
+ {
+ $bufLength = TStringFuncFactory::create()->strlen($this->buf_);
+
+ if ($bufLength === 0) {
+ throw new TTransportException('TMemoryBuffer: Could not read ' .
+ $len . ' bytes from buffer.',
+ TTransportException::UNKNOWN);
+ }
+
+ if ($bufLength <= $len) {
+ $ret = $this->buf_;
+ $this->buf_ = '';
+
+ return $ret;
+ }
+
+ $ret = TStringFuncFactory::create()->substr($this->buf_, 0, $len);
+ $this->buf_ = TStringFuncFactory::create()->substr($this->buf_, $len);
+
+ return $ret;
+ }
+
+ public function getBuffer()
+ {
+ return $this->buf_;
+ }
+
+ public function available()
+ {
+ return TStringFuncFactory::create()->strlen($this->buf_);
+ }
+
+ public function putBack($data)
+ {
+ $this->buf_ = $data.$this->buf_;
+ }
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TNullTransport.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TNullTransport.php b/lib/php/lib/Transport/TNullTransport.php
new file mode 100644
index 0000000..feeb7a4
--- /dev/null
+++ b/lib/php/lib/Transport/TNullTransport.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.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TTransportException;
+
+/**
+ * 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) {}
+
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TPhpStream.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TPhpStream.php b/lib/php/lib/Transport/TPhpStream.php
new file mode 100644
index 0000000..4c14cdf
--- /dev/null
+++ b/lib/php/lib/Transport/TPhpStream.php
@@ -0,0 +1,123 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * 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 (TStringFuncFactory::create()->strlen($buf) > 0) {
+ $got = @fwrite($this->outStream_, $buf);
+ if ($got === 0 || $got === FALSE) {
+ throw new TException('TPhpStream: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes');
+ }
+ $buf = TStringFuncFactory::create()->substr($buf, $got);
+ }
+ }
+
+ public function flush()
+ {
+ @fflush($this->outStream_);
+ }
+
+ private static function inStreamName()
+ {
+ if (php_sapi_name() == 'cli') {
+ return 'php://stdin';
+ }
+
+ return 'php://input';
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TSSLSocket.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TSSLSocket.php b/lib/php/lib/Transport/TSSLSocket.php
new file mode 100644
index 0000000..533b7bb
--- /dev/null
+++ b/lib/php/lib/Transport/TSSLSocket.php
@@ -0,0 +1,112 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TException;
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Sockets implementation of the TTransport interface.
+ *
+ * @package thrift.transport
+ */
+class TSSLSocket extends TSocket
+{
+ /**
+ * Remote port
+ *
+ * @var resource
+ */
+ protected $context_ = null;
+
+ /**
+ * Socket constructor
+ *
+ * @param string $host Remote hostname
+ * @param int $port Remote port
+ * @param resource $context Stream context
+ * @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,
+ $context=null,
+ $debugHandler=null) {
+ $this->host_ = $this->getSSLHost($host);
+ $this->port_ = $port;
+ $this->context_ = $context;
+ $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log';
+ }
+
+ /**
+ * Creates a host name with SSL transport protocol
+ * if no transport protocol already specified in
+ * the host name.
+ *
+ * @param string $host Host to listen on
+ * @return string $host Host name with transport protocol
+ */
+ private function getSSLHost($host)
+ {
+ $transport_protocol_loc = strpos($host, "://");
+ if ($transport_protocol_loc === false) {
+ $host = 'ssl://'.$host;
+ }
+ return $host;
+ }
+
+ /**
+ * Connects the socket.
+ */
+ public function open()
+ {
+ if ($this->isOpen()) {
+ throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN);
+ }
+
+ if (empty($this->host_)) {
+ throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN);
+ }
+
+ if ($this->port_ <= 0) {
+ throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN);
+ }
+
+ $this->handle_ = @stream_socket_client($this->host_.':'.$this->port_,
+ $errno,
+ $errstr,
+ $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000),
+ STREAM_CLIENT_CONNECT,
+ $this->context_);
+
+ // 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);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TSocket.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TSocket.php b/lib/php/lib/Transport/TSocket.php
new file mode 100644
index 0000000..a1872b9
--- /dev/null
+++ b/lib/php/lib/Transport/TSocket.php
@@ -0,0 +1,340 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TException;
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Sockets implementation of the TTransport interface.
+ *
+ * @package thrift.transport
+ */
+class TSocket extends TTransport
+{
+ /**
+ * Handle to PHP socket
+ *
+ * @var resource
+ */
+ protected $handle_ = null;
+
+ /**
+ * Remote hostname
+ *
+ * @var string
+ */
+ protected $host_ = 'localhost';
+
+ /**
+ * Remote port
+ *
+ * @var int
+ */
+ protected $port_ = '9090';
+
+ /**
+ * Send timeout in seconds.
+ *
+ * Combined with sendTimeoutUsec this is used for send timeouts.
+ *
+ * @var int
+ */
+ protected $sendTimeoutSec_ = 0;
+
+ /**
+ * Send timeout in microseconds.
+ *
+ * Combined with sendTimeoutSec this is used for send timeouts.
+ *
+ * @var int
+ */
+ protected $sendTimeoutUsec_ = 100000;
+
+ /**
+ * Recv timeout in seconds
+ *
+ * Combined with recvTimeoutUsec this is used for recv timeouts.
+ *
+ * @var int
+ */
+ protected $recvTimeoutSec_ = 0;
+
+ /**
+ * Recv timeout in microseconds
+ *
+ * Combined with recvTimeoutSec this is used for recv timeouts.
+ *
+ * @var int
+ */
+ protected $recvTimeoutUsec_ = 750000;
+
+ /**
+ * Persistent socket or plain?
+ *
+ * @var bool
+ */
+ protected $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';
+ }
+
+ /**
+ * @param resource $handle
+ * @return void
+ */
+ public function setHandle($handle)
+ {
+ $this->handle_ = $handle;
+ }
+
+ /**
+ * Sets the send timeout.
+ *
+ * @param int $timeout Timeout in milliseconds.
+ */
+ public function setSendTimeout($timeout)
+ {
+ $this->sendTimeoutSec_ = floor($timeout / 1000);
+ $this->sendTimeoutUsec_ =
+ ($timeout - ($this->sendTimeoutSec_ * 1000)) * 1000;
+ }
+
+ /**
+ * Sets the receive timeout.
+ *
+ * @param int $timeout Timeout in milliseconds.
+ */
+ public function setRecvTimeout($timeout)
+ {
+ $this->recvTimeoutSec_ = floor($timeout / 1000);
+ $this->recvTimeoutUsec_ =
+ ($timeout - ($this->recvTimeoutSec_ * 1000)) * 1000;
+ }
+
+ /**
+ * 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->isOpen()) {
+ throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN);
+ }
+
+ if (empty($this->host_)) {
+ throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN);
+ }
+
+ if ($this->port_ <= 0) {
+ throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN);
+ }
+
+ if ($this->persist_) {
+ $this->handle_ = @pfsockopen($this->host_,
+ $this->port_,
+ $errno,
+ $errstr,
+ $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
+ } else {
+ $this->handle_ = @fsockopen($this->host_,
+ $this->port_,
+ $errno,
+ $errstr,
+ $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
+ }
+
+ // 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);
+ }
+
+ if (function_exists('socket_import_stream') && function_exists('socket_set_option')) {
+ $socket = socket_import_stream($this->handle_);
+ socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1);
+ }
+ }
+
+ /**
+ * Closes the socket.
+ */
+ public function close()
+ {
+ @fclose($this->handle_);
+ $this->handle_ = null;
+ }
+
+ /**
+ * Read from the socket at most $len bytes.
+ *
+ * This method will not wait for all the requested data, it will return as
+ * soon as any data is received.
+ *
+ * @param int $len Maximum number of bytes to read.
+ * @return string Binary data
+ */
+ public function read($len)
+ {
+ $null = null;
+ $read = array($this->handle_);
+ $readable = @stream_select($read, $null, $null, $this->recvTimeoutSec_, $this->recvTimeoutUsec_);
+
+ if ($readable > 0) {
+ $data = fread($this->handle_, $len);
+ if ($data === false) {
+ throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
+ } elseif ($data == '' && feof($this->handle_)) {
+ throw new TTransportException('TSocket read 0 bytes');
+ }
+
+ return $data;
+ } elseif ($readable === 0) {
+ throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
+ } else {
+ throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
+ }
+ }
+
+ /**
+ * Write to the socket.
+ *
+ * @param string $buf The data to write
+ */
+ public function write($buf)
+ {
+ $null = null;
+ $write = array($this->handle_);
+
+ // keep writing until all the data has been written
+ while (TStringFuncFactory::create()->strlen($buf) > 0) {
+ // wait for stream to become available for writing
+ $writable = @stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
+ if ($writable > 0) {
+ // write buffer to stream
+ $written = fwrite($this->handle_, $buf);
+ if ($written === -1 || $written === false) {
+ throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
+ $this->host_.':'.$this->port_);
+ }
+ // determine how much of the buffer is left to write
+ $buf = TStringFuncFactory::create()->substr($buf, $written);
+ } elseif ($writable === 0) {
+ throw new TTransportException('TSocket: timed out writing '.TStringFuncFactory::create()->strlen($buf).' bytes from '.
+ $this->host_.':'.$this->port_);
+ } else {
+ throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
+ $this->host_.':'.$this->port_);
+ }
+ }
+ }
+
+ /**
+ * Flush output to the socket.
+ *
+ * Since read(), readAll() and write() operate on the sockets directly,
+ * this is a no-op
+ *
+ * If you wish to have flushable buffering behaviour, wrap this TSocket
+ * in a TBufferedTransport.
+ */
+ public function flush()
+ {
+ // no-op
+ }
+ }
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TSocketPool.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TSocketPool.php b/lib/php/lib/Transport/TSocketPool.php
new file mode 100644
index 0000000..18ffd8d
--- /dev/null
+++ b/lib/php/lib/Transport/TSocketPool.php
@@ -0,0 +1,300 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Exception\TException;
+
+/**
+ * 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);
+ }
+ }
+ }
+
+ // Oh no; 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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Transport/TTransport.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Transport/TTransport.php b/lib/php/lib/Transport/TTransport.php
new file mode 100644
index 0000000..99c39ff
--- /dev/null
+++ b/lib/php/lib/Transport/TTransport.php
@@ -0,0 +1,95 @@
+<?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
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Base interface for a transport agent.
+ *
+ * @package thrift.transport
+ */
+abstract class TTransport
+{
+ /**
+ * Whether this transport is open.
+ *
+ * @return boolean true if open
+ */
+ abstract public function isOpen();
+
+ /**
+ * Open the transport for reading/writing
+ *
+ * @throws TTransportException if cannot open
+ */
+ abstract public function open();
+
+ /**
+ * Close the transport.
+ */
+ abstract public 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
+ */
+ abstract public 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 = TStringFuncFactory::create()->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
+ */
+ abstract public function write($buf);
+
+ /**
+ * Flushes any pending data out of a buffer
+ *
+ * @throws TTransportException if a writing error occurs
+ */
+ public function flush() {}
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Type/TConstant.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Type/TConstant.php b/lib/php/lib/Type/TConstant.php
new file mode 100644
index 0000000..7c8eceb
--- /dev/null
+++ b/lib/php/lib/Type/TConstant.php
@@ -0,0 +1,50 @@
+<?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
+ */
+
+namespace Thrift\Type;
+
+/**
+ * Base class for constant Management
+ */
+abstract class TConstant
+{
+ /**
+ * Don't instanciate this class
+ */
+ protected function __construct() {}
+
+ /**
+ * Get a constant value
+ * @param string $constant
+ * @return mixed
+ */
+ public static function get($constant)
+ {
+ if (is_null(static::$$constant)) {
+ static::$$constant = call_user_func(
+ sprintf('static::init_%s', $constant)
+ );
+ }
+
+ return static::$$constant;
+ }
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Type/TMessageType.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Type/TMessageType.php b/lib/php/lib/Type/TMessageType.php
new file mode 100644
index 0000000..bff224f
--- /dev/null
+++ b/lib/php/lib/Type/TMessageType.php
@@ -0,0 +1,34 @@
+<?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
+ */
+
+namespace Thrift\Type;
+
+/**
+ * Message types for RPC
+ */
+class TMessageType
+{
+ const CALL = 1;
+ const REPLY = 2;
+ const EXCEPTION = 3;
+ const ONEWAY = 4;
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/lib/Type/TType.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Type/TType.php b/lib/php/lib/Type/TType.php
new file mode 100644
index 0000000..71219c2
--- /dev/null
+++ b/lib/php/lib/Type/TType.php
@@ -0,0 +1,47 @@
+<?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
+ */
+
+namespace Thrift\Type;
+
+/**
+ * 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;
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/test/Fixtures.php
----------------------------------------------------------------------
diff --git a/lib/php/test/Fixtures.php b/lib/php/test/Fixtures.php
new file mode 100644
index 0000000..2c60a08
--- /dev/null
+++ b/lib/php/test/Fixtures.php
@@ -0,0 +1,194 @@
+<?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.test
+ */
+
+namespace Test\Thrift;
+
+use ThriftTest\Xtruct;
+use ThriftTest\Xtruct2;
+use ThriftTest\Numberz;
+use ThriftTest\Insanity;
+
+class Fixtures
+{
+ public static $testArgs = array();
+
+ public static function populateTestArgs()
+ {
+ self::$testArgs['testString1'] = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, �
��국어, Къарачай-Малкъар, Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, Bahasa Melayu, مازِرونی, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, Norsk (nynorsk), Norsk (bokmål), Nouormand, Diné bizaad, Occitan, Иронау, Papiamentu, Deitsch, Norfuk / Pitkern, Polski, پنجابی, پښتو, Português, Runa Simi, Rumantsch, Romani, Română, Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá
, Zeêuws, 中文, Bân-lâm-gú, 粵語";
+
+ self::$testArgs['testString2'] =
+ "quote: \\\" backslash:" .
+ " forwardslash-escaped: \\/ " .
+ " backspace: \b formfeed: \f newline: \n return: \r tab: " .
+ " now-all-of-them-together: \"\\\/\b\n\r\t" .
+ " now-a-bunch-of-junk: !@#\$%&()(&%$#{}{}<><><";
+
+ self::$testArgs['testString3'] =
+ "string that ends in double-backslash \\\\";
+
+ self::$testArgs['testUnicodeStringWithNonBMP'] =
+ "สวัสดี/𝒯";
+
+ self::$testArgs['testDouble'] = 3.1415926535898;
+
+ // TODO: add testBinary() call
+
+ self::$testArgs['testByte'] = 0x01;
+
+ self::$testArgs['testI32'] = pow( 2, 30 );
+
+ if (PHP_INT_SIZE == 8) {
+ self::$testArgs['testI64'] = pow( 2, 60 );
+ } else {
+ self::$testArgs['testI64'] = "1152921504606847000";
+ }
+
+ self::$testArgs['testStruct'] =
+ new Xtruct(
+ array(
+ 'string_thing' => 'worked',
+ 'byte_thing' => 0x01,
+ 'i32_thing' => pow( 2, 30 ),
+ 'i64_thing' => self::$testArgs['testI64']
+ )
+ );
+
+ self::$testArgs['testNestNested'] =
+ new Xtruct(
+ array(
+ 'string_thing' => 'worked',
+ 'byte_thing' => 0x01,
+ 'i32_thing' => pow( 2, 30 ),
+ 'i64_thing' => self::$testArgs['testI64']
+ )
+ );
+
+ self::$testArgs['testNest'] =
+ new Xtruct2(
+ array(
+ 'byte_thing' => 0x01,
+ 'struct_thing' => self::$testArgs['testNestNested'],
+ 'i32_thing' => pow( 2, 15 )
+ )
+ );
+
+ self::$testArgs['testMap'] =
+ array(
+ 7 => 77,
+ 8 => 88,
+ 9 => 99
+ );
+
+ self::$testArgs['testStringMap'] =
+ array(
+ "a" => "123",
+ "a b" => "with spaces ",
+ "same" => "same",
+ "0" => "numeric key",
+ "longValue" => self::$testArgs['testString1'],
+ self::$testArgs['testString1'] => "long key"
+ );
+
+ self::$testArgs['testSet'] = array( 1 => true, 5 => true, 6 => true );
+
+ self::$testArgs['testList'] = array( 1, 2, 3 );
+
+ self::$testArgs['testEnum'] = Numberz::ONE;
+
+ self::$testArgs['testTypedef'] = 69;
+
+ self::$testArgs['testMapMapExpectedResult'] =
+ array(
+ 4 => array(
+ 1 => 1,
+ 2 => 2,
+ 3 => 3,
+ 4 => 4,
+ ),
+ -4 => array(
+ -4 => -4,
+ -3 => -3,
+ -2 => -2,
+ -1 => -1
+ )
+ );
+
+ // testInsanity ... takes a few steps to set up!
+
+ $xtruct1 =
+ new Xtruct(
+ array(
+ 'string_thing' => 'Goodbye4',
+ 'byte_thing' => 4,
+ 'i32_thing' => 4,
+ 'i64_thing' => 4
+ )
+ );
+
+ $xtruct2 =
+ new Xtruct(
+ array(
+ 'string_thing' => 'Hello2',
+ 'byte_thing' =>2,
+ 'i32_thing' => 2,
+ 'i64_thing' => 2
+ )
+ );
+
+ $userMap =
+ array(
+ Numberz::FIVE => 5,
+ Numberz::EIGHT => 8
+ );
+
+ $insanity2 =
+ new Insanity(
+ array(
+ 'userMap' => $userMap,
+ 'xtructs' => array($xtruct1,$xtruct2)
+ )
+ );
+
+ $insanity3 = $insanity2;
+
+ $insanity6 =
+ new Insanity(
+ array(
+ 'userMap' => null,
+ 'xtructs' => null
+ )
+ );
+
+ self::$testArgs['testInsanityExpectedResult'] =
+ array(
+ "1" => array(
+ Numberz::TWO => $insanity2,
+ Numberz::THREE => $insanity3
+ ),
+ "2" => array(
+ Numberz::SIX => $insanity6
+ )
+ );
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/test/JsonSerialize/JsonSerializeTest.php
----------------------------------------------------------------------
diff --git a/lib/php/test/JsonSerialize/JsonSerializeTest.php b/lib/php/test/JsonSerialize/JsonSerializeTest.php
new file mode 100644
index 0000000..dfb34c3
--- /dev/null
+++ b/lib/php/test/JsonSerialize/JsonSerializeTest.php
@@ -0,0 +1,114 @@
+<?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.
+ */
+
+namespace Test\Thrift\JsonSerialize;
+
+use stdClass;
+use Thrift\ClassLoader\ThriftClassLoader;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+$loader = new ThriftClassLoader();
+$loader->registerDefinition('ThriftTest', __DIR__ . '/../packages/phpjs');
+$loader->register();
+
+class JsonSerializeTest extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp() {
+ if (version_compare(phpversion(), '5.4', '<')) {
+ $this->markTestSkipped('Requires PHP 5.4 or newer!');
+ }
+ }
+
+ public function testEmptyStruct()
+ {
+ $empty = new \ThriftTest\EmptyStruct(array('non_existing_key' => 'bar'));
+ $this->assertEquals(new stdClass(), json_decode(json_encode($empty)));
+ }
+
+ public function testStringsAndInts()
+ {
+ $input = array(
+ 'string_thing' => 'foo',
+ 'i64_thing' => 1234567890,
+ );
+ $xtruct = new \ThriftTest\Xtruct($input);
+
+ // Xtruct's 'i32_thing' and 'byte_thing' fields should not be present here!
+ $expected = new stdClass();
+ $expected->string_thing = $input['string_thing'];
+ $expected->i64_thing = $input['i64_thing'];
+ $this->assertEquals($expected, json_decode(json_encode($xtruct)));
+ }
+
+ public function testNestedStructs()
+ {
+ $xtruct2 = new \ThriftTest\Xtruct2(array(
+ 'byte_thing' => 42,
+ 'struct_thing' => new \ThriftTest\Xtruct(array(
+ 'i32_thing' => 123456,
+ )),
+ ));
+
+ $expected = new stdClass();
+ $expected->byte_thing = $xtruct2->byte_thing;
+ $expected->struct_thing = new stdClass();
+ $expected->struct_thing->i32_thing = $xtruct2->struct_thing->i32_thing;
+ $this->assertEquals($expected, json_decode(json_encode($xtruct2)));
+ }
+
+ public function testInsanity()
+ {
+ $xinput = array('string_thing' => 'foo');
+ $xtruct = new \ThriftTest\Xtruct($xinput);
+ $insanity = new \ThriftTest\Insanity(array(
+ 'xtructs' => array($xtruct, $xtruct, $xtruct)
+ ));
+ $expected = new stdClass();
+ $expected->xtructs = array((object) $xinput, (object) $xinput, (object) $xinput);
+ $this->assertEquals($expected, json_decode(json_encode($insanity)));
+ }
+
+ public function testNestedLists()
+ {
+ $bonk = new \ThriftTest\Bonk(array('message' => 'foo'));
+ $nested = new \ThriftTest\NestedListsBonk(array('bonk' => array(array(array($bonk)))));
+ $expected = new stdClass();
+ $expected->bonk = array(array(array((object) array('message' => 'foo'))));
+ $this->assertEquals($expected, json_decode(json_encode($nested)));
+ }
+
+ public function testMaps()
+ {
+ $intmap = new \ThriftTest\ThriftTest_testMap_args(['thing' => [0 => 'zero']]);
+ $emptymap = new \ThriftTest\ThriftTest_testMap_args([]);
+ $this->assertEquals('{"thing":{"0":"zero"}}', json_encode($intmap));
+ $this->assertEquals('{}', json_encode($emptymap));
+ }
+
+ public function testScalarTypes()
+ {
+ $b = new \ThriftTest\Bools(['im_true' => '1', 'im_false' => '0']);
+ $this->assertEquals('{"im_true":true,"im_false":false}', json_encode($b));
+ $s = new \ThriftTest\StructA(['s' => 42]);
+ $this->assertEquals('{"s":"42"}', json_encode($s));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/test/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/php/test/Makefile.am b/lib/php/test/Makefile.am
index c4dcde3..5658afa 100755
--- a/lib/php/test/Makefile.am
+++ b/lib/php/test/Makefile.am
@@ -35,16 +35,16 @@ deps: $(top_srcdir)/composer.json
all-local: deps
check-json-serializer: deps stubs
- $(PHPUNIT) --log-junit=TEST-json-serializer.xml Test/Thrift/JsonSerialize/
+ $(PHPUNIT) --log-junit=TEST-json-serializer.xml JsonSerialize/
check-validator: deps stubs
- php Test/Thrift/TestValidators.php
- php Test/Thrift/TestValidators.php -oop
+ php TestValidators.php
+ php TestValidators.php -oop
check-protocol: deps stubs
- $(PHPUNIT) --log-junit=TEST-log-json-protocol.xml Test/Thrift/Protocol/TestTJSONProtocol.php
- $(PHPUNIT) --log-junit=TEST-binary-serializer.xml Test/Thrift/Protocol/TestBinarySerializer.php
- $(PHPUNIT) --log-junit=TEST-log-simple-json-protocol.xml Test/Thrift/Protocol/TestTSimpleJSONProtocol.php
+ $(PHPUNIT) --log-junit=TEST-log-json-protocol.xml Protocol/TestTJSONProtocol.php
+ $(PHPUNIT) --log-junit=TEST-binary-serializer.xml Protocol/TestBinarySerializer.php
+ $(PHPUNIT) --log-junit=TEST-log-simple-json-protocol.xml Protocol/TestTSimpleJSONProtocol.php
check: deps stubs \
check-protocol \
@@ -54,7 +54,3 @@ check: deps stubs \
clean-local:
$(RM) -r ./packages
$(RM) TEST-*.xml
-
-EXTRA_DIST = \
- Test \
- TestValidators.thrift
http://git-wip-us.apache.org/repos/asf/thrift/blob/bfba370b/lib/php/test/Protocol/TestBinarySerializer.php
----------------------------------------------------------------------
diff --git a/lib/php/test/Protocol/TestBinarySerializer.php b/lib/php/test/Protocol/TestBinarySerializer.php
new file mode 100644
index 0000000..e08057b
--- /dev/null
+++ b/lib/php/test/Protocol/TestBinarySerializer.php
@@ -0,0 +1,62 @@
+<?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.test
+ */
+
+namespace Test\Thrift\Protocol;
+
+use Thrift\ClassLoader\ThriftClassLoader;
+use Thrift\Serializer\TBinarySerializer;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+$loader = new ThriftClassLoader();
+$loader->registerDefinition('ThriftTest', __DIR__ . '/../packages');
+$loader->register();
+
+/***
+ * This test suite depends on running the compiler against the
+ * standard ThriftTest.thrift file:
+ *
+ * lib/php/test$ ../../../compiler/cpp/thrift --gen php -r \
+ * --out ./packages ../../../test/ThriftTest.thrift
+ */
+
+class TestBinarySerializer extends \PHPUnit_Framework_TestCase
+{
+
+ public function setUp()
+ {
+ }
+
+ /**
+ * We try to serialize and deserialize a random object to make sure no exceptions are thrown.
+ * @see THRIFT-1579
+ */
+ public function testBinarySerializer()
+ {
+ $struct = new \ThriftTest\Xtruct(array('string_thing' => 'abc'));
+ $serialized = TBinarySerializer::serialize($struct, 'ThriftTest\\Xtruct');
+ $deserialized = TBinarySerializer::deserialize($serialized, 'ThriftTest\\Xtruct');
+ $this->assertEquals($struct, $deserialized);
+ }
+
+}