├── .github └── workflows │ └── split.yml ├── .gitignore ├── LICENSE ├── README.md ├── README_EN.md ├── SWOOLE-ISSUES.md ├── bin ├── release.sh ├── split-darwin.sh ├── split-linux.sh ├── splitsh-lite-darwin └── splitsh-lite-linux ├── composer.json ├── docs ├── 3.0 │ ├── _navbar.md │ ├── index.html │ └── zh-cn │ │ ├── README.md │ │ ├── _navbar.md │ │ ├── benchmarks.md │ │ ├── faq.md │ │ ├── images │ │ ├── techempower-benchmark.png │ │ └── web-frameworks-benchmark.png │ │ ├── instructions.md │ │ ├── mix-cli.md │ │ ├── mix-database.md │ │ ├── mix-event.md │ │ ├── mix-grpc.md │ │ ├── mix-init.md │ │ ├── mix-redis-subscriber.md │ │ ├── mix-redis.md │ │ ├── mix-validator.md │ │ ├── mix-vega.md │ │ ├── mix-websocket.md │ │ ├── mix-worker-pool.md │ │ ├── online-chating.md │ │ ├── server-cli-server.md │ │ ├── server-php-fpm.md │ │ ├── server-swoole-coroutine.md │ │ ├── server-swoole.md │ │ ├── server-swow.md │ │ ├── server-workerman.md │ │ ├── summary.md │ │ ├── write-api.md │ │ ├── write-cli.md │ │ ├── write-grpc.md │ │ ├── write-web.md │ │ └── write-websocket.md └── index.html ├── examples ├── api-skeleton │ ├── .env │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── bin │ │ ├── cli.php │ │ ├── swoole.php │ │ ├── swooleco.php │ │ ├── swow.php │ │ └── workerman.php │ ├── composer.json │ ├── conf │ │ └── config.json │ ├── public │ │ └── index.php │ ├── routes │ │ └── index.php │ ├── runtime │ │ └── .gitignore │ ├── shell │ │ └── server.sh │ └── src │ │ ├── Command │ │ ├── ClearCache.php │ │ └── CoroutineRun.php │ │ ├── Container │ │ ├── Config.php │ │ ├── DB.php │ │ ├── DBLogger.php │ │ ├── Logger.php │ │ ├── RDS.php │ │ ├── RDSLogger.php │ │ └── Shutdown.php │ │ ├── Controller │ │ ├── Auth.php │ │ ├── Hello.php │ │ └── Users.php │ │ ├── Error.php │ │ ├── Middleware │ │ ├── AuthMiddleware.php │ │ └── CorsMiddleware.php │ │ ├── Once.php │ │ ├── Vega.php │ │ └── functions.php ├── cli-skeleton │ ├── .env │ ├── .gitignore │ ├── README.md │ ├── bin │ │ └── cli.php │ ├── composer.json │ ├── conf │ │ └── config.json │ ├── logs │ │ └── .gitignore │ └── src │ │ ├── Command │ │ ├── ClearCache.php │ │ └── CoroutineRun.php │ │ ├── Container │ │ ├── Config.php │ │ ├── DB.php │ │ ├── DBLogger.php │ │ ├── Logger.php │ │ ├── RDS.php │ │ └── RDSLogger.php │ │ ├── Error.php │ │ ├── Once.php │ │ └── functions.php ├── grpc-skeleton │ ├── .env │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── bin │ │ ├── cli.php │ │ ├── swoole.php │ │ ├── swooleco.php │ │ └── swoolecopool.php │ ├── composer.json │ ├── conf │ │ └── config.json │ ├── logs │ │ └── .gitignore │ ├── proto │ │ ├── GPBMetadata │ │ │ └── Greeter.php │ │ ├── Php │ │ │ └── Micro │ │ │ │ └── Grpc │ │ │ │ └── Greeter │ │ │ │ ├── Request.php │ │ │ │ ├── Response.php │ │ │ │ ├── SayClient.php │ │ │ │ └── SayInterface.php │ │ └── greeter.proto │ ├── shell │ │ └── server.sh │ └── src │ │ ├── Command │ │ ├── ClearCache.php │ │ └── CoroutineRun.php │ │ ├── Container │ │ ├── Config.php │ │ ├── DB.php │ │ ├── DBLogger.php │ │ ├── Logger.php │ │ ├── RDS.php │ │ ├── RDSLogger.php │ │ └── Shutdown.php │ │ ├── Error.php │ │ ├── Grpc.php │ │ ├── Once.php │ │ ├── Service │ │ └── Say.php │ │ └── functions.php ├── web-skeleton │ ├── .env │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── bin │ │ ├── cli.php │ │ ├── swoole.php │ │ ├── swooleco.php │ │ ├── swow.php │ │ └── workerman.php │ ├── composer.json │ ├── conf │ │ └── config.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.php │ │ └── static │ │ │ └── index.html │ ├── routes │ │ └── index.php │ ├── runtime │ │ └── .gitignore │ ├── shell │ │ └── server.sh │ ├── src │ │ ├── Command │ │ │ ├── ClearCache.php │ │ │ └── CoroutineRun.php │ │ ├── Container │ │ │ ├── Config.php │ │ │ ├── DB.php │ │ │ ├── DBLogger.php │ │ │ ├── Logger.php │ │ │ ├── RDS.php │ │ │ ├── RDSLogger.php │ │ │ └── Shutdown.php │ │ ├── Controller │ │ │ └── Hello.php │ │ ├── Error.php │ │ ├── Once.php │ │ ├── Vega.php │ │ └── functions.php │ └── views │ │ └── index.php └── websocket-skeleton │ ├── .env │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── bin │ ├── cli.php │ ├── swooleco.php │ └── swoolecopool.php │ ├── composer.json │ ├── conf │ └── config.json │ ├── routes │ └── index.php │ ├── runtime │ └── .gitignore │ ├── shell │ └── server.sh │ ├── src │ ├── Command │ │ ├── ClearCache.php │ │ └── CoroutineRun.php │ ├── Container │ │ ├── Config.php │ │ ├── DB.php │ │ ├── DBLogger.php │ │ ├── Logger.php │ │ ├── RDS.php │ │ ├── RDSLogger.php │ │ ├── Shutdown.php │ │ └── Upgrader.php │ ├── Controller │ │ └── WebSocket.php │ ├── Error.php │ ├── Handler │ │ └── Hello.php │ ├── Once.php │ ├── Service │ │ └── Session.php │ ├── Vega.php │ └── functions.php │ └── views │ └── index.php ├── src ├── auth │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Authorization.php │ │ ├── BearerTokenExtractor.php │ │ ├── Exception │ │ └── ExtractTokenException.php │ │ ├── JWT.php │ │ └── TokenExtractorInterface.php ├── bean │ ├── README.md │ ├── composer.json │ └── src │ │ ├── ApplicationContext.php │ │ ├── BeanDefinition.php │ │ ├── BeanFactoryInterface.php │ │ ├── BeanFactoryTrait.php │ │ ├── BeanInjector.php │ │ ├── Exception │ │ ├── InjectException.php │ │ ├── NotFoundException.php │ │ └── ScopeException.php │ │ ├── FileSystemApplicationContext.php │ │ └── PhpDocReader.php ├── cache │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Cache.php │ │ ├── FileHandler.php │ │ ├── Handler │ │ ├── ArrayHandler.php │ │ ├── FilesystemHandler.php │ │ ├── HandlerInterface.php │ │ └── RedisHandler.php │ │ └── RedisHandler.php ├── cli │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Application.php │ │ ├── Arguments.php │ │ ├── Argv.php │ │ ├── Cli.php │ │ ├── Color.php │ │ ├── Command.php │ │ ├── Exception │ │ │ └── NotFoundException.php │ │ ├── Flag.php │ │ ├── FlagValue.php │ │ ├── Option.php │ │ ├── Program.php │ │ ├── RunInterface.php │ │ └── functions.php │ └── tests │ │ ├── MainTest.php │ │ ├── bootstrap.php │ │ └── phpunit.sh ├── concurrent │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Coroutine.php │ │ ├── CoroutinePool │ │ ├── AbstractWorker.php │ │ └── Dispatcher.php │ │ ├── Exception │ │ └── TypeException.php │ │ ├── Sync │ │ └── WaitGroup.php │ │ ├── Timer.php │ │ └── functions.php ├── console │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Application.php │ │ ├── CommandLine │ │ ├── Argument.php │ │ ├── Color.php │ │ └── Flag.php │ │ ├── Error.php │ │ ├── Event │ │ ├── CommandBeforeExecuteEvent.php │ │ └── HandleExceptionEvent.php │ │ ├── Exception │ │ ├── ErrorException.php │ │ └── NotFoundException.php │ │ ├── Helper │ │ └── ConfigHelper.php │ │ ├── Mix.php │ │ ├── Process.php │ │ └── functions.php ├── context │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Context.php │ │ └── ValueContext.php ├── database │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── AbstractConnection.php │ │ ├── Connection.php │ │ ├── ConnectionInterface.php │ │ ├── Database.php │ │ ├── Driver.php │ │ ├── EmptyDriver.php │ │ ├── Expr.php │ │ ├── LoggerInterface.php │ │ ├── Pool │ │ │ ├── ConnectionPool.php │ │ │ └── Dialer.php │ │ ├── QueryBuilder.php │ │ └── Transaction.php │ └── tests │ │ ├── DeleteTest.php │ │ ├── InsertTest.php │ │ ├── PoolTest.php │ │ ├── RawTest.php │ │ ├── SelectTest.php │ │ ├── TransTest.php │ │ ├── UpdateTest.php │ │ ├── WhereTest.php │ │ ├── bootstrap.php │ │ ├── phpunit.sh │ │ └── test.sql ├── event │ ├── README.md │ ├── composer.json │ └── src │ │ ├── EventDispatcher.php │ │ ├── ListenerInterface.php │ │ └── ListenerProvider.php ├── fast-route │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Exception │ │ │ └── NotFoundException.php │ │ ├── Helper │ │ │ └── ConfigHelper.php │ │ ├── RouteCollector.php │ │ └── Router.php │ └── tests │ │ ├── MainTest.php │ │ └── bootstrap.php ├── grpc │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── composer.json │ ├── protoc-gen-mix │ │ ├── .gitignore │ │ ├── go.mod │ │ ├── go.sum │ │ ├── main.go │ │ ├── php │ │ │ ├── generate.go │ │ │ ├── keywords.go │ │ │ ├── ns.go │ │ │ ├── template.go │ │ │ └── template1.go │ │ ├── plugin_test.go │ │ └── testdata │ │ │ ├── import │ │ │ ├── Import │ │ │ │ └── ServiceInterface.php │ │ │ ├── service.proto │ │ │ └── sub │ │ │ │ └── message.proto │ │ │ ├── import_custom │ │ │ ├── Test │ │ │ │ └── CustomImport │ │ │ │ │ └── ServiceInterface.php │ │ │ ├── service.proto │ │ │ └── sub │ │ │ │ └── message.proto │ │ │ ├── php_namespace │ │ │ ├── Test │ │ │ │ └── CustomNamespace │ │ │ │ │ └── ServiceInterface.php │ │ │ └── service.proto │ │ │ ├── simple │ │ │ ├── TestSimple │ │ │ │ └── SimpleServiceInterface.php │ │ │ └── simple.proto │ │ │ └── use_empty │ │ │ ├── Test │ │ │ └── ServiceInterface.php │ │ │ └── service.proto │ ├── protos │ │ ├── GPBMetadata │ │ │ └── Greeter.php │ │ ├── Php │ │ │ └── Micro │ │ │ │ └── Grpc │ │ │ │ └── Greeter │ │ │ │ ├── Request.php │ │ │ │ ├── Response.php │ │ │ │ ├── SayClient.php │ │ │ │ └── SayInterface.php │ │ └── greeter.proto │ ├── src │ │ ├── Client.php │ │ ├── Client │ │ │ └── AbstractClient.php │ │ ├── Context.php │ │ ├── Exception │ │ │ ├── NotFoundException.php │ │ │ └── RuntimeException.php │ │ ├── Helper │ │ │ └── GrpcHelper.php │ │ ├── Server.php │ │ └── ServiceInterface.php │ └── tests │ │ ├── GoClientTest.php │ │ ├── GoServerTest.php │ │ ├── MainTest.php │ │ ├── benchmark.php │ │ ├── bootstrap.php │ │ ├── goclient │ │ ├── client.go │ │ ├── go.mod │ │ └── greeter.pb.go │ │ ├── goserver │ │ ├── go.mod │ │ ├── greeter.pb.go │ │ └── server.go │ │ └── phpunit.sh ├── guzzle │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Handler │ │ │ ├── Ring │ │ │ │ └── StreamHandler.php │ │ │ └── StreamHandler.php │ │ ├── hook.php │ │ └── hook │ │ │ ├── Handler │ │ │ ├── CurlHandler.php │ │ │ ├── Ring │ │ │ │ ├── CurlHandler.php │ │ │ │ └── StreamHandler.php │ │ │ └── StreamHandler.php │ │ │ └── functions.php │ └── tests │ │ └── MainTest.php ├── helper │ ├── README.md │ ├── composer.json │ └── src │ │ ├── FileSystemHelper.php │ │ ├── JsonHelper.php │ │ ├── NameHelper.php │ │ ├── PhpHelper.php │ │ ├── PidHelper.php │ │ ├── ProcessHelper.php │ │ ├── RandomStringHelper.php │ │ └── XmlHelper.php ├── http-message │ ├── .gitignore │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Cookie.php │ │ ├── Exception │ │ └── UnavailableMethodException.php │ │ ├── Factory │ │ ├── CookieFactory.php │ │ ├── RequestFactory.php │ │ ├── ResponseFactory.php │ │ ├── ServerRequestFactory.php │ │ ├── StreamFactory.php │ │ ├── UploadedFileFactory.php │ │ └── UriFactory.php │ │ ├── Message.php │ │ ├── Request.php │ │ ├── Response.php │ │ ├── ServerRequest.php │ │ ├── Stream │ │ ├── FileStream.php │ │ ├── IOStream.php │ │ ├── StringStream.php │ │ ├── SwooleResourceStream.php │ │ ├── SwowResourceStream.php │ │ └── WorkerManResourceStream.php │ │ ├── UploadedFile.php │ │ └── Uri.php ├── http-server │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Event │ │ │ └── HandledEvent.php │ │ ├── Exception │ │ │ ├── NotFoundException.php │ │ │ └── TypeException.php │ │ ├── FileServer.php │ │ ├── Helper │ │ │ └── ServerHelper.php │ │ ├── Middleware │ │ │ ├── MiddlewareDispatcher.php │ │ │ ├── MiddlewareInterface.php │ │ │ └── RequestHandler.php │ │ ├── Server.php │ │ └── ServerHandlerInterface.php │ └── tests │ │ ├── HackTest.php │ │ ├── MainTest.php │ │ └── bootstrap.php ├── init │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Composer │ │ │ ├── ClassMapGenerator.php │ │ │ ├── Filesystem.php │ │ │ ├── PcreException.php │ │ │ ├── PhpFileCleaner.php │ │ │ ├── Preg.php │ │ │ └── Silencer.php │ │ ├── Finder.php │ │ └── StaticInit.php │ └── tests │ │ ├── Example.php │ │ ├── Example1.php │ │ └── test.php ├── json-rpc │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Client │ │ │ ├── Connection.php │ │ │ └── Dialer.php │ │ ├── Constants.php │ │ ├── Event │ │ │ └── ProcessedEvent.php │ │ ├── Exception │ │ │ └── DeserializeException.php │ │ ├── Factory │ │ │ ├── RequestFactory.php │ │ │ └── ResponseFactory.php │ │ ├── Helper │ │ │ └── JsonRpcHelper.php │ │ ├── Message │ │ │ ├── Error.php │ │ │ ├── Request.php │ │ │ └── Response.php │ │ ├── Middleware │ │ │ ├── MiddlewareDispatcher.php │ │ │ ├── MiddlewareInterface.php │ │ │ └── RequestHandler.php │ │ ├── Server.php │ │ └── ServiceInterface.php │ └── tests │ │ └── ClientTest.php ├── micro-config │ ├── .gitignore │ ├── README.md │ ├── composer.json │ └── src │ │ ├── ConfigInterface.php │ │ └── Event │ │ ├── DeleteEvent.php │ │ └── PutEvent.php ├── micro-etcd │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Client │ │ │ ├── Client.php │ │ │ └── Watcher.php │ │ ├── Config.php │ │ ├── Exception │ │ │ └── UnavailableException.php │ │ ├── Factory │ │ │ ├── EndpointFactory.php │ │ │ ├── NodeFactory.php │ │ │ ├── RequestFactory.php │ │ │ ├── ResponseFactory.php │ │ │ └── ServiceFactory.php │ │ ├── LoadBalancer │ │ │ ├── LoadBalancerInterface.php │ │ │ ├── RandomBalancer.php │ │ │ └── RoundRobinBalancer.php │ │ ├── Monitor │ │ │ └── Monitor.php │ │ ├── Register │ │ │ └── Registrar.php │ │ ├── Registry.php │ │ └── Service │ │ │ ├── Endpoint.php │ │ │ ├── Node.php │ │ │ ├── Request.php │ │ │ ├── Response.php │ │ │ ├── Service.php │ │ │ └── Value.php │ └── tests │ │ ├── ServiceGetTest.php │ │ ├── ServiceRegisterTest.php │ │ └── bootstrap.php ├── micro-hystrix │ ├── .gitignore │ ├── README.md │ ├── composer.json │ └── src │ │ ├── CircuitBreaker.php │ │ ├── Command.php │ │ ├── CommandRuntime.php │ │ ├── Event │ │ └── StatusChangeEvent.php │ │ └── Exception │ │ ├── NotFoundException.php │ │ └── TimeoutException.php ├── micro-register │ ├── .gitignore │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Exception │ │ └── NotFoundException.php │ │ ├── Helper │ │ └── ServiceHelper.php │ │ ├── RegistryInterface.php │ │ └── ServiceInterface.php ├── micro-route │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Router.php │ │ └── RouterInterface.php ├── micro-server │ ├── README.md │ ├── composer.json │ └── src │ │ └── ServerInterface.php ├── micro │ ├── LICENSE │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Micro.php │ │ ├── Options.php │ │ └── Service.php ├── monolog │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Handler │ │ ├── ConsoleHandler.php │ │ ├── RotatingFileHandler.php │ │ └── StreamHandler.php │ │ └── Logger.php ├── object-pool │ ├── README.md │ ├── composer.json │ └── src │ │ ├── AbstractObjectPool.php │ │ ├── DialerInterface.php │ │ ├── Exception │ │ └── WaitTimeoutException.php │ │ └── ObjectTrait.php ├── redis-subscriber │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── CommandInvoker.php │ │ ├── Connection.php │ │ ├── Exception │ │ │ ├── SubscribeException.php │ │ │ └── UnsubscribeException.php │ │ ├── Message.php │ │ ├── Resp.php │ │ └── Subscriber.php │ └── tests │ │ ├── MainTest.php │ │ ├── RespTest.php │ │ ├── bootstrap.php │ │ └── phpunit.sh ├── redis │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── AbstractConnection.php │ │ ├── Connection.php │ │ ├── ConnectionInterface.php │ │ ├── Driver.php │ │ ├── EmptyDriver.php │ │ ├── LoggerInterface.php │ │ ├── Multi.php │ │ ├── Pipeline.php │ │ ├── Pool │ │ │ ├── ConnectionPool.php │ │ │ └── Dialer.php │ │ ├── Redis.php │ │ └── ScanTrait.php │ └── tests │ │ ├── MainTest.php │ │ ├── PoolTest.php │ │ ├── bootstrap.php │ │ └── phpunit.sh ├── route │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Exception │ │ └── NotFoundException.php │ │ ├── Result.php │ │ └── Router.php ├── runtime │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Context │ │ │ ├── CancelContext.php │ │ │ ├── Context.php │ │ │ ├── TimeoutContext.php │ │ │ └── ValueContext.php │ │ ├── Coroutine │ │ │ ├── Channel.php │ │ │ └── Coroutine.php │ │ ├── Process │ │ │ └── Process.php │ │ ├── Select │ │ │ ├── Clause │ │ │ │ ├── ClauseIntercase.php │ │ │ │ ├── PopClause.php │ │ │ │ └── PushClause.php │ │ │ ├── Clauses.php │ │ │ └── Select.php │ │ ├── Signal │ │ │ └── SignalNotify.php │ │ ├── Sync │ │ │ └── WaitGroup.php │ │ ├── Time │ │ │ ├── Ticker.php │ │ │ ├── Time.php │ │ │ └── Timer.php │ │ └── functions.php │ └── tests │ │ ├── ContextTest.php │ │ ├── SelectTest.php │ │ ├── TimeTest.php │ │ └── bootstrap.php ├── server │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Connection.php │ │ ├── ConnectionManager.php │ │ ├── Exception │ │ └── ReceiveException.php │ │ ├── Server.php │ │ └── ServerHandlerInterface.php ├── session │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Handler │ │ ├── HandlerInterface.php │ │ └── RedisHandler.php │ │ ├── RedisHandler.php │ │ └── Session.php ├── sync-invoke │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Client │ │ │ ├── Client.php │ │ │ ├── Connection.php │ │ │ ├── Dialer.php │ │ │ ├── Driver.php │ │ │ └── Pool │ │ │ │ ├── ConnectionPool.php │ │ │ │ └── Dialer.php │ │ ├── Constants.php │ │ ├── Event │ │ │ ├── CalledEvent.php │ │ │ └── InvokedEvent.php │ │ ├── Exception │ │ │ ├── CallException.php │ │ │ └── InvokeException.php │ │ └── Server.php │ └── tests │ │ ├── MainTest.php │ │ ├── PoolTest.php │ │ └── bootstrap.php ├── tracing-zipkin │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Exception │ │ │ ├── NotFoundException.php │ │ │ └── UnavailableException.php │ │ ├── Reporter │ │ │ └── GuzzleFactory.php │ │ ├── Scope │ │ │ └── Scope.php │ │ ├── Span │ │ │ ├── Span.php │ │ │ └── SpanContext.php │ │ ├── Tracer.php │ │ └── Zipkin.php │ └── tests │ │ ├── TracerTest.php │ │ └── bootstrap.php ├── tracing │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Grpc │ │ ├── TracingClientMiddleware.php │ │ └── TracingServerMiddleware.php │ │ ├── Http │ │ └── TracingServerMiddleware.php │ │ ├── JsonRpc │ │ ├── TracingClientMiddleware.php │ │ └── TracingServerMiddleware.php │ │ └── Tracing.php ├── validator │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── AlphaNumericValidator.php │ │ ├── AlphaValidator.php │ │ ├── BaseValidator.php │ │ ├── CallValidator.php │ │ ├── CompareValidator.php │ │ ├── DateValidator.php │ │ ├── DoubleValidator.php │ │ ├── EmailValidator.php │ │ ├── Exception │ │ │ └── InvalidArgumentException.php │ │ ├── FileValidator.php │ │ ├── ImageValidator.php │ │ ├── InValidator.php │ │ ├── IntegerValidator.php │ │ ├── MatchValidator.php │ │ ├── PhoneValidator.php │ │ ├── StringValidator.php │ │ ├── UrlValidator.php │ │ ├── Validate.php │ │ └── Validator.php │ └── tests │ │ ├── MainTest.php │ │ ├── bootstrap.php │ │ └── phpunit.sh ├── vega │ ├── .gitignore │ ├── README.md │ ├── README_EN.md │ ├── composer.json │ ├── composer.lock │ ├── src │ │ ├── Abort.php │ │ ├── Context.php │ │ ├── Engine.php │ │ ├── Exception │ │ │ ├── NotFoundException.php │ │ │ └── RuntimeException.php │ │ ├── Input.php │ │ ├── Route.php │ │ ├── Router.php │ │ ├── RouterPrefix.php │ │ ├── StaticFile.php │ │ ├── Store.php │ │ └── Writer.php │ └── tests │ │ ├── SwooleCurlTest.php │ │ ├── SwooleServerTest.php │ │ ├── WorkerManCurlTest.php │ │ ├── bootstrap.php │ │ ├── phpunit.sh │ │ ├── public │ │ ├── favicon.ico │ │ └── static │ │ │ └── test.js │ │ ├── views │ │ └── foo.php │ │ └── workerman.php ├── view │ ├── README.md │ ├── composer.json │ └── src │ │ ├── Exception │ │ └── ViewException.php │ │ ├── Renderer.php │ │ └── View.php ├── websocket │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ │ ├── Client.php │ │ ├── Connection.php │ │ ├── ConnectionManager.php │ │ ├── Exception │ │ │ ├── CloseFrameException.php │ │ │ ├── ReadMessageException.php │ │ │ ├── UpgradeException.php │ │ │ └── WriteMessageException.php │ │ └── Upgrader.php │ └── tests │ │ ├── MainTest.php │ │ ├── bootstrap.php │ │ └── phpunit.sh └── worker-pool │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── src │ ├── Exception │ │ └── TypeException.php │ ├── RunInterface.php │ ├── Worker.php │ └── WorkerPool.php │ └── tests │ ├── MainTest.php │ ├── bootstrap.php │ └── phpunit.sh ├── techempower-benchmark.png └── web-frameworks-benchmark.png /.github/workflows/split.yml: -------------------------------------------------------------------------------- 1 | name: Split 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | jobs: 7 | split: 8 | runs-on: ubuntu-latest 9 | env: 10 | TOKEN: ${{ secrets.ACCESS_TOKEN }} 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | with: 15 | persist-credentials: false 16 | fetch-depth: 0 17 | - name: Run 18 | run: | 19 | git config pull.rebase true 20 | git config --global user.email "actions@github.com" 21 | git config --global user.name "actions-bot" 22 | bash ./bin/split-linux.sh 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer 16 | composer.phar 17 | /vendor 18 | /composer.lock 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit 24 | phpunit.phar 25 | /phpunit.xml 26 | 27 | # vscode 28 | /.vscode 29 | -------------------------------------------------------------------------------- /SWOOLE-ISSUES.md: -------------------------------------------------------------------------------- 1 | ## Swoole Issues 2 | 3 | - [WebScoket] Coroutine\Http\Server shutdown 在 4.4.13 能实现关闭开启的全部连接,但在 4.4.13 ~ 4.4.14 中有 bug,会提示 Http\Response::close(): http response is unavailable 影响到 WebSocket 服务器无法 shutdown 4 | - [WebScoket] Coroutine\Http\Response->close 在 4.4.8 才加入,能实现 websocket 关闭连接 5 | - [WebScoket] Coroutine\Http\Client->send "incorrect mask flag" 在 4.4.13 才修复 6 | - [ALL] Coroutine\Server $reuse_port 在 4.4.4 或更高版本中可用 7 | - [HTTP] Coroutine\Http\Request->rawContent() 在 4.4.1 才解决内存溢出问题,4.5.0 修改为 getContent() 8 | - [Micro] 4.5.0 才解决 http_compression = false 的问题 https://github.com/swoole/swoole-src/issues/3256 9 | - [HTTP2] 4.5.0 才解决 open_http2_protocol Server Keep-Alive shutdown 问题 https://github.com/swoole/swoole-src/issues/2837#issuecomment-618308281 10 | - [Signal] 发现 signal 之前执行 fopen 和其他文件操作,因为是串行,会导致 signal 失效,Swoole >= 4.5.3 已经解决该问题 11 | - [Hook] >= 4.5.4 SWOOLE_HOOK_ALL 被修改为默认包含了 SWOOLE_HOOK_CURL 12 | - [Hook] php-di/phpdoc-reader 在 swoole >= 4.6 时会在执行过程中切换协程,导致 ApplicationContext->get($beanName) 会多次实例化 13 | -------------------------------------------------------------------------------- /bin/split-darwin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | NOW=$(date +%s) 7 | TOKEN="" 8 | WORKDIR="src" 9 | CURRENT_BRANCH="master" 10 | BASEPATH=$(cd `dirname $0`; cd ../$WORKDIR/; pwd) 11 | REPOS=$@ 12 | 13 | function split() 14 | { 15 | SHA1=`./bin/splitsh-lite-darwin --prefix=$1` 16 | git push $2 "$SHA1:refs/heads/$CURRENT_BRANCH" -f 17 | } 18 | 19 | function remote() 20 | { 21 | git remote add $1 $2 || true 22 | } 23 | 24 | git pull origin $CURRENT_BRANCH 25 | 26 | if [[ $# -eq 0 ]]; then 27 | REPOS=$(ls $BASEPATH) 28 | fi 29 | 30 | for REPO in $REPOS ; do 31 | remote $REPO https://$TOKEN@github.com/mix-php/$REPO.git 32 | 33 | split "$WORKDIR/$REPO" $REPO 34 | done 35 | 36 | TIME=$(echo "$(date +%s) - $NOW" | bc) 37 | printf "Execution time: %f seconds\n" $TIME 38 | -------------------------------------------------------------------------------- /bin/splitsh-lite-darwin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/bin/splitsh-lite-darwin -------------------------------------------------------------------------------- /bin/splitsh-lite-linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/bin/splitsh-lite-linux -------------------------------------------------------------------------------- /docs/3.0/_navbar.md: -------------------------------------------------------------------------------- 1 | * 多语言/Translations 2 | * [简体中文](zh-cn/) -------------------------------------------------------------------------------- /docs/3.0/zh-cn/_navbar.md: -------------------------------------------------------------------------------- 1 | * 多语言/Translations 2 | * [简体中文](zh-cn/) -------------------------------------------------------------------------------- /docs/3.0/zh-cn/benchmarks.md: -------------------------------------------------------------------------------- 1 | ## TechEmpower Benchmark 2 | 3 | TechEmpower 的测试比较科学,包含 SQL 查询、JSON 序列化等各种测试,同时标注了哪些是使用了 ORM,哪些是 RAW 查询。 4 | 5 | - [TechEmpower Benchmark](https://www.techempower.com/benchmarks/#section=data-r21&test=db&l=zik073-6bj) 6 | - 在 WorkerMan 平台下:MixPHP 与 WorkerMan 官方的 webman 旗鼓相当相差很小,在实际生产中由于 webman 是使用的 laveral orm,性能要比 mix/database 低很多。 7 | - 在 Swoole 平台下:MixPHP 也只比 simps 低一些,但是由于 simps 使用的原生查询,因此综合性能 MixPHP 应该更高一些。 8 | 9 | ![techempower-benchmark.png](images/techempower-benchmark.png) 10 | 11 | ## Web Frameworks Benchmark 12 | 13 | 这个测试只包含路由与 echo 测试,因此只能证明基础平台协议解析与框架路由的性能。 14 | 15 | - [Web Frameworks Benchmark](https://web-frameworks-benchmark.netlify.app/result?l=php) 16 | - 由于这个测试的规则特性,有些框架采用 TCP 直接解析请求参数、TCP 直接发送 HTTP 协议字符串的方式投机,MixPHP 没有这么做,性能依然高于流行的大部分其他框架。 17 | 18 | ![web-frameworks-benchmark.png](images/web-frameworks-benchmark.png) 19 | -------------------------------------------------------------------------------- /docs/3.0/zh-cn/images/techempower-benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/docs/3.0/zh-cn/images/techempower-benchmark.png -------------------------------------------------------------------------------- /docs/3.0/zh-cn/images/web-frameworks-benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/docs/3.0/zh-cn/images/web-frameworks-benchmark.png -------------------------------------------------------------------------------- /docs/3.0/zh-cn/mix-init.md: -------------------------------------------------------------------------------- 1 | ## Mix Init 2 | 3 | Help execute static initialization of the class, usually for preloading singletons 4 | 5 | 帮助执行类的静态初始化,通常用于预加载单例 6 | 7 | ## Installation 8 | 9 | ``` 10 | composer require mix/init 11 | ``` 12 | 13 | ## Quick start 14 | 15 | 定义类的静态初始化方法 16 | 17 | ```php 18 | class Example 19 | { 20 | public static function init() 21 | { 22 | // do something 23 | } 24 | } 25 | ``` 26 | 27 | 从目录执行 28 | 29 | > 可以通过定制方法名称,达到在不同的场景初始化的目的 30 | 31 | ```php 32 | Mix\Init\StaticInit::finder('/path/classdir')->exec('init'); 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/3.0/zh-cn/online-chating.md: -------------------------------------------------------------------------------- 1 | ## QQ 交流群 2 | 3 | 敲门暗号:`phper` 4 | 5 | - OpenMix 技术交流 A 群: [284806582](https://shang.qq.com/wpa/qunwpa?idkey=b3a8618d3977cda4fed2363a666b081a31d89e3d31ab164497f53b72cf49968a) 6 | - OpenMix 技术交流 B 群: [825122875](http://shang.qq.com/wpa/qunwpa?idkey=d2908b0c7095fc7ec63a2391fa4b39a8c5cb16952f6cfc3f2ce4c9726edeaf20) 7 | 8 | ## 知乎 9 | 10 | - 作者: https://www.zhihu.com/people/onanying 11 | - MixPHP 专栏: https://www.zhihu.com/column/mix-php 12 | 13 | ## 推荐阅读 14 | 15 | - [MixPHP V3 开发流程体验 Swoole, Workerman, FPM, CLI-Server 多种运行模式介绍](https://zhuanlan.zhihu.com/p/398381870) 16 | - [MixPHP V3 增加了 PHP-FPM、CLI-Server 的支持](https://zhuanlan.zhihu.com/p/394059925) 17 | - [MixPHP V3 发布前的感想, 有哪些变化和特点](https://zhuanlan.zhihu.com/p/392558932) 18 | -------------------------------------------------------------------------------- /docs/3.0/zh-cn/server-cli-server.md: -------------------------------------------------------------------------------- 1 | # PHP Built-in CLI-Server 2 | 3 | [CLI-Server](https://www.php.net/manual/zh/features.commandline.webserver.php) 是 PHP 内置的 Web 服务器,具有 `零扩展依赖` `热更新` `适合本机开发` 的特点。 4 | 5 | ## 入口文件 6 | 7 | 骨架路径 `public/index.php` 8 | 9 | ```php 10 | load(); 22 | define("APP_DEBUG", env('APP_DEBUG')); 23 | 24 | Error::register(); 25 | 26 | return Vega::new()->run(); 27 | ``` 28 | 29 | ## 启动服务 30 | 31 | - API 32 | 33 | ``` 34 | php -S localhost:8000 public/index.php 35 | ``` 36 | 37 | - Web 38 | 39 | 支持静态文件处理 40 | 41 | ``` 42 | php -S localhost:8000 -t public 43 | ``` -------------------------------------------------------------------------------- /examples/api-skeleton/.env: -------------------------------------------------------------------------------- 1 | # APP 2 | APP_DEBUG=true 3 | 4 | # DATABASE 5 | DATABASE_DSN='mysql:host=127.0.0.1;port=3306;charset=utf8;dbname=test' 6 | DATABASE_USERNAME=root 7 | DATABASE_PASSWORD=123456 8 | 9 | # REDIS 10 | REDIS_HOST=127.0.0.1 11 | REDIS_PORT=6379 12 | REDIS_DATABASE=0 13 | REDIS_PASSWORD= 14 | 15 | # JWT 16 | JWT_KEY=my_secret_key 17 | -------------------------------------------------------------------------------- /examples/api-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | composer.lock 18 | vendor/ 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit itself is not needed 24 | phpunit.phar 25 | # local phpunit config 26 | /phpunit.xml 27 | -------------------------------------------------------------------------------- /examples/api-skeleton/bin/cli.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | load(); 14 | define("APP_DEBUG", env('APP_DEBUG')); 15 | 16 | Error::register(); 17 | 18 | Cli::setName('app')->setVersion('0.0.0-alpha'); 19 | $cmds = [ 20 | new Mix\Cli\Command([ 21 | 'name' => 'clearcache', 22 | 'short' => 'Clear cache', 23 | 'options' => [ 24 | new Mix\Cli\Option([ 25 | 'names' => ['k', 'key'], 26 | 'usage' => 'Key name' 27 | ]), 28 | ], 29 | 'run' => new App\Command\ClearCache(), 30 | ]) 31 | ]; 32 | Cli::addCommand(...$cmds)->run(); 33 | -------------------------------------------------------------------------------- /examples/api-skeleton/conf/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } -------------------------------------------------------------------------------- /examples/api-skeleton/public/index.php: -------------------------------------------------------------------------------- 1 | load(); 13 | define("APP_DEBUG", env('APP_DEBUG')); 14 | 15 | Error::register(); 16 | 17 | return Vega::new()->run(); 18 | -------------------------------------------------------------------------------- /examples/api-skeleton/routes/index.php: -------------------------------------------------------------------------------- 1 | handle('/hello', [new Hello(), 'index'])->methods('GET'); 10 | $vega->handle('/users/{id}', /* AuthMiddleware::callback(), */ [new Users(), 'index'])->methods('GET'); 11 | $vega->handle('/auth', [new Auth(), 'index'])->methods('GET'); 12 | }; 13 | -------------------------------------------------------------------------------- /examples/api-skeleton/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /examples/api-skeleton/src/Command/ClearCache.php: -------------------------------------------------------------------------------- 1 | string(); 19 | RDS::instance()->del($key); 20 | print 'ok'; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /examples/api-skeleton/src/Command/CoroutineRun.php: -------------------------------------------------------------------------------- 1 | do(function () { 39 | self::$instance = new \Noodlehaus\Config(__DIR__ . '/../../conf'); 40 | }); 41 | } 42 | return self::$instance; 43 | } 44 | 45 | } 46 | 47 | Config::init(); 48 | -------------------------------------------------------------------------------- /examples/api-skeleton/src/Container/DBLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('SQL: %sms %s %s %d', $time, $sql, json_encode($bindings), $rowCount)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/api-skeleton/src/Container/RDSLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('RDS: %sms %s %s', $time, $cmd, json_encode($args))); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /examples/api-skeleton/src/Container/Shutdown.php: -------------------------------------------------------------------------------- 1 | "http://example.org", // 签发人 19 | 'iat' => $time, // 签发时间 20 | 'exp' => $time + 7200, // 过期时间 21 | 'uid' => 100008, 22 | ]; 23 | $token = JWT::encode($payload, $_ENV['JWT_KEY'], 'HS256'); 24 | $ctx->JSON(200, [ 25 | 'code' => 0, 26 | 'message' => 'ok', 27 | 'data' => [ 28 | 'access_token' => $token, 29 | 'expire_in' => 7200, 30 | ] 31 | ]); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /examples/api-skeleton/src/Controller/Hello.php: -------------------------------------------------------------------------------- 1 | string(200, 'hello, world!'); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /examples/api-skeleton/src/Controller/Users.php: -------------------------------------------------------------------------------- 1 | table('users')->where('id = ?', $ctx->param('id'))->first(); 18 | if (!$row) { 19 | throw new \Exception('User not found'); 20 | } 21 | $ctx->JSON(200, [ 22 | 'code' => 0, 23 | 'message' => 'ok', 24 | 'data' => $row 25 | ]); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /examples/api-skeleton/src/Middleware/CorsMiddleware.php: -------------------------------------------------------------------------------- 1 | setHeader('Access-Control-Allow-Origin', '*'); 21 | $ctx->setHeader('Access-Control-Allow-Headers', 'Origin, Accept, Keep-Alive, User-Agent, Cache-Control, Content-Type, X-Requested-With, Authorization'); 22 | $ctx->setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS'); 23 | if ($ctx->request->getMethod() == 'OPTIONS') { 24 | $ctx->abortWithStatus(200); 25 | } 26 | 27 | $ctx->next(); 28 | }; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /examples/cli-skeleton/.env: -------------------------------------------------------------------------------- 1 | # APP 2 | APP_DEBUG=true 3 | 4 | # DATABASE 5 | DATABASE_DSN='mysql:host=127.0.0.1;port=3306;charset=utf8;dbname=test' 6 | DATABASE_USERNAME=root 7 | DATABASE_PASSWORD=123456 8 | 9 | # REDIS 10 | REDIS_HOST=127.0.0.1 11 | REDIS_PORT=6379 12 | REDIS_DATABASE=0 13 | REDIS_PASSWORD= 14 | -------------------------------------------------------------------------------- /examples/cli-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | composer.lock 18 | vendor/ 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit itself is not needed 24 | phpunit.phar 25 | # local phpunit config 26 | /phpunit.xml 27 | -------------------------------------------------------------------------------- /examples/cli-skeleton/bin/cli.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | load(); 14 | define("APP_DEBUG", env('APP_DEBUG')); 15 | 16 | Error::register(); 17 | 18 | Cli::setName('app')->setVersion('0.0.0-alpha'); 19 | $cmds = [ 20 | new Mix\Cli\Command([ 21 | 'name' => 'clearcache', 22 | 'short' => 'Clear cache', 23 | 'options' => [ 24 | new Mix\Cli\Option([ 25 | 'names' => ['k', 'key'], 26 | 'usage' => 'Key name' 27 | ]), 28 | ], 29 | 'run' => new App\Command\ClearCache(), 30 | ]) 31 | ]; 32 | Cli::addCommand(...$cmds)->run(); 33 | -------------------------------------------------------------------------------- /examples/cli-skeleton/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/cli-skeleton", 3 | "description": "CLI development skeleton", 4 | "type": "project", 5 | "homepage": "https://openmix.org/mix-php", 6 | "license": "Apache-2.0", 7 | "scripts": { 8 | "cli:clearcache": [ 9 | "Composer\\Config::disableProcessTimeout", 10 | "php bin/cli.php clearcache" 11 | ] 12 | }, 13 | "autoload": { 14 | "psr-4": { 15 | "App\\": "src/" 16 | }, 17 | "files": [ 18 | "src/functions.php" 19 | ] 20 | }, 21 | "require": { 22 | "mix/cli": "~3.0.0", 23 | "mix/database": "~3.0.0", 24 | "mix/redis": "~3.0.0", 25 | "vlucas/phpdotenv": "^5.3", 26 | "hassankhan/config": "^3.0", 27 | "monolog/monolog": "^3.1" 28 | }, 29 | "require-dev": { 30 | "swoole/ide-helper": "^4.6" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/cli-skeleton/conf/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } -------------------------------------------------------------------------------- /examples/cli-skeleton/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /examples/cli-skeleton/src/Command/ClearCache.php: -------------------------------------------------------------------------------- 1 | string(); 19 | RDS::instance()->del($key); 20 | print 'ok'; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /examples/cli-skeleton/src/Command/CoroutineRun.php: -------------------------------------------------------------------------------- 1 | do(function () { 39 | self::$instance = new \Noodlehaus\Config(__DIR__ . '/../../conf'); 40 | }); 41 | } 42 | return self::$instance; 43 | } 44 | 45 | } 46 | 47 | Config::init(); 48 | -------------------------------------------------------------------------------- /examples/cli-skeleton/src/Container/DBLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('SQL: %sms %s %s %d', $time, $sql, json_encode($bindings), $rowCount)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/cli-skeleton/src/Container/RDSLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('RDS: %sms %s %s', $time, $cmd, json_encode($args))); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /examples/grpc-skeleton/.env: -------------------------------------------------------------------------------- 1 | # APP 2 | APP_DEBUG=true 3 | 4 | # DATABASE 5 | DATABASE_DSN='mysql:host=127.0.0.1;port=3306;charset=utf8;dbname=test' 6 | DATABASE_USERNAME=root 7 | DATABASE_PASSWORD=123456 8 | 9 | # REDIS 10 | REDIS_HOST=127.0.0.1 11 | REDIS_PORT=6379 12 | REDIS_DATABASE=0 13 | REDIS_PASSWORD= 14 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | composer.lock 18 | vendor/ 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit itself is not needed 24 | phpunit.phar 25 | # local phpunit config 26 | /phpunit.xml 27 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/bin/cli.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | load(); 14 | define("APP_DEBUG", env('APP_DEBUG')); 15 | 16 | Error::register(); 17 | 18 | Cli::setName('app')->setVersion('0.0.0-alpha'); 19 | $cmds = [ 20 | new Mix\Cli\Command([ 21 | 'name' => 'clearcache', 22 | 'short' => 'Clear cache', 23 | 'options' => [ 24 | new Mix\Cli\Option([ 25 | 'names' => ['k', 'key'], 26 | 'usage' => 'Key name' 27 | ]), 28 | ], 29 | 'run' => new App\Command\ClearCache(), 30 | ]) 31 | ]; 32 | Cli::addCommand(...$cmds)->run(); 33 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/conf/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } -------------------------------------------------------------------------------- /examples/grpc-skeleton/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /examples/grpc-skeleton/proto/GPBMetadata/Greeter.php: -------------------------------------------------------------------------------- 1 | internalAddGeneratedFile(hex2bin( 18 | "0ab6010a0d677265657465722e70726f746f12167068702e6d6963726f2e677270632e6772656574657222170a0752657175657374120c0a046e616d6518012001280922170a08526573706f6e7365120b0a036d736718012001280932530a03536179124c0a0548656c6c6f121f2e7068702e6d6963726f2e677270632e677265657465722e526571756573741a202e7068702e6d6963726f2e677270632e677265657465722e526573706f6e73652200620670726f746f33" 19 | ), true); 20 | 21 | static::$is_initialized = true; 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/proto/Php/Micro/Grpc/Greeter/SayClient.php: -------------------------------------------------------------------------------- 1 | _simpleRequest('/php.micro.grpc.greeter.Say/Hello', $context, $request, new Response()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/proto/Php/Micro/Grpc/Greeter/SayInterface.php: -------------------------------------------------------------------------------- 1 | string(); 19 | RDS::instance()->del($key); 20 | print 'ok'; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/src/Command/CoroutineRun.php: -------------------------------------------------------------------------------- 1 | do(function () { 39 | self::$instance = new \Noodlehaus\Config(__DIR__ . '/../../conf'); 40 | }); 41 | } 42 | return self::$instance; 43 | } 44 | 45 | } 46 | 47 | Config::init(); 48 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/src/Container/DBLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('SQL: %sms %s %s %d', $time, $sql, json_encode($bindings), $rowCount)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/src/Container/RDSLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('RDS: %sms %s %s', $time, $cmd, json_encode($args))); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /examples/grpc-skeleton/src/Container/Shutdown.php: -------------------------------------------------------------------------------- 1 | register(Say::class); 22 | return $server; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/grpc-skeleton/src/Service/Say.php: -------------------------------------------------------------------------------- 1 | setMsg(sprintf('hello, %s', $request->getName())); 25 | return $response; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /examples/web-skeleton/.env: -------------------------------------------------------------------------------- 1 | # APP 2 | APP_DEBUG=true 3 | 4 | # DATABASE 5 | DATABASE_DSN='mysql:host=127.0.0.1;port=3306;charset=utf8;dbname=test' 6 | DATABASE_USERNAME=root 7 | DATABASE_PASSWORD=123456 8 | 9 | # REDIS 10 | REDIS_HOST=127.0.0.1 11 | REDIS_PORT=6379 12 | REDIS_DATABASE=0 13 | REDIS_PASSWORD= 14 | -------------------------------------------------------------------------------- /examples/web-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | composer.lock 18 | vendor/ 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit itself is not needed 24 | phpunit.phar 25 | # local phpunit config 26 | /phpunit.xml 27 | -------------------------------------------------------------------------------- /examples/web-skeleton/bin/cli.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | load(); 14 | define("APP_DEBUG", env('APP_DEBUG')); 15 | 16 | Error::register(); 17 | 18 | Cli::setName('app')->setVersion('0.0.0-alpha'); 19 | $cmds = [ 20 | new Mix\Cli\Command([ 21 | 'name' => 'clearcache', 22 | 'short' => 'Clear cache', 23 | 'options' => [ 24 | new Mix\Cli\Option([ 25 | 'names' => ['k', 'key'], 26 | 'usage' => 'Key name' 27 | ]), 28 | ], 29 | 'run' => new App\Command\ClearCache(), 30 | ]) 31 | ]; 32 | Cli::addCommand(...$cmds)->run(); 33 | -------------------------------------------------------------------------------- /examples/web-skeleton/conf/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } -------------------------------------------------------------------------------- /examples/web-skeleton/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/examples/web-skeleton/public/favicon.ico -------------------------------------------------------------------------------- /examples/web-skeleton/public/index.php: -------------------------------------------------------------------------------- 1 | load(); 13 | define("APP_DEBUG", env('APP_DEBUG')); 14 | 15 | Error::register(); 16 | 17 | return Vega::new()->run(); 18 | -------------------------------------------------------------------------------- /examples/web-skeleton/public/static/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/examples/web-skeleton/public/static/index.html -------------------------------------------------------------------------------- /examples/web-skeleton/routes/index.php: -------------------------------------------------------------------------------- 1 | handle('/', [new Hello(), 'index'])->methods('GET'); 7 | }; 8 | -------------------------------------------------------------------------------- /examples/web-skeleton/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /examples/web-skeleton/src/Command/ClearCache.php: -------------------------------------------------------------------------------- 1 | string(); 19 | RDS::instance()->del($key); 20 | print 'ok'; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /examples/web-skeleton/src/Command/CoroutineRun.php: -------------------------------------------------------------------------------- 1 | do(function () { 39 | self::$instance = new \Noodlehaus\Config(__DIR__ . '/../../conf'); 40 | }); 41 | } 42 | return self::$instance; 43 | } 44 | 45 | } 46 | 47 | Config::init(); 48 | -------------------------------------------------------------------------------- /examples/web-skeleton/src/Container/DBLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('SQL: %sms %s %s %d', $time, $sql, json_encode($bindings), $rowCount)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/web-skeleton/src/Container/RDSLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('RDS: %sms %s %s', $time, $cmd, json_encode($args))); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /examples/web-skeleton/src/Container/Shutdown.php: -------------------------------------------------------------------------------- 1 | HTML(200, 'index', [ 16 | 'title' => 'Hello, World!' 17 | ]); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /examples/web-skeleton/views/index.php: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/.env: -------------------------------------------------------------------------------- 1 | # APP 2 | APP_DEBUG=true 3 | 4 | # DATABASE 5 | DATABASE_DSN='mysql:host=127.0.0.1;port=3306;charset=utf8;dbname=test' 6 | DATABASE_USERNAME=root 7 | DATABASE_PASSWORD=123456 8 | 9 | # REDIS 10 | REDIS_HOST=127.0.0.1 11 | REDIS_PORT=6379 12 | REDIS_DATABASE=0 13 | REDIS_PASSWORD= 14 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | composer.lock 18 | vendor/ 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit itself is not needed 24 | phpunit.phar 25 | # local phpunit config 26 | /phpunit.xml 27 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/bin/cli.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | load(); 14 | define("APP_DEBUG", env('APP_DEBUG')); 15 | 16 | Error::register(); 17 | 18 | Cli::setName('app')->setVersion('0.0.0-alpha'); 19 | $cmds = [ 20 | new Mix\Cli\Command([ 21 | 'name' => 'clearcache', 22 | 'short' => 'Clear cache', 23 | 'options' => [ 24 | new Mix\Cli\Option([ 25 | 'names' => ['k', 'key'], 26 | 'usage' => 'Key name' 27 | ]), 28 | ], 29 | 'run' => new App\Command\ClearCache(), 30 | ]) 31 | ]; 32 | Cli::addCommand(...$cmds)->run(); 33 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/websocket-skeleton", 3 | "description": "WebSocket development skeleton", 4 | "type": "project", 5 | "homepage": "https://openmix.org/mix-php", 6 | "license": "Apache-2.0", 7 | "scripts": { 8 | "swooleco:start": [ 9 | "Composer\\Config::disableProcessTimeout", 10 | "php bin/swooleco.php" 11 | ], 12 | "cli:clearcache": [ 13 | "Composer\\Config::disableProcessTimeout", 14 | "php bin/cli.php clearcache" 15 | ] 16 | }, 17 | "autoload": { 18 | "psr-4": { 19 | "App\\": "src/" 20 | }, 21 | "files": [ 22 | "src/functions.php" 23 | ] 24 | }, 25 | "require": { 26 | "mix/vega": "~3.0.0", 27 | "mix/websocket": "~3.0.0", 28 | "mix/cli": "~3.0.0", 29 | "mix/database": "~3.0.0", 30 | "mix/redis": "~3.0.0", 31 | "vlucas/phpdotenv": "^5.3", 32 | "hassankhan/config": "^3.0", 33 | "monolog/monolog": "^3.1" 34 | }, 35 | "require-dev": { 36 | "swoole/ide-helper": "^4.6" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/conf/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } -------------------------------------------------------------------------------- /examples/websocket-skeleton/routes/index.php: -------------------------------------------------------------------------------- 1 | handle('/websocket', [new WebSocket(), 'index'])->methods('GET'); 7 | }; 8 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /examples/websocket-skeleton/src/Command/ClearCache.php: -------------------------------------------------------------------------------- 1 | string(); 19 | RDS::instance()->del($key); 20 | print 'ok'; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/src/Command/CoroutineRun.php: -------------------------------------------------------------------------------- 1 | do(function () { 39 | self::$instance = new \Noodlehaus\Config(__DIR__ . '/../../conf'); 40 | }); 41 | } 42 | return self::$instance; 43 | } 44 | 45 | } 46 | 47 | Config::init(); 48 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/src/Container/DBLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('SQL: %sms %s %s %d', $time, $sql, json_encode($bindings), $rowCount)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/src/Container/RDSLogger.php: -------------------------------------------------------------------------------- 1 | debug(sprintf('RDS: %sms %s %s', $time, $cmd, json_encode($args))); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /examples/websocket-skeleton/src/Container/Shutdown.php: -------------------------------------------------------------------------------- 1 | upgrade($ctx->request, $ctx->response); 18 | $session = new Session($conn); 19 | $session->start(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/src/Handler/Hello.php: -------------------------------------------------------------------------------- 1 | session = $session; 22 | } 23 | 24 | public function index(string $message): void 25 | { 26 | $this->session->send('hello, world!'); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /examples/websocket-skeleton/views/index.php: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | -------------------------------------------------------------------------------- /src/auth/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Auth 2 | 3 | 基于 PSR-7 标准的 JWT 授权库 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/auth 11 | ``` 12 | 13 | 文档: 14 | 15 | - https://www.kancloud.cn/onanying/mixphp2-2/1708709 16 | 17 | ## License 18 | 19 | Apache License Version 2.0, http://www.apache.org/licenses/ 20 | -------------------------------------------------------------------------------- /src/auth/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/auth", 3 | "description": "JWT authorization library based on PSR-7 standard", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "auth", 8 | "jwt", 9 | "psr" 10 | ], 11 | "homepage": "https://openmix.org/", 12 | "license": "Apache-2.0", 13 | "authors": [ 14 | { 15 | "name": "liu,jian", 16 | "email": "coder.keda@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=7.0.0", 21 | "firebase/php-jwt": "^5.0", 22 | "psr/http-message": "^1.0", 23 | "mix/bean": "~2.2.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Mix\\Auth\\": "src/" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/auth/src/Exception/ExtractTokenException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | interface TokenExtractorInterface 11 | { 12 | 13 | /** 14 | * 提取token 15 | * @return string 16 | */ 17 | public function extractToken(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/bean/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Bean 2 | 3 | DI、IoC 容器,参考 spring bean 设计 4 | 5 | DI, IoC container, reference spring bean 6 | 7 | > 该库还有 go 版本:https://github.com/mix-go/bean 8 | 9 | ## Usage 10 | 11 | 安装: 12 | 13 | ``` 14 | composer require mix/bean 15 | ``` 16 | 17 | 文档: 18 | 19 | - https://www.kancloud.cn/onanying/mixphp2-2/1708689 20 | 21 | ## License 22 | 23 | Apache License Version 2.0, http://www.apache.org/licenses/ 24 | -------------------------------------------------------------------------------- /src/bean/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/bean", 3 | "description": "DI, IoC container, reference spring bean", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "bean", 8 | "di", 9 | "ico" 10 | ], 11 | "homepage": "https://openmix.org/", 12 | "license": "Apache-2.0", 13 | "authors": [ 14 | { 15 | "name": "liu,jian", 16 | "email": "coder.keda@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=7.0.0", 21 | "psr/container": "~1.0", 22 | "php-di/phpdoc-reader": "~2.1" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\Bean\\": "src/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/bean/src/BeanFactoryInterface.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | interface BeanFactoryInterface 11 | { 12 | 13 | /** 14 | * 获取BeanDefinition 15 | * @param $beanName 16 | * @return BeanDefinition 17 | */ 18 | public function getBeanDefinition(string $beanName): BeanDefinition; 19 | 20 | /** 21 | * 获取Bean 22 | * @param string $beanName 23 | * @param array $config 24 | * @return object 25 | */ 26 | public function getBean(string $beanName, array $config = []); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/bean/src/Exception/InjectException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class InjectException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/bean/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class NotFoundException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/bean/src/Exception/ScopeException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class ScopeException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/cache/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Cache 2 | 3 | 基于 PSR-6 标准的缓存库,支持 file, redis 存储 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/cache 11 | ``` 12 | 13 | 文档: 14 | 15 | - https://www.kancloud.cn/onanying/mixphp2-2/1708751 16 | 17 | ## License 18 | 19 | Apache License Version 2.0, http://www.apache.org/licenses/ 20 | -------------------------------------------------------------------------------- /src/cache/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/cache", 3 | "description": "PSR-6 standard based cache library, support file, redis storage", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "cache", 8 | "psr", 9 | "file", 10 | "redis" 11 | ], 12 | "homepage": "https://openmix.org/", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.0.0", 22 | "psr/simple-cache": "~1.0", 23 | "mix/redis": "~2.2.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Mix\\Cache\\": "src/" 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/cache/src/Handler/HandlerInterface.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | interface HandlerInterface 11 | { 12 | 13 | /** 14 | * 获取缓存 15 | * @param $key 16 | * @param null $default 17 | * @return mixed 18 | */ 19 | public function get($key, $default = null); 20 | 21 | /** 22 | * 设置缓存 23 | * @param $key 24 | * @param $value 25 | * @param null $ttl 26 | * @return bool 27 | */ 28 | public function set($key, $value, $ttl = null); 29 | 30 | /** 31 | * 删除缓存 32 | * @param $key 33 | * @return bool 34 | */ 35 | public function delete($key); 36 | 37 | /** 38 | * 清除缓存 39 | * @return bool 40 | */ 41 | public function clear(); 42 | 43 | /** 44 | * 判断缓存是否存在 45 | * @param $key 46 | * @return bool 47 | */ 48 | public function has($key); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/cli/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/cli/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/cli", 3 | "description": "PHP CLI Interactive Commander", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "cli", 8 | "commander" 9 | ], 10 | "homepage": "https://openmix.org/mix-php", 11 | "license": "Apache-2.0", 12 | "authors": [ 13 | { 14 | "name": "liu,jian", 15 | "email": "coder.keda@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.0.0" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "^7.0.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\Cli\\": "src/" 27 | }, 28 | "files": [ 29 | "src/functions.php" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/cli/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | $value) { 29 | $this->$key = $value; 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/cli/src/Program.php: -------------------------------------------------------------------------------- 1 | =7.0.0", 21 | "ext-swoole": ">=4.4.4" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "Mix\\Concurrent\\": "src/" 26 | }, 27 | "files": [ 28 | "src/functions.php" 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/concurrent/src/Exception/TypeException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class TypeException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/concurrent/src/functions.php: -------------------------------------------------------------------------------- 1 | 6 | */ 7 | 8 | if (!function_exists('xgo')) { 9 | // 创建协程 10 | function xgo($function, ...$params) 11 | { 12 | \Mix\Concurrent\Coroutine::create($function, ...$params); 13 | } 14 | } 15 | 16 | if (!function_exists('xdefer')) { 17 | // 创建延迟执行 18 | function xdefer($function) 19 | { 20 | return \Mix\Concurrent\Coroutine::defer($function); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/console/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Console 2 | 3 | 命令行控制台程序开发库 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/console 11 | ``` 12 | 13 | 文档: 14 | 15 | - https://www.kancloud.cn/onanying/mixphp2-2/1708692 16 | 17 | ## License 18 | 19 | Apache License Version 2.0, http://www.apache.org/licenses/ 20 | -------------------------------------------------------------------------------- /src/console/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/console", 3 | "description": "Command line console program development library", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "cli", 8 | "console" 9 | ], 10 | "homepage": "https://openmix.org/", 11 | "license": "Apache-2.0", 12 | "authors": [ 13 | { 14 | "name": "liu,jian", 15 | "email": "coder.keda@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.0.0", 20 | "psr/log": "~1.0", 21 | "psr/event-dispatcher": "^1.0", 22 | "mix/bean": "~2.2.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\Console\\": "src/" 27 | }, 28 | "classmap": [ 29 | "src/Mix.php" 30 | ], 31 | "files": [ 32 | "src/functions.php" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/console/src/CommandLine/Argument.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class Argument 11 | { 12 | 13 | /** 14 | * 获取脚本 15 | * @return string 16 | */ 17 | public static function script() 18 | { 19 | $argv = $GLOBALS['argv']; 20 | return $argv[0]; 21 | } 22 | 23 | /** 24 | * 获取命令 25 | * @return string 26 | */ 27 | public static function command() 28 | { 29 | static $command; 30 | if (!isset($command)) { 31 | $argv = $GLOBALS['argv']; 32 | $command = $argv[1] ?? ''; 33 | $command = preg_match('/^[a-zA-Z0-9_\-:]+$/i', $command) ? $command : ''; 34 | $command = substr($command, 0, 1) == '-' ? '' : $command; 35 | } 36 | return trim($command); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/console/src/Event/CommandBeforeExecuteEvent.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class ErrorException extends \RuntimeException 11 | { 12 | 13 | // 构造 14 | public function __construct($type, $message, $file, $line) 15 | { 16 | $this->code = $type; 17 | $this->message = $message; 18 | $this->file = $file; 19 | $this->line = $line; 20 | // 父类构造 21 | parent::__construct(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/console/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class NotFoundException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/console/src/Mix.php: -------------------------------------------------------------------------------- 1 | 6 | */ 7 | class Mix 8 | { 9 | 10 | /** 11 | * @var string 12 | */ 13 | public static $version = '2.2.17'; 14 | 15 | /** 16 | * @var \Mix\Console\Application 17 | */ 18 | public static $app; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/console/src/Process.php: -------------------------------------------------------------------------------- 1 | -1) { 21 | throw new \Swoole\Exception('MacOS unsupport fork in coroutine, please use it before the Swoole\Coroutine\Scheduler start.'); 22 | } 23 | return \Swoole\Process::daemon($nochdir, $noclose); 24 | } 25 | 26 | /** 27 | * kill进程 28 | * @param int $pid 29 | * @param int $signal 30 | * @return bool 31 | */ 32 | public static function kill(int $pid, int $signal = SIGTERM) 33 | { 34 | return posix_kill($pid, $signal); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/context/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Context 2 | 3 | 上下文处理库 4 | 5 | ## Usage 6 | 7 | ``` 8 | composer require mix/context 9 | ``` 10 | 11 | ## License 12 | 13 | Apache License Version 2.0, http://www.apache.org/licenses/ 14 | -------------------------------------------------------------------------------- /src/context/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/context", 3 | "description": "Context processing library", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "context" 8 | ], 9 | "homepage": "https://openmix.org/", 10 | "license": "Apache-2.0", 11 | "authors": [ 12 | { 13 | "name": "liu,jian", 14 | "email": "coder.keda@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=7.2.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "Mix\\Context\\": "src/" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/database/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/database/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/database", 3 | "description": "Simple database for use in multiple execution environments, with support for FPM, Swoole, Workerman, and optional pools", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "database", 8 | "mysql", 9 | "swoole", 10 | "workerman" 11 | ], 12 | "homepage": "https://openmix.org/mix-php", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.2.0", 22 | "ext-pdo": "*", 23 | "mix/object-pool": "~3.0.0" 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "^7.0.0" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Mix\\Database\\": "src/" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/database/src/EmptyDriver.php: -------------------------------------------------------------------------------- 1 | errorMessage); 21 | } 22 | 23 | public function options(): array 24 | { 25 | throw new \RuntimeException($this->errorMessage); 26 | } 27 | 28 | public function connect() 29 | { 30 | throw new \RuntimeException($this->errorMessage); 31 | } 32 | 33 | public function close() 34 | { 35 | throw new \RuntimeException($this->errorMessage); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/database/src/Expr.php: -------------------------------------------------------------------------------- 1 | expr = $expr; 30 | $this->values = $values; 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | public function __toString(): string 37 | { 38 | $expr = $this->expr; 39 | foreach ($this->values as $value) { 40 | $expr = preg_replace('/\?/', is_string($value) ? "'%s'" : "%s", $expr, 1); 41 | } 42 | return vsprintf($expr, $this->values); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/database/src/LoggerInterface.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class ConnectionPool extends AbstractObjectPool 14 | { 15 | 16 | /** 17 | * 借用连接 18 | * @return Driver 19 | */ 20 | public function borrow(): object 21 | { 22 | return parent::borrow(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/database/tests/DeleteTest.php: -------------------------------------------------------------------------------- 1 | table('users')->where('id = ?', 100000)->delete()->rowCount(); 14 | $this->assertEquals(0, $rowsAffected); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/database/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | startPool(10,10); 22 | return $db; 23 | } 24 | 25 | function swoole_co_run($func) 26 | { 27 | $scheduler = new \Swoole\Coroutine\Scheduler; 28 | $scheduler->set([ 29 | 'hook_flags' => SWOOLE_HOOK_ALL, 30 | ]); 31 | $scheduler->add(function () use ($func) { 32 | call_user_func($func); 33 | }); 34 | $scheduler->start(); 35 | } 36 | -------------------------------------------------------------------------------- /src/database/tests/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( "$#" != 1 )) 4 | then 5 | echo "The target cannot be empty" 6 | exit 1 7 | fi 8 | 9 | /usr/local/bin/php8 vendor/bin/phpunit --bootstrap=tests/bootstrap.php $1 10 | -------------------------------------------------------------------------------- /src/event/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/event", 3 | "description": "Event dispatcher based on PSR-14 standard", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "event", 8 | "dispatch", 9 | "psr" 10 | ], 11 | "homepage": "https://openmix.org/mix-php", 12 | "license": "Apache-2.0", 13 | "authors": [ 14 | { 15 | "name": "liu,jian", 16 | "email": "coder.keda@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=7.2.0", 21 | "psr/event-dispatcher": "^1.0" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "Mix\\Event\\": "src/" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/event/src/ListenerInterface.php: -------------------------------------------------------------------------------- 1 | =7.0.0", 21 | "nikic/fast-route": "^1.3", 22 | "mix/http-server": "~2.2.0", 23 | "mix/http-message": "~2.2.0", 24 | "mix/micro-route": "~2.2.0" 25 | }, 26 | "require-dev": { 27 | "phpunit/phpunit": "^7.0.0", 28 | "mix/guzzle": "~2.2.0" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Mix\\FastRoute\\": "src/" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/fast-route/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/grpc/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit 4 | .idea -------------------------------------------------------------------------------- /src/grpc/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/grpc", 3 | "description": "PHP gRPC based on Swoole coroutine, including protoc code generator, server, and client", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "coroutine", 9 | "grpc", 10 | "protoc", 11 | "server", 12 | "client" 13 | ], 14 | "homepage": "https://openmix.org/mix-php", 15 | "license": "Apache-2.0", 16 | "authors": [ 17 | { 18 | "name": "liu,jian", 19 | "email": "coder.keda@gmail.com" 20 | } 21 | ], 22 | "require": { 23 | "php": ">=7.0.0", 24 | "ext-swoole": ">=4.4.4", 25 | "google/protobuf": "^3.20" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "Mix\\Grpc\\": "src/" 30 | } 31 | }, 32 | "require-dev": { 33 | "phpunit/phpunit": "^7.0.0" 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "GPBMetadata\\": "protos/GPBMetadata/", 38 | "Php\\": "protos/Php/" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/grpc/protoc-gen-mix/.gitignore: -------------------------------------------------------------------------------- 1 | Test_Simple_in_mixgrpc 2 | bin 3 | .idea 4 | !.gitignore -------------------------------------------------------------------------------- /src/grpc/protoc-gen-mix/go.mod: -------------------------------------------------------------------------------- 1 | module mixgrpc 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/c9s/inflect v0.0.0-20130402162822-006c50878f3f 7 | github.com/davecgh/go-spew v1.1.1 // indirect 8 | github.com/golang/protobuf v1.3.5 9 | github.com/stretchr/testify v1.7.1 10 | gopkg.in/yaml.v3 v3.0.0 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /src/grpc/protoc-gen-mix/testdata/import/Import/ServiceInterface.php: -------------------------------------------------------------------------------- 1 | internalAddGeneratedFile(hex2bin( 18 | "0ab6010a0d677265657465722e70726f746f12167068702e6d6963726f2e677270632e6772656574657222170a0752657175657374120c0a046e616d6518012001280922170a08526573706f6e7365120b0a036d736718012001280932530a03536179124c0a0548656c6c6f121f2e7068702e6d6963726f2e677270632e677265657465722e526571756573741a202e7068702e6d6963726f2e677270632e677265657465722e526573706f6e73652200620670726f746f33" 19 | ), true); 20 | 21 | static::$is_initialized = true; 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/grpc/protos/Php/Micro/Grpc/Greeter/SayClient.php: -------------------------------------------------------------------------------- 1 | _simpleRequest('/php.micro.grpc.greeter.Say/Hello', $context, $request, new Response()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/grpc/protos/Php/Micro/Grpc/Greeter/SayInterface.php: -------------------------------------------------------------------------------- 1 | /dev/null 2>&1 &'); 14 | usleep(1000000); 15 | 16 | $client = new Mix\Grpc\Client('127.0.0.1', 9596); 17 | $say = new \Php\Micro\Grpc\Greeter\SayClient($client); 18 | $request = new \Php\Micro\Grpc\Greeter\Request(); 19 | $request->setName('xiaoming'); 20 | $response = $say->Hello(new \Mix\Grpc\Context(), $request); 21 | 22 | $_this->assertEquals($response->getMsg(), 'hello, xiaoming'); 23 | 24 | $client->close(); 25 | exec("ps -ef | grep \"greeter.pb\" | grep -v grep | awk '{print $2}' | xargs kill"); 26 | }; 27 | run($func); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/grpc/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/grpc/tests/goclient/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "google.golang.org/grpc" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | addr := ":9597" 12 | ctx, _ := context.WithTimeout(context.Background(), time.Duration(5)*time.Second) 13 | conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithBlock()) 14 | if err != nil { 15 | panic(err) 16 | } 17 | defer func() { 18 | _ = conn.Close() 19 | }() 20 | cli := NewSayClient(conn) 21 | req := Request{ 22 | Name: "xiaoming", 23 | } 24 | resp, err := cli.Hello(ctx, &req) 25 | if err != nil { 26 | panic(err) 27 | } 28 | fmt.Print(resp.GetMsg()) 29 | } 30 | -------------------------------------------------------------------------------- /src/grpc/tests/goclient/go.mod: -------------------------------------------------------------------------------- 1 | module tests 2 | 3 | go 1.16 4 | 5 | require ( 6 | google.golang.org/grpc v1.40.0 7 | google.golang.org/protobuf v1.33.0 8 | ) 9 | -------------------------------------------------------------------------------- /src/grpc/tests/goserver/go.mod: -------------------------------------------------------------------------------- 1 | module tests 2 | 3 | go 1.16 4 | 5 | require ( 6 | google.golang.org/grpc v1.40.0 7 | google.golang.org/protobuf v1.33.0 8 | ) 9 | -------------------------------------------------------------------------------- /src/grpc/tests/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( "$#" != 1 )) 4 | then 5 | echo "The target cannot be empty" 6 | exit 1 7 | fi 8 | 9 | /usr/local/bin/php8 vendor/bin/phpunit --bootstrap=tests/bootstrap.php $1 10 | -------------------------------------------------------------------------------- /src/guzzle/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/guzzle/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/guzzle", 3 | "description": "Guzzle that support the Swoole coroutine", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "guzzle", 8 | "swoole", 9 | "coroutine" 10 | ], 11 | "homepage": "https://openmix.org/", 12 | "license": "Apache-2.0", 13 | "authors": [ 14 | { 15 | "name": "liu,jian", 16 | "email": "coder.keda@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "__guzzlehttp/guzzle": ">=6.0,<6.5", 21 | "ezimuel/ringphp": "^1.1.2" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "^7.0.0" 25 | }, 26 | "autoload": { 27 | "psr-4": { 28 | "Mix\\Guzzle\\": "src/" 29 | }, 30 | "classmap": [ 31 | "src/hook/Handler/CurlHandler.php", 32 | "src/hook/Handler/StreamHandler.php", 33 | "src/hook/Handler/Ring/CurlHandler.php", 34 | "src/hook/Handler/Ring/StreamHandler.php" 35 | ], 36 | "files": [ 37 | "src/hook/functions.php" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/guzzle/src/hook.php: -------------------------------------------------------------------------------- 1 | =7.0.0", 19 | "ext-json": "*" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Mix\\Helper\\": "src/" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/helper/src/JsonHelper.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class JsonHelper 11 | { 12 | 13 | /** 14 | * 编码 15 | * @param $value 16 | * @param int $options 17 | * @param int $depth 18 | * @return string 19 | */ 20 | public static function encode($value, $options = 0, $depth = 512) 21 | { 22 | return json_encode($value, $options, $depth); 23 | } 24 | 25 | /** 26 | * 解码 27 | * @param $json 28 | * @param bool $assoc 29 | * @param int $depth 30 | * @param int $options 31 | * @return mixed 32 | */ 33 | public static function decode($json, $assoc = false, $depth = 512, $options = 0) 34 | { 35 | return json_decode($json, $assoc, $depth, $options); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/helper/src/PhpHelper.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | class PhpHelper 10 | { 11 | 12 | /** 13 | * 是否为 CLI 模式 14 | * @return bool 15 | */ 16 | public static function isCli() 17 | { 18 | return PHP_SAPI === 'cli'; 19 | } 20 | 21 | /** 22 | * 是否为 Win 系统 23 | * @return bool 24 | */ 25 | public static function isWin() 26 | { 27 | if (static::isMac()) { 28 | return false; 29 | } 30 | return stripos(PHP_OS, 'WIN') !== false; 31 | } 32 | 33 | /** 34 | * 是否为 Mac 系统 35 | * @return bool 36 | */ 37 | public static function isMac() 38 | { 39 | return stripos(PHP_OS, 'Darwin') !== false; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/helper/src/PidHelper.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class PidHelper 11 | { 12 | 13 | /** 14 | * 写入pid 15 | * @param string $file 16 | * @return bool 17 | */ 18 | public static function write(string $file): bool 19 | { 20 | return file_put_contents($file, getmypid(), LOCK_EX) ? true : false; 21 | } 22 | 23 | /** 24 | * 读取pid 25 | * @param string $file 26 | * @return bool|string 27 | */ 28 | public static function read(string $file) 29 | { 30 | if (!file_exists($file)) { 31 | return false; 32 | } 33 | $pid = file_get_contents($file); 34 | if (!is_numeric($pid) || !posix_kill($pid, 0)) { 35 | return false; 36 | } 37 | return $pid; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/http-message/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/http-message/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Http Message 2 | 3 | Http message library based on PSR-7 / PSR-17 standard, supports FPM, Swoole, WorkerMan 4 | 5 | 基于 PSR-7 / PSR-17 标准的 Http 消息库,支持 FPM, Swoole, WorkerMan 6 | 7 | ## Installation 8 | 9 | ``` 10 | composer require mix/http-message 11 | ``` 12 | 13 | ## License 14 | 15 | Apache License Version 2.0, http://www.apache.org/licenses/ 16 | -------------------------------------------------------------------------------- /src/http-message/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/http-message", 3 | "description": "Http message library based on PSR-7 / PSR-17 standard, support Swoole, WorkerMan", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "http", 9 | "message", 10 | "psr" 11 | ], 12 | "homepage": "https://openmix.org/mix-php", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.0.0", 22 | "psr/http-message": "^1.0", 23 | "psr/http-factory": "^1.0", 24 | "ralouphie/getallheaders": "^3.0", 25 | "lukasoppermann/http-status": "^3.2" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "Mix\\Http\\Message\\": "src/" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/http-message/src/Exception/UnavailableMethodException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class UnavailableMethodException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/http-message/src/Factory/CookieFactory.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class CookieFactory 13 | { 14 | 15 | /** 16 | * Create cookie 17 | * @param string $method 18 | * @param $uri 19 | * @return Cookie 20 | */ 21 | public function createCookie(string $name, string $value = '', int $expire = 0): Cookie 22 | { 23 | return new Cookie($name, $value, $expire); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/http-message/src/Factory/UriFactory.php: -------------------------------------------------------------------------------- 1 | =7.0.0", 22 | "ext-swoole": ">=4.4.4", 23 | "psr/http-server-middleware": "^1.0", 24 | "psr/http-server-handler": "^1.0", 25 | "mix/http-message": "~2.2.0", 26 | "mix/micro-server": "~2.2.0" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Mix\\Http\\Server\\": "src/" 31 | } 32 | }, 33 | "require-dev": { 34 | "phpunit/phpunit": "^7.0.0", 35 | "mix/guzzle": "~2.2.0" 36 | } 37 | } -------------------------------------------------------------------------------- /src/http-server/src/Event/HandledEvent.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class NotFoundException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/http-server/src/Exception/TypeException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class TypeException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/http-server/src/Helper/ServerHelper.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | interface MiddlewareInterface extends \Psr\Http\Server\MiddlewareInterface 14 | { 15 | 16 | /** 17 | * MiddlewareInterface constructor. 18 | * @param ServerRequest $request 19 | * @param Response $response 20 | */ 21 | public function __construct(ServerRequest $request, Response $response); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/http-server/src/ServerHandlerInterface.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | interface ServerHandlerInterface 14 | { 15 | 16 | /** 17 | * Handle HTTP 18 | * @param ServerRequest $request 19 | * @param Response $response 20 | */ 21 | public function handleHTTP(ServerRequest $request, Response $response); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/http-server/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/init/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/init/README.md: -------------------------------------------------------------------------------- 1 | > OpenMix 出品:[https://openmix.org](https://openmix.org/mix-php) 2 | 3 | # Mix Init 4 | 5 | Help execute static initialization of the class, usually for preloading singletons 6 | 7 | 帮助执行类的静态初始化,通常用于预加载单例 8 | 9 | ## Installation 10 | 11 | ``` 12 | composer require mix/init 13 | ``` 14 | 15 | ## Quick start 16 | 17 | 定义类的静态初始化方法 18 | 19 | ```php 20 | class Example 21 | { 22 | public static function init() 23 | { 24 | // do something 25 | } 26 | } 27 | ``` 28 | 29 | 从目录执行 30 | 31 | > 可以通过定制方法名称,达到在不同的场景初始化的目的 32 | 33 | ```php 34 | Mix\Init\StaticInit::finder('/path/classdir')->exec('init'); 35 | ``` 36 | 37 | ## License 38 | 39 | Apache License Version 2.0, http://www.apache.org/licenses/ 40 | -------------------------------------------------------------------------------- /src/init/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/init", 3 | "description": "Help execute static initialization, usually for preloading singletons", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "init" 8 | ], 9 | "homepage": "https://openmix.org/mix-php", 10 | "license": "Apache-2.0", 11 | "authors": [ 12 | { 13 | "name": "liu,jian", 14 | "email": "coder.keda@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=7.1.0", 19 | "symfony/finder": "^5.4" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Mix\\Init\\": "src/" 24 | } 25 | }, 26 | "autoload-dev": { 27 | "psr-4": { 28 | "Test\\": "tests/" 29 | } 30 | }, 31 | "require-dev": { 32 | "phpunit/phpunit": "^7.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/init/src/StaticInit.php: -------------------------------------------------------------------------------- 1 | exec('init'); 5 | -------------------------------------------------------------------------------- /src/json-rpc/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | vendor 18 | composer.lock 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit itself is not needed 24 | phpunit.phar 25 | # local phpunit config 26 | /phpunit.xml 27 | -------------------------------------------------------------------------------- /src/json-rpc/src/Constants.php: -------------------------------------------------------------------------------- 1 | jsonrpc = '2.0'; 26 | $request->method = $method; 27 | $request->params = $params; 28 | $request->id = $id; 29 | $request->context = new Context(); 30 | return $request; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/json-rpc/src/Message/Error.php: -------------------------------------------------------------------------------- 1 | =7.2.0" 20 | }, 21 | "require-dev": { 22 | "swoole/ide-helper": "dev-master" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\Micro\\Config\\": "src/" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/micro-config/src/Event/DeleteEvent.php: -------------------------------------------------------------------------------- 1 | '127.0.0.1', 15 | 'port' => 2379, 16 | 'version' => 'v3', 17 | 'ttl' => 10, 18 | ]); 19 | for ($i = 0; $i < 5; $i++) { 20 | $service = $center->service('php.micro.srv.test'); 21 | var_dump($service); 22 | sleep(1); 23 | } 24 | $center->clear(); 25 | }; 26 | run($func); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/micro-etcd/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | set([ 7 | 'hook_flags' => SWOOLE_HOOK_ALL, 8 | ]); 9 | $scheduler->add(function () use ($func) { 10 | call_user_func($func); 11 | }); 12 | $scheduler->start(); 13 | } 14 | -------------------------------------------------------------------------------- /src/micro-hystrix/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | vendor 18 | 19 | # Mac DS_Store Files 20 | .DS_Store 21 | 22 | # phpunit itself is not needed 23 | phpunit.phar 24 | # local phpunit config 25 | /phpunit.xml 26 | -------------------------------------------------------------------------------- /src/micro-hystrix/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Micro Hystrix 2 | 3 | 微服务熔断器,参考 spring hystrix 设计,基于 Swoole 开发 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/micro-hystrix 11 | ``` 12 | 13 | 文档: 14 | 15 | - https://www.kancloud.cn/onanying/mixphp2-2/1712343 16 | 17 | ## License 18 | 19 | Apache License Version 2.0, http://www.apache.org/licenses/ 20 | -------------------------------------------------------------------------------- /src/micro-hystrix/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/micro-hystrix", 3 | "description": "Microservice circuit breaker, reference spring hystrix, developed based on Swoole", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "hystrix", 9 | "microservice", 10 | "circuitbreaker" 11 | ], 12 | "homepage": "https://openmix.org/", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.2.0", 22 | "ext-swoole": ">=4.4.4", 23 | "psr/event-dispatcher": "^1.0" 24 | }, 25 | "require-dev": { 26 | "swoole/ide-helper": "dev-master" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Mix\\Micro\\Hystrix\\": "src/" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/micro-hystrix/src/Event/StatusChangeEvent.php: -------------------------------------------------------------------------------- 1 | =7.2.0", 21 | "ext-swoole": ">=4.4.4", 22 | "ramsey/uuid": "^3.9" 23 | }, 24 | "require-dev": { 25 | "swoole/ide-helper": "dev-master" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "Mix\\Micro\\Register\\": "src/" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/micro-register/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | uuid1(crc32(static::localIP()))->toString(); 22 | } 23 | 24 | /** 25 | * Get local IP 26 | * @return string 27 | */ 28 | public static function localIP() 29 | { 30 | return current(swoole_get_local_ip()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/micro-register/src/ServiceInterface.php: -------------------------------------------------------------------------------- 1 | =7.0.0", 20 | "mix/http-server": "~2.2.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Mix\\Micro\\Route\\": "src/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/micro-route/src/RouterInterface.php: -------------------------------------------------------------------------------- 1 | [pattern,...]] 28 | */ 29 | public function services(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/micro-server/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Micro Server 2 | 3 | 微服务 Server 库通用接口 4 | 5 | Common interface for microservice server library 6 | 7 | ## Usage 8 | 9 | 安装: 10 | 11 | ``` 12 | composer require mix/micro-server 13 | ``` 14 | 15 | ## License 16 | 17 | Apache License Version 2.0, http://www.apache.org/licenses/ 18 | -------------------------------------------------------------------------------- /src/micro-server/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/micro-server", 3 | "description": "Common interface for microservice server library", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "server", 8 | "microservice" 9 | ], 10 | "homepage": "https://openmix.org/", 11 | "license": "Apache-2.0", 12 | "authors": [ 13 | { 14 | "name": "liu,jian", 15 | "email": "coder.keda@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.0.0" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Mix\\Micro\\Server\\": "src/" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/micro-server/src/ServerInterface.php: -------------------------------------------------------------------------------- 1 | [class,...]] 15 | */ 16 | public function services(); 17 | 18 | /** 19 | * Host 20 | * @return string 21 | */ 22 | public function host(); 23 | 24 | /** 25 | * Port 26 | * @return int 27 | */ 28 | public function port(); 29 | 30 | /** 31 | * Shutdown 32 | * @throws \Swoole\Exception 33 | */ 34 | public function shutdown(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/micro/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/micro", 3 | "description": "PHP microservice development framework deeply integrated with go-micro ecology", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "micro", 8 | "microservice" 9 | ], 10 | "homepage": "https://openmix.org/", 11 | "license": "Apache-2.0", 12 | "authors": [ 13 | { 14 | "name": "liu,jian", 15 | "email": "coder.keda@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.2.0", 20 | "ext-swoole": ">=4.5.0", 21 | "psr/log": "~1.0", 22 | "mix/runtime": "~2.2.0", 23 | "mix/micro-register": "~2.2.0", 24 | "mix/micro-config": "~2.2.0", 25 | "mix/micro-route": "~2.2.0", 26 | "mix/micro-server": "~2.2.0" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Mix\\Micro\\": "src/" 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/monolog/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Monolog 2 | 3 | 支持 Swoole 协程的 Monolog,支持 cli 控制台打印 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/monolog 11 | ``` 12 | 13 | 创建 Logger: 14 | 15 | ``` 16 | $logger = new \Mix\Monolog\Logger('API', [new \Mix\Monolog\Handler\ConsoleHandler], [new \Monolog\Processor\PsrLogMessageProcessor]); 17 | $handler = new \Mix\Monolog\Handler\RotatingFileHandler(sprintf('%s/runtime/logs/api.log', $basePath), 7); 18 | $logger->pushHandler($handler); 19 | ``` 20 | 21 | 调用: 22 | 23 | ``` 24 | $logger->info('server started'); 25 | ``` 26 | 27 | ## License 28 | 29 | Apache License Version 2.0, http://www.apache.org/licenses/ 30 | -------------------------------------------------------------------------------- /src/monolog/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/monolog", 3 | "description": "Monolog support Swoole coroutine and cli console printing", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "coroutine", 9 | "log", 10 | "monolog" 11 | ], 12 | "homepage": "https://openmix.org/", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.2.0", 22 | "monolog/monolog": "^2.0", 23 | "mix/console": "~2.2.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Mix\\Monolog\\": "src/" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/monolog/src/Handler/StreamHandler.php: -------------------------------------------------------------------------------- 1 | =7.2.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Mix\\ObjectPool\\": "src/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/object-pool/src/DialerInterface.php: -------------------------------------------------------------------------------- 1 | pool)) { 29 | return $this->pool->discard($this); 30 | } 31 | return false; 32 | } 33 | 34 | /** 35 | * 归还连接 36 | * @return bool 37 | */ 38 | public function __return(): bool 39 | { 40 | if (isset($this->pool)) { 41 | return $this->pool->return($this); 42 | } 43 | return false; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/redis-subscriber/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | vendor 18 | 19 | # Mac DS_Store Files 20 | .DS_Store 21 | 22 | # phpunit itself is not needed 23 | phpunit.phar 24 | # local phpunit config 25 | /phpunit.xml 26 | -------------------------------------------------------------------------------- /src/redis-subscriber/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/redis-subscriber", 3 | "description": "Redis native protocol Subscriber based on Swoole coroutine", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "redis", 9 | "subscribe", 10 | "subscriber" 11 | ], 12 | "homepage": "https://openmix.org/mix-php", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.0.0", 22 | "ext-swoole": ">=4.4.4" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\Redis\\Subscriber\\": "src/" 27 | } 28 | }, 29 | "require-dev": { 30 | "phpunit/phpunit": "^7.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/redis-subscriber/src/Exception/SubscribeException.php: -------------------------------------------------------------------------------- 1 | assertEquals(\Mix\Redis\Subscriber\Resp::build(null), "$-1\r\n"); 16 | $this->assertEquals(\Mix\Redis\Subscriber\Resp::build(1), ":1\r\n"); 17 | $this->assertEquals(\Mix\Redis\Subscriber\Resp::build('foo'), "$3\r\nfoo\r\n"); 18 | $this->assertEquals(\Mix\Redis\Subscriber\Resp::build(['foo', 'bar']), "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"); 19 | $this->assertEquals(\Mix\Redis\Subscriber\Resp::build([1, [2, '4'], 2, 'bar']), "*4\r\n:1\r\n*2\r\n:2\r\n$1\r\n4\r\n:2\r\n$3\r\nbar\r\n"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/redis-subscriber/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/redis-subscriber/tests/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( "$#" != 1 )) 4 | then 5 | echo "The target cannot be empty" 6 | exit 1 7 | fi 8 | 9 | /usr/local/bin/php8 vendor/bin/phpunit --bootstrap=tests/bootstrap.php $1 10 | -------------------------------------------------------------------------------- /src/redis/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/redis/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/redis", 3 | "description": "Coroutine redis library based on Swoole, built-in connection pool", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "coroutine", 9 | "redis", 10 | "connection-pool" 11 | ], 12 | "homepage": "https://openmix.org/mix-php", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.2.0", 22 | "ext-redis": "*", 23 | "mix/object-pool": "~3.0.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Mix\\Redis\\": "src/" 28 | } 29 | }, 30 | "require-dev": { 31 | "phpunit/phpunit": "^7.0.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/redis/src/EmptyDriver.php: -------------------------------------------------------------------------------- 1 | errorMessage); 21 | } 22 | 23 | public function connect() 24 | { 25 | throw new \RuntimeException($this->errorMessage); 26 | } 27 | 28 | public function close() 29 | { 30 | throw new \RuntimeException($this->errorMessage); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/redis/src/LoggerInterface.php: -------------------------------------------------------------------------------- 1 | driver = $driver; 20 | $this->logger = $logger; 21 | $this->watch = $watch; 22 | 23 | $this->__call('multi', [\Redis::PIPELINE]); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/redis/src/Pool/ConnectionPool.php: -------------------------------------------------------------------------------- 1 | set('foo', 'bar'); 14 | $result = $rds->get('foo'); 15 | $this->assertEquals('bar', $result); 16 | 17 | $rds->del('foo'); 18 | $result = $rds->get('foo'); 19 | $this->assertEquals(false, $result); 20 | } 21 | 22 | public function testMulti(): void 23 | { 24 | $rds = redis(); 25 | 26 | $tx = $rds->multi(); 27 | $tx->set('foo2', "bar2"); 28 | $tx->del('foo1'); 29 | $tx->incr('foo1'); 30 | $tx->incr('foo1'); 31 | $result = $tx->exec(); 32 | 33 | $value = $rds->get('foo1'); 34 | $this->assertEquals(2, $value); 35 | 36 | $this->assertEquals([true, 1, 1, 2], $result); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/redis/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | set([ 20 | 'hook_flags' => SWOOLE_HOOK_ALL, 21 | ]); 22 | $scheduler->add(function () use ($func) { 23 | call_user_func($func); 24 | }); 25 | $scheduler->start(); 26 | } 27 | -------------------------------------------------------------------------------- /src/redis/tests/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( "$#" != 1 )) 4 | then 5 | echo "The target cannot be empty" 6 | exit 1 7 | fi 8 | 9 | /usr/local/bin/php8 vendor/bin/phpunit --bootstrap=tests/bootstrap.php $1 10 | -------------------------------------------------------------------------------- /src/route/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Route 2 | 3 | Http 路由类库,遵循 PSR-7 / PSR-15 标准 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/route 11 | ``` 12 | 13 | 文档: 14 | 15 | - https://www.kancloud.cn/onanying/mixphp2-2/1708702 16 | 17 | ## License 18 | 19 | Apache License Version 2.0, http://www.apache.org/licenses/ 20 | -------------------------------------------------------------------------------- /src/route/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/route", 3 | "description": "Http route library, following PSR-7 / PSR-15 standard", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "route", 8 | "psr" 9 | ], 10 | "homepage": "https://openmix.org/", 11 | "license": "Apache-2.0", 12 | "authors": [ 13 | { 14 | "name": "liu,jian", 15 | "email": "coder.keda@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.0.0", 20 | "mix/bean": "~2.2.0", 21 | "mix/http-server": "~2.2.0", 22 | "mix/http-message": "~2.2.0", 23 | "mix/micro-route": "~2.2.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Mix\\Route\\": "src/" 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/route/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class NotFoundException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/runtime/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Runtime 2 | 3 | 运行时库 4 | 5 | Runtime library 6 | 7 | ## Usage 8 | 9 | 安装: 10 | 11 | - Swoole >= 4.4.4 12 | 13 | ``` 14 | composer require mix/runtime 15 | ``` 16 | 17 | ## License 18 | 19 | Apache License Version 2.0, http://www.apache.org/licenses/ 20 | -------------------------------------------------------------------------------- /src/runtime/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/runtime", 3 | "description": "Runtime library", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "runtime" 8 | ], 9 | "homepage": "https://openmix.org/", 10 | "license": "Apache-2.0", 11 | "authors": [ 12 | { 13 | "name": "liu,jian", 14 | "email": "coder.keda@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=7.2.0", 19 | "ext-swoole": ">=4.4.4" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "^7.0.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\": "src/" 27 | }, 28 | "files": [ 29 | "src/functions.php" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/runtime/src/Select/Clause/ClauseIntercase.php: -------------------------------------------------------------------------------- 1 | clauseChannel = $channel; 28 | } 29 | 30 | /** 31 | * Channel 32 | * @return Channel 33 | */ 34 | public function channel(): Channel 35 | { 36 | return $this->clauseChannel; 37 | } 38 | 39 | /** 40 | * @return mixed 41 | */ 42 | public function run() 43 | { 44 | return $this->clauseChannel->pop(); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/runtime/src/Select/Clauses.php: -------------------------------------------------------------------------------- 1 | ClauseIntercase, 'statement' => \Closure], ...] 14 | */ 15 | public $cases; 16 | 17 | /** 18 | * @var \Closure 19 | */ 20 | public $default; 21 | 22 | } -------------------------------------------------------------------------------- /src/runtime/src/Time/Time.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/server/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Server 2 | 3 | 基于 Swoole 协程的 tcp server 类库 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/server 11 | ``` 12 | 13 | ## License 14 | 15 | Apache License Version 2.0, http://www.apache.org/licenses/ 16 | -------------------------------------------------------------------------------- /src/server/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/server", 3 | "description": "Tcp server library based on Swoole coroutine", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "coroutine", 9 | "tcp", 10 | "server" 11 | ], 12 | "homepage": "https://openmix.org/", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.0.0", 22 | "ext-swoole": ">=4.4.4" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\Server\\": "src/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/server/src/Exception/ReceiveException.php: -------------------------------------------------------------------------------- 1 | =7.0.0", 20 | "mix/http-message": "^3.0", 21 | "mix/redis": "^3.0" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "Mix\\Session\\": "src/" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/sync-invoke/.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer itself is not needed 16 | composer.phar 17 | vendor 18 | composer.lock 19 | 20 | # Mac DS_Store Files 21 | .DS_Store 22 | 23 | # phpunit itself is not needed 24 | phpunit.phar 25 | # local phpunit config 26 | /phpunit.xml 27 | -------------------------------------------------------------------------------- /src/sync-invoke/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Sync Invoke 2 | 3 | Swoole 同步阻塞代码调用库,用于执行无法被 Swoole Hook 协程化的同步阻塞代码 4 | 5 | ## Usage 6 | 7 | - 安装 8 | 9 | ``` 10 | composer require mix/sync-invoke 11 | ``` 12 | 13 | - Server 14 | 15 | 创建服务器,用于执行同步代码,第二个参数为 `true` 可复用端口 16 | 17 | ``` 18 | $server = new \Mix\SyncInvoke\Server(9505, true); 19 | $server->start(); 20 | ``` 21 | 22 | - Client 23 | 24 | ``` 25 | $dialer = new \Mix\SyncInvoke\Client\Dialer(); 26 | $client = $dialer->dial(9505); 27 | $data = $client->invoke(function () { 28 | $obj = new Hello(); 29 | return [1, 2, 3, $obj]; 30 | }); 31 | var_dump($data); 32 | ``` 33 | 34 | ## License 35 | 36 | Apache License Version 2.0, http://www.apache.org/licenses/ 37 | -------------------------------------------------------------------------------- /src/sync-invoke/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/sync-invoke", 3 | "description": "Swoole synchronous blocking code invoke library", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "sync", 9 | "block", 10 | "invoke" 11 | ], 12 | "homepage": "https://openmix.org/", 13 | "license": "Apache-2.0", 14 | "authors": [ 15 | { 16 | "name": "liu,jian", 17 | "email": "coder.keda@gmail.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=7.0.0", 22 | "ext-swoole": ">=4.4.4", 23 | "opis/closure": "^3.5", 24 | "psr/event-dispatcher": "^1.0", 25 | "mix/bean": "~2.2.0", 26 | "mix/server": "~2.2.0", 27 | "mix/object-pool": "~2.2.0" 28 | }, 29 | "require-dev": { 30 | "swoole/ide-helper": "dev-master" 31 | }, 32 | "autoload": { 33 | "psr-4": { 34 | "Mix\\SyncInvoke\\": "src/" 35 | } 36 | }, 37 | "require-dev": { 38 | "phpunit/phpunit": "^7.0.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/sync-invoke/src/Client/Pool/ConnectionPool.php: -------------------------------------------------------------------------------- 1 | message = $message; 30 | $this->code = $code; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/sync-invoke/src/Exception/InvokeException.php: -------------------------------------------------------------------------------- 1 | start(); 16 | }); 17 | 18 | $dialer = new \Mix\SyncInvoke\Client\Dialer(); 19 | $client = $dialer->dial(9505); 20 | $data = $client->invoke(function () { 21 | $obj = new Hello(); 22 | return [1, 2, 3, $obj]; 23 | }); 24 | 25 | $_this->assertEquals(count($data), 4); 26 | $_this->assertEquals(get_class($data[3]), Hello::class); 27 | $server->shutdown(); 28 | }; 29 | run($func); 30 | } 31 | 32 | } 33 | 34 | class Hello 35 | { 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/sync-invoke/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/tracing-zipkin/.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | !.gitignore -------------------------------------------------------------------------------- /src/tracing-zipkin/README.md: -------------------------------------------------------------------------------- 1 | ## Mix Tracing Zipkin 2 | 3 | Zipkin 调用链追踪库,基于 Opentracing 标准 4 | 5 | ## Usage 6 | 7 | 安装: 8 | 9 | ``` 10 | composer require mix/tracing-zipkin 11 | ``` 12 | 13 | 支持的 zipkin 版本: 14 | 15 | - V2 16 | 17 | 文档: 18 | 19 | - https://www.kancloud.cn/onanying/mixphp2-2/1712344 20 | 21 | ## License 22 | 23 | Apache License Version 2.0, http://www.apache.org/licenses/ 24 | -------------------------------------------------------------------------------- /src/tracing-zipkin/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/tracing-zipkin", 3 | "description": "Zipkin tracing library based on Opentracing standard", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "tracing", 8 | "zipkin", 9 | "opentracing" 10 | ], 11 | "homepage": "https://openmix.org/", 12 | "license": "Apache-2.0", 13 | "authors": [ 14 | { 15 | "name": "liu,jian", 16 | "email": "coder.keda@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=7.2.0", 21 | "mix/opentracing": "^1.0", 22 | "openzipkin/zipkin": "^1.3", 23 | "mix/guzzle": "~2.2.0", 24 | "mix/bean": "~2.2.0", 25 | "mix/runtime": "~2.2.0" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "^7.0.0" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Mix\\Tracing\\Zipkin\\": "src/" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/tracing-zipkin/src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | =7.2.0", 21 | "mix/opentracing": "^1.0", 22 | "mix/runtime": "~2.2.0", 23 | "mix/grpc": "~2.2.0", 24 | "mix/json-rpc": "~2.2.0", 25 | "mix/http-server": "~2.2.0" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "^7.0.0" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Mix\\Tracing\\": "src/" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/tracing/src/Tracing.php: -------------------------------------------------------------------------------- 1 | value('__tracer__'); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/validator/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/validator/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/validator", 3 | "description": "Validator based on PSR-7 standard", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "validate", 8 | "validator", 9 | "validation" 10 | ], 11 | "homepage": "https://openmix.org/mix-php", 12 | "license": "Apache-2.0", 13 | "authors": [ 14 | { 15 | "name": "liu,jian", 16 | "email": "coder.keda@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=7.0.0", 21 | "ext-mbstring": "*", 22 | "psr/http-message": "^1.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Mix\\Validator\\": "src/" 27 | } 28 | }, 29 | "require-dev": { 30 | "phpunit/phpunit": "^7.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/validator/src/AlphaNumericValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 24 | if (!Validate::isAlphaNumeric($value)) { 25 | // 设置错误消息 26 | $defaultMessage = "{$this->attribute}只能为字母和数字."; 27 | $this->setError(__FUNCTION__, $defaultMessage); 28 | // 返回 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/src/AlphaValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 24 | if (!Validate::isAlpha($value)) { 25 | // 设置错误消息 26 | $defaultMessage = "{$this->attribute}只能为字母."; 27 | $this->setError(__FUNCTION__, $defaultMessage); 28 | // 返回 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/src/CallValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 19 | if (!call_user_func_array($param, [$value])) { 20 | // 设置错误消息 21 | $defaultMessage = "{$this->attribute}是无效的值."; 22 | $this->setError(__FUNCTION__, $defaultMessage); 23 | // 返回 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/validator/src/CompareValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 19 | if (!isset($this->attributes[$param]) || $value != $this->attributes[$param]) { 20 | // 设置错误消息 21 | $defaultMessage = "{$this->attribute}不等于{$param}."; 22 | $this->setError(__FUNCTION__, $defaultMessage); 23 | // 返回 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/validator/src/DateValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 21 | if (!Validate::isDate($value, $param)) { 22 | // 设置错误消息 23 | $defaultMessage = "{$this->attribute}不符合日期格式."; 24 | $this->setError(__FUNCTION__, $defaultMessage); 25 | // 返回 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/validator/src/DoubleValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 24 | if (!Validate::isDouble($value)) { 25 | // 设置错误消息 26 | $defaultMessage = "{$this->attribute}只能为小数."; 27 | $this->setError(__FUNCTION__, $defaultMessage); 28 | // 返回 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/src/EmailValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 24 | if (!Validate::isEmail($value)) { 25 | // 设置错误消息 26 | $defaultMessage = "{$this->attribute}不符合邮箱格式."; 27 | $this->setError(__FUNCTION__, $defaultMessage); 28 | // 返回 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/src/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | attributeValue; 21 | $strict = empty($this->settings['strict']) ? false : true; 22 | if (!Validate::in($value, $param, $strict)) { 23 | // 设置错误消息 24 | $defaultMessage = "{$this->attribute}不在" . implode(',', $param) . "范围内."; 25 | $this->setError(__FUNCTION__, $defaultMessage); 26 | // 返回 27 | return false; 28 | } 29 | return true; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/validator/src/IntegerValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 24 | if (!Validate::isInteger($value)) { 25 | // 设置错误消息 26 | $defaultMessage = "{$this->attribute}只能为整数."; 27 | $this->setError(__FUNCTION__, $defaultMessage); 28 | // 返回 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/src/MatchValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 21 | if (!Validate::match($value, $param)) { 22 | // 设置错误消息 23 | $defaultMessage = "{$this->attribute}是无效的值."; 24 | $this->setError(__FUNCTION__, $defaultMessage); 25 | // 返回 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/validator/src/PhoneValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 24 | if (!Validate::isPhone($value)) { 25 | // 设置错误消息 26 | $defaultMessage = "{$this->attribute}不符合手机号格式."; 27 | $this->setError(__FUNCTION__, $defaultMessage); 28 | // 返回 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/src/StringValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue = trim($this->attributeValue); 22 | break; 23 | case 'strip_tags': 24 | $this->attributeValue = strip_tags($this->attributeValue); 25 | break; 26 | case 'htmlspecialchars': 27 | $this->attributeValue = htmlspecialchars($this->attributeValue); 28 | break; 29 | } 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/src/UrlValidator.php: -------------------------------------------------------------------------------- 1 | attributeValue; 24 | if (!Validate::isUrl($value)) { 25 | // 设置错误消息 26 | $defaultMessage = "{$this->attribute}不符合网址格式."; 27 | $this->setError(__FUNCTION__, $defaultMessage); 28 | // 返回 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/validator/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | =7.3.0", 20 | "nikic/fast-route": "^1.3", 21 | "mix/http-message": "~3.0.0", 22 | "mix/view": "~3.0.0" 23 | }, 24 | "require-dev": { 25 | "swoole/ide-helper": "dev-master", 26 | "workerman/workerman": "^4.0", 27 | "phpunit/phpunit": "^9.5" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Mix\\Vega\\": "src/" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/vega/src/Abort.php: -------------------------------------------------------------------------------- 1 | on('Request', $vega->handler()); 7 | $http->start(); 8 | } 9 | 10 | function swoole_co_run(Mix\Vega\Engine $vega) 11 | { 12 | $scheduler = new \Swoole\Coroutine\Scheduler; 13 | $scheduler->set([ 14 | 'hook_flags' => SWOOLE_HOOK_ALL, 15 | ]); 16 | $scheduler->add(function () use ($vega) { 17 | $server = new Swoole\Coroutine\Http\Server('127.0.0.1', 9502, false); 18 | $server->handle('/', $vega->handler()); 19 | $server->start(); 20 | }); 21 | $scheduler->start(); 22 | } 23 | 24 | function wokerman_run(Mix\Vega\Engine $vega) 25 | { 26 | $http_worker = new Workerman\Worker("http://0.0.0.0:2345"); 27 | $http_worker->onMessage = $vega->handler(); 28 | $http_worker->count = 4; 29 | Workerman\Worker::runAll(); 30 | } 31 | -------------------------------------------------------------------------------- /src/vega/tests/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( "$#" != 1 )) 4 | then 5 | echo "The target cannot be empty" 6 | exit 1 7 | fi 8 | 9 | /usr/local/bin/php8 vendor/bin/phpunit --bootstrap=tests/bootstrap.php $1 10 | -------------------------------------------------------------------------------- /src/vega/tests/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/src/vega/tests/public/favicon.ico -------------------------------------------------------------------------------- /src/vega/tests/public/static/test.js: -------------------------------------------------------------------------------- 1 | var test = 'test'; -------------------------------------------------------------------------------- /src/vega/tests/views/foo.php: -------------------------------------------------------------------------------- 1 |

