From a50840f84bb2808ba206209120685d73c7696826 Mon Sep 17 00:00:00 2001 From: Holger Woltersdorf Date: Tue, 3 Jan 2017 19:16:42 +0100 Subject: [PATCH] Changes class constant visibilities, requires php >= 7.1, bumping v2.0.0 --- .travis.yml | 1 - CHANGELOG.md | 11 ++ bin/fcgiget | 4 +- composer.json | 3 + composer.lock | 6 +- src/Client.php | 208 +++++++++++++++-------------- src/Encoders/PacketEncoder.php | 2 +- src/SocketConnections/Defaults.php | 8 +- src/Timing/Timer.php | 4 +- 9 files changed, 132 insertions(+), 115 deletions(-) diff --git a/.travis.yml b/.travis.yml index f772f45..587afff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - 7.0 - 7.1 branches: diff --git a/CHANGELOG.md b/CHANGELOG.md index 822194f..814c1f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a CHANGELOG](http://keepachangelog.com). +## [2.0.0] - 2017-01-03 + +### Changed + + * Class constant visibility to private in class `Client` + * Class constant visibility to privare in class `Encoders\PacketEncoder` + * Class constant visibility to public in class `SocketConnections\Defaults` + * Composer requires php >= 7.1 + + ## [1.0.0] - 2017-01-03 Based on [Pierrick Charron](https://github.com/adoy)'s [PHP-FastCGI-Client](https://github.com/adoy/PHP-FastCGI-Client/): @@ -27,4 +37,5 @@ Based on [Pierrick Charron](https://github.com/adoy)'s [PHP-FastCGI-Client](http * Getters/Setters for connect timeout, read/write timeout, keep alive, socket persistence from `Client` (now part of the socket connection) * Method `Client->getValues()` +[2.0.0]: https://github.com/hollodotme/fast-cgi-client/compare/v1.0.0...v2.0.0 [1.0.0]: https://github.com/hollodotme/fast-cgi-client/tree/v1.0.0 diff --git a/bin/fcgiget b/bin/fcgiget index 623e714..b6f671e 100755 --- a/bin/fcgiget +++ b/bin/fcgiget @@ -31,9 +31,9 @@ if ( file_exists( __DIR__ . '/../vendor/autoload.php' ) ) { require(__DIR__ . '/../vendor/autoload.php'); } -elseif ( file_exists( __DIR__ . '/../autoload.php' ) ) +elseif ( file_exists( __DIR__ . '/../../../autoload.php' ) ) { - require(__DIR__ . '/../autoload.php'); + require(__DIR__ . '/../../../autoload.php'); } else { diff --git a/composer.json b/composer.json index 20b2e74..6b00a00 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,9 @@ "hollodotme\\FastCGI\\Tests\\": "tests/" } }, + "require": { + "php": ">=7.1" + }, "require-dev": { "tm/tooly-composer-script": "^1.0" }, diff --git a/composer.lock b/composer.lock index a9e2bc5..0ffa1da 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "90c9c7c7931efbf66721a0b3f50c48b4", + "content-hash": "ed4e56b6726c512637db45e2f7aa6b6a", "packages": [], "packages-dev": [ { @@ -92,6 +92,8 @@ "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, - "platform": [], + "platform": { + "php": ">=7.1" + }, "platform-dev": [] } diff --git a/src/Client.php b/src/Client.php index b275a06..8f3e683 100644 --- a/src/Client.php +++ b/src/Client.php @@ -39,35 +39,35 @@ */ class Client { - const BEGIN_REQUEST = 1; + private const BEGIN_REQUEST = 1; - const END_REQUEST = 3; + private const END_REQUEST = 3; - const PARAMS = 4; + private const PARAMS = 4; - const STDIN = 5; + private const STDIN = 5; - const STDOUT = 6; + private const STDOUT = 6; - const STDERR = 7; + private const STDERR = 7; - const RESPONDER = 1; + private const RESPONDER = 1; - const REQUEST_COMPLETE = 0; + private const REQUEST_COMPLETE = 0; - const CANT_MPX_CONN = 1; + private const CANT_MPX_CONN = 1; - const OVERLOADED = 2; + private const OVERLOADED = 2; - const UNKNOWN_ROLE = 3; + private const UNKNOWN_ROLE = 3; - const HEADER_LEN = 8; + private const HEADER_LEN = 8; - const REQ_STATE_WRITTEN = 1; + private const REQ_STATE_WRITTEN = 1; - const REQ_STATE_OK = 2; + private const REQ_STATE_OK = 2; - const REQ_STATE_ERR = 3; + private const REQ_STATE_ERR = 3; /** @var ConfiguresSocketConnection */ private $connection; @@ -99,7 +99,95 @@ public function __construct( ConfiguresSocketConnection $connection ) $this->nameValuePairEncoder = new NameValuePairEncoder(); } - private function connect() + /** + * Execute a request to the FastCGI application + * + * @param array $params Array of parameters + * @param string $content Content + * + * @return string + */ + public function sendRequest( array $params, string $content ) : string + { + $requestId = $this->sendAsyncRequest( $params, $content ); + + return $this->waitForResponse( $requestId ); + } + + /** + * Execute a request to the FastCGI application asyncronously + * This sends request to application and returns the assigned ID for that request. + * You should keep this id for later use with wait_for_response(). Ids are chosen randomly + * rather than seqentially to guard against false-positives when using persistent sockets. + * In that case it is possible that a delayed response to a request made by a previous script + * invocation comes back on this socket and is mistaken for response to request made with same ID + * during this request. + +* +* @param array $params Array of parameters + * @param string $content Content + +* +* @throws TimedoutException + * @throws WriteFailedException + * @return int + */ + public function sendAsyncRequest( array $params, string $content ) : int + { + $this->connect(); + + // Pick random number between 1 and max 16 bit unsigned int 65535 + $requestId = mt_rand( 1, (1 << 16) - 1 ); + + // Using persistent sockets implies you want them kept alive by server + $keepAlive = intval( $this->connection->keepAlive() || $this->connection->isPersistent() ); + + $request = $this->packetEncoder->encodePacket( + self::BEGIN_REQUEST, + chr( 0 ) . chr( self::RESPONDER ) . chr( $keepAlive ) . str_repeat( chr( 0 ), 5 ), + $requestId + ); + + $paramsRequest = $this->nameValuePairEncoder->encodePairs( $params ); + + if ( $paramsRequest ) + { + $request .= $this->packetEncoder->encodePacket( self::PARAMS, $paramsRequest, $requestId ); + } + + $request .= $this->packetEncoder->encodePacket( self::PARAMS, '', $requestId ); + + if ( $content ) + { + $request .= $this->packetEncoder->encodePacket( self::STDIN, $content, $requestId ); + } + + $request .= $this->packetEncoder->encodePacket( self::STDIN, '', $requestId ); + + if ( fwrite( $this->socket, $request ) === false || fflush( $this->socket ) === false ) + { + $info = stream_get_meta_data( $this->socket ); + + if ( $info['timed_out'] ) + { + throw new TimedoutException( 'Write timed out' ); + } + + // Broken pipe, tear down so future requests might succeed + fclose( $this->socket ); + + throw new WriteFailedException( 'Failed to write request to socket [broken pipe]' ); + } + + $this->requests[ $requestId ] = [ + 'state' => self::REQ_STATE_WRITTEN, + 'response' => null, + ]; + + return $requestId; + } + + private function connect() : void { if ( $this->socket === null ) { @@ -157,7 +245,7 @@ private function setStreamTimeout( int $timeoutMs ) : bool * Read a FastCGI PacketEncoder * @return array|null */ - private function readPacket() + private function readPacket() : ?array { if ( $packet = fread( $this->socket, self::HEADER_LEN ) ) { @@ -188,92 +276,6 @@ private function readPacket() } } - /** - * Execute a request to the FastCGI application - * - * @param array $params Array of parameters - * @param string $content Content - * - * @return string - */ - public function sendRequest( array $params, string $content ) : string - { - $requestId = $this->sendAsyncRequest( $params, $content ); - - return $this->waitForResponse( $requestId ); - } - - /** - * Execute a request to the FastCGI application asyncronously - * This sends request to application and returns the assigned ID for that request. - * You should keep this id for later use with wait_for_response(). Ids are chosen randomly - * rather than seqentially to guard against false-positives when using persistent sockets. - * In that case it is possible that a delayed response to a request made by a previous script - * invocation comes back on this socket and is mistaken for response to request made with same ID - * during this request. - * - * @param array $params Array of parameters - * @param string $content Content - * -*@throws TimedoutException - * @throws WriteFailedException - * @return int - */ - public function sendAsyncRequest( array $params, string $content ) : int - { - $this->connect(); - - // Pick random number between 1 and max 16 bit unsigned int 65535 - $requestId = mt_rand( 1, (1 << 16) - 1 ); - - // Using persistent sockets implies you want them kept alive by server - $keepAlive = intval( $this->connection->keepAlive() || $this->connection->isPersistent() ); - - $request = $this->packetEncoder->encodePacket( - self::BEGIN_REQUEST, - chr( 0 ) . chr( self::RESPONDER ) . chr( $keepAlive ) . str_repeat( chr( 0 ), 5 ), - $requestId - ); - - $paramsRequest = $this->nameValuePairEncoder->encodePairs( $params ); - - if ( $paramsRequest ) - { - $request .= $this->packetEncoder->encodePacket( self::PARAMS, $paramsRequest, $requestId ); - } - - $request .= $this->packetEncoder->encodePacket( self::PARAMS, '', $requestId ); - - if ( $content ) - { - $request .= $this->packetEncoder->encodePacket( self::STDIN, $content, $requestId ); - } - - $request .= $this->packetEncoder->encodePacket( self::STDIN, '', $requestId ); - - if ( fwrite( $this->socket, $request ) === false || fflush( $this->socket ) === false ) - { - $info = stream_get_meta_data( $this->socket ); - - if ( $info['timed_out'] ) - { - throw new TimedoutException( 'Write timed out' ); - } - - // Broken pipe, tear down so future requests might succeed - fclose( $this->socket ); - - throw new WriteFailedException( 'Failed to write request to socket [broken pipe]' ); - } - - $this->requests[ $requestId ] = [ - 'state' => self::REQ_STATE_WRITTEN, - 'response' => null, - ]; - - return $requestId; - } - /** * Blocking call that waits for response to specific request * diff --git a/src/Encoders/PacketEncoder.php b/src/Encoders/PacketEncoder.php index dc4322c..c6a6d80 100644 --- a/src/Encoders/PacketEncoder.php +++ b/src/Encoders/PacketEncoder.php @@ -29,7 +29,7 @@ */ final class PacketEncoder { - const VERSION = 1; + private const VERSION = 1; public function encodePacket( int $type, string $content, int $requestId ) : string { diff --git a/src/SocketConnections/Defaults.php b/src/SocketConnections/Defaults.php index 4dbc4a7..b5bdbf9 100644 --- a/src/SocketConnections/Defaults.php +++ b/src/SocketConnections/Defaults.php @@ -29,11 +29,11 @@ */ abstract class Defaults { - const CONNECT_TIMEOUT = 5000; + public const CONNECT_TIMEOUT = 5000; - const READ_WRITE_TIMEOUT = 5000; + public const READ_WRITE_TIMEOUT = 5000; - const KEEP_ALIVE = false; + public const KEEP_ALIVE = false; - const PERSISTENT = false; + public const PERSISTENT = false; } diff --git a/src/Timing/Timer.php b/src/Timing/Timer.php index 990783c..048b239 100644 --- a/src/Timing/Timer.php +++ b/src/Timing/Timer.php @@ -42,7 +42,7 @@ public function __construct( int $timeoutMs ) $this->timeoutMs = $timeoutMs; } - public function start() + public function start() : void { $this->startTime = microtime( true ); } @@ -57,7 +57,7 @@ public function timedOut() : bool return ((microtime( true ) - $this->startTime) > ($this->timeoutMs / 1000)); } - public function reset() + public function reset() : void { $this->startTime = null; }