diff --git a/.editorconfig b/.editorconfig index 2365f05..db25999 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,10 @@ root = true [*] charset = utf-8 end_of_line = lf -indent_size = 4 +indent_size = 2 indent_style = space + +[*.php] +indent_size = 4 insert_final_newline = true trim_trailing_whitespace = true diff --git a/.gitattributes b/.gitattributes index 3dc84fd..8d49fb8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,3 @@ -* text=auto *.java eol=lf text ident diff=java *.c eol=lf text ident diff=cpp *.h eol=lf text ident diff=cpp @@ -6,9 +5,23 @@ *.xml eol=lf text ident diff=html *.vm text ident *.php eol=lf text ident diff=php +*.phps eol=lf text ident diff=php *.properties text ident -*.js text ident diff=html -*.css text ident diff=html +*.js eol=lf text ident diff=java +*.json eol=lf text ident diff=java +*.css eol=lf text ident diff=html *.sh eol=lf text ident *.bat eol=crlf text ident -*.vcproj eol=crlf text ident \ No newline at end of file +*.cmd eol=crlf text ident +*.vcproj eol=crlf text ident +*.md eol=lf text ident diff=html +*.gif binary +*.png binary +*.jpg binary +*.jar binary +*.class binary +*.gz binary +*.tar binary +*.dll binary +*.exe binary +*.zip binary \ No newline at end of file diff --git a/.gitignore b/.gitignore index fdecffc..fa9a3eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,69 +1,8 @@ -### PhpStorm ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm - -*.iml - -## Directory-based project format: -.idea/ - -## File-based project format: -*.ipr -*.iws - -## Plugin-specific files: - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties - -### Windows ### -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# Project specific +# clickalicious __*/ -docs/coverage/* +build/* bin/* -# Common -*.bak -*.tmp -*.log -*.old -.settings -.buildpath -.project -.externalToolBuilders - # Composer vendor/ composer.lock - -# Node & npm -npm_modules/ diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 702693b..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,88 +0,0 @@ -# language: php -# .scrutinizer.yml -before_commands: - - "composer install --prefer-dist --no-interaction" - -filter: - paths: - - src/* - - tests/* - excluded_paths: - - docs/* - - src/Clickalicious/Memcached/Autoloader.php - - src/Clickalicious/Memcached/Bootstrap.php - - src/Clickalicious/Memcached/Cache.php - - src/Clickalicious/Memcached/Exception.php - - src/Clickalicious/Memcached/Compression/* - -tools: - external_code_coverage: true - php_code_sniffer: - enabled: true - config: - standard: PSR2 - php_cs_fixer: - enabled: true - filter: - paths: - - src/* - - tests/* - excluded_paths: - - docs/* - - src/Clickalicious/Memcached/Autoloader.php - - src/Clickalicious/Memcached/Bootstrap.php - - src/Clickalicious/Memcached/Cache.php - - src/Clickalicious/Memcached/Exception.php - - src/Clickalicious/Memcached/Compression/* - config: - level: all - -checks: - php: - code_rating: true - duplication: true - remove_extra_empty_lines: true - remove_php_closing_tag: true - remove_trailing_whitespace: true - fix_use_statements: - remove_unused: true - preserve_multiple: false - preserve_blanklines: true - order_alphabetically: true - fix_php_opening_tag: true - fix_linefeed: true - fix_line_ending: true - fix_identation_4spaces: true - fix_doc_comments: true - use_self_instead_of_fqcn: true - uppercase_constants: true - simplify_boolean_return: true - return_doc_comments: true - properties_in_camelcaps: true - prefer_while_loop_over_for_loop: true - phpunit_assertions: true - parameters_in_camelcaps: true - optional_parameters_at_the_end: true - no_short_variable_names: - minimum: '3' - no_short_method_names: - minimum: '3' - no_new_line_at_end_of_file: true - no_long_variable_names: - maximum: '20' - no_goto: true - newline_at_end_of_file: true - line_length: - max_length: '120' - function_in_camel_caps: true - encourage_single_quotes: true - encourage_postdec_operator: true - avoid_perl_style_comments: true - avoid_multiple_statements_on_same_line: true - avoid_fixme_comments: true - align_assignments: true - return_doc_comment_if_not_inferrable: true - parameter_doc_comments: true - param_doc_comment_if_not_inferrable: true - more_specific_types_in_doc_comments: true - avoid_unnecessary_concatenation: true diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..f014f74 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,9 @@ +preset: symfony + +risky: true + +finder: + exclude: + - "tests" + name: + - "*.php" diff --git a/.travis.yml b/.travis.yml index 4a09ad2..83d83c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,17 @@ language: php php: - - 5.4 - - 5.5 - 5.6 - 7.0 + - 7.1 + - nightly - hhvm sudo: false matrix: allow_failures: + - php: nightly - php: hhvm fast_finish: true @@ -26,21 +27,20 @@ env: - PREFER_LOWEST="" before_script: - - composer update --prefer-dist $PREFER_LOWEST + - composer update --ignore-platform-reqs --prefer-dist $PREFER_LOWEST - composer --optimize-autoloader --no-interaction script: - - bin/phpunit -c tests/ --coverage-clover=coverage.clover --coverage-html=./docs/coverage + - bin/phpunit --configuration . --coverage-clover=build/logs/clover.xml --coverage-html=build/html/coverage after_script: - # We upload only for reference platform! This is our base for further code analyses and so on. - - if [ $(phpenv version-name) == "5.4" ] && [ "$PREFER_LOWEST" == "--prefer-lowest" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi - - if [ $(phpenv version-name) == "5.4" ] && [ "$PREFER_LOWEST" == "--prefer-lowest" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover > /dev/null 2>&1; fi + - if [ $(phpenv version-name) == "5.6" ] && [ "$PREFER_LOWEST" == "--prefer-lowest" ]; then bin/codacycoverage clover build/logs/clover.xml > /dev/null 2>&1; fi + - if [ $(phpenv version-name) == "5.6" ] && [ "$PREFER_LOWEST" == "--prefer-lowest" ]; then cat build/logs/clover.xml; fi after_success: # Push coverage to github pages branch - chmod +x ./update-gh-pages.sh - - if [ $(phpenv version-name) == "5.4" ] && [ "$PREFER_LOWEST" == "--prefer-lowest" ]; then bash ./update-gh-pages.sh; fi + - if [ $(phpenv version-name) == "5.6" ] && [ "$PREFER_LOWEST" == "--prefer-lowest" ]; then bash ./update-gh-pages.sh; fi # CREATE GIT TAG - git config --global user.email "builds@travis-ci.org" - git config --global user.name "Travis" @@ -48,7 +48,7 @@ after_success: - echo -n $GIT_TAG > public/version - git commit -m "Set build VERSION number" public/version - git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" - - git push --tags --quiet https://$GITHUBKEY@github.com/clickalicious/Memcached.php > /dev/null 2>&1 + - git push --tags --quiet https://$GITHUBKEY@github.com/clickalicious/memcached-php > /dev/null 2>&1 # Blacklist the pushed tag from above to prevent black hole branches: @@ -57,7 +57,8 @@ branches: # Who to notify? notifications: - slack: clickalicious:$SLACKKEY + slack: + secure: UFIXK2u7xalPWZppJ+X8aU9qjHWompS6qpBxyjYd8NyYIdTC8HvrovatS150F/b0QUnZXGaHe416vmooKRVDv6JgsR+v+sf/XAiAsc/vPSDO734zWZgubQCF3+jmKV2rD7OGnHgn/LBnREJhF26o10ox3A2UQ3G4kkFwP1q+i6g= email: recipients: - - opensource@clickalicious.de \ No newline at end of file + - opensource@clickalicious.de diff --git a/Demo.php b/Demo.php deleted file mode 100644 index 3fcdd6f..0000000 --- a/Demo.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ - -/** - * THE FOLLOWING REQUIRE IS ONLY REQUIRED AND RECOMMENDED IN DEVELOPMENT/FOR DEVELOPMENT OF Rng - * IT DOES NOT ONLY INSTALL AN ADDITIONAL AUTOLOADER (IN ADDITION TO COMPOSER) IT ALSO ADJUST - * THE DEBUG SETTINGS, ERROR-REPORTING AND THINGS LIKE THAT! SO DO NOT BOOTSTRAP IN PRODUCTION! - */ -require_once 'src/Clickalicious/Memcached/Bootstrap.php'; - -use Clickalicious\Memcached\Client; - -/** - * Memcached.php - * - * Demonstration of Memcached.php Memcached Client. - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Demo - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ - -// Create Memcached.php instance ... -$memcached = new Client( - '127.0.0.1' -); - -// Some setup for randomized key(s) for demonstration ... -srand(microtime(true)); -$dummy = md5(rand(1111, 9999)); - -// Try to do some stuff with memcached instance ... -try { - - $memcached->set($dummy, 1); - $memcached->increment($dummy, 2); - $memcached->increment($dummy, 2); - $memcached->increment($dummy, 2); - $memcached->decrement($dummy, 3); - $memcached->increment($dummy, 1); - - $result = $memcached->get($dummy); - - $memcached->delete($dummy); - -} catch (Exception $e) { - $result = $e->getMessage(); - -} - -echo '
';
-echo '

Simple Demonstration

