├── .gitattributes ├── .gitignore ├── bin ├── mongo-proxy-darwin-amd64 ├── mongo-proxy-linux-amd64 └── build.sh ├── .phpstorm.meta.php ├── publish └── mongodb.php ├── phpunit.xml ├── .travis.yml ├── LICENSE ├── src ├── ConfigProvider.php └── DomainConfig.php ├── composer.json ├── README.md └── .php-cs-fixer.php /.gitattributes: -------------------------------------------------------------------------------- 1 | /tests export-ignore -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock 3 | *.cache 4 | *.log 5 | /.idea/ 6 | -------------------------------------------------------------------------------- /bin/mongo-proxy-darwin-amd64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reasno/fastmongo/HEAD/bin/mongo-proxy-darwin-amd64 -------------------------------------------------------------------------------- /bin/mongo-proxy-linux-amd64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reasno/fastmongo/HEAD/bin/mongo-proxy-linux-amd64 -------------------------------------------------------------------------------- /.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | env('MONGODB_URI', 'mongodb://127.0.0.1:27017'), 14 | 'connect_timeout' => env('MONGODB_CONNECT_TIMEOUT', '3s'), 15 | 'read_write_timeout' => env('MONGODB_READ_WRITE_TIMEOUT', '60s'), 16 | ]; 17 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | ./tests/ 14 | 15 | -------------------------------------------------------------------------------- /bin/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | package=../example/mongo_client/sidecar.go 3 | package_name=mongo-proxy 4 | 5 | #the full list of the platforms: https://golang.org/doc/install/source#environment 6 | platforms=( 7 | "darwin/amd64" 8 | "linux/amd64" 9 | ) 10 | 11 | for platform in "${platforms[@]}" 12 | do 13 | platform_split=(${platform//\// }) 14 | GOOS=${platform_split[0]} 15 | GOARCH=${platform_split[1]} 16 | output_name=$package_name'-'$GOOS'-'$GOARCH 17 | if [ $GOOS = "windows" ]; then 18 | output_name+='.exe' 19 | fi 20 | echo GOOS=$GOOS GOARCH=$GOARCH go build -ldflags="-s -w" -o $output_name $package 21 | GOOS=$GOOS GOARCH=$GOARCH go build -ldflags="-s -w" -o $output_name $package 22 | if [ $? -ne 0 ]; then 23 | echo 'An error has occurred! Aborting the script execution...' 24 | exit 1 25 | fi 26 | done 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | sudo: required 4 | 5 | matrix: 6 | include: 7 | - php: 7.2 8 | env: SW_VERSION="4.4.7" 9 | - php: 7.3 10 | env: SW_VERSION="4.4.7" 11 | - php: master 12 | env: SW_VERSION="4.4.7" 13 | 14 | allow_failures: 15 | - php: master 16 | 17 | services: 18 | - mysql 19 | - redis-server 20 | - docker 21 | 22 | before_install: 23 | - export PHP_MAJOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 1)" 24 | - export PHP_MINOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 2)" 25 | - echo $PHP_MAJOR 26 | - echo $PHP_MINOR 27 | 28 | install: 29 | - cd $TRAVIS_BUILD_DIR 30 | - bash ./tests/swoole.install.sh 31 | - phpenv config-rm xdebug.ini || echo "xdebug not available" 32 | - phpenv config-add ./tests/ci.ini 33 | 34 | before_script: 35 | - cd $TRAVIS_BUILD_DIR 36 | - composer config -g process-timeout 900 && composer update 37 | 38 | script: 39 | - composer analyse 40 | - composer test -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 谷溪 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/ConfigProvider.php: -------------------------------------------------------------------------------- 1 | [ 20 | \Hyperf\GoTask\Config\DomainConfig::class => DomainConfig::class, 21 | ], 22 | 'commands' => [ 23 | ], 24 | 'annotations' => [ 25 | 'scan' => [ 26 | 'paths' => [ 27 | __DIR__, 28 | ], 29 | ], 30 | ], 31 | 'publish' => [ 32 | [ 33 | 'id' => 'config', 34 | 'description' => 'The config for mongodb.', 35 | 'source' => __DIR__ . '/../publish/mongodb.php', 36 | 'destination' => BASE_PATH . '/config/autoload/mongodb.php', 37 | ], 38 | ], 39 | ]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reasno/fastmongo", 3 | "type": "library", 4 | "license": "MIT", 5 | "keywords": [ 6 | "php", 7 | "hyperf" 8 | ], 9 | "description": "mongodb driver via hyperf/gotask", 10 | "autoload": { 11 | "psr-4": { 12 | "Reasno\\Fastmongo\\": "src/" 13 | } 14 | }, 15 | "autoload-dev": { 16 | "psr-4": { 17 | "HyperfTest\\": "tests" 18 | } 19 | }, 20 | "require": { 21 | "php": ">=8.1", 22 | "ext-swoole": ">=5.0", 23 | "ext-mongodb": "*", 24 | "hyperf/gotask": "^3.0" 25 | }, 26 | "require-dev": { 27 | "friendsofphp/php-cs-fixer": "^3.21", 28 | "phpstan/phpstan": "^1.10", 29 | "hyperf/testing": "^3.0", 30 | "swoole/ide-helper": "^5.0" 31 | }, 32 | "minimum-stability": "dev", 33 | "prefer-stable": true, 34 | "config": { 35 | "sort-packages": true 36 | }, 37 | "scripts": { 38 | "test": "co-phpunit -c phpunit.xml --colors=always", 39 | "analyse": "phpstan analyse --memory-limit 300M -l 0 ./src", 40 | "cs-fix": "php-cs-fixer fix $1" 41 | }, 42 | "bin": ["bin/mongo-proxy-darwin-amd64", "bin/mongo-proxy-linux-amd64"], 43 | "extra": { 44 | "hyperf": { 45 | "config": "Reasno\\Fastmongo\\ConfigProvider" 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/DomainConfig.php: -------------------------------------------------------------------------------- 1 | addr = \Hyperf\GoTask\ConfigProvider::address(); 33 | $this->uri = $config->get('mongodb.uri', 'mongodb://127.0.0.1:27017'); 34 | $this->readWriteTimeout = $config->get('mongodb.read_write_timeout', '60s'); 35 | $this->connectTimeout = $config->get('mongodb.connect_timeout', '3s'); 36 | } 37 | 38 | public function getExecutable(): string 39 | { 40 | if ($this->isMac()) { 41 | return BASE_PATH . '/vendor/bin/mongo-proxy-darwin-amd64'; 42 | } 43 | return BASE_PATH . '/vendor/bin/mongo-proxy-linux-amd64'; 44 | } 45 | 46 | public function getArgs(): array 47 | { 48 | $args = parent::getArgs(); 49 | return array_merge($args, [ 50 | '-mongodb-uri', 51 | $this->uri, 52 | '-mongodb-connect-timeout', 53 | $this->connectTimeout, 54 | '-mongodb-read-write-timeout', 55 | $this->readWriteTimeout, 56 | ]); 57 | } 58 | 59 | public function getAddress(): string 60 | { 61 | $addr = parent::getAddress(); 62 | return ! empty($addr) ? $addr : $this->addr; 63 | } 64 | 65 | public function isEnabled(): bool 66 | { 67 | return true; 68 | } 69 | 70 | private function isMac() 71 | { 72 | return in_array(PHP_OS, [ 73 | 'Darwin', 74 | ]); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `reasno/fastmongo` is the a coroutine-based mongodb client for Hyperf, powered by `hyperf/gotask`. 2 | 3 | ## Installation 4 | 5 | ```php 6 | composer require reasno/fastmongo 7 | ``` 8 | - MongoDB extension is required. 9 | - MongoDB > 4.0 10 | - MongoDB PHP library is ***NOT*** required. 11 | - Go is ***NOT*** required. 12 | 13 | ## Configuration 14 | 15 | Just set the environmental variable MONGODB_URI. (Defaults to `mongodb://127.0.0.1:27017`) 16 | 17 | You may also use `php bin/hyperf.php vendor:publish reasno/fastmongo` to export a configuration. 18 | 19 | ## API List 20 | 21 | ```php 22 | my_database->my_col; 32 | $col->insertOne(['gender' => 'male', 'age' => 18]); 33 | $col->insertMany([['gender' => 'male', 'age' => 20], ['gender' => 'female', 'age' => 18]]); 34 | $col->countDocuments(); 35 | $col->findOne(['gender' => 'male']); 36 | $col->find(['gender' => 'male'], ['skip' => 1, 'limit' => 1]); 37 | $col->updateOne(['gender' => 'male'], ['$inc' => ['age' => 1]]); 38 | $col->updateMany(['gender' => 'male'], ['$inc' => ['age' => 1]]); 39 | $col->replaceOne(['gender' => 'female'], ['gender' => 'female', 'age' => 15]); 40 | $col->aggregate([ 41 | ['$match' => ['gender' => 'male']], 42 | ['$group' => ['_id' => '$gender', 'total' => ['$sum' => '$age']]], 43 | ]); 44 | $col->deleteOne(['gender' => 'male']); 45 | $col->deleteMany(['age' => 15]); 46 | $col->drop(); 47 | // if there is a command not yet supported, use runCommand or runCommandCursor. 48 | $client->my_database->runCommand(['ping' => 1]); 49 | return $client->my_database->runCommandCursor(['listCollections' => 1]); 50 | } 51 | } 52 | ``` 53 | 54 | ## Background 55 | 56 | This package makes use of `hyperf/gotask` to achieve coroutine. 57 | 58 | In `hyperf/gotask` v2.1.0 a new mongodb package is added. Normally GoTask requires you to do some coding in Go. However this approach demands some proficiency in Go, which can be prohibitive. `reasno/fastmongo` is a prebuilt version of the newly added mongodb package. It vendors the Go binary for you so you don't have to compile your own. 59 | 60 | This package only exposes a very simple yet optimized configuration interface. Should more customization be needed, checkout out the original `hyperf/gotask`. 61 | 62 | > Please do not turn on `hyperf/gotask` and this package at the same time. 63 | 64 | ## Future Scope 65 | * More mongodb commands can be added. Please feel free to create issues or submit your PRs to `hyperf/gotask`. 66 | 67 | 68 | -------------------------------------------------------------------------------- /.php-cs-fixer.php: -------------------------------------------------------------------------------- 1 | setRiskyAllowed(true) 14 | ->setRules([ 15 | '@PSR2' => true, 16 | '@Symfony' => true, 17 | '@DoctrineAnnotation' => true, 18 | '@PhpCsFixer' => true, 19 | 'header_comment' => [ 20 | 'comment_type' => 'PHPDoc', 21 | 'header' => $header, 22 | 'separate' => 'none', 23 | 'location' => 'after_declare_strict', 24 | ], 25 | 'array_syntax' => [ 26 | 'syntax' => 'short' 27 | ], 28 | 'list_syntax' => [ 29 | 'syntax' => 'short' 30 | ], 31 | 'concat_space' => [ 32 | 'spacing' => 'one' 33 | ], 34 | 'blank_line_before_statement' => [ 35 | 'statements' => [ 36 | 'declare', 37 | ], 38 | ], 39 | 'general_phpdoc_annotation_remove' => [ 40 | 'annotations' => [ 41 | 'author' 42 | ], 43 | ], 44 | 'ordered_imports' => [ 45 | 'imports_order' => [ 46 | 'class', 'function', 'const', 47 | ], 48 | 'sort_algorithm' => 'alpha', 49 | ], 50 | 'single_line_comment_style' => [ 51 | 'comment_types' => [ 52 | ], 53 | ], 54 | 'yoda_style' => [ 55 | 'always_move_variable' => false, 56 | 'equal' => false, 57 | 'identical' => false, 58 | ], 59 | 'phpdoc_align' => [ 60 | 'align' => 'left', 61 | ], 62 | 'multiline_whitespace_before_semicolons' => [ 63 | 'strategy' => 'no_multi_line', 64 | ], 65 | 'constant_case' => [ 66 | 'case' => 'lower', 67 | ], 68 | 'global_namespace_import' => [ 69 | 'import_classes' => true, 70 | 'import_constants' => true, 71 | 'import_functions' => true, 72 | ], 73 | 'class_attributes_separation' => true, 74 | 'combine_consecutive_unsets' => true, 75 | 'declare_strict_types' => true, 76 | 'linebreak_after_opening_tag' => true, 77 | 'lowercase_static_reference' => true, 78 | 'no_useless_else' => true, 79 | 'no_unused_imports' => true, 80 | 'not_operator_with_successor_space' => true, 81 | 'not_operator_with_space' => false, 82 | 'ordered_class_elements' => true, 83 | 'php_unit_strict' => false, 84 | 'phpdoc_separation' => false, 85 | 'single_quote' => true, 86 | 'standardize_not_equals' => true, 87 | 'multiline_comment_opening_closing' => true, 88 | ]) 89 | ->setFinder( 90 | PhpCsFixer\Finder::create() 91 | ->exclude('bin') 92 | ->exclude('public') 93 | ->exclude('runtime') 94 | ->exclude('vendor') 95 | ->in(__DIR__) 96 | ) 97 | ->setUsingCache(false); 98 | --------------------------------------------------------------------------------