id: , name:

2 |

friends:

3 | 8 | -------------------------------------------------------------------------------- /src/view/README.md: -------------------------------------------------------------------------------- 1 | ## Mix View 2 | 3 | Simple rendering of PHP native templates 4 | 5 | 简易的 PHP 原生模板渲染 6 | 7 | ## Installation 8 | 9 | ``` 10 | composer require mix/view 11 | ``` 12 | 13 | ## License 14 | 15 | Apache License Version 2.0, http://www.apache.org/licenses/ 16 | -------------------------------------------------------------------------------- /src/view/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/view", 3 | "description": "View library, reference Yii2", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "view" 8 | ], 9 | "homepage": "https://openmix.org/", 10 | "license": "Apache-2.0", 11 | "authors": [ 12 | { 13 | "name": "liu,jian", 14 | "email": "coder.keda@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=7.0.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "Mix\\View\\": "src/" 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/view/src/Exception/ViewException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class ViewException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/websocket/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/websocket/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/websocket", 3 | "description": "WebSocket server and client based on Swoole coroutine", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "coroutine", 9 | "websocket", 10 | "server", 11 | "client" 12 | ], 13 | "homepage": "https://openmix.org/mix-php", 14 | "license": "Apache-2.0", 15 | "authors": [ 16 | { 17 | "name": "liu,jian", 18 | "email": "coder.keda@gmail.com" 19 | } 20 | ], 21 | "require": { 22 | "php": ">=7.0.0", 23 | "ext-swoole": ">=4.4.15", 24 | "mix/http-message": "~3.0.0" 25 | }, 26 | "require-dev": { 27 | "phpunit/phpunit": "^7.0.0", 28 | "mix/vega": "^3.0" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Mix\\WebSocket\\": "src/" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/websocket/src/Exception/CloseFrameException.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/websocket/tests/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( "$#" != 1 )) 4 | then 5 | echo "The target cannot be empty" 6 | exit 1 7 | fi 8 | 9 | /usr/local/bin/php8 vendor/bin/phpunit --bootstrap=tests/bootstrap.php $1 10 | -------------------------------------------------------------------------------- /src/worker-pool/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor/ 3 | .phpunit -------------------------------------------------------------------------------- /src/worker-pool/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mix/worker-pool", 3 | "description": "Swoole-based worker pool, coroutine pool", 4 | "type": "library", 5 | "keywords": [ 6 | "mix", 7 | "swoole", 8 | "worker-pool", 9 | "coroutine-pool" 10 | ], 11 | "homepage": "https://openmix.org/mix-php", 12 | "license": "Apache-2.0", 13 | "authors": [ 14 | { 15 | "name": "liu,jian", 16 | "email": "coder.keda@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=7.0.0", 21 | "ext-swoole": ">=4.4.4" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "Mix\\WorkerPool\\": "src/" 26 | } 27 | }, 28 | "require-dev": { 29 | "phpunit/phpunit": "^7.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/worker-pool/src/Exception/TypeException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class TypeException extends \RuntimeException 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/worker-pool/src/RunInterface.php: -------------------------------------------------------------------------------- 1 | set([ 8 | 'hook_flags' => SWOOLE_HOOK_ALL, 9 | ]); 10 | $scheduler->add(function () use ($func) { 11 | call_user_func($func); 12 | }); 13 | $scheduler->start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/worker-pool/tests/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( "$#" != 1 )) 4 | then 5 | echo "The target cannot be empty" 6 | exit 1 7 | fi 8 | 9 | /usr/local/bin/php8 vendor/bin/phpunit --bootstrap=tests/bootstrap.php $1 10 | -------------------------------------------------------------------------------- /techempower-benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/techempower-benchmark.png -------------------------------------------------------------------------------- /web-frameworks-benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mix-php/mix/41d74d8b34b0c1c648516ed305af5c49fdb356cc/web-frameworks-benchmark.png --------------------------------------------------------------------------------