'; -echo 'Result should be "5":
'; -echo $result; -echo '
'; diff --git a/LICENSE b/LICENSE index 988e504..be011f9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,27 +1,22 @@ -Copyright (c) 2014 - 2015, clickalicious GmbH, Benjamin Carl -All rights reserved. +(The MIT license) +Copyright 2017 clickalicious, Benjamin Carl -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Memcached.php nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index bc28ce4..7d3c7ed 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ - + --- -![Logo of Memcached.php](docs/logo-large.png) +![Logo of memcached-php](docs/logo-large.png) -Plain vanilla PHP `Memcached` client library with full support of Memcached ASCII protocol +`Memcached` client library in plain vanilla PHP. -| [![Build Status](https://travis-ci.org/clickalicious/Memcached.php.svg?branch=master)](https://travis-ci.org/clickalicious/Memcached.php) | [![Scrutinizer](https://img.shields.io/scrutinizer/g/clickalicious/Memcached.php.svg)](https://scrutinizer-ci.com/g/clickalicious/Memcached.php/) | [![Scrutinizer Coverage](https://img.shields.io/scrutinizer/coverage/g/clickalicious/Memcached.php.svg?maxAge=2592000)](http://clickalicious.github.io/Memcached.php/) | [![clickalicious open-source](https://img.shields.io/badge/clickalicious-open--source-green.svg?style=flat)](https://www.clickalicious.de/) | +| [![Build Status](https://travis-ci.org/clickalicious/memcached-php.svg?branch=master)](https://travis-ci.org/clickalicious/memcached-php) | [![Codacy branch grade](https://img.shields.io/codacy/grade/76a1648856b64c728b3e00c4954342ad/master.svg)](https://www.codacy.com/app/clickalicious/memcached-php?utm_source=github.com&utm_medium=referral&utm_content=clickalicious/memcached-php&utm_campaign=Badge_Grade) | [![Codacy coverage](https://img.shields.io/codacy/coverage/76a1648856b64c728b3e00c4954342ad.svg)](https://www.codacy.com/app/clickalicious/memcached-php?utm_source=github.com&utm_medium=referral&utm_content=clickalicious/webserver-daemon&utm_campaign=Badge_Grade) | [![clickalicious open-source](https://img.shields.io/badge/clickalicious-open--source-green.svg?style=flat)](https://www.clickalicious.de/) | |--- |--- |--- |--- | -| [![GitHub release](https://img.shields.io/github/release/clickalicious/Memcached.php.svg?style=flat)](https://github.com/clickalicious/Memcached.php/releases) | [![Waffle.io](https://img.shields.io/waffle/label/clickalicious/Memcached.php/in%20progress.svg)](https://waffle.io/clickalicious/Memcached.php) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/57efa79c-5ece-4296-abab-5c3eb9053c2c/mini.png)](https://insight.sensiolabs.com/projects/57efa79c-5ece-4296-abab-5c3eb9053c2c) | [![Packagist](https://img.shields.io/packagist/l/clickalicious/memcached.php.svg?style=flat)](http://opensource.org/licenses/BSD-3-Clause) | +| [![GitHub release](https://img.shields.io/github/release/clickalicious/memcached-php.svg?style=flat)](https://github.com/clickalicious/memcached-php/releases) | [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://opensource.org/licenses/MIT) | [![Issue Stats](https://img.shields.io/issuestats/i/github/clickalicious/memcached-php.svg)](https://github.com/clickalicious/memcached-php/issues) | [![Dependency Status](https://dependencyci.com/github/clickalicious/memcached-php/badge)](https://dependencyci.com/github/clickalicious/memcached-php) | ## Table of Contents @@ -23,18 +23,22 @@ Plain vanilla PHP `Memcached` client library with full support of Memcached ASCI - [Security-Issues](#security-issues) - [License »](LICENSE) - ## Features - - ~ 100% of `Memcached` *ASCII*-protocol specification covered + - 100% of `Memcached` *ASCII*-protocol specification covered - Support for storing native PHP variable types (arrays, objects ...) - Increment & Decrement support - Efficient connection sharing - Configurable connection close behavior - - Clean & well documented code - - Unit-Tested + - High-quality & stable codebase (following PSR standards e.g. `PSR-1,2,4`) + - Built on top of good PHP libraries + - Clean + well documented code + - Unit-tested with a good coverage + -**Memcached.php** covers almost 100% of the `Memcached` protocol specification. The code is clean, full documented and developed following the PSR coding standards (PSR-0/4, PSR-1, PSR-2). The code is unit-tested (PHPUnit) and the coverage is high. The library supports \ and \ command on stored integers (strings) and the [connection handling is done like recommended](https://github.com/memcached/memcached/blob/master/doc/protocol.txt#L10 "Keep connections open and share them via a pool across instances.") in the `Memcached` protocol specification. Last but not least it supports seven of [PHP's eight variable types](http://php.net/manual/en/language.types.intro.php "PHP's variable types") - in detail four scalar types: +## Example + +**memcached-php** covers almost 100% of the `Memcached` protocol specification. The code is clean, full documented and developed following the PSR coding standards (PSR-1, PSR-2, PSR-4). The code is unit-tested and the coverage is > 80%. The library supports \ and \ command on stored integers (strings) and the [connection handling is done like recommended](https://github.com/memcached/memcached/blob/master/doc/protocol.txt#L10 "Keep connections open and share them via a pool across instances.") in the `Memcached` protocol specification. Last but not least it supports seven of [PHP's eight variable types](http://php.net/manual/en/language.types.intro.php "PHP's variable types") - in detail four scalar types: boolean integer @@ -52,15 +56,12 @@ and finally one special type: So `resource` is the only type not supported. - -## Example - - - Create a `client` instance and connect it (*lazy*) to `Memcached` daemon on host *127.0.0.1* (on default port [11211]) + - Create a `Client` instance and connect it (*lazy*) to `Memcached` daemon on host *127.0.0.1* (on default port [11211]) - Set *key* **foo** with *value* **1.00** - Retrieve *value* for *key* **foo** ```php -$client = new \Clickalicious\Memcached\Client('127.0.0.1'); +$client = new \Clickalicious\Memcached\Php\Client('127.0.0.1'); // Set a value of type float $client->set('foo', 1.00); @@ -68,106 +69,55 @@ $client->set('foo', 1.00); // Returns 1.00 as PHP's type float! $client->get('foo'); ``` -You will find a demonstration `Demo.php` showing in detail how to use the **Memcached.php** `client`. - - -## Requirements +You will find a demonstration [`Demo.php` »](demo/Client.php) showing in detail how to use the **memcached-php** `client`. - - `PHP >= 5.4` (compatible up to version 5.6 as well as 7.x - but **not compatible** with HHVM) - - -## Philosophy - -This client is neither tested nor designed to be used in heavy load environments. It was designed and developed by me as a client library for my [phpMemAdmin](https://github.com/clickalicious/phpMemAdmin "phpMemAdmin on github") project. So I was able to remove dependencies of both `Memcache` + `Memcached` (PECL) extensions - both are designed in a way i don't like. I've tried to align 100% with the Memcached protocol specification. In some cases I didn't liked the naming convention and so I created some proxies. As an example - I decided to implement increment() as proxy to incr() and decrement() as proxy to decr(). I will add some more responsibilities in some more classes like a [PSR compatible](https://github.com/php-fig/fig-standards/blob/master/proposed/cache.md "PSR Cache proposal") Caching proxy and a Pool/Cluster Class for management operations soon. - - -## Versioning - -For a consistent versioning i decided to make use of `Semantic Versioning 2.0.0` http://semver.org. Its easy to understand, very common and known from many other software projects. - - -## Roadmap - -- [x] Target stable release `1.0.0` -- [x] `>= 90%` test coverage -- [ ] Security check through 3rd-Party (Please get in contact with me) - -[![Throughput Graph](https://graphs.waffle.io/clickalicious/Memcached.php/throughput.svg)](https://waffle.io/clickalicious/Memcached.php/metrics) - - -## Installation - -The recommended way to install this library is through [Composer](http://getcomposer.org/). Require the `clickalicious/memcached.php` package into your `composer.json` file: - -```json -{ - "require": { - "clickalicious/memcached.php": "~0.1" - } -} -``` - -**Memcached.php** is also available as [download from github packed as zip-file](https://github.com/clickalicious/Memcached.php/archive/master.zip "zip package containing library for download") or via `git clone https://github.com/clickalicious/Memcached.php.git .` - - -## Data +### Data `Strings`, `Integers` and `Float-Values` are never modified by this library in any way. Those types will be stored by `Memcached`'s internal system - while all other types will be serialized by this client and can optionally be stored compressed (*LZW*/*Smaz*) - in one of the next releases of this library - targeting 0.4.0. I'm working on an PoC implementation of `Smaz - a short string compression library` (https://github.com/zhenhao/smaz.php) and on a german translation of the translation table used by `Smaz`. -## Metadata +### Metadata `Memcached` provides a 32 Bit (Version > 1.2.1) unsigned Integer field for meta data. From the `Memcached` protocol specification: > Note that in memcached 1.2.1 and higher, flags may be 32-bits, instead of 16, but you might want to restrict yourself to 16 bits for compatibility with older versions. -**Memcached.php** uses this field for its meta data. The meta data is required to mark data for serialization and stuff like this. This meta data is stored via the clients` flags field. The lower first **8 Bits** (*lowest Byte*) are reserved by **Memcached.php**. The other 8 Bits (half of the 16 Bits) can be used by your app. - - -## Documentation - -The best and currently only existing documentation is the inline documentation of this project. So please have a look at the source to understand how **Memcached.php** works internally. - +**memcached-php** uses this field for its meta data. The meta data is required to mark data for serialization and stuff like this. This meta data is stored via the clients` flags field. The lower first **8 Bits** (*lowest Byte*) are reserved by **memcached-php**. The other 8 Bits (half of the 16 Bits) can be used by your app. -## Tests -**Memcached.php** is unit-tested and the code coverage is high. For an in-detail view have a look at this always up to date [Code Coverage report](http://clickalicious.github.io/Memcached.php/dashboard.html "Code Coverage"). +## Requirements -Running the Tests -You will find a PHPUnit configuration including testsuites in directory `tests/`. To run those configuration execute the following command on `cli`: + - `PHP >= 5.6` (compatible up to version `7.2` as well as `HHVM`) -```sh -phpunit -c tests/phpunit.xml --testdox -``` +## Philosophy -### Tests -The unit-tests are fired against an existing and real `Memcached` daemon. Please be aware that you need a running `Memcached` deamon on the host you run the unit-tests listening on the default port (11211). In Result the unit-tests are not that isolated cause they are bound to a running `Memcached` daemon and network as well. +This client is neither tested nor designed to be used in heavy load environments. It was designed and developed by me as a client library for my [phpMemAdmin](https://github.com/clickalicious/phpMemAdmin "phpMemAdmin on github") project. So I was able to remove dependencies of both `Memcache` + `Memcached` (PECL) extensions - both are designed in a way I don't like. I've tried to align 100% with the Memcached protocol specification. In some cases I didn't liked the naming convention and so I created some proxies. As an example - I decided to implement increment() as proxy to incr() and decrement() as proxy to decr(). I will add some more responsibilities in some more classes like a [PSR compatible](https://github.com/php-fig/fig-standards/blob/master/proposed/cache.md "PSR Cache proposal") Caching proxy and a Pool/Cluster Class for management operations soon. ## Versioning -For a consistent versioning i decided to make use of `Semantic Versioning 2.0.0` http://semver.org. Its easy to understand, very common and known from many other software projects. + +For a consistent versioning I decided to make use of `Semantic Versioning 2.0.0` http://semver.org. Its easy to understand, very common and known from many other software projects. ## Roadmap - - [ ] Hardening code - more stability! - - [ ] `\Clickalicious\Memcached\Proxy` - This should become a proxy implementation which is able to act as `Memcache` or `Memcached` (both PECL) extension (emulate) for testing (primary mocking/stubbing). - - [ ] `\Clickalicious\Memcached\Server` - This should become a virtual (emulated) mode which emulates a complete `Memcached` backend. - - [ ] Add compression support to be able to manipulate PECL Memcached stored data (FastLZ, zlib, LZW) - - [ ] Replace explodes and array operations for data anlysis with regular expressions. - - [ ] Increase coverage and cover (currently unused compression classes) more parts. +- [ ] `\Clickalicious\Memcached\Proxy` + This should become a proxy implementation which is able to act as `Memcache` or `Memcached` (both PECL) extension (emulate) for testing (primary mocking/stubbing). +- [ ] `\Clickalicious\Memcached\Server` + This should become a virtual (emulated) mode which emulates a complete `Memcached` backend. +- [ ] Add compression support to be able to manipulate PECL Memcached stored data (FastLZ, zlib, LZW) +- [ ] Replace explodes and array operations for data anlysis with regular expressions. +- [ ] Increase coverage and cover (currently unused compression classes) more parts. -If you are interested in any of these features too - please let me know. Maybe we can adjust the priority and speed things up ... +[![Throughput Graph](https://graphs.waffle.io/clickalicious/memcached-php/throughput.svg)](https://waffle.io/clickalicious/memcached-php/metrics) ## Participate & share ... yeah. If you're a code monkey too - maybe we can build a force ;) If you would like to participate in either **Code**, **Comments**, **Documentation**, **Wiki**, **Bug-Reports**, **Unit-Tests**, **Bug-Fixes**, **Feedback** and/or **Critic** then please let me know as well! - + @@ -181,4 +131,4 @@ Thanks to our sponsors and supporters: ###### Copyright -Icons made by Freepik licensed by CC 3.0 BY +
Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY
\ No newline at end of file diff --git a/composer.json b/composer.json index e3f1607..f404e8f 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "clickalicious/memcached.php", - "description": "Memcached.php - Plain vanilla PHP Memcached client with full support of Memcached protocol.", + "name": "clickalicious/memcached-php", + "description": "Memcached client library in plain vanilla PHP.", "type": "library", "authors": [ { @@ -10,22 +10,29 @@ "role": "Lead" } ], - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": ">=5.4.0", - "gpupo/cache": "^1.2" + "php": ">=5.6.0", + "roave/security-advisories": "dev-master as 1.0.x-dev", + "gpupo/cache": "dev-master as 1.3.x-dev" }, "require-dev": { - "satooshi/php-coveralls": "^1.0", - "phpunit/phpunit": "^4.8" + "phpunit/phpunit": "^5.7", + "codacy/coverage": "^1.0.5", + "symfony/var-dumper": "^3.2" }, "autoload": { - "psr-4": { - "Clickalicious\\": "src/Clickalicious/" - } + "psr-4": { + "Clickalicious\\Memcached\\Php\\": "src/" + }, + "files": ["src/Util.php"] + }, + "autoload-dev": { + "psr-4": { + "Clickalicious\\Memcached\\Php\\": "tests/" + } }, - "include-path": ["src/"], "keywords": [ "Memcached", "Client", @@ -35,12 +42,13 @@ "inmemory", "nosql" ], - "homepage": "https://github.com/clickalicious/Memcached.php", - "license": "BSD-3-Clause", + "homepage": "https://github.com/clickalicious/memcached-php", + "license": "MIT", "support": { "email": "opensource@clickalicious.de", - "issues": "https://github.com/clickalicious/Memcached.php/issues", - "wiki": "https://github.com/clickalicious/Memcached.php/wiki" + "issues": "https://github.com/clickalicious/memcached-php/issues", + "wiki": "https://github.com/clickalicious/memcached-php/wiki", + "tests": "https://clickalicious.github.io/memcached-php" }, "config" : { "bin-dir" : "bin", diff --git a/demo/Client.php b/demo/Client.php new file mode 100644 index 0000000..c8818cd --- /dev/null +++ b/demo/Client.php @@ -0,0 +1,54 @@ +set($dummy, 1); + $memcached->increment($dummy, 2); + $memcached->increment($dummy, 2); + $memcached->increment($dummy, 2); + $memcached->decrement($dummy, 3); + $memcached->increment($dummy, 1); + + $result = $memcached->get($dummy); + + $memcached->delete($dummy); +} catch (Exception $e) { + $result = $e->getMessage(); +} + +echo sprintf('Result = "%s" (should be "5")', $result).PHP_EOL; diff --git a/docs/coverage/.gitkeep b/docs/coverage/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/docs/info.txt b/docs/info.txt new file mode 100644 index 0000000..bcf9485 --- /dev/null +++ b/docs/info.txt @@ -0,0 +1,3 @@ +url: http://www.flaticon.com/free-icon/data-storage_359133 +color: #66B0A0 +author:
Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY
\ No newline at end of file diff --git a/docs/logo-128x128.png b/docs/logo-128x128.png new file mode 100644 index 0000000..1b69172 Binary files /dev/null and b/docs/logo-128x128.png differ diff --git a/docs/logo-16x16.png b/docs/logo-16x16.png new file mode 100644 index 0000000..92e1c5e Binary files /dev/null and b/docs/logo-16x16.png differ diff --git a/docs/logo-24x24.png b/docs/logo-24x24.png new file mode 100644 index 0000000..cc984e7 Binary files /dev/null and b/docs/logo-24x24.png differ diff --git a/docs/logo-256x256.png b/docs/logo-256x256.png new file mode 100644 index 0000000..30d9399 Binary files /dev/null and b/docs/logo-256x256.png differ diff --git a/docs/logo-32x32.png b/docs/logo-32x32.png new file mode 100644 index 0000000..225eb6a Binary files /dev/null and b/docs/logo-32x32.png differ diff --git a/docs/logo-512x512.png b/docs/logo-512x512.png new file mode 100644 index 0000000..2f89deb Binary files /dev/null and b/docs/logo-512x512.png differ diff --git a/docs/logo-64x64.png b/docs/logo-64x64.png new file mode 100644 index 0000000..bf1604e Binary files /dev/null and b/docs/logo-64x64.png differ diff --git a/docs/logo-large.png b/docs/logo-large.png index dde9cb2..30d9399 100644 Binary files a/docs/logo-large.png and b/docs/logo-large.png differ diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..8f7080b --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,25 @@ + + + + + + ./tests + + + + + + ./src + + ./bin + ./build + ./docs + ./vendor + ./tests + ./demo + + + + diff --git a/src/Clickalicious/Memcached/Autoloader.php b/src/Clickalicious/Memcached/Autoloader.php deleted file mode 100644 index d7d003d..0000000 --- a/src/Clickalicious/Memcached/Autoloader.php +++ /dev/null @@ -1,211 +0,0 @@ - - * @copyright 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ - -/** - * Memcached.php - * - * Autoloader.php - Autoloader of Memcached.php. - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Autoloader - * @author Benjamin Carl - * @copyright 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ -class Autoloader -{ - /** - * An associative array where the key is a namespace prefix and the value - * is an array of base directories for classes in that namespace. - * - * @var array - */ - protected $prefixes = array(); - - /** - * Register loader with SPL autoloader stack. - * - * @return void - */ - public function register() - { - spl_autoload_register(array($this, 'loadClass')); - } - - /** - * Adds a base directory for a namespace prefix. - * - * @param string $prefix The namespace prefix. - * @param string $base_dir A base directory for class files in the - * namespace. - * @param bool $prepend If true, prepend the base directory to the stack - * instead of appending it; this causes it to be searched first rather - * than last. - * @return void - */ - public function addNamespace($prefix, $base_dir, $prepend = false) - { - // normalize namespace prefix - $prefix = trim($prefix, '\\') . '\\'; - - // normalize the base directory with a trailing separator - $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - - // initialize the namespace prefix array - if (isset($this->prefixes[$prefix]) === false) { - $this->prefixes[$prefix] = array(); - } - - // retain the base directory for the namespace prefix - if ($prepend === true) { - array_unshift($this->prefixes[$prefix], $base_dir); - } else { - array_push($this->prefixes[$prefix], $base_dir); - } - } - - /** - * Loads the class file for a given class name. - * - * @param string $class The fully-qualified class name. - * @return mixed The mapped file name on success, or boolean false on - * failure. - */ - public function loadClass($class) - { - // the current namespace prefix - $prefix = $class; - - // work backwards through the namespace names of the fully-qualified - // class name to find a mapped file name - while (false !== $pos = strrpos($prefix, '\\')) { - - // retain the trailing namespace separator in the prefix - $prefix = substr($class, 0, $pos + 1); - - // the rest is the relative class name - $relative_class = substr($class, $pos + 1); - - // try to load a mapped file for the prefix and relative class - $mapped_file = $this->loadMappedFile($prefix, $relative_class); - - if ($mapped_file !== false) { - return $mapped_file; - } - - // remove the trailing namespace separator for the next iteration - // of strrpos() - $prefix = rtrim($prefix, '\\'); - } - - // never found a mapped file - return false; - } - - /** - * Load the mapped file for a namespace prefix and relative class. - * - * @param string $prefix The namespace prefix. - * @param string $relative_class The relative class name. - * - * @return mixed Boolean false if no mapped file can be loaded, or the name of the mapped file that was loaded. - */ - protected function loadMappedFile($prefix, $relative_class) - { - // are there any base directories for this namespace prefix? - if (isset($this->prefixes[$prefix]) === false) { - return false; - } - - // look through base directories for this namespace prefix - foreach ($this->prefixes[$prefix] as $base_dir) { - - // replace the namespace prefix with the base directory, - // replace namespace separators with directory separators - // in the relative class name, append with .php - $file = $base_dir - . str_replace('\\', '/', $relative_class) - . '.php'; - - // if the mapped file exists, require it - if ($this->requireFile($file)) { - // yes, we're done - return $file; - } - } - - // never found it - return false; - } - - /** - * If a file exists, require it from the file system. - * - * @param string $file The file to require. - * @return bool True if the file exists, false if not. - */ - protected function requireFile($file) - { - if (file_exists($file)) { - require $file; - return true; - } - return false; - } -} diff --git a/src/Clickalicious/Memcached/Bootstrap.php b/src/Clickalicious/Memcached/Bootstrap.php deleted file mode 100644 index 666f395..0000000 --- a/src/Clickalicious/Memcached/Bootstrap.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ - -// Include autoloader -require_once 'Autoloader.php'; - -/** - * Detects composer in global scope - * - * @author Benjamin Carl - * @return bool TRUE if composer is active, otherwise FALSE - * @access public - */ -function composer_running() -{ - $result = false; - $classes = get_declared_classes(); - natsort($classes); - foreach ($classes as $class) { - if (stristr($class, 'ComposerAutoloaderInit')) { - $result = true; - break; - } - } - - return $result; -} - - -// The base path to /src/ if we don't have Composer we need to know root path -define( - 'CLICKALICIOUS_MEMCACHED_BASE_PATH', - realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR) . - DIRECTORY_SEPARATOR -); - -// Root node -$root = realpath(CLICKALICIOUS_MEMCACHED_BASE_PATH . '../'); - -// Check for composer existence -if (true === $composerExist = $composerRunning = file_exists($root . '/vendor/autoload.php')) { - include_once $root . '/vendor/autoload.php'; - -} else { - $composerExist = $composerRunning = composer_running(); -} - -// No need to double detect and so on ... -define( - 'CLICKALICIOUS_MEMCACHED_COMPOSER_EXISTS', - $composerExist -); - -define( - 'CLICKALICIOUS_MEMCACHED_COMPOSER_RUNNING', - $composerRunning -); - -// Force reporting of all errors ... -error_reporting(-1); - -// Init autoloading -$loader = new Autoloader(); - -// register the autoloader -$loader->register(); - -// register the base directories for the namespace prefix -$loader->addNamespace('Clickalicious\Memcached', CLICKALICIOUS_MEMCACHED_BASE_PATH . 'Clickalicious\Memcached'); diff --git a/src/Clickalicious/Memcached/Cache.php b/src/Clickalicious/Memcached/Cache.php deleted file mode 100644 index 1b3768e..0000000 --- a/src/Clickalicious/Memcached/Cache.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ - -use Psr\Cache\CacheItemInterface; - -/** - * Memcached.php - * - * PSR compatbile Cache-Client() based on Client() - Plain vanilla PHP Memcached client with full - * support of Memcached protocol. - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Cache - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ -class Cache extends Client implements CacheItemInterface -{ - /** - * Returns the key for the current cache item. - * - * The key is loaded by the Implementing Library, but should be available to - * the higher level callers when needed. - * - * @return string - * The key string for this cache item. - */ - public function getKey() - { - - } - - /** - * Confirms if the cache item lookup resulted in a cache hit. - * - * Note: This method MUST NOT have a race condition between calling isHit() - * and calling get(). - * - * @return boolean - * True if the request resulted in a cache hit. False otherwise. - */ - public function isHit() - { - - } - - /** - * Confirms if the cache item exists in the cache. - * - * Note: This method MAY avoid retrieving the cached value for performance - * reasons, which could result in a race condition between exists() and get(). - * To avoid that potential race condition use isHit() instead. - * - * @return boolean - * True if item exists in the cache, false otherwise. - */ - public function exists() - { - - } - - /** - * Sets the expiration for this cache item. - * - * @param int|\DateTime $ttl - * - If an integer is passed, it is interpreted as the number of seconds - * after which the item MUST be considered expired. - * - If a DateTime object is passed, it is interpreted as the point in - * time after which the item MUST be considered expired. - * - If null is passed, a default value MAY be used. If none is set, - * the value should be stored permanently or for as long as the - * implementation allows. - * - * @return static - * The called object. - */ - public function setExpiration($ttl = null) - { - - } - - /** - * Returns the expiration time of a not-yet-expired cache item. - * - * If this cache item is a Cache Miss, this method MAY return the time at - * which the item expired or the current time if that is not available. - * - * @return \DateTime - * The timestamp at which this cache item will expire. - */ - public function getExpiration() - { - - } -} diff --git a/src/Clickalicious/Memcached/Compression/CompressionInterface.php b/src/Clickalicious/Memcached/Compression/CompressionInterface.php deleted file mode 100644 index 90e299c..0000000 --- a/src/Clickalicious/Memcached/Compression/CompressionInterface.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch - */ - -/** - * Memcached.php - * - * Compression interface. - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Compression - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch - */ -interface CompressionInterface -{ - /** - * Compresses a buffer. - * - * @param string $buffer The buffer to compress - * - * @author Benjamin Carl - * @return string The compressed input - * @access protected - */ - public function compress($buffer); - - /** - * Decompresses a buffer. - * - * @param string $buffer The buffer to decompress - * - * @author Benjamin Carl - * @return string The decompressed input - * @access protected - */ - public function decompress($buffer); -} diff --git a/src/Clickalicious/Memcached/Compression/Smaz.php b/src/Clickalicious/Memcached/Compression/Smaz.php deleted file mode 100644 index 76e14dd..0000000 --- a/src/Clickalicious/Memcached/Compression/Smaz.php +++ /dev/null @@ -1,271 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see https://github.com/zhenhao/smaz.php - */ - -use Clickalicious\Memcached\Compression\CompressionInterface; - -/** - * Memcached.php - * - * SMAZ - compression for very small strings - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Compression - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see https://github.com/zhenhao/smaz.php - */ -class Smaz implements CompressionInterface -{ - /** - * The encode book. - * - * @var array|null - * @access private - * @static - */ - private static $encodeBook; - - /** - * The decode book. - * - * @var array - * @access private - * @static - */ - private static $decodeBook = array( - " ", "the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th", - " t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an", - "er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at", - " ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en", - " ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ", - "w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his", - "st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ", - "b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"", - "hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ", - "ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p", - "es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la", - "h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o", - "ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere", - " co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e", - "s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no", - "ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr", - "ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ", - "pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z", - "fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad", - " we", "ly", "ee", " n", "id", " cl", "ac", "il", " - * @return string The compressed input - * @access protected - */ - public function compress($buffer) - { - $inLen = strlen($buffer); - $inIdx = 0; - $encodeBook = $this->getEncodeBook(); - $output = ''; - $verbatim = ''; - - while ($inIdx < $inLen) { - $encode = false; - - for ($j = min(7, $inLen - $inIdx); $j > 0; --$j) { - $code = isset($encodeBook[substr($buffer, $inIdx, $j)]) ? - $encodeBook[substr($buffer, $inIdx, $j)] : null; - - if($code !== null) { - if(strlen($verbatim)) { - $output .= $this->flushVerbatim($verbatim); - $verbatim = ''; - } - - $output .= chr($code); - $inIdx += $j; - $encode = true; - - break; - } - } - - if(!$encode) { - $verbatim .= $buffer[$inIdx]; - $inIdx++; - - if(strlen($verbatim) == 255) { - $output .= $this->flushVerbatim($verbatim); - $verbatim = ''; - } - } - } - - if(strlen($verbatim)) { - $output .= $this->flushVerbatim($verbatim); - } - - return $output; - } - - /** - * Decompresses a buffer. - * - * @param string $buffer The buffer to decompress - * - * @author Benjamin Carl - * @return string The decompressed input - * @access protected - */ - public function decompress($buffer) - { - $decodeBook = $this->getDecodeBook(); - $output = ''; - $i = 0; - - while ($i < strlen($buffer)) { - $code = ord($buffer[$i]); - - if ($code == 254) { - $output .= $buffer[$i + 1]; - $i += 2; - - } else if($code == 255) { - $len = ord($buffer[$i + 1]); - $output .= substr($buffer, $i + 2, $len); - $i += 2 + $len; - - } else { - $output .= $decodeBook[$code]; - $i++; - } - } - - return $output; - } - - /** - * Flushes ... - * - * @param $verbatim - * @return string - */ - protected function flushVerbatim($verbatim) - { - $output = ''; - - if (!strlen($verbatim)) { - return $output; - } - - if (strlen($verbatim) > 1) { - $output .= chr(255); - $output .= chr(strlen($verbatim)); - - } else { - $output .= chr(254); - } - - $output .= $verbatim; - - return $output; - } - - /** - * Returns the book used to encode. - * - * @author Benjamin Carl - * @return array The encode book - * @access protected - */ - protected function getEncodeBook() - { - if (self::$encodeBook === null) { - self::$encodeBook = array_flip(self::$decodeBook); - } - - return self::$encodeBook; - } - - /** - * Returns the book used to decode. - * - * @author Benjamin Carl - * @return array The decode book - * @access protected - */ - protected function getDecodeBook() - { - return self::$decodeBook; - } -} diff --git a/src/Clickalicious/Memcached/Compression/Zlib.php b/src/Clickalicious/Memcached/Compression/Zlib.php deleted file mode 100644 index 92bf858..0000000 --- a/src/Clickalicious/Memcached/Compression/Zlib.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see - - */ - -use Clickalicious\Memcached\Compression\CompressionInterface; - -/** - * Memcached.php - * - * ZLIB-compression. - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Compression - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see - - */ -class Zlib implements CompressionInterface -{ - /** - * Compresses a buffer. - * - * @param string $buffer The buffer to compress - * - * @author Benjamin Carl - * @return string The compressed input - * @access protected - */ - public function compress($buffer) - { - return gzcompress($buffer); - } - - /** - * Decompresses a buffer. - * - * @param string $buffer The buffer to decompress - * - * @author Benjamin Carl - * @return string The decompressed input - * @access protected - */ - public function decompress($buffer) - { - return gzuncompress($buffer); - } -} diff --git a/src/Clickalicious/Memcached/Exception.php b/src/Clickalicious/Memcached/Exception.php deleted file mode 100644 index 2911b35..0000000 --- a/src/Clickalicious/Memcached/Exception.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ - -/** - * Memcached.php - * - * Exception of Memcached.php package. - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Exception - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ -class Exception extends \Exception -{ - // Namespace -} diff --git a/src/Clickalicious/Memcached/Client.php b/src/Client.php similarity index 73% rename from src/Clickalicious/Memcached/Client.php rename to src/Client.php index 150b6c1..206bacb 100644 --- a/src/Clickalicious/Memcached/Client.php +++ b/src/Client.php @@ -1,74 +1,36 @@ - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ -use Clickalicious\Memcached\Exception; +namespace Clickalicious\Memcached\Php; /** - * Memcached.php - * - * Plain vanilla PHP Memcached client with full support of Memcached protocol. + * Class Client. * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Client - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php + * @author Benjamin Carl */ class Client { @@ -76,7 +38,6 @@ class Client * The persistent ID of the instance for sharing connections via static! * * @var string - * @access protected */ protected $persistentId; @@ -84,7 +45,6 @@ class Client * The Memcached daemons host. * * @var string - * @access protected */ protected $host; @@ -92,23 +52,20 @@ class Client * The Memcached daemons port. * * @var string - * @access protected */ protected $port; /** - * The timeout for connecting in seconds + * The timeout for connecting in seconds. * * @var int - * @access protected */ protected $timeout; /** - * Weather compression enabled + * Weather compression enabled. * * @var bool - * @access protected */ protected $compression; @@ -116,23 +73,20 @@ class Client * The default compressor used. * * @var string - * @access protected */ protected $compressor = self::DEFAULT_COMPRESSOR; /** - * All open connections + * All open connections. * * @var array - * @access protected */ protected static $connections = array(); /** - * Last result + * Last result. * * @var int - * @access protected */ protected $lastResponse = 0; @@ -140,7 +94,6 @@ class Client * Signals for transfer ended. Send as terminator by Memcached instance. * * @var array - * @access protected */ protected $sigsEnd = array( self::RESPONSE_END, @@ -159,7 +112,6 @@ class Client * A VALUE intro - used to detect VALUES response of get() & gets(). * * @var string - * @access public * @const */ const RESPONSE_VALUE = 'VALUE'; @@ -168,7 +120,6 @@ class Client * A STAT intro - used to detect STAT response of . * * @var string - * @access public * @const */ const RESPONSE_STAT = 'STAT'; @@ -177,106 +128,94 @@ class Client * A STAT VALUE intro - used to detect STAT VALUE response of . * * @var string - * @access public * @const */ const RESPONSE_ITEM = 'ITEM'; /** - * Response END + * Response END. * * @var string - * @access public * @const */ const RESPONSE_END = 'END'; /** - * Response DELETED + * Response DELETED. * * @var string - * @access public * @const */ const RESPONSE_DELETED = 'DELETED'; /** - * Response NOT_FOUND + * Response NOT_FOUND. * * @var string - * @access public * @const */ const RESPONSE_NOT_FOUND = 'NOT_FOUND'; /** - * Response OK + * Response OK. * * @var string - * @access public * @const */ const RESPONSE_OK = 'OK'; /** - * Response EXISTS + * Response EXISTS. * * @var string - * @access public * @const */ const RESPONSE_EXISTS = 'EXISTS'; /** - * Response ERROR + * Response ERROR. * * @var string - * @access public * @const */ const RESPONSE_ERROR = 'ERROR'; /** - * Response RESET + * Response RESET. * * @var string - * @access public * @const */ const RESPONSE_RESET = 'RESET'; /** - * Response STORED + * Response STORED. * * @var string - * @access public * @const */ const RESPONSE_STORED = 'STORED'; /** - * Response NOT_STORED + * Response NOT_STORED. * * @var string - * @access public * @const */ const RESPONSE_NOT_STORED = 'NOT_STORED'; /** - * Response VERSION + * Response VERSION. * * @var string - * @access public * @const */ const RESPONSE_VERSION = 'VERSION'; /** - * Response CLIENT_ERROR + * Response CLIENT_ERROR. * * @var string - * @access public * @const */ const RESPONSE_CLIENT_ERROR = 'CLIENT_ERROR'; @@ -285,7 +224,6 @@ class Client * A collection of allowed commands which can be send to Memcached instance. * * @var array - * @access protected */ protected $allowedCommands = array( self::COMMAND_SET, @@ -310,7 +248,6 @@ class Client * The command for setting a key value pair to a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_SET = 'set'; @@ -319,7 +256,6 @@ class Client * Command for adding data to if not already exists. * * @var string - * @access public * @const */ const COMMAND_ADD = 'add'; @@ -328,7 +264,6 @@ class Client * Command for replacing a value with another one. * * @var string - * @access public * @const */ const COMMAND_REPLACE = 'replace'; @@ -337,7 +272,6 @@ class Client * Command for append data to existing data of an existing key. * * @var string - * @access public * @const */ const COMMAND_APPEND = 'append'; @@ -346,7 +280,6 @@ class Client * Command for prepend data to existing data of an existing key. * * @var string - * @access public * @const */ const COMMAND_PREPEND = 'prepend'; @@ -355,7 +288,6 @@ class Client * Command for cas. * * @var string - * @access public * @const */ const COMMAND_CAS = 'cas'; @@ -364,7 +296,6 @@ class Client * Command for incr. * * @var string - * @access public * @const */ const COMMAND_INCR = 'incr'; @@ -373,7 +304,6 @@ class Client * Command for decr. * * @var string - * @access public * @const */ const COMMAND_DECR = 'decr'; @@ -382,7 +312,6 @@ class Client * Command for retrieving a key and its value from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_GET = 'get'; @@ -391,7 +320,6 @@ class Client * Command for retrieving multiple keys and the values from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_GETS = 'gets'; @@ -400,7 +328,6 @@ class Client * The command for deleting a key value pair from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_DELETE = 'delete'; @@ -409,7 +336,6 @@ class Client * The command for touching a key value pair from a Memcached instance to change expiration time. * * @var string - * @access public * @const */ const COMMAND_TOUCH = 'touch'; @@ -418,7 +344,6 @@ class Client * The command for retrieving the version from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_VERSION = 'version'; @@ -427,7 +352,6 @@ class Client * The command for retrieving the stats from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_STATS = 'stats'; @@ -436,7 +360,6 @@ class Client * The command for flushing all keys from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_FLUSH_ALL = 'flush_all'; @@ -445,7 +368,6 @@ class Client * The command which will fail for unit testing. * * @var string - * @access public * @const */ const COMMAND_PHPUNIT = 'phpunit'; @@ -454,7 +376,6 @@ class Client * The command for retrieving the stats settings from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_STATS_SETTINGS = 'settings'; @@ -463,7 +384,6 @@ class Client * The command for retrieving the stats items from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_STATS_ITEMS = 'items'; @@ -472,7 +392,6 @@ class Client * The command for retrieving the stats slabs from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_STATS_SLABS = 'slabs'; @@ -481,7 +400,6 @@ class Client * The command for retrieving the stats reset from a Memcached instance. * * @var string - * @access public * @const */ const COMMAND_STATS_RESET = 'reset'; @@ -490,7 +408,6 @@ class Client * Command for retrieving stats sizes. * * @var string - * @access public * @const */ const COMMAND_STATS_SIZES = 'sizes'; @@ -499,7 +416,6 @@ class Client * Command for retrieving stats conns. * * @var string - * @access public * @const */ const COMMAND_STATS_CONNS = 'conns'; @@ -508,7 +424,6 @@ class Client * Command for retrieving stats cachedump. * * @var string - * @access public * @const */ const COMMAND_STATS_CACHEDUMP = 'cachedump'; @@ -517,7 +432,6 @@ class Client * The settings stats type. * * @var string - * @access public * @const */ const STATS_TYPE_SETTINGS = self::COMMAND_STATS_SETTINGS; @@ -526,7 +440,6 @@ class Client * The items stats type. * * @var string - * @access public * @const */ const STATS_TYPE_ITEMS = self::COMMAND_STATS_ITEMS; @@ -535,7 +448,6 @@ class Client * The slabs stats type. * * @var string - * @access public * @const */ const STATS_TYPE_SLABS = self::COMMAND_STATS_SLABS; @@ -544,7 +456,6 @@ class Client * The reset stats type. * * @var string - * @access public * @const */ const STATS_TYPE_RESET = self::COMMAND_STATS_RESET; @@ -553,7 +464,6 @@ class Client * The conns stats type. * * @var string - * @access public * @const */ const STATS_TYPE_CONNS = self::COMMAND_STATS_CONNS; @@ -562,7 +472,6 @@ class Client * The cachedump stats type. * * @var string - * @access public * @const */ const STATS_TYPE_CACHEDUMP = self::COMMAND_STATS_CACHEDUMP; @@ -571,7 +480,6 @@ class Client * The sizes stats type. * * @var string - * @access public * @const */ const STATS_TYPE_SIZES = self::COMMAND_STATS_SIZES; @@ -580,7 +488,6 @@ class Client * Number of bytes fetched in one cycle from socket. * * @var int - * @access public * @const */ const SOCKET_READ_FETCH_BYTES = 256; @@ -589,7 +496,6 @@ class Client * Maximum items to fetch if not overridden. * * @var int - * @access public * @const */ const CACHEDUMP_ITEMS_MAX = PHP_INT_MAX; @@ -598,7 +504,6 @@ class Client * The default compressor. * * @var string - * @access public * @const */ const DEFAULT_COMPRESSOR = 'SMAZ'; @@ -607,7 +512,6 @@ class Client * The default port of a host added. * * @var int - * @access public * @const */ const DEFAULT_PORT = 11211; @@ -616,7 +520,6 @@ class Client * The default timeout when connecting to instance. * * @var null - * @access public * @const */ const DEFAULT_TIMEOUT = null; @@ -625,16 +528,14 @@ class Client * The separator for building commandline for Memcached instance. * * @var string - * @access public * @const */ - const COMMAND_SEPARATOR = ' '; + const COMMAND_SEPARATOR = ' '; /** * The terminator used to terminate a commandline send to Memcached instance. * * @var string - * @access public * @const */ const COMMAND_TERMINATOR = "\r\n"; @@ -643,7 +544,6 @@ class Client * The default and generic Memcached error. * * @var string - * @access public * @const */ const ERROR = 'ERROR'; @@ -652,7 +552,6 @@ class Client * The Memcached error for client error. * * @var string - * @access public * @const */ const ERROR_CLIENT = 'CLIENT_ERROR'; @@ -661,7 +560,6 @@ class Client * The Memcached error for server error. * * @var string - * @access public * @const */ const ERROR_SERVER = 'SERVER_ERROR'; @@ -670,102 +568,153 @@ class Client * The default bitmask to detect serialization support. * * @var int - * @access public * @const */ const FLAG_DEFAULT = 4; /** - * Flags for PHP types + * Flags for PHP types. * * (Memcached PHP extension compatible) - * @access public + * * @const */ - const FLAG_DECIMAL_STRING = 0; // PHP Type "string" Mask - Decimal: 0 - Bit(s): 0 - const FLAG_DECIMAL_INTEGER = 1; // PHP Type "integer" Mask - Decimal: 1 - Bit(s): 1 - const FLAG_DECIMAL_FLOAT = 2; // PHP Type "float" Mask - Decimal: 2 - Bit(s): 2 - const FLAG_DECIMAL_BOOLEAN = 3; // PHP Type "boolean" Mask - Decimal: 3 - Bit(s): 1 & 2 + const FLAG_DECIMAL_STRING = 0; // PHP Type "string" Mask - Decimal: 0 - Bit(s): 0 + + const FLAG_DECIMAL_INTEGER = 1; // PHP Type "integer" Mask - Decimal: 1 - Bit(s): 1 + + const FLAG_DECIMAL_FLOAT = 2; // PHP Type "float" Mask - Decimal: 2 - Bit(s): 2 + + const FLAG_DECIMAL_BOOLEAN = 3; // PHP Type "boolean" Mask - Decimal: 3 - Bit(s): 1 & 2 + const FLAG_DECIMAL_SERIALIZED = 4; // PHP Type "object" || "array" Mask - Decimal: 4 - Bit(s): 4 /** - * Memcached Constant Values + * Memcached Constant Values. */ - const MEMCACHED_SUCCESS = 0; - const MEMCACHED_FAILURE = 1; - const MEMCACHED_HOST_LOOKUP_FAILURE = 2; - const MEMCACHED_CONNECTION_FAILURE = 3; - const MEMCACHED_CONNECTION_BIND_FAILURE = 4; - const MEMCACHED_WRITE_FAILURE = 5; - const MEMCACHED_READ_FAILURE = 6; - const MEMCACHED_UNKNOWN_READ_FAILURE = 7; - const MEMCACHED_PROTOCOL_ERROR = 8; - const MEMCACHED_CLIENT_ERROR = 9; - const MEMCACHED_SERVER_ERROR = 10; + const MEMCACHED_SUCCESS = 0; + + const MEMCACHED_FAILURE = 1; + + const MEMCACHED_HOST_LOOKUP_FAILURE = 2; + + const MEMCACHED_CONNECTION_FAILURE = 3; + + const MEMCACHED_CONNECTION_BIND_FAILURE = 4; + + const MEMCACHED_WRITE_FAILURE = 5; + + const MEMCACHED_READ_FAILURE = 6; + + const MEMCACHED_UNKNOWN_READ_FAILURE = 7; + + const MEMCACHED_PROTOCOL_ERROR = 8; + + const MEMCACHED_CLIENT_ERROR = 9; + + const MEMCACHED_SERVER_ERROR = 10; + const MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE = 11; - const MEMCACHED_DATA_EXISTS = 12; - const MEMCACHED_DATA_DOES_NOT_EXIST = 13; - const MEMCACHED_NOTSTORED = 14; - const MEMCACHED_STORED = 15; - const MEMCACHED_NOTFOUND = 16; - const MEMCACHED_MEMORY_ALLOCATION_FAILURE = 17; - const MEMCACHED_PARTIAL_READ = 18; - const MEMCACHED_SOME_ERRORS = 19; - const MEMCACHED_NO_SERVERS = 20; - const MEMCACHED_END = 21; - const MEMCACHED_DELETED = 22; - const MEMCACHED_VALUE = 23; - const MEMCACHED_STAT = 24; - const MEMCACHED_ITEM = 25; - const MEMCACHED_ERRNO = 26; - const MEMCACHED_FAIL_UNIX_SOCKET = 27; - const MEMCACHED_NOT_SUPPORTED = 28; - const MEMCACHED_NO_KEY_PROVIDED = 29; /* Deprecated. Use const MEMCACHED_BAD_KEY_PROVIDED! */ - const MEMCACHED_FETCH_NOTFINISHED = 30; - const MEMCACHED_TIMEOUT = 31; - const MEMCACHED_BUFFERED = 32; - const MEMCACHED_BAD_KEY_PROVIDED = 33; - const MEMCACHED_INVALID_HOST_PROTOCOL = 34; - const MEMCACHED_SERVER_MARKED_DEAD = 35; - const MEMCACHED_UNKNOWN_STAT_KEY = 36; - const MEMCACHED_E2BIG = 37; - const MEMCACHED_INVALID_ARGUMENTS = 38; - const MEMCACHED_KEY_TOO_BIG = 39; - const MEMCACHED_AUTH_PROBLEM = 40; - const MEMCACHED_AUTH_FAILURE = 41; - const MEMCACHED_AUTH_CONTINUE = 42; - const MEMCACHED_PARSE_ERROR = 43; - const MEMCACHED_PARSE_USER_ERROR = 44; - const MEMCACHED_DEPRECATED = 45; - const MEMCACHED_IN_PROGRESS = 46; - const MEMCACHED_SERVER_TEMPORARILY_DISABLED = 47; + + const MEMCACHED_DATA_EXISTS = 12; + + const MEMCACHED_DATA_DOES_NOT_EXIST = 13; + + const MEMCACHED_NOTSTORED = 14; + + const MEMCACHED_STORED = 15; + + const MEMCACHED_NOTFOUND = 16; + + const MEMCACHED_MEMORY_ALLOCATION_FAILURE = 17; + + const MEMCACHED_PARTIAL_READ = 18; + + const MEMCACHED_SOME_ERRORS = 19; + + const MEMCACHED_NO_SERVERS = 20; + + const MEMCACHED_END = 21; + + const MEMCACHED_DELETED = 22; + + const MEMCACHED_VALUE = 23; + + const MEMCACHED_STAT = 24; + + const MEMCACHED_ITEM = 25; + + const MEMCACHED_ERRNO = 26; + + const MEMCACHED_FAIL_UNIX_SOCKET = 27; + + const MEMCACHED_NOT_SUPPORTED = 28; + + const MEMCACHED_NO_KEY_PROVIDED = 29; /* Deprecated. Use const MEMCACHED_BAD_KEY_PROVIDED! */ + const MEMCACHED_FETCH_NOTFINISHED = 30; + + const MEMCACHED_TIMEOUT = 31; + + const MEMCACHED_BUFFERED = 32; + + const MEMCACHED_BAD_KEY_PROVIDED = 33; + + const MEMCACHED_INVALID_HOST_PROTOCOL = 34; + + const MEMCACHED_SERVER_MARKED_DEAD = 35; + + const MEMCACHED_UNKNOWN_STAT_KEY = 36; + + const MEMCACHED_E2BIG = 37; + + const MEMCACHED_INVALID_ARGUMENTS = 38; + + const MEMCACHED_KEY_TOO_BIG = 39; + + const MEMCACHED_AUTH_PROBLEM = 40; + + const MEMCACHED_AUTH_FAILURE = 41; + + const MEMCACHED_AUTH_CONTINUE = 42; + + const MEMCACHED_PARSE_ERROR = 43; + + const MEMCACHED_PARSE_USER_ERROR = 44; + + const MEMCACHED_DEPRECATED = 45; + + const MEMCACHED_IN_PROGRESS = 46; + + const MEMCACHED_SERVER_TEMPORARILY_DISABLED = 47; + const MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE = 48; - const MEMCACHED_MAXIMUM_RETURN = 49; - /* Always add new error code before */ + const MEMCACHED_MAXIMUM_RETURN = 49; + + /* Always add new error code before */ /** * Constructor. * * @param string $host The host name this instance works on - * @param int $port The port to connect to. + * @param int $port the port to connect to * @param int|null $timeout The timeout for connecting in seconds * @param string $persistentId By default the Memcached instances are destroyed at the end of the request. - * To create an instance that persists between requests, use persistent_id to specify a - * unique ID for the instance. All instances created with the same persistent_id will - * share the same connection. - * @param bool $compression TRUE to enable compression (default), FALSE to disable + * To create an instance that persists between requests, use persistent_id to specify + * a unique ID for the instance. All instances created with the same persistent_id + * will share the same connection. + * @param bool $compression TRUE to enable compression (default), FALSE to disable * * @author Benjamin Carl + * * @return Client - * @access public */ public function __construct( - $host = null, - $port = self::DEFAULT_PORT, - $timeout = self::DEFAULT_TIMEOUT, + $host = null, + $port = self::DEFAULT_PORT, + $timeout = self::DEFAULT_TIMEOUT, $persistentId = null, - $compression = true + $compression = true ) { // Extract host and port from host string if ($host !== null) { @@ -799,11 +748,9 @@ public function __construct( /** * Setter for host. * - * @param string $host The host to set. + * @param string $host the host to set * * @author Benjamin Carl - * @return void - * @access public */ public function setHost($host) { @@ -813,15 +760,16 @@ public function setHost($host) /** * Setter for host. * - * @param string $host The host to set. + * @param string $host the host to set * * @author Benjamin Carl + * * @return $this Instance for chaining - * @access public */ public function host($host) { $this->setHost($host); + return $this; } @@ -829,8 +777,8 @@ public function host($host) * Getter for host. * * @author Benjamin Carl - * @return string The host if set, otherwise NULL. - * @access public + * + * @return string the host if set, otherwise NULL */ public function getHost() { @@ -840,11 +788,9 @@ public function getHost() /** * Setter for port. * - * @param string $port The port to set. + * @param string $port the port to set * * @author Benjamin Carl - * @return void - * @access public */ public function setPort($port) { @@ -854,15 +800,16 @@ public function setPort($port) /** * Setter for port. * - * @param string $port The port to set. + * @param string $port the port to set * * @author Benjamin Carl + * * @return $this Instance for chaining - * @access public */ public function port($port) { $this->setPort($port); + return $this; } @@ -870,8 +817,8 @@ public function port($port) * Getter for port. * * @author Benjamin Carl - * @return string The port if set, otherwise NULL. - * @access public + * + * @return string the port if set, otherwise NULL */ public function getPort() { @@ -884,8 +831,6 @@ public function getPort() * @param int $timeout Timeout for connecting in seconds!!! * * @author Benjamin Carl - * @return void - * @access public */ public function setTimeout($timeout) { @@ -898,12 +843,13 @@ public function setTimeout($timeout) * @param int $timeout Timeout for connecting in seconds!!! * * @author Benjamin Carl + * * @return $this Instance for chaining - * @access public */ public function timeout($timeout) { $this->setTimeout($timeout); + return $this; } @@ -911,8 +857,8 @@ public function timeout($timeout) * Getter for timeout. * * @author Benjamin Carl - * @return integer The timeout in seconds or NULL - * @access public + * + * @return int The timeout in seconds or NULL */ public function getTimeout() { @@ -927,9 +873,10 @@ public function getTimeout() * @param int|null $timeout Timeout in seconds * * @author Benjamin Carl + * * @return resource|null The resource (socket) on success, otherwise NULL - * @access public - * @throws \Clickalicious\Memcached\Exception + * + * @throws \Clickalicious\Memcached\Php\Exception */ public function connect($host, $port, $timeout = null) { @@ -977,7 +924,6 @@ public function connect($host, $port, $timeout = null) // Store for further access/use ... self::$connections[$this->getPersistentId()][$uuid] = $connection; - } else { $connection = self::$connections[$this->getPersistentId()][$uuid]; } @@ -992,9 +938,10 @@ public function connect($host, $port, $timeout = null) * @param string $data The data to pass with command * * @author Benjamin Carl + * * @return mixed|array The result from Memcached daemon - * @access public - * @throws \Clickalicious\Memcached\Exception + * + * @throws \Clickalicious\Memcached\Php\Exception */ public function send($command, $data = '') { @@ -1019,7 +966,6 @@ public function send($command, $data = '') // Fetch while receiving data ... while ((!feof($socket))) { - // Fetch Bytes from socket ... $buffer .= fgets($socket, self::SOCKET_READ_FETCH_BYTES); @@ -1029,7 +975,7 @@ public function send($command, $data = '') } foreach ($this->sigsEnd as $sigEnd) { - if (preg_match('/^' . $sigEnd . '/imu', $buffer)) { + if (preg_match('/^'.$sigEnd.'/imu', $buffer)) { break 2; } } @@ -1042,7 +988,7 @@ public function send($command, $data = '') 'Error "%s" while sending command "%s" to host "%s"', $this->getLastResponse(), $command, - $this->getHost() . ':' . $this->getPort() + $this->getHost().':'.$this->getPort() ) ); } @@ -1058,33 +1004,33 @@ public function send($command, $data = '') * @param int $expiration When to expire * * @author Benjamin Carl + * * @return string The result of operation - * @access public * @codeCoverageIgnore */ public function touch($key, $expiration) { /** - * touch [noreply]\r\n + * touch [noreply]\r\n. */ // Build packet to send ... - $data = self::COMMAND_TOUCH . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $expiration . self::COMMAND_TERMINATOR; + $data = self::COMMAND_TOUCH.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $expiration.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_TOUCH, $data); } /** - * Proxy to: incr() + * Proxy to: incr(). * - * @param string $key The key to increment - * @param int $offset How much to increment + * @param string $key The key to increment + * @param int $offset How much to increment * * @author Benjamin Carl + * * @return string The result of operation - * @access public */ public function increment($key, $offset = 1) { @@ -1095,23 +1041,23 @@ public function increment($key, $offset = 1) * Increments an existing key by offset. * Does currently not support the creation of not existing keys. * - * @param string $key The key to increment - * @param int $offset How much to increment + * @param string $key The key to increment + * @param int $offset How much to increment * * @author Benjamin Carl + * * @return string The result of operation - * @access public */ public function incr($key, $offset = 1) { /** - * incr [noreply]\r\n + * incr [noreply]\r\n. */ // Build packet to send ... - $data = self::COMMAND_INCR . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $offset . self::COMMAND_TERMINATOR; + $data = self::COMMAND_INCR.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $offset.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_INCR, $data); } @@ -1119,12 +1065,12 @@ public function incr($key, $offset = 1) /** * Proxy to: decr(). * - * @param string $key The key to decrement - * @param int $offset How much to decrement + * @param string $key The key to decrement + * @param int $offset How much to decrement * * @author Benjamin Carl + * * @return string The result of operation - * @access public */ public function decrement($key, $offset = 1) { @@ -1135,23 +1081,23 @@ public function decrement($key, $offset = 1) * Decrements an existing key by offset. * Does currently not support the creation of not existing keys. * - * @param string $key The key to decrement - * @param int $offset How much to decrement + * @param string $key The key to decrement + * @param int $offset How much to decrement * * @author Benjamin Carl + * * @return string The result of operation - * @access public */ public function decr($key, $offset = 1) { /** - * decr [noreply]\r\n + * decr [noreply]\r\n. */ // Build packet to send ... - $data = self::COMMAND_DECR . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $offset . self::COMMAND_TERMINATOR; + $data = self::COMMAND_DECR.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $offset.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_DECR, $data); } @@ -1167,14 +1113,14 @@ public function decr($key, $offset = 1) * @param int|null $bytes The length in bytes * * @author Benjamin Carl + * * @return mixed The response for command set - * @access public */ public function set($key, $value, $expiration = 0, $flags = 0, $bytes = null) { /** * set [noreply]\r\n - * \r\n + * \r\n. */ // Run through our serializer @@ -1188,12 +1134,12 @@ public function set($key, $value, $expiration = 0, $flags = 0, $bytes = null) $bytes = ($bytes !== null) ? $bytes : strlen($value); // Build packet to send ... - $data = self::COMMAND_SET . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $flags . self::COMMAND_SEPARATOR . - $expiration . self::COMMAND_SEPARATOR . - $bytes . self::COMMAND_TERMINATOR . - $value . self::COMMAND_TERMINATOR; + $data = self::COMMAND_SET.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $flags.self::COMMAND_SEPARATOR. + $expiration.self::COMMAND_SEPARATOR. + $bytes.self::COMMAND_TERMINATOR. + $value.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_SET, $data); } @@ -1210,14 +1156,14 @@ public function set($key, $value, $expiration = 0, $flags = 0, $bytes = null) * @param int|null $bytes The length in bytes * * @author Benjamin Carl + * * @return mixed The response for command add - * @access public */ public function add($key, $value, $expiration = 0, $flags = 0, $bytes = null) { /** * add [noreply]\r\n - * \r\n + * \r\n. */ // Run through our serializer @@ -1231,12 +1177,12 @@ public function add($key, $value, $expiration = 0, $flags = 0, $bytes = null) $bytes = ($bytes !== null) ? $bytes : strlen($value); // Build packet to send ... - $data = self::COMMAND_ADD . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $flags . self::COMMAND_SEPARATOR . - $expiration . self::COMMAND_SEPARATOR . - $bytes . self::COMMAND_TERMINATOR . - $value . self::COMMAND_TERMINATOR; + $data = self::COMMAND_ADD.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $flags.self::COMMAND_SEPARATOR. + $expiration.self::COMMAND_SEPARATOR. + $bytes.self::COMMAND_TERMINATOR. + $value.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_ADD, $data); } @@ -1253,14 +1199,14 @@ public function add($key, $value, $expiration = 0, $flags = 0, $bytes = null) * @param int|null $bytes The length in bytes * * @author Benjamin Carl + * * @return mixed The response for command replace - * @access public */ public function replace($key, $value, $expiration = 0, $flags = 0, $bytes = null) { /** * replace [noreply]\r\n - * \r\n + * \r\n. */ // Run through our serializer @@ -1274,12 +1220,12 @@ public function replace($key, $value, $expiration = 0, $flags = 0, $bytes = null $bytes = ($bytes !== null) ? $bytes : strlen($value); // Build packet to send ... - $data = self::COMMAND_REPLACE . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $flags . self::COMMAND_SEPARATOR . - $expiration . self::COMMAND_SEPARATOR . - $bytes . self::COMMAND_TERMINATOR . - $value . self::COMMAND_TERMINATOR; + $data = self::COMMAND_REPLACE.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $flags.self::COMMAND_SEPARATOR. + $expiration.self::COMMAND_SEPARATOR. + $bytes.self::COMMAND_TERMINATOR. + $value.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_REPLACE, $data); } @@ -1295,26 +1241,26 @@ public function replace($key, $value, $expiration = 0, $flags = 0, $bytes = null * @param int|null $bytes The length in bytes * * @author Benjamin Carl + * * @return mixed The response for command append - * @access public */ public function append($key, $value, $expiration = 0, $flags = self::FLAG_DEFAULT, $bytes = null) { /** * replace [noreply]\r\n - * \r\n + * \r\n. */ // Calculate bytes if not precalculated $bytes = ($bytes !== null) ? $bytes : strlen($value); // Build packet to send ... - $data = self::COMMAND_APPEND . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $flags . self::COMMAND_SEPARATOR . - $expiration . self::COMMAND_SEPARATOR . - $bytes . self::COMMAND_TERMINATOR . - $value . self::COMMAND_TERMINATOR; + $data = self::COMMAND_APPEND.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $flags.self::COMMAND_SEPARATOR. + $expiration.self::COMMAND_SEPARATOR. + $bytes.self::COMMAND_TERMINATOR. + $value.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_APPEND, $data); } @@ -1330,26 +1276,26 @@ public function append($key, $value, $expiration = 0, $flags = self::FLAG_DEFAUL * @param int|null $bytes The length in bytes * * @author Benjamin Carl + * * @return mixed The response for command prepend - * @access public */ public function prepend($key, $value, $expiration = 0, $flags = self::FLAG_DEFAULT, $bytes = null) { /** * replace [noreply]\r\n - * \r\n + * \r\n. */ // Calculate bytes if not precalculated $bytes = ($bytes !== null) ? $bytes : strlen($value); // Build packet to send ... - $data = self::COMMAND_PREPEND . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $flags . self::COMMAND_SEPARATOR . - $expiration . self::COMMAND_SEPARATOR . - $bytes . self::COMMAND_TERMINATOR . - $value . self::COMMAND_TERMINATOR; + $data = self::COMMAND_PREPEND.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $flags.self::COMMAND_SEPARATOR. + $expiration.self::COMMAND_SEPARATOR. + $bytes.self::COMMAND_TERMINATOR. + $value.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_PREPEND, $data); } @@ -1369,14 +1315,14 @@ public function prepend($key, $value, $expiration = 0, $flags = self::FLAG_DEFAU * @param int|null $bytes The length in bytes * * @author Benjamin Carl + * * @return mixed The response for command cas - * @access public */ public function cas($token, $key, $value, $expiration = 0, $flags = self::FLAG_DEFAULT, $bytes = null) { /** * cas [noreply]\r\n - * \r\n + * \r\n. */ // Run through our serializer @@ -1390,13 +1336,13 @@ public function cas($token, $key, $value, $expiration = 0, $flags = self::FLAG_D $bytes = ($bytes !== null) ? $bytes : strlen($value); // Build packet to send ... - $data = self::COMMAND_CAS . self::COMMAND_SEPARATOR . - $key . self::COMMAND_SEPARATOR . - $flags . self::COMMAND_SEPARATOR . - $expiration . self::COMMAND_SEPARATOR . - $bytes . self::COMMAND_SEPARATOR . - $token . self::COMMAND_TERMINATOR . - $value . self::COMMAND_TERMINATOR; + $data = self::COMMAND_CAS.self::COMMAND_SEPARATOR. + $key.self::COMMAND_SEPARATOR. + $flags.self::COMMAND_SEPARATOR. + $expiration.self::COMMAND_SEPARATOR. + $bytes.self::COMMAND_SEPARATOR. + $token.self::COMMAND_TERMINATOR. + $value.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_CAS, $data); } @@ -1404,22 +1350,22 @@ public function cas($token, $key, $value, $expiration = 0, $flags = self::FLAG_D /** * Returns the response for passed key. * - * @param string $key The key to return response for. + * @param string $key the key to return response for * @param bool $metadata TRUE to return metadata like lifetime ... as well, FALSE to return value only * * @author Benjamin Carl + * * @return mixed The response for command get - * @access public */ public function get($key, $metadata = false) { /** - * get *\r\n + * get *\r\n. */ // Build packet to send ... - $data = self::COMMAND_GET . self::COMMAND_SEPARATOR . - $key . self::COMMAND_TERMINATOR; + $data = self::COMMAND_GET.self::COMMAND_SEPARATOR. + $key.self::COMMAND_TERMINATOR; $result = $this->send(self::COMMAND_GET, $data); @@ -1435,25 +1381,25 @@ public function get($key, $metadata = false) /** * Returns the response for passed keys. * - * @param array $keys The keys to return response for. + * @param array $keys the keys to return response for * @param bool $metadata TRUE to return metadata like lifetime ... as well, FALSE to return value only * * @author Benjamin Carl + * * @return mixed The response for command get - * @access public */ public function gets(array $keys, $metadata = false) { /** - * gets *\r\n + * gets *\r\n. */ // Build key request string $keys = implode(self::COMMAND_SEPARATOR, $keys); // Build packet to send ... - $data = self::COMMAND_GETS . self::COMMAND_SEPARATOR . - $keys . self::COMMAND_TERMINATOR; + $data = self::COMMAND_GETS.self::COMMAND_SEPARATOR. + $keys.self::COMMAND_TERMINATOR; $result = $this->send(self::COMMAND_GETS, $data); @@ -1468,21 +1414,21 @@ public function gets(array $keys, $metadata = false) /** * Deletes an element/key (+ its data) from Memcached instance. * - * @param string $key The key to delete. + * @param string $key the key to delete * * @author Benjamin Carl + * * @return mixed The response for command delete - * @access public */ public function delete($key) { /** - * delete [noreply]\r\n + * delete [noreply]\r\n. */ // Build packet to send ... - $data = self::COMMAND_DELETE . self::COMMAND_SEPARATOR . - $key . self::COMMAND_TERMINATOR; + $data = self::COMMAND_DELETE.self::COMMAND_SEPARATOR. + $key.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_DELETE, $data); } @@ -1490,42 +1436,41 @@ public function delete($key) /** * Stats - sends the stats command with default or custom type to Memcached instance. * - * @param string $type The type to send to Memcached instance. - * @param string $argument1 Optional additional argument. - * @param string $argument2 Optional additional argument. + * @param string $type the type to send to Memcached instance + * @param string $argument1 optional additional argument + * @param string $argument2 optional additional argument * * @author Benjamin Carl + * * @return mixed The response for command stats - * @access public */ public function stats($type = '', $argument1 = '', $argument2 = '') { - /** + /* * stats [noreply]\r\n * [TYPES ] */ if ($type !== '') { - $type = self::COMMAND_SEPARATOR . $type; + $type = self::COMMAND_SEPARATOR.$type; } if ($argument1 !== '') { - $argument1 = self::COMMAND_SEPARATOR . $argument1; + $argument1 = self::COMMAND_SEPARATOR.$argument1; } if ($argument2 !== '') { - $argument2 = self::COMMAND_SEPARATOR . $argument2; + $argument2 = self::COMMAND_SEPARATOR.$argument2; } // Build packet to send ... - $data = self::COMMAND_STATS . $type . - $argument1 . - $argument2 . - self::COMMAND_TERMINATOR; + $data = self::COMMAND_STATS.$type. + $argument1. + $argument2. + self::COMMAND_TERMINATOR; // Generic stats requires us to fetch as long as data arrives ... if ($type === '') { - // Initial fetch ... $result = $this->send(self::COMMAND_STATS, $data); @@ -1539,21 +1484,17 @@ public function stats($type = '', $argument1 = '', $argument2 = '') $result[$key] = $value; } } - - } elseif ($type === self::COMMAND_SEPARATOR . self::STATS_TYPE_SLABS) { - + } elseif ($type === self::COMMAND_SEPARATOR.self::STATS_TYPE_SLABS) { // Initial fetch ... $result = $this->send(self::COMMAND_STATS, $data); // Now read until whole structure contains finally "active_slabs" key! while (isset($result['active_slabs']) === false) { - // Issue stat command ... $memory = $this->send(self::COMMAND_STATS, $data); // Iterate Slabs from response foreach ($memory as $key => $value) { - // Now check for slabId or meta-data key. Slab = numeric, otherwise String. if (is_numeric($key) === true) { // Slab! @@ -1562,15 +1503,12 @@ public function stats($type = '', $argument1 = '', $argument2 = '') } $result[$key] = array_merge($result[$key], $value); - } else { // Meta! $result[$key] = $value; - } } } - } else { // Issue stat command ... $result = $this->send(self::COMMAND_STATS, $data); @@ -1592,27 +1530,27 @@ public function stats($type = '', $argument1 = '', $argument2 = '') * Version - sends the version command to Memcached instance and returns the result. * * @author Benjamin Carl + * * @return mixed The response for command version - * @access public */ public function version() { /** - * version\r\n + * version\r\n. */ // Build packet to send ... - $data = self::COMMAND_VERSION . self::COMMAND_TERMINATOR; + $data = self::COMMAND_VERSION.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_VERSION, $data); } /** - * Proxy to: flush_all() + * Proxy to: flush_all(). * * @author Benjamin Carl + * * @return mixed The response for command version - * @access public */ public function flush() { @@ -1623,17 +1561,17 @@ public function flush() * Flush - sends the flush_all command to Memcached instance and returns the result. * * @author Benjamin Carl + * * @return mixed The response for command version - * @access public */ public function flush_all() { /** - * flush_all\r\n + * flush_all\r\n. */ // Build packet to send ... - $data = self::COMMAND_FLUSH_ALL . self::COMMAND_TERMINATOR; + $data = self::COMMAND_FLUSH_ALL.self::COMMAND_TERMINATOR; return $this->send(self::COMMAND_FLUSH_ALL, $data); } @@ -1648,8 +1586,6 @@ public function flush_all() * @param bool $compression TRUE or FALSE * * @author Benjamin Carl - * @return void - * @access public */ protected function setCompression($compression) { @@ -1662,12 +1598,13 @@ protected function setCompression($compression) * @param bool $compression TRUE or FALSE * * @author Benjamin Carl + * * @return $this Instance for chaining - * @access public */ protected function compression($compression) { $this->setCompression($compression); + return $this; } @@ -1675,8 +1612,8 @@ protected function compression($compression) * Getter for compression. * * @author Benjamin Carl + * * @return bool TRUE if compression is enabled, otherwise FALSE - * @access public * @codeCoverageIgnore */ protected function getCompression() @@ -1690,8 +1627,6 @@ protected function getCompression() * @param string $persistentId The persistent Id to store * * @author Benjamin Carl - * @return void - * @access protected */ protected function setPersistentId($persistentId) { @@ -1704,12 +1639,13 @@ protected function setPersistentId($persistentId) * @param string $persistentId The persistent Id to store * * @author Benjamin Carl + * * @return $this Instance for chaining - * @access protected */ protected function persistentId($persistentId) { $this->setPersistentId($persistentId); + return $this; } @@ -1717,8 +1653,8 @@ protected function persistentId($persistentId) * Getter for persistent Id. * * @author Benjamin Carl + * * @return string The persistent Id set at instantiation or generated by this instance - * @access protected */ protected function getPersistentId() { @@ -1731,13 +1667,14 @@ protected function getPersistentId() * @param int $response The response * * @author Benjamin Carl - * @return boolean TRUE if response valid (0) was set, otherwise FALSE - * @access protected + * + * @return bool TRUE if response valid (0) was set, otherwise FALSE */ protected function setLastResponse($response) { $this->lastResponse = $response; - return ($response === 0); + + return $response === 0; } /** @@ -1746,12 +1683,13 @@ protected function setLastResponse($response) * @param int $response The response array (command => buffer) * * @author Benjamin Carl + * * @return $this Instance for chaining - * @access protected */ protected function lastResponse($response) { $this->setLastResponse($response); + return $this; } @@ -1759,8 +1697,8 @@ protected function lastResponse($response) * Getter for lastResponse. * * @author Benjamin Carl + * * @return int The last response - * @access protected */ protected function getLastResponse() { @@ -1771,8 +1709,8 @@ protected function getLastResponse() * Simple generic hashing of dynamic input. * * @author Benjamin Carl + * * @return string The calculated UUID - * @access protected */ protected function uuid() { @@ -1787,35 +1725,34 @@ protected function uuid() * @param mixed $value The value to check * * @author Benjamin Carl + * * @return bool TRUE if is serializable, otherwise FALSE - * @access public */ protected function isSerializable($value) { $type = gettype($value); - return ( - $type !== "string" && // Mask - Decimal: 0 - Bit(s): 0 - $type !== "integer" && // Mask - Decimal: 1 - Bit(s): 1 - $type !== "double" && // Mask - Decimal: 2 - Bit(s): 2 - $type !== "boolean" // Mask - Decimal: 3 - Bit(s): 1 & 2 - // Mask - Decimal: 4 - Bit(s): 4 - ); + return + $type !== 'string' && // Mask - Decimal: 0 - Bit(s): 0 + $type !== 'integer' && // Mask - Decimal: 1 - Bit(s): 1 + $type !== 'double' && // Mask - Decimal: 2 - Bit(s): 2 + $type !== 'boolean' // Mask - Decimal: 3 - Bit(s): 1 & 2 + // Mask - Decimal: 4 - Bit(s): 4 + ; } /** * Resets state to clean fresh as new instantiated. * * @author Benjamin Carl + * * @return $this Instance for chaining - * @access protected */ protected function reset() { return $this ->lastResponse(0); - } /** @@ -1825,9 +1762,10 @@ protected function reset() * @param array $lines The buffer separated into single lines in a collection * * @author Benjamin Carl + * * @return array|bool Response parsed as collection, otherwise FALSE (ERROR) - * @access protected - * @throws \Clickalicious\Memcached\Exception + * + * @throws \Clickalicious\Memcached\Php\Exception */ protected function parseReadResponse($buffer, array $lines) { @@ -1843,7 +1781,7 @@ protected function parseReadResponse($buffer, array $lines) * Try to fetch metadata. Why try? Cause we can receive multiple lines for a value. If the current key * reference to a simple value like an integer (65000 for example) then we have one line data and * one line data. But if the value contains a "\r\n" itself it breaks this simple assumption so - * that we must + * that we must. */ $metaData = explode(self::COMMAND_SEPARATOR, $lines[$line]); @@ -1857,21 +1795,21 @@ protected function parseReadResponse($buffer, array $lines) // @codeCoverageIgnoreEnd // Value must be at least starting on next line - and can continue to spawn on n following lines ... - $key = $metaData[1]; - $value = ''; - $flags = (int)$metaData[2]; + $key = $metaData[1]; + $value = ''; + $flags = (int) $metaData[2]; $length = $metaData[3]; - $cas = (isset($metaData[4])) ? (float)$metaData[4] : null; - $frame = 0; + $cas = (isset($metaData[4])) ? (float) $metaData[4] : null; + $frame = 0; if ($length > 0) { // Fetch whole & complete value! while (strlen($value) < $length) { ++$frame; - if($lines[$line + $frame] === self::RESPONSE_END && !isset($lines[$line + $frame+1])) { + if ($lines[$line + $frame] === self::RESPONSE_END && !isset($lines[$line + $frame + 1])) { $frame_break = true; break; - } + } $value .= $lines[$line + $frame]; } } else { @@ -1882,34 +1820,31 @@ protected function parseReadResponse($buffer, array $lines) $result[$key] = array( // 1st bit set = we use un-/serialize to keep the values intact ... //'value' => $value, - 'key' => $key, - 'meta' => array( - 'key' => $key, - 'flags' => $flags, + 'key' => $key, + 'meta' => array( + 'key' => $key, + 'flags' => $flags, 'length' => $length, - 'cas' => $cas, - 'frames' => $frame - ) + 'cas' => $cas, + 'frames' => $frame, + ), ); if ($this->isFlagSet($flags, self::FLAG_DECIMAL_SERIALIZED) === true) { $length = strlen($value); - $value = unserialize($value); - + $value = unserialize($value); } elseif ($this->isFlagSet($flags, self::FLAG_DECIMAL_BOOLEAN) === true) { - $value = boolval($value); + $value = boolval($value); $length = strlen($value); - } elseif ($this->isFlagSet($flags, self::FLAG_DECIMAL_FLOAT) === true) { - $value = floatval($value); + $value = floatval($value); $length = strlen($value); - } elseif ($this->isFlagSet($flags, self::FLAG_DECIMAL_INTEGER) === true) { - $value = intval($value); + $value = intval($value); $length = strlen($value); } - $result[$key]['value'] = $value; + $result[$key]['value'] = $value; $result[$key]['meta']['length'] = $length; // Increment by one and check @@ -1923,17 +1858,15 @@ protected function parseReadResponse($buffer, array $lines) // Memcached compatible success $this->lastResponse(self::MEMCACHED_SUCCESS); - } else { $result = $this->setLastResponse(self::MEMCACHED_NOTFOUND); - } return $result; } /** - * Parser for response of write operations like: + * Parser for response of write operations like: . * * - "STORED\r\n" to indicate success. * - "NOT_STORED\r\n" to indicate the data was not stored, but not because of an error. This normally means that the @@ -1946,18 +1879,17 @@ protected function parseReadResponse($buffer, array $lines) * @param array $lines Response split into single lines * * @author Benjamin Carl + * * @return bool TRUE if write operation was successful (STORED), otherwise (ALL OTHER CASE) FALSE - * @access protected */ protected function parseWriteResponse($buffer, array $lines) { // We assume that everything beside "STORED" is an error case ... - $result = ($buffer === self::RESPONSE_STORED . self::COMMAND_TERMINATOR); + $result = ($buffer === self::RESPONSE_STORED.self::COMMAND_TERMINATOR); // Successful? if ($result === true) { $this->lastResponse(self::MEMCACHED_SUCCESS); - } else { // Default error case $this->lastResponse(self::MEMCACHED_FAILURE); @@ -1983,25 +1915,25 @@ protected function parseWriteResponse($buffer, array $lines) } /** - * Parser for response of flush operation: + * Parser for response of flush operation: . * * SUCCESS = RESPONSE = "OK" * FAILED = RESPONSE = "?" * - * @param string $buffer We do only need the buffer. + * @param string $buffer we do only need the buffer * * @author Benjamin Carl + * * @return bool TRUE if flush operation was successful (STORED), otherwise (ALL OTHER CASE) FALSE - * @access protected */ protected function parseFlushResponse($buffer) { // We assume that everything beside "OK" is an error case ... - return ($buffer === self::RESPONSE_OK . self::COMMAND_TERMINATOR); + return $buffer === self::RESPONSE_OK.self::COMMAND_TERMINATOR; } /** - * Parser for response of delete operation: + * Parser for response of delete operation: . * * SUCCESS = RESPONSE = "DELETED" * FAILED = RESPONSE = "NOT_FOUND" @@ -2009,8 +1941,8 @@ protected function parseFlushResponse($buffer) * @param array $lines Response split into single lines * * @author Benjamin Carl + * * @return bool TRUE if delete operation was successful (STORED), otherwise (ALL OTHER CASE) FALSE - * @access protected */ protected function parseDeleteResponse(array $lines) { @@ -2021,7 +1953,6 @@ protected function parseDeleteResponse(array $lines) if ($metaData[0] !== self::RESPONSE_DELETED) { if ($metaData[0] === self::RESPONSE_NOT_FOUND) { $result = $this->setLastResponse(self::MEMCACHED_NOTFOUND); - } else { // Generic error $result = $this->setLastResponse(self::MEMCACHED_FAILURE); @@ -2034,14 +1965,15 @@ protected function parseDeleteResponse(array $lines) /** * Parser for response of stats* operation: * Try to fetch in this way: split descriptor/key from value - each stats entry is on one line - * STAT \r\n + * STAT \r\n. * * @param array $lines The buffer separated into single lines in a collection * * @author Benjamin Carl + * * @return array|bool The stats as collection indexed by hostname?, otherwise FALSE (ERROR) - * @access protected - * @throws \Clickalicious\Memcached\Exception + * + * @throws \Clickalicious\Memcached\Php\Exception */ protected function parseStatsResponse(array $lines) { @@ -2067,7 +1999,7 @@ protected function parseStatsResponse(array $lines) } // @codeCoverageIgnoreEnd - $nodes = explode(':', $metaData[1]); + $nodes = explode(':', $metaData[1]); $countNodes = count($nodes); if ($countNodes === 2) { @@ -2076,7 +2008,6 @@ protected function parseStatsResponse(array $lines) $result[$nodes[0]] = array(); } $result[$nodes[0]][$nodes[1]] = $metaData[2]; - } elseif ($countNodes === 3) { // ??? if (isset($result[$nodes[0]]) === false) { @@ -2087,13 +2018,12 @@ protected function parseStatsResponse(array $lines) } } $result[$nodes[0]][$nodes[1]][$nodes[2]] = $metaData[2]; - } else { - $identifier = array_shift($metaData); - $key = array_shift($metaData); - $value = implode(self::COMMAND_SEPARATOR, $metaData); + array_shift($metaData); + $key = array_shift($metaData); + $value = implode(self::COMMAND_SEPARATOR, $metaData); $result[$key] = $value; - }; + } ++$line; } @@ -2109,11 +2039,11 @@ protected function parseStatsResponse(array $lines) * SUCCESS = RESPONSE = "\r\n" * FAILED = RESPONSE = "???" * - * @param array $lines Response split into single lines + * @param array $lines Response split into single lines * * @author Benjamin Carl + * * @return string|bool The version as string if valid, otherwise FALSE - * @access protected */ protected function parseVersionResponse(array $lines) { @@ -2123,7 +2053,6 @@ protected function parseVersionResponse(array $lines) // If Version response valid if ($metaData[0] === strtoupper(self::COMMAND_VERSION)) { $result = $metaData[1]; - } else { $result = $this->setLastResponse(self::MEMCACHED_FAILURE); } @@ -2141,8 +2070,8 @@ protected function parseVersionResponse(array $lines) * @param array $lines Response split into single lines * * @author Benjamin Carl + * * @return string|bool The version as string if valid, otherwise FALSE - * @access protected */ protected function parseArithmeticResponse($buffer, array $lines) { @@ -2150,12 +2079,11 @@ protected function parseArithmeticResponse($buffer, array $lines) $metaData = explode(self::COMMAND_SEPARATOR, $lines[0]); // Check buffer for failure response - if ($buffer === self::RESPONSE_NOT_FOUND . self::COMMAND_TERMINATOR) { + if ($buffer === self::RESPONSE_NOT_FOUND.self::COMMAND_TERMINATOR) { $result = $this->setLastResponse(self::MEMCACHED_NOTFOUND); - } else { // Insert the response (= new value) as result - $result = (float)$metaData[0]; + $result = (float) $metaData[0]; } return $result; @@ -2167,24 +2095,21 @@ protected function parseArithmeticResponse($buffer, array $lines) * @param string $buffer The buffer to check * * @author Benjamin Carl + * * @return bool TRUE on success, otherwise FALSE if response contains ERROR(s) - * @access protected */ protected function checkResponse($buffer) { // Check for HARD errors. Not an unsuccessful response from command -> here = real errors - if (preg_match('/' . self::ERROR . '(.*)\R/mu', $buffer, $error) > 0) { + if (preg_match('/'.self::ERROR.'(.*)\R/mu', $buffer, $error) > 0) { // ERROR\r\n $result = self::MEMCACHED_FAILURE; - - } elseif (preg_match('/' . self::ERROR_CLIENT . '(.*)\R/mu', $buffer, $error) > 0) { + } elseif (preg_match('/'.self::ERROR_CLIENT.'(.*)\R/mu', $buffer, $error) > 0) { // CLIENT_ERROR\r\n $result = self::RESPONSE_CLIENT_ERROR; - - } elseif (preg_match('/' . self::ERROR_SERVER . '(.*)\R/mu', $buffer, $error) > 0) { + } elseif (preg_match('/'.self::ERROR_SERVER.'(.*)\R/mu', $buffer, $error) > 0) { // SERVER_ERROR\r\n $result = self::ERROR_SERVER; - } else { $result = self::MEMCACHED_SUCCESS; } @@ -2194,22 +2119,23 @@ protected function checkResponse($buffer) } /** - * Parses a response from a Memcached daemon + * Parses a response from a Memcached daemon. * - * @param string $command The command which has triggered the buffer response from instance. - * @param string $buffer The buffer to parse. + * @param string $command the command which has triggered the buffer response from instance + * @param string $buffer the buffer to parse * * @author Benjamin Carl + * * @return bool|mixed FALSE on error, otherwise parsed response - * @access protected - * @throws \Clickalicious\Memcached\Exception + * + * @throws \Clickalicious\Memcached\Php\Exception */ protected function parseResponse($command, $buffer) { // At this point we retrieve a raw response containing at least a trailing terminator - rip it $response = substr($buffer, 0, strlen($buffer) - strlen(self::COMMAND_TERMINATOR)); - $lines = explode(self::COMMAND_TERMINATOR, $response); - $result = false; + $lines = explode(self::COMMAND_TERMINATOR, $response); + $result = false; if ( $command === self::COMMAND_GET || @@ -2217,36 +2143,31 @@ protected function parseResponse($command, $buffer) ) { // PARSER for $result = $this->parseReadResponse($buffer, $lines); - } elseif ( - $command === self::COMMAND_SET || - $command === self::COMMAND_ADD || + $command === self::COMMAND_SET || + $command === self::COMMAND_ADD || $command === self::COMMAND_REPLACE || - $command === self::COMMAND_APPEND || + $command === self::COMMAND_APPEND || $command === self::COMMAND_PREPEND || $command === self::COMMAND_CAS ) { // PARSER for $result = $this->parseWriteResponse($buffer, $lines); - } elseif ( $command === self::COMMAND_DELETE ) { // PARSER for $result = $this->parseDeleteResponse($lines); - } elseif ( $command === self::COMMAND_STATS ) { // PARSER for $result = $this->parseStatsResponse($lines); - } elseif ( $command === self::COMMAND_VERSION ) { // PARSER for $result = $this->parseVersionResponse($lines); - } elseif ( $command === self::COMMAND_INCR || $command === self::COMMAND_DECR @@ -2269,9 +2190,10 @@ protected function parseResponse($command, $buffer) * @param mixed $value The value to serialize * * @author Benjamin Carl + * * @return array ... - * @access protected - * @throws \Clickalicious\Memcached\Exception + * + * @throws \Clickalicious\Memcached\Php\Exception */ protected function serializeValue($value) { @@ -2280,23 +2202,18 @@ protected function serializeValue($value) $value = serialize($value); $bytes = strlen($value); $flags = self::FLAG_DECIMAL_SERIALIZED; - } else { // Real numbers should keep real numbers - Bit 2 = int , 3 = double/float if (is_int($value) === true) { $flags = self::FLAG_DECIMAL_INTEGER; - } elseif (is_float($value) === true) { $flags = self::FLAG_DECIMAL_FLOAT; - } elseif (is_string($value) === true) { // Never serialize strings! Otherwise append() & prepend() won't work! $flags = self::FLAG_DECIMAL_STRING; - } elseif (is_bool($value) === true) { $value = strval($value); $flags = self::FLAG_DECIMAL_BOOLEAN; - } else { throw new Exception( sprintf('Unhandable value. Don\'t know how to process!') @@ -2317,27 +2234,28 @@ protected function serializeValue($value) * Checks if a decimal flag ($flag) is set in passed ($flags). * * @author Benjamin Carl - * @param integer $flags - * @param integer $flag + * + * @param int $flags + * @param int $flag + * * @return bool TRUE if flag is set in flags, otherwise FALSE - * @access protected */ protected function isFlagSet($flags, $flag) { - return (($flags & $flag) === $flag); + return ($flags & $flag) === $flag; } /** * Sets a decimal flag ($lfag) in passed flags ($flags). * * @author Benjamin Carl + * * @return int The flags after setting new flag - * @access protected */ protected function setFlag($flags, $flag) { $flags |= $flag; + return $flags; } } - diff --git a/src/Compression/CompressionInterface.php b/src/Compression/CompressionInterface.php new file mode 100644 index 0000000..73fc7ca --- /dev/null +++ b/src/Compression/CompressionInterface.php @@ -0,0 +1,58 @@ + + */ +interface CompressionInterface +{ + /** + * Compresses a buffer. + * + * @param string $buffer The buffer to compress + * + * @author Benjamin Carl + * + * @return string The compressed input + */ + public function compress($buffer); + + /** + * Decompresses a buffer. + * + * @param string $buffer The buffer to decompress + * + * @author Benjamin Carl + * + * @return string The decompressed input + */ + public function decompress($buffer); +} diff --git a/src/Clickalicious/Memcached/Compression/Lzw.php b/src/Compression/Lzw.php similarity index 50% rename from src/Clickalicious/Memcached/Compression/Lzw.php rename to src/Compression/Lzw.php index 88c0469..23a3daf 100644 --- a/src/Clickalicious/Memcached/Compression/Lzw.php +++ b/src/Compression/Lzw.php @@ -1,10 +1,36 @@ - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch - */ - -use Clickalicious\Memcached\Compression\CompressionInterface; -use Clickalicious\Memcached\Exception; - -/** - * Memcached.php - * - * LZW-compression (LZW = Lempel–Ziv–Welch). - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Compression - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - * @see http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch + * @author Benjamin Carl */ class Lzw implements CompressionInterface { @@ -84,8 +47,9 @@ class Lzw implements CompressionInterface * Constructor. * * @author Benjamin Carl + * * @return Lzw - * @access public + * * @throws Exception */ public function __construct() @@ -103,33 +67,32 @@ public function __construct() * @param string $buffer The buffer to compress * * @author Benjamin Carl + * * @return string The compressed input - * @access protected */ public function compress($buffer) { $dictionary = array(); - $data = str_split($buffer . ''); - $out = array(); - $phrase = $data[0]; - $code = 256; - $countData = count($data); + $data = str_split($buffer.''); + $out = array(); + $phrase = $data[0]; + $code = 256; + $countData = count($data); for ($i = 1; $i < $countData; ++$i) { $currentCharacter = $data[$i]; if (isset($dictionary[$phrase.$currentCharacter])) { $phrase .= $currentCharacter; - } else { - $out[] = strlen($phrase) > 1 ? $dictionary[$phrase] : $this->charCodeAt($phrase,0); + $out[] = strlen($phrase) > 1 ? $dictionary[$phrase] : $this->charCodeAt($phrase, 0); $dictionary[$phrase.$currentCharacter] = $code; - $code++; + ++$code; $phrase = $currentCharacter; } } - $out[] = strlen($phrase) > 1 ? $dictionary[$phrase] : $this->charCodeAt($phrase,0); + $out[] = strlen($phrase) > 1 ? $dictionary[$phrase] : $this->charCodeAt($phrase, 0); $countOut = count($out); for ($i = 0; $i < $countOut; ++$i) { @@ -145,35 +108,34 @@ public function compress($buffer) * @param string $buffer The buffer to decompress * * @author Benjamin Carl + * * @return string The decompressed input - * @access protected */ public function decompress($buffer) { - $dictionary = array(); - $data = $this->multibyteStringSplit($buffer); + $dictionary = array(); + $data = $this->multibyteStringSplit($buffer); $currentCharacter = $data[0]; - $oldPhrase = $currentCharacter; - $out = array($currentCharacter); - $code = 256; - $countData = count($data); + $oldPhrase = $currentCharacter; + $out = array($currentCharacter); + $code = 256; + $countData = count($data); for ($i = 1; $i < $countData; ++$i) { $currCode = $this->uniord($data[$i]); if ($currCode < 256) { $phrase = $data[$i]; - } else { $phrase = isset($dictionary[$currCode]) ? $dictionary[$currCode] : $oldPhrase.$currentCharacter; } - $out[] = $phrase; - $currentCharacter = $phrase[0]; - $dictionary[$code] = $oldPhrase . $currentCharacter; + $out[] = $phrase; + $currentCharacter = $phrase[0]; + $dictionary[$code] = $oldPhrase.$currentCharacter; - $code++; + ++$code; $oldPhrase = $phrase; } @@ -187,8 +149,8 @@ public function decompress($buffer) * @param string $string The input to split * * @author Benjamin Carl + * * @return array The splitted string - * @access protected */ protected function multibyteStringSplit($string) { @@ -202,8 +164,8 @@ protected function multibyteStringSplit($string) * @param int $position The position to return character from * * @author Benjamin Carl + * * @return int The position - * @access protected */ protected function charCodeAt($buffer, $position) { @@ -217,8 +179,8 @@ protected function charCodeAt($buffer, $position) * @param string $character The character * * @author Benjamin Carl + * * @return string The unicode character - * @access protected */ protected function unichr($character) { @@ -234,8 +196,8 @@ protected function unichr($character) * @param string $buffer The buffer to return character from * * @author Benjamin Carl + * * @return int The ASCII value of the character - * @access protected */ protected function uniord($buffer) { diff --git a/src/Compression/Smaz.php b/src/Compression/Smaz.php new file mode 100644 index 0000000..64808f1 --- /dev/null +++ b/src/Compression/Smaz.php @@ -0,0 +1,229 @@ + + */ +class Smaz implements CompressionInterface +{ + /** + * The encode book. + * + * @var array|null + * @static + */ + private static $encodeBook; + + /** + * The decode book. + * + * @var array + * @static + */ + private static $decodeBook = array( + ' ', 'the', 'e', 't', 'a', 'of', 'o', 'and', 'i', 'n', 's', 'e ', 'r', ' th', + ' t', 'in', 'he', 'th', 'h', 'he ', 'to', "\r\n", 'l', 's ', 'd', ' a', 'an', + 'er', 'c', ' o', 'd ', 'on', ' of', 're', 'of ', 't ', ', ', 'is', 'u', 'at', + ' ', 'n ', 'or', 'which', 'f', 'm', 'as', 'it', 'that', "\n", 'was', 'en', + ' ', ' w', 'es', ' an', ' i', "\r", 'f ', 'g', 'p', 'nd', ' s', 'nd ', 'ed ', + 'w', 'ed', 'http://', 'for', 'te', 'ing', 'y ', 'The', ' c', 'ti', 'r ', 'his', + 'st', ' in', 'ar', 'nt', ',', ' to', 'y', 'ng', ' h', 'with', 'le', 'al', 'to ', + 'b', 'ou', 'be', 'were', ' b', 'se', 'o ', 'ent', 'ha', 'ng ', 'their', '"', + 'hi', 'from', ' f', 'in ', 'de', 'ion', 'me', 'v', '.', 've', 'all', 're ', + 'ri', 'ro', 'is ', 'co', 'f t', 'are', 'ea', '. ', 'her', ' m', 'er ', ' p', + 'es ', 'by', 'they', 'di', 'ra', 'ic', 'not', 's, ', 'd t', 'at ', 'ce', 'la', + 'h ', 'ne', 'as ', 'tio', 'on ', 'n t', 'io', 'we', ' a ', 'om', ', a', 's o', + 'ur', 'li', 'll', 'ch', 'had', 'this', 'e t', 'g ', "e\r\n", ' wh', 'ere', + ' co', 'e o', 'a ', 'us', ' d', 'ss', "\n\r\n", "\r\n\r", '="', ' be', ' e', + 's a', 'ma', 'one', 't t', 'or ', 'but', 'el', 'so', 'l ', 'e s', 's,', 'no', + 'ter', ' wa', 'iv', 'ho', 'e a', ' r', 'hat', 's t', 'ns', 'ch ', 'wh', 'tr', + 'ut', '/', 'have', 'ly ', 'ta', ' ha', ' on', 'tha', '-', ' l', 'ati', 'en ', + 'pe', ' re', 'there', 'ass', 'si', ' fo', 'wa', 'ec', 'our', 'who', 'its', 'z', + 'fo', 'rs', '>', 'ot', 'un', '<', 'im', 'th ', 'nc', 'ate', '><', 'ver', 'ad', + ' we', 'ly', 'ee', ' n', 'id', ' cl', 'ac', 'il', ' + * + * @return string The compressed input + */ + public function compress($buffer) + { + $inLen = strlen($buffer); + $inIdx = 0; + $encodeBook = $this->getEncodeBook(); + $output = ''; + $verbatim = ''; + + while ($inIdx < $inLen) { + $encode = false; + + for ($j = min(7, $inLen - $inIdx); $j > 0; --$j) { + $code = isset($encodeBook[substr($buffer, $inIdx, $j)]) ? + $encodeBook[substr($buffer, $inIdx, $j)] : null; + + if ($code !== null) { + if (strlen($verbatim)) { + $output .= $this->flushVerbatim($verbatim); + $verbatim = ''; + } + + $output .= chr($code); + $inIdx += $j; + $encode = true; + + break; + } + } + + if (!$encode) { + $verbatim .= $buffer[$inIdx]; + ++$inIdx; + + if (strlen($verbatim) == 255) { + $output .= $this->flushVerbatim($verbatim); + $verbatim = ''; + } + } + } + + if (strlen($verbatim)) { + $output .= $this->flushVerbatim($verbatim); + } + + return $output; + } + + /** + * Decompresses a buffer. + * + * @param string $buffer The buffer to decompress + * + * @author Benjamin Carl + * + * @return string The decompressed input + */ + public function decompress($buffer) + { + $decodeBook = $this->getDecodeBook(); + $output = ''; + $count = 0; + + while ($count < strlen($buffer)) { + $code = ord($buffer[$count]); + + if (254 === $code) { + $output .= $buffer[$count + 1]; + $count += 2; + } elseif (255 === $code) { + $len = ord($buffer[$count + 1]); + $output .= substr($buffer, $count + 2, $len); + $count += 2 + $len; + } else { + $output .= $decodeBook[$code]; + ++$count; + } + } + + return $output; + } + + /** + * Flushes ... + * + * @param $verbatim + * + * @return string + */ + protected function flushVerbatim($verbatim) + { + $output = ''; + + if (!strlen($verbatim)) { + return $output; + } + + if (strlen($verbatim) > 1) { + $output .= chr(255); + $output .= chr(strlen($verbatim)); + } else { + $output .= chr(254); + } + + $output .= $verbatim; + + return $output; + } + + /** + * Returns the book used to encode. + * + * @author Benjamin Carl + * + * @return array The encode book + */ + protected function getEncodeBook() + { + if (self::$encodeBook === null) { + self::$encodeBook = array_flip(self::$decodeBook); + } + + return self::$encodeBook; + } + + /** + * Returns the book used to decode. + * + * @author Benjamin Carl + * + * @return array The decode book + */ + protected function getDecodeBook() + { + return self::$decodeBook; + } +} diff --git a/src/Compression/Zlib.php b/src/Compression/Zlib.php new file mode 100644 index 0000000..91dac53 --- /dev/null +++ b/src/Compression/Zlib.php @@ -0,0 +1,68 @@ + + */ +class Zlib implements CompressionInterface +{ + /** + * Compresses a buffer. + * + * @param string $buffer The buffer to compress + * + * @author Benjamin Carl + * + * @return string The compressed input + */ + public function compress($buffer) + { + return gzcompress($buffer); + } + + /** + * Decompresses a buffer. + * + * @param string $buffer The buffer to decompress + * + * @author Benjamin Carl + * + * @return string The decompressed input + */ + public function decompress($buffer) + { + return gzuncompress($buffer); + } +} diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 0000000..79d7145 --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,38 @@ + + */ +class Exception extends \Exception +{ + // Intentionally left empty. +} diff --git a/src/Clickalicious/Memcached/Util.php b/src/Util.php similarity index 64% rename from src/Clickalicious/Memcached/Util.php rename to src/Util.php index d533d1b..ff04f9d 100644 --- a/src/Clickalicious/Memcached/Util.php +++ b/src/Util.php @@ -1,65 +1,37 @@ 5.3. array_column() for example. - * - * - * PHP versions 5.3 - * - * LICENSE: - * Memcached.php - Plain vanilla PHP Memcached client with full support of Memcached protocol. - * - * Copyright (c) 2014 - 2015, Benjamin Carl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of Memcached.php nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Please feel free to contact us via e-mail: opensource@clickalicious.de - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Util - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php + * (The MIT license) + * Copyright 2017 clickalicious, Benjamin Carl. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ +namespace Clickalicious\Memcached\Php; + /*---------------------------------------------------------------------------------------------------------------------- | General Tools & Helper +---------------------------------------------------------------------------------------------------------------------*/ -/** +/* * Copyright (c) 2013 Ben Ramsey * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -80,30 +52,30 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * - * @author Ben Ramsey + * @author Ben Ramsey * @copyright 2013 Ben Ramsey - * @license http://opensource.org/licenses/MIT MIT + * @license http://opensource.org/licenses/MIT MIT * @codeCoverageIgnore */ if (false === function_exists('array_column')) { - /** * Returns the values from a single column of the input array, identified by the $columnKey. * * Optionally, you may provide an $indexKey to index the values in the returned array by the values from the * $indexKey column in the input array. * - * @param array $input A multi-dimensional array (record set) from which to pull a column of values. + * @param array $input a multi-dimensional array (record set) from which to pull a column of values * @param mixed $column_key The column of values to return. This value may be the integer key of the column you * wish to retrieve, or it may be the string key name for an associative array. * @param mixed $index_key (Optional.) The column to use as the index/keys for the returned array. This value * may be the integer key of the column, or it may be the string key name. + * * @return array * @codeCoverageIgnore */ function array_column(array $input, $column_key, $index_key = null) { - /** + /* * Proxy call to array_column_emulation(): makes it a bit cleaner and testing on all systems possible */ return array_column_emulation($input, $column_key, $index_key); @@ -116,20 +88,21 @@ function array_column(array $input, $column_key, $index_key = null) * Optionally, you may provide an $indexKey to index the values in the returned array by the values from the * $indexKey column in the input array. * - * @param array $input A multi-dimensional array (record set) from which to pull a column of values. + * @param array $input a multi-dimensional array (record set) from which to pull a column of values * @param mixed $column_key The column of values to return. This value may be the integer key of the column you * wish to retrieve, or it may be the string key name for an associative array. * @param mixed $index_key (Optional.) The column to use as the index/keys for the returned array. This value * may be the integer key of the column, or it may be the string key name. + * * @return array */ function array_column_emulation(array $input, $column_key, $index_key = null) { // Check for ... - if (!is_int($column_key) && - !is_float($column_key) && + if (!is_int($column_key) && + !is_float($column_key) && !is_string($column_key) && - $column_key !== null && + $column_key !== null && !( is_object($column_key) && method_exists($column_key, '__toString') ) @@ -141,10 +114,10 @@ function array_column_emulation(array $input, $column_key, $index_key = null) } // Check for ... - if (null !== $index_key && - !is_int($index_key) && - !is_float($index_key) && - !is_string($index_key) && + if (null !== $index_key && + !is_int($index_key) && + !is_float($index_key) && + !is_string($index_key) && !( is_object($index_key) && method_exists($index_key, '__toString') ) @@ -158,21 +131,21 @@ function array_column_emulation(array $input, $column_key, $index_key = null) // Check for passed index key if (null !== $index_key) { if (is_float($index_key) || is_int($index_key)) { - $index_key = (int)$index_key; + $index_key = (int) $index_key; } else { - $index_key = (string)$index_key; + $index_key = (string) $index_key; } } $result = array(); foreach ($input as $row) { - $key = null; + $key = null; $keySet = false; if (null !== $index_key && true === is_array($row) && true === array_key_exists($index_key, $row)) { $keySet = true; - $key = (string)$row[$index_key]; + $key = (string) $row[$index_key]; } if (true === is_array($row) && true === array_key_exists($column_key, $row)) { @@ -184,14 +157,14 @@ function array_column_emulation(array $input, $column_key, $index_key = null) if ($keySet === true) { $result[$key] = $value; } else { - $result[] = $value; + $result[] = $value; } } return $result; } -/** +/* * Alternative implementation of boolval() for PHP releases < 5.5. * * @param mixed $boolean The potential boolean @@ -202,20 +175,19 @@ function array_column_emulation(array $input, $column_key, $index_key = null) * @codeCoverageIgnore */ if (false === function_exists('boolval')) { - /** * Alternative implementation of boolval() for PHP releases < 5.5. * * @param mixed $boolean The potential boolean * * @author Benjamin Carl - * @return bool TRUE || FALSE depending on input. - * @access public + * + * @return bool tRUE || FALSE depending on input * @codeCoverageIgnore */ function boolval($boolean) { - /** + /* * Proxy call to boolval_emulation() */ return boolval_emulation($boolean); @@ -228,8 +200,8 @@ function boolval($boolean) * @param mixed $boolean The potential boolean * * @author Benjamin Carl - * @return bool TRUE || FALSE depending on input. - * @access public + * + * @return bool tRUE || FALSE depending on input */ function boolval_emulation($boolean) { diff --git a/tests/Clickalicious/Memcached/UtilTest.php b/tests/Clickalicious/Memcached/UtilTest.php deleted file mode 100644 index 360d93e..0000000 --- a/tests/Clickalicious/Memcached/UtilTest.php +++ /dev/null @@ -1,377 +0,0 @@ - - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ - -require_once CLICKALICIOUS_MEMCACHED_BASE_PATH . 'Clickalicious/Memcached/Util.php'; - -/** - * Memcached.php - * - * Unit tests for util functionality. - * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Tests - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php - */ -class UtilTest extends PHPUnit_Framework_TestCase -{ - /** - * The PHP version running on. - * - * @var string - * @access protected - */ - protected $phpVersion; - - /** - * Controls if we need to test the array_column() - * - * @var bool - * @access protected - */ - protected $testProxy = true; - - /** - * The test data we work on. - * - * @var array - * @access protected - */ - protected $data; - - - /** - * Prepare some stuff. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - protected function setUp() - { - $phpVersion = explode('.', PHP_VERSION); - $phpVersion = $phpVersion[0] . $phpVersion[1]; - - if ($phpVersion >= 5.5) { - $this->testProxy = false; - } - - // Test data - $this->data = array( - array( - 'id' => 2135, - 'first_name' => 'John', - 'last_name' => 'Doe', - ), - array( - 'id' => 3245, - 'first_name' => 'Sally', - 'last_name' => 'Smith', - ), - array( - 'id' => 5342, - 'first_name' => 'Jane', - 'last_name' => 'Jones', - ), - array( - 'id' => 5623, - 'first_name' => 'Peter', - 'last_name' => 'Doe', - ) - ); - } - - /** - * Test: array_column implementation. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - public function testArrayColumnEmulation() - { - /** - Array - ( - [0] => John - [1] => Sally - [2] => Jane - [3] => Peter - ) - */ - $data = \Clickalicious\Memcached\array_column_emulation($this->data, 'first_name'); - - $this->assertContains('John', $data); - $this->assertContains('Sally', $data); - $this->assertContains('Jane', $data); - $this->assertContains('Peter', $data); - - $this->assertArrayHasKey(0, $data); - $this->assertArrayHasKey(1, $data); - $this->assertArrayHasKey(2, $data); - $this->assertArrayHasKey(3, $data); - } - - /** - * Test: array_column implementation: id as index. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - public function testArrayColumnEmulationCustomIndex() - { - /** - Array - ( - [2135] => Doe - [3245] => Smith - [5342] => Jones - [5623] => Doe - ) - */ - $data = \Clickalicious\Memcached\array_column_emulation($this->data, 'first_name', 'id'); - - $this->assertContains('John', $data); - $this->assertContains('Sally', $data); - $this->assertContains('Jane', $data); - $this->assertContains('Peter', $data); - - $this->assertArrayHasKey(2135, $data); - $this->assertArrayHasKey(3245, $data); - $this->assertArrayHasKey(5342, $data); - $this->assertArrayHasKey(5623, $data); - } - - /** - * Test: array_column implementation: wrong id int as index. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - public function testArrayColumnEmulationWrongColumnString() - { - /** - Array - ( - [2135] => Doe - [3245] => Smith - [5342] => Jones - [5623] => Doe - ) - */ - $data = \Clickalicious\Memcached\array_column_emulation($this->data, 'foo'); - $this->assertArrayHasKey(0, $data); - $this->assertArrayHasKey(1, $data); - $this->assertArrayHasKey(2, $data); - $this->assertArrayHasKey(3, $data); - } - - /** - * Test: array_column implementation: custom int as index. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - public function testArrayColumnEmulationCustomIndexInt() - { - /** - Array - ( - [2135] => Doe - [3245] => Smith - [5342] => Jones - [5623] => Doe - ) - */ - $data = \Clickalicious\Memcached\array_column_emulation($this->data, 'first_name', 1); - $this->assertArrayHasKey(0, $data); - $this->assertArrayHasKey(1, $data); - $this->assertArrayHasKey(2, $data); - $this->assertArrayHasKey(3, $data); - } - - /** - * Test: array_column implementation: wrong id string as index. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - public function testArrayColumnEmulationCustomIndexString() - { - /** - Array - ( - [2135] => Doe - [3245] => Smith - [5342] => Jones - [5623] => Doe - ) - */ - $data = \Clickalicious\Memcached\array_column_emulation($this->data, 'first_name', 'foo'); - $this->assertArrayHasKey(0, $data); - $this->assertArrayHasKey(1, $data); - $this->assertArrayHasKey(2, $data); - $this->assertArrayHasKey(3, $data); - } - - /** - * Test: array_column implementation: error handling. - * - * @author Benjamin Carl - * @return void - * @access protected - * @expectedException PHPUnit_Framework_Error - */ - public function testArrayColumnEmulationErrorHandlingWrongSecondArgument() - { - \Clickalicious\Memcached\array_column_emulation($this->data, new stdClass()); - } - - /** - * Test: array_column implementation: error handling. - * - * @author Benjamin Carl - * @return void - * @access protected - * @expectedException PHPUnit_Framework_Error - */ - public function testArrayColumnEmulationErrorHandlingWrongThirdArgument() - { - \Clickalicious\Memcached\array_column_emulation($this->data, 'first_name', new stdClass()); - } - - /** - * Test: Set a key value pair. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - public function testArrayColumnProxy() - { - if ($this->testProxy === true) { - /** - Array - ( - [0] => John - [1] => Sally - [2] => Jane - [3] => Peter - ) - */ - $data = \Clickalicious\Memcached\array_column($this->data, 'first_name'); - - $this->assertContains('John', $data); - $this->assertContains('Sally', $data); - $this->assertContains('Jane', $data); - $this->assertContains('Peter', $data); - - $this->assertArrayHasKey(0, $data); - $this->assertArrayHasKey(1, $data); - $this->assertArrayHasKey(2, $data); - $this->assertArrayHasKey(3, $data); - - - } else { - $this->assertTrue(true); - } - } - - - - /** - * Test: Set a key value pair. - * - * @author Benjamin Carl - * @return void - * @access protected - */ - public function testBoolvalEmulation() - { - $data = true; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = 1; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = 'TRUE'; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = 'YES'; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = 'Y'; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = 'ON'; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = '1'; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = '-1'; - $this->assertTrue(\Clickalicious\Memcached\boolval_emulation($data)); - - $data = false; - $this->assertFalse(\Clickalicious\Memcached\boolval_emulation($data)); - } -} diff --git a/tests/Clickalicious/Memcached/ClientTest.php b/tests/ClientTest.php similarity index 81% rename from tests/Clickalicious/Memcached/ClientTest.php rename to tests/ClientTest.php index a603a24..a18ed37 100644 --- a/tests/Clickalicious/Memcached/ClientTest.php +++ b/tests/ClientTest.php @@ -1,74 +1,39 @@ - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ -use Clickalicious\Memcached\Client; +namespace Clickalicious\Memcached\Php; /** - * Memcached.php - * - * Unit tests for client functionality. + * Class ClientTest * - * @category Clickalicious - * @package Clickalicious_Memcached - * @subpackage Clickalicious_Memcached_Tests - * @author Benjamin Carl - * @copyright 2014 - 2015 Benjamin Carl - * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @version Git: $Id$ - * @link https://github.com/clickalicious/Memcached.php + * @package Clickalicious\Memcached + * @author Benjamin Carl */ -class ClientTest extends PHPUnit_Framework_TestCase +class ClientTest extends \PHPUnit_Framework_TestCase { /** * The Host used for testing. @@ -81,7 +46,7 @@ class ClientTest extends PHPUnit_Framework_TestCase /** * Client instance * - * @var \Clickalicious\Memcached\Client + * @var \Clickalicious\Memcached\Php\Client * @access protected */ protected $client; @@ -102,7 +67,6 @@ class ClientTest extends PHPUnit_Framework_TestCase */ protected $value; - /** * Prepare some stuff. * @@ -112,7 +76,7 @@ class ClientTest extends PHPUnit_Framework_TestCase */ protected function setUp() { - $this->key = md5(microtime(true)); + $this->key = md5(microtime(true)); $this->value = sha1($this->key); $this->client = new Client( @@ -299,7 +263,7 @@ public function testSendAValidCustomCommandString() * @author Benjamin Carl * @return void * @access protected - * @expectedException \Clickalicious\Memcached\Exception + * @expectedException \Clickalicious\Memcached\Php\Exception */ public function testSendAnInvalidCustomCommandString() { @@ -310,7 +274,6 @@ public function testSendAnInvalidCustomCommandString() $this->client->send(Client::COMMAND_VERSION, $testCommand); } - /** * Test: Retrieve version. * @@ -466,9 +429,9 @@ public function testStoringPhpTypeBoolean() /** * Test: a stored value. * - * @author Benjamin Carl + * @author Benjamin Carl * @return void - * @access protected + * @access protected * @depends testStoringPhpTypeInteger */ public function testIncrementAStoredValue() @@ -487,9 +450,9 @@ public function testIncrementAStoredValue() /** * Test: a stored value. * - * @author Benjamin Carl + * @author Benjamin Carl * @return void - * @access protected + * @access protected * @depends testStoringPhpTypeInteger */ public function testDecrementAStoredValue() @@ -511,7 +474,7 @@ public function testDecrementAStoredValue() * @author Benjamin Carl * @return void * @access protected - * @expectedException \Clickalicious\Memcached\Exception + * @expectedException \Clickalicious\Memcached\Php\Exception */ public function testConnectToAMemcachedDaemon() { @@ -577,7 +540,7 @@ public function testRetrieveStats() $cachedump = array(); - for ($i = 1; $i <= $slabs; ++$i) { + for ($i = 1; $i <= $slabs; ++ $i) { $cachedumpTemp = $this->client->stats( Client::STATS_TYPE_CACHEDUMP, $i, @@ -602,7 +565,7 @@ public function testRetrieveStats() * @author Benjamin Carl * @return void * @access protected - * @expectedException \Clickalicious\Memcached\Exception + * @expectedException \Clickalicious\Memcached\Php\Exception */ public function testTriggerAndHandleError() { @@ -615,7 +578,7 @@ public function testTriggerAndHandleError() * @author Benjamin Carl * @return void * @access protected - * @expectedException \Clickalicious\Memcached\Exception + * @expectedException \Clickalicious\Memcached\Php\Exception */ public function testTriggerAndHandleClientError() { @@ -628,7 +591,7 @@ public function testTriggerAndHandleClientError() * @author Benjamin Carl * @return void * @access protected - * @expectedException \Clickalicious\Memcached\Exception + * @expectedException \Clickalicious\Memcached\Php\Exception */ public function testTriggerAndHandleServerError() { diff --git a/tests/UtilTest.php b/tests/UtilTest.php new file mode 100644 index 0000000..a2cf2c9 --- /dev/null +++ b/tests/UtilTest.php @@ -0,0 +1,337 @@ + + */ +class UtilTest extends \PHPUnit_Framework_TestCase +{ + /** + * PHP version running on. + * + * @var string + * @access protected + */ + protected $phpVersion; + + /** + * Controls if we need to test the array_column() + * + * @var bool + * @access protected + */ + protected $testProxy = true; + + /** + * The test data we work on. + * + * @var array + * @access protected + */ + protected $data; + + /** + * Prepare some stuff. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + protected function setUp() + { + $phpVersion = explode('.', PHP_VERSION); + $phpVersion = $phpVersion[0] . $phpVersion[1]; + + if ($phpVersion >= 5.5) { + $this->testProxy = false; + } + + // Test data + $this->data = array( + array( + 'id' => 2135, + 'first_name' => 'John', + 'last_name' => 'Doe', + ), + array( + 'id' => 3245, + 'first_name' => 'Sally', + 'last_name' => 'Smith', + ), + array( + 'id' => 5342, + 'first_name' => 'Jane', + 'last_name' => 'Jones', + ), + array( + 'id' => 5623, + 'first_name' => 'Peter', + 'last_name' => 'Doe', + ) + ); + } + + /** + * Test: array_column implementation. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + public function testArrayColumnEmulation() + { + /** + * Array + * ( + * [0] => John + * [1] => Sally + * [2] => Jane + * [3] => Peter + * ) + */ + $data = array_column_emulation($this->data, 'first_name'); + + $this->assertContains('John', $data); + $this->assertContains('Sally', $data); + $this->assertContains('Jane', $data); + $this->assertContains('Peter', $data); + + $this->assertArrayHasKey(0, $data); + $this->assertArrayHasKey(1, $data); + $this->assertArrayHasKey(2, $data); + $this->assertArrayHasKey(3, $data); + } + + /** + * Test: array_column implementation: id as index. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + public function testArrayColumnEmulationCustomIndex() + { + /** + * Array + * ( + * [2135] => Doe + * [3245] => Smith + * [5342] => Jones + * [5623] => Doe + * ) + */ + $data = array_column_emulation($this->data, 'first_name', 'id'); + + $this->assertContains('John', $data); + $this->assertContains('Sally', $data); + $this->assertContains('Jane', $data); + $this->assertContains('Peter', $data); + + $this->assertArrayHasKey(2135, $data); + $this->assertArrayHasKey(3245, $data); + $this->assertArrayHasKey(5342, $data); + $this->assertArrayHasKey(5623, $data); + } + + /** + * Test: array_column implementation: wrong id int as index. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + public function testArrayColumnEmulationWrongColumnString() + { + /** + * Array + * ( + * [2135] => Doe + * [3245] => Smith + * [5342] => Jones + * [5623] => Doe + * ) + */ + $data = array_column_emulation($this->data, 'foo'); + $this->assertArrayHasKey(0, $data); + $this->assertArrayHasKey(1, $data); + $this->assertArrayHasKey(2, $data); + $this->assertArrayHasKey(3, $data); + } + + /** + * Test: array_column implementation: custom int as index. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + public function testArrayColumnEmulationCustomIndexInt() + { + /** + * Array + * ( + * [2135] => Doe + * [3245] => Smith + * [5342] => Jones + * [5623] => Doe + * ) + */ + $data = array_column_emulation($this->data, 'first_name', 1); + $this->assertArrayHasKey(0, $data); + $this->assertArrayHasKey(1, $data); + $this->assertArrayHasKey(2, $data); + $this->assertArrayHasKey(3, $data); + } + + /** + * Test: array_column implementation: wrong id string as index. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + public function testArrayColumnEmulationCustomIndexString() + { + /** + * Array + * ( + * [2135] => Doe + * [3245] => Smith + * [5342] => Jones + * [5623] => Doe + * ) + */ + $data = array_column_emulation($this->data, 'first_name', 'foo'); + $this->assertArrayHasKey(0, $data); + $this->assertArrayHasKey(1, $data); + $this->assertArrayHasKey(2, $data); + $this->assertArrayHasKey(3, $data); + } + + /** + * Test: array_column implementation: error handling. + * + * @author Benjamin Carl + * @return void + * @access protected + * @expectedException \PHPUnit_Framework_Error + */ + public function testArrayColumnEmulationErrorHandlingWrongSecondArgument() + { + array_column_emulation($this->data, new \stdClass()); + } + + /** + * Test: array_column implementation: error handling. + * + * @author Benjamin Carl + * @return void + * @access protected + * @expectedException \PHPUnit_Framework_Error + */ + public function testArrayColumnEmulationErrorHandlingWrongThirdArgument() + { + array_column_emulation($this->data, 'first_name', new \stdClass()); + } + + /** + * Test: Set a key value pair. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + public function testArrayColumnProxy() + { + if ($this->testProxy === true) { + /** + * Array + * ( + * [0] => John + * [1] => Sally + * [2] => Jane + * [3] => Peter + * ) + */ + $data = \Clickalicious\Memcached\Php\array_column($this->data, 'first_name'); + + $this->assertContains('John', $data); + $this->assertContains('Sally', $data); + $this->assertContains('Jane', $data); + $this->assertContains('Peter', $data); + + $this->assertArrayHasKey(0, $data); + $this->assertArrayHasKey(1, $data); + $this->assertArrayHasKey(2, $data); + $this->assertArrayHasKey(3, $data); + } else { + $this->assertTrue(true); + } + } + + /** + * Test: Set a key value pair. + * + * @author Benjamin Carl + * @return void + * @access protected + */ + public function testBoolvalEmulation() + { + $data = true; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = 1; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = 'TRUE'; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = 'YES'; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = 'Y'; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = 'ON'; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = '1'; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = '-1'; + $this->assertTrue(\Clickalicious\Memcached\Php\boolval_emulation($data)); + + $data = false; + $this->assertFalse(\Clickalicious\Memcached\Php\boolval_emulation($data)); + } +} diff --git a/tests/phpunit.xml b/tests/phpunit.xml deleted file mode 100644 index 6cbf3d3..0000000 --- a/tests/phpunit.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - . - - - - - - ../src - - ../vendor - ../src/Clickalicious/Memcached/Autoloader.php - ../src/Clickalicious/Memcached/Bootstrap.php - ../src/Clickalicious/Memcached/Cache.php - ../src/Clickalicious/Memcached/Exception.php - ../src/Clickalicious/Memcached/Compression - - - - diff --git a/update-gh-pages.sh b/update-gh-pages.sh index 14dd9a1..07dd9bd 100644 --- a/update-gh-pages.sh +++ b/update-gh-pages.sh @@ -11,7 +11,7 @@ if [ $TRAVIS_PULL_REQUEST == 'false' ]; then git config --global user.name "Travis" #using token clone gh-pages branch - git clone --quiet --branch=gh-pages https://$GITHUBKEY@github.com/clickalicious/Memcached.php.git gh-pages > /dev/null 2>&1 + git clone --quiet --branch=gh-pages https://$GITHUBKEY@github.com/clickalicious/memcached-php.git gh-pages > /dev/null 2>&1 #go into diractory and copy data we're interested in to that directory cd gh-pages