From 4dfa7f1632a8fbefe25d879375582e26bbf44515 Mon Sep 17 00:00:00 2001 From: zhaoxiang Date: Tue, 16 Apr 2019 15:59:08 +0800 Subject: [PATCH] =?UTF-8?q?init=20=E5=85=A8=E9=9D=A2=E5=8E=BB=E9=99=A4?= =?UTF-8?q?=E5=85=A8=E9=83=A83.0=E6=95=B0=E6=8D=AE=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E6=9E=84=E5=BB=BA4.0=E7=89=88=E6=9C=AC=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 191 -- README.md | 80 +- application/.htaccess | 1 - application/admin/behavior/AdminLog.php | 52 - application/admin/behavior/ApiAuth.php | 38 - application/admin/behavior/ApiPermission.php | 103 - application/admin/behavior/BuildResponse.php | 26 - application/admin/behavior/Mock.php | 224 -- application/admin/controller/App.php | 198 -- application/admin/controller/AppGroup.php | 137 - application/admin/controller/Auth.php | 296 -- application/admin/controller/Base.php | 57 - application/admin/controller/Fields.php | 264 -- application/admin/controller/Index.php | 53 - .../admin/controller/InterfaceGroup.php | 160 - .../admin/controller/InterfaceList.php | 194 -- application/admin/controller/Log.php | 72 - application/admin/controller/Login.php | 101 - application/admin/controller/Menu.php | 108 - application/admin/controller/Miss.php | 15 - application/admin/controller/User.php | 269 -- application/admin/tags.php | 18 - application/adminRoute.php | 279 -- application/api/behavior/ApiAuth.php | 124 - application/api/behavior/ApiPermission.php | 44 - application/api/behavior/BuildResponse.php | 99 - application/api/behavior/RequestFilter.php | 179 - application/api/controller/Base.php | 56 - application/api/controller/BuildToken.php | 90 - application/api/controller/Index.php | 19 - application/api/controller/Miss.php | 22 - application/api/tags.php | 18 - application/apiRoute.php | 13 - application/command.php | 12 - application/common.php | 65 - application/config.php | 241 -- application/database.php | 53 - application/extra/apiAdmin.php | 38 - application/model/AdminApp.php | 8 - application/model/AdminAppGroup.php | 13 - application/model/AdminAuthGroup.php | 17 - application/model/AdminAuthGroupAccess.php | 13 - application/model/AdminAuthRule.php | 13 - application/model/AdminFields.php | 12 - application/model/AdminGroup.php | 13 - application/model/AdminList.php | 11 - application/model/AdminMenu.php | 8 - application/model/AdminUser.php | 12 - application/model/AdminUserAction.php | 13 - application/model/AdminUserData.php | 12 - application/model/Base.php | 15 - application/tags.php | 28 - application/util/ApiLog.php | 109 - application/util/DataType.php | 24 - application/util/MockConf.php | 21 - application/util/ReturnCode.php | 49 - application/util/StrRandom.php | 186 - application/util/Strs.php | 252 -- application/util/Tools.php | 115 - application/wiki/controller/Base.php | 90 - application/wiki/controller/Index.php | 178 - application/wiki/view/index/calculation.html | 44 - application/wiki/view/index/detail.html | 199 -- application/wiki/view/index/error_code.html | 45 - application/wiki/view/index/index.html | 78 - application/wiki/view/index/login.html | 96 - application/wikiRoute.php | 38 - build.php | 25 - composer.json | 33 - composer.lock | 77 - data/apiRoute.tpl | 15 - data/apiadmin_3.0.8.sql | 358 -- extend/.gitignore | 2 - public/.htaccess | 8 - public/favicon.ico | Bin 1150 -> 0 bytes public/index.php | 17 - public/robots.txt | 2 - public/router.php | 20 - public/static/defaultImg.jpg | Bin 15839 -> 0 bytes public/static/jsonFormater/Collapsed.gif | Bin 215 -> 0 bytes public/static/jsonFormater/Expanded.gif | Bin 206 -> 0 bytes public/static/jsonFormater/jsonFormater.css | 35 - public/static/jsonFormater/jsonFormater.js | 202 -- runtime/index.html | 0 think | 17 - thinkphp/.gitignore | 4 - thinkphp/.htaccess | 1 - thinkphp/.travis.yml | 47 - thinkphp/CONTRIBUTING.md | 119 - thinkphp/LICENSE.txt | 32 - thinkphp/README.md | 114 - thinkphp/base.php | 65 - thinkphp/codecov.yml | 12 - thinkphp/composer.json | 35 - thinkphp/console.php | 20 - thinkphp/convention.php | 298 -- thinkphp/helper.php | 589 ---- thinkphp/lang/zh-cn.php | 136 - thinkphp/library/think/App.php | 677 ---- thinkphp/library/think/Build.php | 235 -- thinkphp/library/think/Cache.php | 247 -- thinkphp/library/think/Collection.php | 457 --- thinkphp/library/think/Config.php | 214 -- thinkphp/library/think/Console.php | 863 ----- thinkphp/library/think/Controller.php | 229 -- thinkphp/library/think/Cookie.php | 268 -- thinkphp/library/think/Db.php | 180 - thinkphp/library/think/Debug.php | 252 -- thinkphp/library/think/Env.php | 39 - thinkphp/library/think/Error.php | 136 - thinkphp/library/think/Exception.php | 55 - thinkphp/library/think/File.php | 478 --- thinkphp/library/think/Hook.php | 148 - thinkphp/library/think/Lang.php | 265 -- thinkphp/library/think/Loader.php | 677 ---- thinkphp/library/think/Log.php | 237 -- thinkphp/library/think/Model.php | 2348 ------------- thinkphp/library/think/Paginator.php | 409 --- thinkphp/library/think/Process.php | 1205 ------- thinkphp/library/think/Request.php | 1768 ---------- thinkphp/library/think/Response.php | 332 -- thinkphp/library/think/Route.php | 1645 --------- thinkphp/library/think/Session.php | 366 -- thinkphp/library/think/Template.php | 1139 ------ thinkphp/library/think/Url.php | 333 -- thinkphp/library/think/Validate.php | 1367 -------- thinkphp/library/think/View.php | 239 -- thinkphp/library/think/cache/Driver.php | 231 -- thinkphp/library/think/cache/driver/File.php | 268 -- thinkphp/library/think/cache/driver/Lite.php | 187 - .../library/think/cache/driver/Memcache.php | 177 - .../library/think/cache/driver/Memcached.php | 187 - thinkphp/library/think/cache/driver/Redis.php | 188 - .../library/think/cache/driver/Sqlite.php | 199 -- .../library/think/cache/driver/Wincache.php | 152 - .../library/think/cache/driver/Xcache.php | 155 - thinkphp/library/think/config/driver/Ini.php | 24 - thinkphp/library/think/config/driver/Json.php | 24 - thinkphp/library/think/config/driver/Xml.php | 31 - thinkphp/library/think/console/Command.php | 470 --- thinkphp/library/think/console/Input.php | 464 --- thinkphp/library/think/console/LICENSE | 19 - thinkphp/library/think/console/Output.php | 222 -- thinkphp/library/think/console/bin/README.md | 1 - .../library/think/console/bin/hiddeninput.exe | Bin 9216 -> 0 bytes .../library/think/console/command/Build.php | 56 - .../library/think/console/command/Clear.php | 63 - .../library/think/console/command/Help.php | 69 - .../library/think/console/command/Lists.php | 74 - .../library/think/console/command/Make.php | 110 - .../think/console/command/make/Controller.php | 50 - .../think/console/command/make/Model.php | 36 - .../command/make/stubs/controller.plain.stub | 10 - .../command/make/stubs/controller.stub | 85 - .../console/command/make/stubs/model.stub | 10 - .../console/command/optimize/Autoload.php | 294 -- .../think/console/command/optimize/Config.php | 93 - .../think/console/command/optimize/Route.php | 75 - .../think/console/command/optimize/Schema.php | 118 - .../library/think/console/input/Argument.php | 115 - .../think/console/input/Definition.php | 375 -- .../library/think/console/input/Option.php | 190 - thinkphp/library/think/console/output/Ask.php | 340 -- .../think/console/output/Descriptor.php | 319 -- .../think/console/output/Formatter.php | 198 -- .../library/think/console/output/Question.php | 211 -- .../console/output/descriptor/Console.php | 149 - .../think/console/output/driver/Buffer.php | 52 - .../think/console/output/driver/Console.php | 373 -- .../think/console/output/driver/Nothing.php | 33 - .../think/console/output/formatter/Stack.php | 116 - .../think/console/output/formatter/Style.php | 189 - .../think/console/output/question/Choice.php | 163 - .../console/output/question/Confirmation.php | 57 - thinkphp/library/think/controller/Rest.php | 99 - thinkphp/library/think/controller/Yar.php | 51 - thinkphp/library/think/db/Builder.php | 899 ----- thinkphp/library/think/db/Connection.php | 1059 ------ thinkphp/library/think/db/Expression.php | 48 - thinkphp/library/think/db/Query.php | 3045 ----------------- thinkphp/library/think/db/builder/Mysql.php | 137 - thinkphp/library/think/db/builder/Pgsql.php | 89 - thinkphp/library/think/db/builder/Sqlite.php | 82 - thinkphp/library/think/db/builder/Sqlsrv.php | 137 - thinkphp/library/think/db/connector/Mysql.php | 126 - thinkphp/library/think/db/connector/Pgsql.php | 103 - .../library/think/db/connector/Sqlite.php | 104 - .../library/think/db/connector/Sqlsrv.php | 125 - thinkphp/library/think/db/connector/pgsql.sql | 117 - .../think/db/exception/BindParamException.php | 35 - .../db/exception/DataNotFoundException.php | 43 - .../db/exception/ModelNotFoundException.php | 43 - thinkphp/library/think/debug/Console.php | 160 - thinkphp/library/think/debug/Html.php | 111 - .../exception/ClassNotFoundException.php | 32 - .../library/think/exception/DbException.php | 43 - .../think/exception/ErrorException.php | 57 - thinkphp/library/think/exception/Handle.php | 282 -- .../library/think/exception/HttpException.php | 36 - .../think/exception/HttpResponseException.php | 33 - .../library/think/exception/PDOException.php | 39 - .../exception/RouteNotFoundException.php | 22 - .../exception/TemplateNotFoundException.php | 33 - .../think/exception/ThrowableError.php | 47 - .../think/exception/ValidateException.php | 33 - thinkphp/library/think/log/driver/File.php | 270 -- thinkphp/library/think/log/driver/Socket.php | 250 -- thinkphp/library/think/log/driver/Test.php | 30 - thinkphp/library/think/model/Collection.php | 79 - thinkphp/library/think/model/Merge.php | 322 -- thinkphp/library/think/model/Pivot.php | 42 - thinkphp/library/think/model/Relation.php | 155 - .../think/model/relation/BelongsTo.php | 243 -- .../think/model/relation/BelongsToMany.php | 644 ---- .../library/think/model/relation/HasMany.php | 311 -- .../think/model/relation/HasManyThrough.php | 157 - .../library/think/model/relation/HasOne.php | 215 -- .../think/model/relation/MorphMany.php | 304 -- .../library/think/model/relation/MorphOne.php | 252 -- .../library/think/model/relation/MorphTo.php | 299 -- .../library/think/model/relation/OneToOne.php | 337 -- .../think/paginator/driver/Bootstrap.php | 205 -- thinkphp/library/think/process/Builder.php | 233 -- thinkphp/library/think/process/Utils.php | 75 - .../think/process/exception/Failed.php | 42 - .../think/process/exception/Timeout.php | 61 - .../library/think/process/pipes/Pipes.php | 93 - thinkphp/library/think/process/pipes/Unix.php | 196 -- .../library/think/process/pipes/Windows.php | 228 -- thinkphp/library/think/response/Json.php | 51 - thinkphp/library/think/response/Jsonp.php | 58 - thinkphp/library/think/response/Redirect.php | 105 - thinkphp/library/think/response/View.php | 89 - thinkphp/library/think/response/Xml.php | 102 - .../library/think/session/driver/Memcache.php | 118 - .../think/session/driver/Memcached.php | 126 - .../library/think/session/driver/Redis.php | 128 - thinkphp/library/think/template/TagLib.php | 334 -- .../library/think/template/driver/File.php | 74 - thinkphp/library/think/template/taglib/Cx.php | 673 ---- thinkphp/library/think/view/driver/Php.php | 160 - thinkphp/library/think/view/driver/Think.php | 167 - thinkphp/library/traits/controller/Jump.php | 167 - thinkphp/library/traits/model/SoftDelete.php | 200 -- thinkphp/library/traits/think/Instance.php | 54 - thinkphp/logo.png | Bin 6995 -> 0 bytes thinkphp/phpunit.xml | 35 - thinkphp/start.php | 19 - thinkphp/tpl/default_index.tpl | 10 - thinkphp/tpl/dispatch_jump.tpl | 49 - thinkphp/tpl/page_trace.tpl | 71 - thinkphp/tpl/think_exception.tpl | 537 --- vendor/.gitignore | 2 - 253 files changed, 1 insertion(+), 47475 deletions(-) delete mode 100644 LICENSE delete mode 100644 application/.htaccess delete mode 100644 application/admin/behavior/AdminLog.php delete mode 100644 application/admin/behavior/ApiAuth.php delete mode 100644 application/admin/behavior/ApiPermission.php delete mode 100644 application/admin/behavior/BuildResponse.php delete mode 100644 application/admin/behavior/Mock.php delete mode 100644 application/admin/controller/App.php delete mode 100644 application/admin/controller/AppGroup.php delete mode 100644 application/admin/controller/Auth.php delete mode 100644 application/admin/controller/Base.php delete mode 100644 application/admin/controller/Fields.php delete mode 100644 application/admin/controller/Index.php delete mode 100644 application/admin/controller/InterfaceGroup.php delete mode 100644 application/admin/controller/InterfaceList.php delete mode 100644 application/admin/controller/Log.php delete mode 100644 application/admin/controller/Login.php delete mode 100644 application/admin/controller/Menu.php delete mode 100644 application/admin/controller/Miss.php delete mode 100644 application/admin/controller/User.php delete mode 100644 application/admin/tags.php delete mode 100644 application/adminRoute.php delete mode 100644 application/api/behavior/ApiAuth.php delete mode 100644 application/api/behavior/ApiPermission.php delete mode 100644 application/api/behavior/BuildResponse.php delete mode 100644 application/api/behavior/RequestFilter.php delete mode 100644 application/api/controller/Base.php delete mode 100644 application/api/controller/BuildToken.php delete mode 100644 application/api/controller/Index.php delete mode 100644 application/api/controller/Miss.php delete mode 100644 application/api/tags.php delete mode 100644 application/apiRoute.php delete mode 100644 application/command.php delete mode 100644 application/common.php delete mode 100644 application/config.php delete mode 100755 application/database.php delete mode 100644 application/extra/apiAdmin.php delete mode 100644 application/model/AdminApp.php delete mode 100644 application/model/AdminAppGroup.php delete mode 100644 application/model/AdminAuthGroup.php delete mode 100644 application/model/AdminAuthGroupAccess.php delete mode 100644 application/model/AdminAuthRule.php delete mode 100644 application/model/AdminFields.php delete mode 100644 application/model/AdminGroup.php delete mode 100644 application/model/AdminList.php delete mode 100644 application/model/AdminMenu.php delete mode 100644 application/model/AdminUser.php delete mode 100644 application/model/AdminUserAction.php delete mode 100644 application/model/AdminUserData.php delete mode 100644 application/model/Base.php delete mode 100755 application/tags.php delete mode 100644 application/util/ApiLog.php delete mode 100644 application/util/DataType.php delete mode 100644 application/util/MockConf.php delete mode 100644 application/util/ReturnCode.php delete mode 100644 application/util/StrRandom.php delete mode 100644 application/util/Strs.php delete mode 100644 application/util/Tools.php delete mode 100644 application/wiki/controller/Base.php delete mode 100644 application/wiki/controller/Index.php delete mode 100644 application/wiki/view/index/calculation.html delete mode 100644 application/wiki/view/index/detail.html delete mode 100644 application/wiki/view/index/error_code.html delete mode 100644 application/wiki/view/index/index.html delete mode 100644 application/wiki/view/index/login.html delete mode 100644 application/wikiRoute.php delete mode 100644 build.php delete mode 100644 composer.json delete mode 100644 composer.lock delete mode 100644 data/apiRoute.tpl delete mode 100644 data/apiadmin_3.0.8.sql delete mode 100644 extend/.gitignore delete mode 100644 public/.htaccess delete mode 100644 public/favicon.ico delete mode 100644 public/index.php delete mode 100644 public/robots.txt delete mode 100644 public/router.php delete mode 100644 public/static/defaultImg.jpg delete mode 100644 public/static/jsonFormater/Collapsed.gif delete mode 100644 public/static/jsonFormater/Expanded.gif delete mode 100644 public/static/jsonFormater/jsonFormater.css delete mode 100644 public/static/jsonFormater/jsonFormater.js delete mode 100644 runtime/index.html delete mode 100644 think delete mode 100755 thinkphp/.gitignore delete mode 100755 thinkphp/.htaccess delete mode 100755 thinkphp/.travis.yml delete mode 100755 thinkphp/CONTRIBUTING.md delete mode 100755 thinkphp/LICENSE.txt delete mode 100755 thinkphp/README.md delete mode 100755 thinkphp/base.php delete mode 100755 thinkphp/codecov.yml delete mode 100755 thinkphp/composer.json delete mode 100755 thinkphp/console.php delete mode 100755 thinkphp/convention.php delete mode 100755 thinkphp/helper.php delete mode 100755 thinkphp/lang/zh-cn.php delete mode 100755 thinkphp/library/think/App.php delete mode 100755 thinkphp/library/think/Build.php delete mode 100755 thinkphp/library/think/Cache.php delete mode 100755 thinkphp/library/think/Collection.php delete mode 100755 thinkphp/library/think/Config.php delete mode 100755 thinkphp/library/think/Console.php delete mode 100755 thinkphp/library/think/Controller.php delete mode 100755 thinkphp/library/think/Cookie.php delete mode 100755 thinkphp/library/think/Db.php delete mode 100755 thinkphp/library/think/Debug.php delete mode 100755 thinkphp/library/think/Env.php delete mode 100755 thinkphp/library/think/Error.php delete mode 100755 thinkphp/library/think/Exception.php delete mode 100755 thinkphp/library/think/File.php delete mode 100755 thinkphp/library/think/Hook.php delete mode 100755 thinkphp/library/think/Lang.php delete mode 100755 thinkphp/library/think/Loader.php delete mode 100755 thinkphp/library/think/Log.php delete mode 100755 thinkphp/library/think/Model.php delete mode 100755 thinkphp/library/think/Paginator.php delete mode 100755 thinkphp/library/think/Process.php delete mode 100755 thinkphp/library/think/Request.php delete mode 100755 thinkphp/library/think/Response.php delete mode 100755 thinkphp/library/think/Route.php delete mode 100755 thinkphp/library/think/Session.php delete mode 100755 thinkphp/library/think/Template.php delete mode 100755 thinkphp/library/think/Url.php delete mode 100755 thinkphp/library/think/Validate.php delete mode 100755 thinkphp/library/think/View.php delete mode 100755 thinkphp/library/think/cache/Driver.php delete mode 100755 thinkphp/library/think/cache/driver/File.php delete mode 100755 thinkphp/library/think/cache/driver/Lite.php delete mode 100755 thinkphp/library/think/cache/driver/Memcache.php delete mode 100755 thinkphp/library/think/cache/driver/Memcached.php delete mode 100755 thinkphp/library/think/cache/driver/Redis.php delete mode 100755 thinkphp/library/think/cache/driver/Sqlite.php delete mode 100755 thinkphp/library/think/cache/driver/Wincache.php delete mode 100755 thinkphp/library/think/cache/driver/Xcache.php delete mode 100755 thinkphp/library/think/config/driver/Ini.php delete mode 100755 thinkphp/library/think/config/driver/Json.php delete mode 100755 thinkphp/library/think/config/driver/Xml.php delete mode 100755 thinkphp/library/think/console/Command.php delete mode 100755 thinkphp/library/think/console/Input.php delete mode 100755 thinkphp/library/think/console/LICENSE delete mode 100755 thinkphp/library/think/console/Output.php delete mode 100755 thinkphp/library/think/console/bin/README.md delete mode 100755 thinkphp/library/think/console/bin/hiddeninput.exe delete mode 100755 thinkphp/library/think/console/command/Build.php delete mode 100755 thinkphp/library/think/console/command/Clear.php delete mode 100755 thinkphp/library/think/console/command/Help.php delete mode 100755 thinkphp/library/think/console/command/Lists.php delete mode 100755 thinkphp/library/think/console/command/Make.php delete mode 100755 thinkphp/library/think/console/command/make/Controller.php delete mode 100755 thinkphp/library/think/console/command/make/Model.php delete mode 100755 thinkphp/library/think/console/command/make/stubs/controller.plain.stub delete mode 100755 thinkphp/library/think/console/command/make/stubs/controller.stub delete mode 100755 thinkphp/library/think/console/command/make/stubs/model.stub delete mode 100755 thinkphp/library/think/console/command/optimize/Autoload.php delete mode 100755 thinkphp/library/think/console/command/optimize/Config.php delete mode 100755 thinkphp/library/think/console/command/optimize/Route.php delete mode 100755 thinkphp/library/think/console/command/optimize/Schema.php delete mode 100755 thinkphp/library/think/console/input/Argument.php delete mode 100755 thinkphp/library/think/console/input/Definition.php delete mode 100755 thinkphp/library/think/console/input/Option.php delete mode 100755 thinkphp/library/think/console/output/Ask.php delete mode 100755 thinkphp/library/think/console/output/Descriptor.php delete mode 100755 thinkphp/library/think/console/output/Formatter.php delete mode 100755 thinkphp/library/think/console/output/Question.php delete mode 100755 thinkphp/library/think/console/output/descriptor/Console.php delete mode 100755 thinkphp/library/think/console/output/driver/Buffer.php delete mode 100755 thinkphp/library/think/console/output/driver/Console.php delete mode 100755 thinkphp/library/think/console/output/driver/Nothing.php delete mode 100755 thinkphp/library/think/console/output/formatter/Stack.php delete mode 100755 thinkphp/library/think/console/output/formatter/Style.php delete mode 100755 thinkphp/library/think/console/output/question/Choice.php delete mode 100755 thinkphp/library/think/console/output/question/Confirmation.php delete mode 100755 thinkphp/library/think/controller/Rest.php delete mode 100755 thinkphp/library/think/controller/Yar.php delete mode 100755 thinkphp/library/think/db/Builder.php delete mode 100755 thinkphp/library/think/db/Connection.php delete mode 100755 thinkphp/library/think/db/Expression.php delete mode 100755 thinkphp/library/think/db/Query.php delete mode 100755 thinkphp/library/think/db/builder/Mysql.php delete mode 100755 thinkphp/library/think/db/builder/Pgsql.php delete mode 100755 thinkphp/library/think/db/builder/Sqlite.php delete mode 100755 thinkphp/library/think/db/builder/Sqlsrv.php delete mode 100755 thinkphp/library/think/db/connector/Mysql.php delete mode 100755 thinkphp/library/think/db/connector/Pgsql.php delete mode 100755 thinkphp/library/think/db/connector/Sqlite.php delete mode 100755 thinkphp/library/think/db/connector/Sqlsrv.php delete mode 100755 thinkphp/library/think/db/connector/pgsql.sql delete mode 100755 thinkphp/library/think/db/exception/BindParamException.php delete mode 100755 thinkphp/library/think/db/exception/DataNotFoundException.php delete mode 100755 thinkphp/library/think/db/exception/ModelNotFoundException.php delete mode 100755 thinkphp/library/think/debug/Console.php delete mode 100755 thinkphp/library/think/debug/Html.php delete mode 100755 thinkphp/library/think/exception/ClassNotFoundException.php delete mode 100755 thinkphp/library/think/exception/DbException.php delete mode 100755 thinkphp/library/think/exception/ErrorException.php delete mode 100755 thinkphp/library/think/exception/Handle.php delete mode 100755 thinkphp/library/think/exception/HttpException.php delete mode 100755 thinkphp/library/think/exception/HttpResponseException.php delete mode 100755 thinkphp/library/think/exception/PDOException.php delete mode 100755 thinkphp/library/think/exception/RouteNotFoundException.php delete mode 100755 thinkphp/library/think/exception/TemplateNotFoundException.php delete mode 100755 thinkphp/library/think/exception/ThrowableError.php delete mode 100755 thinkphp/library/think/exception/ValidateException.php delete mode 100755 thinkphp/library/think/log/driver/File.php delete mode 100755 thinkphp/library/think/log/driver/Socket.php delete mode 100755 thinkphp/library/think/log/driver/Test.php delete mode 100755 thinkphp/library/think/model/Collection.php delete mode 100755 thinkphp/library/think/model/Merge.php delete mode 100755 thinkphp/library/think/model/Pivot.php delete mode 100755 thinkphp/library/think/model/Relation.php delete mode 100755 thinkphp/library/think/model/relation/BelongsTo.php delete mode 100755 thinkphp/library/think/model/relation/BelongsToMany.php delete mode 100755 thinkphp/library/think/model/relation/HasMany.php delete mode 100755 thinkphp/library/think/model/relation/HasManyThrough.php delete mode 100755 thinkphp/library/think/model/relation/HasOne.php delete mode 100755 thinkphp/library/think/model/relation/MorphMany.php delete mode 100755 thinkphp/library/think/model/relation/MorphOne.php delete mode 100755 thinkphp/library/think/model/relation/MorphTo.php delete mode 100755 thinkphp/library/think/model/relation/OneToOne.php delete mode 100755 thinkphp/library/think/paginator/driver/Bootstrap.php delete mode 100755 thinkphp/library/think/process/Builder.php delete mode 100755 thinkphp/library/think/process/Utils.php delete mode 100755 thinkphp/library/think/process/exception/Failed.php delete mode 100755 thinkphp/library/think/process/exception/Timeout.php delete mode 100755 thinkphp/library/think/process/pipes/Pipes.php delete mode 100755 thinkphp/library/think/process/pipes/Unix.php delete mode 100755 thinkphp/library/think/process/pipes/Windows.php delete mode 100755 thinkphp/library/think/response/Json.php delete mode 100755 thinkphp/library/think/response/Jsonp.php delete mode 100755 thinkphp/library/think/response/Redirect.php delete mode 100755 thinkphp/library/think/response/View.php delete mode 100755 thinkphp/library/think/response/Xml.php delete mode 100755 thinkphp/library/think/session/driver/Memcache.php delete mode 100755 thinkphp/library/think/session/driver/Memcached.php delete mode 100755 thinkphp/library/think/session/driver/Redis.php delete mode 100755 thinkphp/library/think/template/TagLib.php delete mode 100755 thinkphp/library/think/template/driver/File.php delete mode 100755 thinkphp/library/think/template/taglib/Cx.php delete mode 100755 thinkphp/library/think/view/driver/Php.php delete mode 100755 thinkphp/library/think/view/driver/Think.php delete mode 100755 thinkphp/library/traits/controller/Jump.php delete mode 100755 thinkphp/library/traits/model/SoftDelete.php delete mode 100755 thinkphp/library/traits/think/Instance.php delete mode 100755 thinkphp/logo.png delete mode 100755 thinkphp/phpunit.xml delete mode 100755 thinkphp/start.php delete mode 100755 thinkphp/tpl/default_index.tpl delete mode 100755 thinkphp/tpl/dispatch_jump.tpl delete mode 100755 thinkphp/tpl/page_trace.tpl delete mode 100755 thinkphp/tpl/think_exception.tpl delete mode 100644 vendor/.gitignore diff --git a/LICENSE b/LICENSE deleted file mode 100644 index c6b604c..0000000 --- a/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "{}" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright 2018 Zhao - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index c7ec68d..612b896 100644 --- a/README.md +++ b/README.md @@ -7,82 +7,4 @@ [![ApiAdmin](https://img.shields.io/badge/build-passing-brightgreen.svg)](http://www.apiadmin.org/) [![ApiAdmin](https://img.shields.io/badge/ApiAdmin-v3.0.8-brightgreen.svg)](http://www.apiadmin.org/) -## 前端页面 -ApiAdmin3.0是一个前后端完全分离的项目,前端采用Vue构建,如需要可视化配置的请移步:[ApiAdmin-WEB](https://gitee.com/apiadmin/ApiAdmin-WEB) - -## 灵 感 - -首先自我介绍下吧,我是一个PHP程序员,目前就职于某上市集团。我第一份工作是做微信开发的,这也是我入行以来第一次做的商业上线项目,虽然我只是充当了其中一个不是太重要的角色,但是感谢它让我第一次接触了API,也让我第一次对于API产生了浓厚的兴趣。之后的一段时间内甚至疯狂的收集过各种免费的API接口!然而一直只是在用API,却没有为API贡献过些什么。 - -开源框架用了很多,开源代码看了很多,github、git@osc、Stack Overflow这些优秀的平台帮助了我很多,所以,我觉得是时候为开源做点什么。更是给开源项目PhalApi贡献过代码,也正是这一个契机使得我正式迈向开源社区。随着时间的推移,PhalApi的战绩赫赫,它的壮大更加坚定了Api的地位,既然未来的互联网世界中API占了很重要的地位,既然越来越多的人开始开发API,那么无状态的API如何去管理呢?因此**ApiAdmin**来了~ - -## 愿 景 - -> 希望有人用它,希望更多的人用它。 -> 希望它能帮助到你,希望它能帮助到更多的你。 - -## 项目简介 - -**系统需求** - -- PHP >= 5.6 -- MySQL >= 5.5.3 -- Redis - -**项目构成** - -- ThinkPHP v5.0.19 -- Vue 2.0 -- semanticUI -- ... - -**功能简介** - - 1. 接口文档自动生成 - 2. 接口输入参数自动检查 - 3. 接口输出参数数据类型自动规整 - 4. 灵活的参数规则设定 - 5. 支持三方Api无缝融合 - 6. 本地二次开发友好 - 7. ... - - ``` - ApiAdmin(PHP部分) - ├─ 系统维护 - | ├─ 菜单管理 - 编辑访客权限,处理菜单父子关系,被权限系统依赖(极为重要) - | ├─ 用户管理 - 添加新用户,封号,删号以及给账号分配权限组 - | ├─ 权限管理 - 权限组管理,给权限组添加权限,将用户提出权限组 - | └─ 操作日志 - 记录管理员的操作,用于追责,回溯和备案 - | ... - ``` - -**页面截图** - -![输入图片说明](https://gitee.com/uploads/images/2018/0224/095358_19cb42d0_110856.png "api.png") - -![输入图片说明](https://gitee.com/uploads/images/2018/0224/095410_55dc23e1_110856.png "app.png") - -![输入图片说明](https://gitee.com/uploads/images/2018/0224/095420_bddff990_110856.png "auth1.png") - -![输入图片说明](https://gitee.com/uploads/images/2018/0224/095427_fa86e42d_110856.png "auth2.png") - -![输入图片说明](https://gitee.com/uploads/images/2018/0224/095436_3600de17_110856.png "lock.png") - -![输入图片说明](https://gitee.com/uploads/images/2018/0224/095444_d2a88da0_110856.png "user.png") - -**项目特性** - -- 开放源码 -- 保持生机 -- 不断更新 -- 响应市场 - -**开源,我们在路上!** - -## 鸣谢 - -ApiAdmin走到今天,也正式迈入3.0时代了,同时,ApiAdmin也迎来了它的一岁生日,我们怀着激动的心情迎来这次发布。在新版本发布之际,我们真诚的感谢从1.0到2.0陪我们一路走来的朋友们。感谢你们的支持和信任!当然也感谢#开源中国#给大陆本土开源提供这样一个优秀的平台。 - -## 附:升级指南 - -很抱歉的告诉大家,虽然我们尽可能的和往期版本进行了兼容,但是,由于整体架构变化很大,所以想要零成本升级有点困难。我们建议大家可以使用3.0做新接口,慢慢的将2.0版本的接口移植到3.0。 +# 感谢大家的支持,当前项目正在进行ApiAdmin-4.0的开发,ApiAdmin-3.0已被迁移至[ApiAdmin-3.0](https://gitee.com/apiadmin/ApiAdmin-3.0)。又一次颠覆性的升级。我们即将回归,敬请期待! diff --git a/application/.htaccess b/application/.htaccess deleted file mode 100644 index 3418e55..0000000 --- a/application/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all \ No newline at end of file diff --git a/application/admin/behavior/AdminLog.php b/application/admin/behavior/AdminLog.php deleted file mode 100644 index f876cbb..0000000 --- a/application/admin/behavior/AdminLog.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ - -namespace app\admin\behavior; - - -use app\model\AdminMenu; -use app\model\AdminUserAction; -use app\util\ReturnCode; -use think\Request; - -class AdminLog { - - /** - * 后台操作日志记录 - * @author zhaoxiang - * @return \think\response\Json - * @throws \think\Exception - * @throws \think\exception\DbException - */ - public function run() { - $header = config('apiAdmin.CROSS_DOMAIN'); - $request = Request::instance(); - $route = $request->routeInfo(); - $ApiAuth = $request->header('ApiAuth', ''); - $userInfo = cache('Login:' . $ApiAuth); - $userInfo = json_decode($userInfo, true); - $menuInfo = AdminMenu::get(['url' => $route['route']]); - - if ($menuInfo) { - $menuInfo = $menuInfo->toArray(); - } else { - $data = ['code' => ReturnCode::INVALID, 'msg' => '当前路由非法:'. $route['route'], 'data' => []]; - - return json($data, 200, $header); - } - - AdminUserAction::create([ - 'actionName' => $menuInfo['name'], - 'uid' => $userInfo['id'], - 'nickname' => $userInfo['nickname'], - 'addTime' => time(), - 'url' => $route['route'], - 'data' => json_encode($request->param()) - ]); - } - -} diff --git a/application/admin/behavior/ApiAuth.php b/application/admin/behavior/ApiAuth.php deleted file mode 100644 index 19f755a..0000000 --- a/application/admin/behavior/ApiAuth.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ - -namespace app\admin\behavior; - - -use app\util\ReturnCode; -use think\Request; - -class ApiAuth { - - /** - * 默认行为函数 - * @return \think\response\Json - * @author zhaoxiang - */ - public function run() { - $request = Request::instance(); - $header = config('apiAdmin.CROSS_DOMAIN'); - $ApiAuth = $request->header('ApiAuth', ''); - if ($ApiAuth) { - $userInfo = cache('Login:' . $ApiAuth); - $userInfo = json_decode($userInfo, true); - if (!$userInfo || !isset($userInfo['id'])) { - $data = ['code' => ReturnCode::AUTH_ERROR, 'msg' => 'ApiAuth不匹配', 'data' => []]; - return json($data, 200, $header); - } - } else { - $data = ['code' => ReturnCode::AUTH_ERROR, 'msg' => '缺少ApiAuth', 'data' => []]; - return json($data, 200, $header); - } - } - -} diff --git a/application/admin/behavior/ApiPermission.php b/application/admin/behavior/ApiPermission.php deleted file mode 100644 index 9a1c39e..0000000 --- a/application/admin/behavior/ApiPermission.php +++ /dev/null @@ -1,103 +0,0 @@ - - */ - -namespace app\admin\behavior; - - -use app\model\AdminAuthGroup; -use app\model\AdminAuthGroupAccess; -use app\model\AdminAuthRule; -use app\util\ReturnCode; -use app\util\Tools; -use think\Request; - -class ApiPermission { - - /** - * 用户权限检测 - * @return \think\response\Json - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function run() { - $request = Request::instance(); - $route = $request->routeInfo(); - $header = config('apiAdmin.CROSS_DOMAIN'); - $ApiAuth = $request->header('ApiAuth', ''); - $userInfo = cache('Login:' . $ApiAuth); - $userInfo = json_decode($userInfo, true); - if (!$this->checkAuth($userInfo['id'], $route['route'])) { - $data = ['code' => ReturnCode::INVALID, 'msg' => '非常抱歉,您没有权限这么做!', 'data' => []]; - - return json($data, 200, $header); - } - } - - /** - * 检测用户权限 - * @param $uid - * @param $route - * @return bool - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - private function checkAuth($uid, $route) { - $isSupper = Tools::isAdministrator($uid); - if (!$isSupper) { - $rules = $this->getAuth($uid); - - return in_array($route, $rules); - } else { - return true; - } - - } - - /** - * 根据用户ID获取全部权限节点 - * @param $uid - * @return array - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - private function getAuth($uid) { - $groups = AdminAuthGroupAccess::get(['uid' => $uid]); - if (isset($groups) && $groups->groupId) { - $openGroup = (new AdminAuthGroup())->whereIn('id', $groups->groupId)->where(['status' => 1])->select(); - if (isset($openGroup)) { - $openGroupArr = []; - foreach ($openGroup as $group) { - $openGroupArr[] = $group->id; - } - $allRules = (new AdminAuthRule())->whereIn('groupId', $openGroupArr)->select(); - if (isset($allRules)) { - $rules = []; - foreach ($allRules as $rule) { - $rules[] = $rule->url; - } - $rules = array_unique($rules); - - return $rules; - } else { - return []; - } - } else { - return []; - } - } else { - return []; - } - } - - -} diff --git a/application/admin/behavior/BuildResponse.php b/application/admin/behavior/BuildResponse.php deleted file mode 100644 index 5e76c2a..0000000 --- a/application/admin/behavior/BuildResponse.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace app\admin\behavior; - - -use think\Config; -use think\Response; - -class BuildResponse { - - /** - * 返回参数过滤(主要是将返回参数的数据类型给规范) - * @param $response - * @author zhaoxiang - */ - public function run(Response $response) { - $header = Config::get('apiAdmin.CROSS_DOMAIN'); - $response->header($header); - } - -} diff --git a/application/admin/behavior/Mock.php b/application/admin/behavior/Mock.php deleted file mode 100644 index c248bdf..0000000 --- a/application/admin/behavior/Mock.php +++ /dev/null @@ -1,224 +0,0 @@ - - */ - -namespace app\admin\behavior; - - -use app\util\ReturnCode; -use app\util\StrRandom; -use app\util\Strs; -use think\Config; - -class Mock { - - /** - * 拦截并且返回Mock数据 - * @return \think\response\Json - * @author zhaoxiang - */ - public function run() { - $header = Config::get('apiAdmin.CROSS_DOMAIN'); - - $config = [ - "myField|1-10" => "1", - "myNum|1-100" => 1, - "myFloat|1-100.1-10" => 1, - "myFa|123.1-10" => 1, - "myFb|123.3" => 1, - "object|2" => [ - "name|1-3" => ['myName', 123123, '1231541asdasd', 'jjjjsssss', '2345123afasgvawe'], - "name2|2" => ['myName', 123123, '1231541asdasd', 'jjjjsssss', '2345123afasgvawe'], - 'age|25-68' => 1 - ] - ]; - $data = $this->buildData($config); - - $return = ['code' => ReturnCode::SUCCESS, 'msg' => '操作成功', 'data' => $data]; - - return json($return, 200, $header); - } - - /** - * 构建随机数据 - * @param $config - * @return array - * @author zhaoxiang - */ - private function buildData($config) { - $data = []; - - foreach ($config as $key => $value) { - $vType = gettype($value); - list($name, $rule) = explode('|', $key); - switch ($vType) { - case 'integer': - $data[$name] = $this->buildInt($rule); - break; - case 'array': - $data[$name] = $this->buildArray($rule, $value); - break; - case 'string': - $data[$name] = $this->buildString($rule); - break; - case 'double': - $data[$name] = $this->buildFloat($rule); - break; - case 'boolean': - break; - } - } - - return $data; - } - - /** - * 构建随机浮点数 - * @param string $rule - * @return float|int - * @author zhaoxiang - */ - private function buildFloat($rule = '') { - $hasDot = strstr($rule, '.'); - if (!$hasDot) { - return $this->buildInt($rule); - } - list($intPart, $floatPart) = explode('.', $rule); - - $intVertical = strstr($intPart, '-'); - if ($intVertical) { - list($intMin, $intMax) = explode('-', $intPart); - } else { - $intMin = $intMax = $intPart; - } - - $floatVertical = strstr($floatPart, '-'); - if ($floatVertical) { - list($floatMin, $floatMax) = explode('-', $floatPart); - } else { - $floatMin = $floatMax = $floatPart; - } - - return StrRandom::randomFloat($intMin, $intMax, $floatMin, $floatMax); - } - - /** - * 构建随机的整型数据 - * @param string $rule - * @return float|integer - * @author zhaoxiang - */ - private function buildInt($rule = '') { - $hasDot = strstr($rule, '.'); - if ($hasDot) { - return $this->buildFloat($rule); - } - $hasVertical = strstr($rule, '-'); - if ($hasVertical) { - list($min, $max) = explode('-', $rule); - - return mt_rand($min, $max); - } else { - return intval($rule); - } - } - - /** - * 构建随机字符串 - * @param string $rule - * @return string - * @author zhaoxiang - */ - private function buildString($rule = '') { - $hasVertical = strstr($rule, '-'); - if ($hasVertical) { - list($minLen, $maxLen) = explode('-', $rule); - $len = mt_rand($minLen, $maxLen); - } else { - $len = $rule; - } - - return Strs::randString($len); - } - - /** - * 构建随机的数组列表数据 - * @param string $rule - * @param array $value - * @return array - * @author zhaoxiang - */ - private function buildArray($rule = '', $value = []) { - $isAssoc = $this->isAssoc($value); - if ($isAssoc) { - $has = strstr($rule, '-'); - if ($has) { - list($min, $max) = explode('-', $rule); - $num = mt_rand($min, $max); - } else { - $num = intval($rule); - } - - $res = []; - for ($i = 0; $i < $num; $i++) { - $new = []; - foreach ($value as $vKey => $item) { - $hasVertical = strstr($vKey, '|'); - if ($hasVertical) { - $new = array_merge($new, $this->buildData([$vKey => $item])); - } else { - $new[$vKey] = $item; - } - } - $res[] = $new; - } - - return $res; - } else { - $hasVertical = strstr($rule, '-'); - if ($hasVertical) { - $new = []; - list($min, $max) = explode('-', $rule); - $num = mt_rand($min, $max); - for ($i = 0; $i < $num; $i++) { - $new = array_merge($new, $value); - } - - return $new; - } else { - $rule = intval($rule); - if (count($value) <= $rule) { - return $value; - } else { - $new = []; - shuffle($value); - for ($i = 0; $i < $rule; $i++) { - $new[] = $value[$i]; - } - - return $new; - } - } - } - } - - /** - * 判断是否是关联数组 - * @param $array - * @return bool true 是关联数组 false 是索引数组 - * @author zhaoxiang - */ - private function isAssoc($array) { - if (is_array($array)) { - $keys = array_keys($array); - - return $keys !== array_keys($keys); - } - - return false; - } - -} diff --git a/application/admin/controller/App.php b/application/admin/controller/App.php deleted file mode 100644 index 7afbefc..0000000 --- a/application/admin/controller/App.php +++ /dev/null @@ -1,198 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminApp; -use app\model\AdminList; -use app\model\AdminGroup; -use app\util\ReturnCode; -use app\util\Strs; -use app\util\Tools; - -class App extends Base { - /** - * 获取应用列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $keywords = $this->request->get('keywords', ''); - $type = $this->request->get('type', ''); - $status = $this->request->get('status', ''); - - $where = []; - if ($status === '1' || $status === '0') { - $where['app_status'] = $status; - } - if ($type) { - switch ($type) { - case 1: - $where['app_id'] = $keywords; - break; - case 2: - $where['app_name'] = ['like', "%{$keywords}%"]; - break; - } - } - $listObj = (new AdminApp())->where($where)->order('app_addTime DESC') - ->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'] - ]); - } - - /** - * 获取AppId,AppSecret,接口列表,应用接口权限细节 - * @author zhaoxiang - * @return array - * @throws \think\Exception - * @throws \think\exception\DbException - */ - public function getAppInfo() { - $apiArr = AdminList::all(); - foreach ($apiArr as $api) { - $res['apiList'][$api['groupHash']][] = $api; - } - $groupArr = AdminGroup::all(); - $groupArr = Tools::buildArrFromObj($groupArr); - $res['groupInfo'] = array_column($groupArr, 'name', 'hash'); - $id = $this->request->get('id', 0); - if ($id) { - $appInfo = AdminApp::get($id)->toArray(); - $res['app_detail'] = json_decode($appInfo['app_api_show'], true); - } else { - $res['app_id'] = mt_rand(1, 9) . Strs::randString(7, 1); - $res['app_secret'] = Strs::randString(32); - } - - return $this->buildSuccess($res); - } - - /** - * 刷新APPSecret - * @author zhaoxiang - * @return array - */ - public function refreshAppSecret() { - $id = $this->request->get('id', 0); - $data['app_secret'] = Strs::randString(32); - if ($id) { - $res = AdminApp::update($data, ['id' => $id]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } - } - - return $this->buildSuccess($data); - } - - /** - * 新增应用 - * @return array - * @author zhaoxiang - */ - public function add() { - $postData = $this->request->post(); - $data = [ - 'app_id' => $postData['app_id'], - 'app_secret' => $postData['app_secret'], - 'app_name' => $postData['app_name'], - 'app_info' => $postData['app_info'], - 'app_group' => $postData['app_group'], - 'app_addTime' => time(), - 'app_api' => '', - 'app_api_show' => '', - ]; - if (isset($postData['app_api']) && $postData['app_api']) { - $appApi = []; - $data['app_api_show'] = json_encode($postData['app_api']); - foreach ($postData['app_api'] as $value) { - $appApi = array_merge($appApi, $value); - } - $data['app_api'] = implode(',', $appApi); - } - $res = AdminApp::create($data); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 应用状态编辑 - * @return array - * @author zhaoxiang - */ - public function changeStatus() { - $id = $this->request->get('id'); - $status = $this->request->get('status'); - $res = AdminApp::update([ - 'app_status' => $status - ], [ - 'id' => $id - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 编辑应用 - * @return array - * @author zhaoxiang - */ - public function edit() { - $postData = $this->request->post(); - $data = [ - 'app_name' => $postData['app_name'], - 'app_info' => $postData['app_info'], - 'app_group' => $postData['app_group'], - 'app_api' => '', - 'app_api_show' => '', - ]; - if (isset($postData['app_api']) && $postData['app_api']) { - $appApi = []; - $data['app_api_show'] = json_encode($postData['app_api']); - foreach ($postData['app_api'] as $value) { - $appApi = array_merge($appApi, $value); - } - $data['app_api'] = implode(',', $appApi); - } - $res = AdminApp::update($data, ['id' => $postData['id']]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 删除应用 - * @return array - * @author zhaoxiang - */ - public function del() { - $id = $this->request->get('id'); - if (!$id) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - AdminApp::destroy($id); - - return $this->buildSuccess([]); - } -} diff --git a/application/admin/controller/AppGroup.php b/application/admin/controller/AppGroup.php deleted file mode 100644 index 3ee1d6f..0000000 --- a/application/admin/controller/AppGroup.php +++ /dev/null @@ -1,137 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminApp; -use app\model\AdminAppGroup; -use app\util\ReturnCode; -use app\util\Tools; - -class AppGroup extends Base { - /** - * 获取应用组列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $keywords = $this->request->get('keywords', ''); - $type = $this->request->get('type', ''); - $status = $this->request->get('status', ''); - - $where = []; - if ($status === '1' || $status === '0') { - $where['status'] = $status; - } - if ($type) { - switch ($type) { - case 1: - $where['hash'] = $keywords; - break; - case 2: - $where['name'] = ['like', "%{$keywords}%"]; - break; - } - } - $listObj = (new AdminAppGroup())->where($where)->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'] - ]); - } - - /** - * 获取全部有效的应用组 - * @author zhaoxiang - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - */ - public function getAll() { - $listInfo = (new AdminAppGroup())->where(['status' => 1])->select(); - - return $this->buildSuccess([ - 'list' => $listInfo - ]); - } - - /** - * 应用组状态编辑 - * @return array - * @author zhaoxiang - */ - public function changeStatus() { - $id = $this->request->get('id'); - $status = $this->request->get('status'); - $res = AdminAppGroup::update([ - 'status' => $status - ], [ - 'id' => $id - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 添加应用组 - * @author zhaoxiang - * @return array - */ - public function add() { - $postData = $this->request->post(); - $res = AdminAppGroup::create($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 应用组编辑 - * @author zhaoxiang - * @return array - */ - public function edit() { - $postData = $this->request->post(); - $res = AdminAppGroup::update($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 应用组删除 - * @author zhaoxiang - * @return array - */ - public function del() { - $hash = $this->request->get('hash'); - if (!$hash) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - - $has = (new AdminApp())->where(['app_group' => $hash])->count(); - if ($has) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '当前分组存在' . $has . '个应用,禁止删除'); - } - - AdminAppGroup::destroy(['hash' => $hash]); - - return $this->buildSuccess([]); - } -} diff --git a/application/admin/controller/Auth.php b/application/admin/controller/Auth.php deleted file mode 100644 index 8e577d4..0000000 --- a/application/admin/controller/Auth.php +++ /dev/null @@ -1,296 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminAuthGroup; -use app\model\AdminAuthGroupAccess; -use app\model\AdminAuthRule; -use app\model\AdminMenu; -use app\util\ReturnCode; -use app\util\Tools; - -class Auth extends Base { - - /** - * 获取权限组列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $keywords = $this->request->get('keywords', ''); - $status = $this->request->get('status', ''); - - $where['name'] = ['like', "%{$keywords}%"]; - if ($status === '1' || $status === '0') { - $where['status'] = $status; - } - $listObj = (new AdminAuthGroup())->where($where)->order('id DESC') - ->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'] - ]); - } - - /** - * 获取全部已开放的可选组 - * @author zhaoxiang - * @return array - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - */ - public function getGroups() { - $listInfo = (new AdminAuthGroup())->where(['status' => 1])->order('id', 'DESC')->select(); - $count = count($listInfo); - $listInfo = Tools::buildArrFromObj($listInfo); - - return $this->buildSuccess([ - 'list' => $listInfo, - 'count' => $count - ]); - } - - /** - * 获取组所在权限列表 - * @return array - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function getRuleList() { - $groupId = $this->request->get('groupId', 0); - - $list = (new AdminMenu)->where([])->order('sort', 'ASC')->select(); - $list = Tools::buildArrFromObj($list); - $list = listToTree($list); - - $rules = []; - if ($groupId) { - $rules = (new AdminAuthRule())->where(['groupId' => $groupId])->select(); - $rules = Tools::buildArrFromObj($rules); - $rules = array_column($rules, 'url'); - } - $newList = $this->buildList($list, $rules); - - return $this->buildSuccess([ - 'list' => $newList - ]); - } - - /** - * 新增组 - * @return array - * @throws \Exception - * @author zhaoxiang - */ - public function add() { - $rules = []; - $postData = $this->request->post(); - if ($postData['rules']) { - $rules = $postData['rules']; - $rules = array_filter($rules); - } - unset($postData['rules']); - $res = AdminAuthGroup::create($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - if ($rules) { - $insertData = []; - foreach ($rules as $value) { - if ($value) { - $insertData[] = [ - 'groupId' => $res->id, - 'url' => $value - ]; - } - } - (new AdminAuthRule())->saveAll($insertData); - } - - return $this->buildSuccess([]); - } - } - - /** - * 权限组状态编辑 - * @return array - * @author zhaoxiang - */ - public function changeStatus() { - $id = $this->request->get('id'); - $status = $this->request->get('status'); - $res = AdminAuthGroup::update([ - 'id' => $id, - 'status' => $status - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 编辑用户 - * @return array - * @throws \Exception - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function edit() { - $postData = $this->request->post(); - if ($postData['rules']) { - $this->editRule(); - } - unset($postData['rules']); - $res = AdminAuthGroup::update($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 删除组 - * @return array - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function del() { - $id = $this->request->get('id'); - if (!$id) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - - $listInfo = (new AdminAuthGroupAccess())->where(['groupId' => ['like', "%{$id}%"]])->select(); - if ($listInfo) { - foreach ($listInfo as $value) { - $valueArr = $value->toArray(); - $oldGroupArr = explode(',', $valueArr['groupId']); - $key = array_search($id, $oldGroupArr); - unset($oldGroupArr[$key]); - $newData = implode(',', $oldGroupArr); - $value->groupId = $newData; - $value->save(); - } - } - - AdminAuthGroup::destroy($id); - AdminAuthRule::destroy(['groupId' => $id]); - - return $this->buildSuccess([]); - } - - /** - * 从指定组中删除指定用户 - * @return array - * @throws \think\Exception - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function delMember() { - $gid = $this->request->get('gid', 0); - $uid = $this->request->get('uid', 0); - if (!$gid || !$uid) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - $oldInfo = AdminAuthGroupAccess::get(['uid' => $uid])->toArray(); - $oldGroupArr = explode(',', $oldInfo['groupId']); - $key = array_search($gid, $oldGroupArr); - unset($oldGroupArr[$key]); - $newData = implode(',', $oldGroupArr); - $res = AdminAuthGroupAccess::update([ - 'groupId' => $newData - ], [ - 'uid' => $uid - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 构建适用前端的权限数据 - * @param $list - * @param $rules - * @return array - * @author zhaoxiang - */ - private function buildList($list, $rules) { - $newList = []; - foreach ($list as $key => $value) { - $newList[$key]['title'] = $value['name']; - $newList[$key]['key'] = $value['url']; - if (isset($value['_child'])) { - $newList[$key]['expand'] = true; - $newList[$key]['children'] = $this->buildList($value['_child'], $rules); - } else { - if (in_array($value['url'], $rules)) { - $newList[$key]['checked'] = true; - } - } - } - - return $newList; - } - - /** - * 编辑权限细节 - * @throws \Exception - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - private function editRule() { - $postData = $this->request->post(); - $needAdd = []; - $has = (new AdminAuthRule())->where(['groupId' => $postData['id']])->select(); - $has = Tools::buildArrFromObj($has); - $hasRule = array_column($has, 'url'); - $needDel = array_flip($hasRule); - foreach ($postData['rules'] as $key => $value) { - if (!empty($value)) { - if (!in_array($value, $hasRule)) { - $data['url'] = $value; - $data['groupId'] = $postData['id']; - $needAdd[] = $data; - } else { - unset($needDel[$value]); - } - } - } - if (count($needAdd)) { - (new AdminAuthRule())->saveAll($needAdd); - } - if (count($needDel)) { - $urlArr = array_keys($needDel); - AdminAuthRule::destroy([ - 'groupId' => $postData['id'], - 'url' => ['in', $urlArr] - ]); - } - } - -} diff --git a/application/admin/controller/Base.php b/application/admin/controller/Base.php deleted file mode 100644 index 4245d49..0000000 --- a/application/admin/controller/Base.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ - -namespace app\admin\controller; -use app\util\ReturnCode; -use think\Controller; - -class Base extends Controller { - - private $debug = []; - protected $userInfo; - - public function _initialize() { - $ApiAuth = $this->request->header('ApiAuth'); - if ($ApiAuth) { - $userInfo = cache('Login:' . $ApiAuth); - $this->userInfo = json_decode($userInfo, true); - } - } - - public function buildSuccess($data, $msg = '操作成功', $code = ReturnCode::SUCCESS) { - $return = [ - 'code' => $code, - 'msg' => $msg, - 'data' => $data - ]; - if ($this->debug) { - $return['debug'] = $this->debug; - } - - return $return; - } - - public function buildFailed($code, $msg, $data = []) { - $return = [ - 'code' => $code, - 'msg' => $msg, - 'data' => $data - ]; - if ($this->debug) { - $return['debug'] = $this->debug; - } - - return $return; - } - - protected function debug($data) { - if ($data) { - $this->debug[] = $data; - } - } - -} diff --git a/application/admin/controller/Fields.php b/application/admin/controller/Fields.php deleted file mode 100644 index 6dfc032..0000000 --- a/application/admin/controller/Fields.php +++ /dev/null @@ -1,264 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminFields; -use app\model\AdminList; -use app\util\DataType; -use app\util\ReturnCode; -use app\util\Tools; - -class Fields extends Base { - private $dataType = array( - DataType::TYPE_INTEGER => 'Integer', - DataType::TYPE_STRING => 'String', - DataType::TYPE_BOOLEAN => 'Boolean', - DataType::TYPE_ENUM => 'Enum', - DataType::TYPE_FLOAT => 'Float', - DataType::TYPE_FILE => 'File', - DataType::TYPE_MOBILE => 'Mobile', - DataType::TYPE_OBJECT => 'Object', - DataType::TYPE_ARRAY => 'Array' - ); - - public function index() { - return $this->buildSuccess($this->dataType); - } - - /** - * 获取请求参数 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function request() { - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $hash = $this->request->get('hash', ''); - - if (!empty($hash)) { - $listObj = (new AdminFields())->where(['hash' => $hash, 'type' => 0]) - ->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'], - 'dataType' => $this->dataType - ]); - } else { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - } - - /** - * 获取返回参数 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function response() { - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $hash = $this->request->get('hash', ''); - - if (!empty($hash)) { - $listObj = (new AdminFields())->where(['hash' => $hash, 'type' => 1]) - ->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'], - 'dataType' => $this->dataType - ]); - } else { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - } - - /** - * 新增字段 - * @author zhaoxiang - * @return array - */ - public function add() { - $postData = $this->request->post(); - $postData['showName'] = $postData['fieldName']; - $postData['default'] = $postData['defaults']; - unset($postData['defaults']); - $res = AdminFields::create($postData); - - cache('RequestFields:NewRule:' . $postData['hash'], null); - cache('RequestFields:Rule:' . $postData['hash'], null); - cache('ResponseFieldsRule:' . $postData['hash'], null); - - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess('操作成功'); - } - } - - /** - * 字段编辑 - * @author zhaoxiang - * @return array - */ - public function edit() { - $postData = $this->request->post(); - $postData['showName'] = $postData['fieldName']; - $postData['default'] = $postData['defaults']; - unset($postData['defaults']); - $res = AdminFields::update($postData); - - cache('RequestFields:NewRule:' . $postData['hash'], null); - cache('RequestFields:Rule:' . $postData['hash'], null); - cache('ResponseFieldsRule:' . $postData['hash'], null); - - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 字段删除 - * @author zhaoxiang - * @return array - * @throws \think\exception\DbException - */ - public function del() { - $id = $this->request->get('id'); - if (!$id) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - - $fieldsInfo = AdminFields::get($id); - cache('RequestFields:NewRule:' . $fieldsInfo->hash, null); - cache('RequestFields:Rule:' . $fieldsInfo->hash, null); - cache('ResponseFieldsRule:' . $fieldsInfo->hash, null); - - AdminFields::destroy($id); - - return $this->buildSuccess([]); - } - - /** - * 批量上传返回字段 - * @author zhaoxiang - * @return array - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - */ - public function upload() { - $hash = $this->request->post('hash'); - $type = $this->request->post('type'); - $jsonStr = $this->request->post('jsonStr'); - $jsonStr = html_entity_decode($jsonStr); - $data = json_decode($jsonStr, true); - if ($data === null) { - return $this->buildFailed(ReturnCode::EXCEPTION, 'JSON数据格式有误'); - } - AdminList::update(['returnStr' => json_encode($data)], ['hash' => $hash]); - $this->handle($data['data'], $dataArr); - $old = (new AdminFields())->where([ - 'hash' => $hash, - 'type' => $type - ])->select(); - $old = Tools::buildArrFromObj($old); - $oldArr = array_column($old, 'showName'); - $newArr = array_column($dataArr, 'showName'); - $addArr = array_diff($newArr, $oldArr); - $delArr = array_diff($oldArr, $newArr); - if ($delArr) { - AdminFields::destroy(['showName' => ['in', $delArr]]); - } - if ($addArr) { - $addData = []; - foreach ($dataArr as $item) { - if (in_array($item['showName'], $addArr)) { - $addData[] = $item; - } - } - (new AdminFields())->insertAll($addData); - } - - cache('RequestFields:NewRule:' . $hash, null); - cache('RequestFields:Rule:' . $hash, null); - cache('ResponseFieldsRule:' . $hash, null); - - return $this->buildSuccess([]); - } - - private function handle($data, &$dataArr, $prefix = 'data', $index = 'data') { - if (!$this->isAssoc($data)) { - $addArr = array( - 'fieldName' => $index, - 'showName' => $prefix, - 'hash' => $this->request->post('hash'), - 'isMust' => 1, - 'dataType' => DataType::TYPE_ARRAY, - 'type' => $this->request->post('type') - ); - $dataArr[] = $addArr; - $prefix .= '[]'; - if (isset($data[0]) && is_array($data[0])) { - $this->handle($data[0], $dataArr, $prefix); - } - } else { - $addArr = array( - 'fieldName' => $index, - 'showName' => $prefix, - 'hash' => $this->request->post('hash'), - 'isMust' => 1, - 'dataType' => DataType::TYPE_OBJECT, - 'type' => $this->request->post('type') - ); - $dataArr[] = $addArr; - $prefix .= '{}'; - foreach ($data as $index => $datum) { - $myPre = $prefix . $index; - $addArr = array( - 'fieldName' => $index, - 'showName' => $myPre, - 'hash' => $this->request->post('hash'), - 'isMust' => 1, - 'dataType' => DataType::TYPE_STRING, - 'type' => $this->request->post('type') - ); - if (is_numeric($datum)) { - if (preg_match('/^\d*$/', $datum)) { - $addArr['dataType'] = DataType::TYPE_INTEGER; - } else { - $addArr['dataType'] = DataType::TYPE_FLOAT; - } - $dataArr[] = $addArr; - } elseif (is_array($datum)) { - $this->handle($datum, $dataArr, $myPre, $index); - } else { - $addArr['dataType'] = DataType::TYPE_STRING; - $dataArr[] = $addArr; - } - } - } - } - - /** - * 判断是否是关联数组(true表示是关联数组) - * @param array $arr - * @author zhaoxiang - * @return bool - */ - private function isAssoc(array $arr) { - if (array() === $arr) return false; - - return array_keys($arr) !== range(0, count($arr) - 1); - } -} diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php deleted file mode 100644 index f965292..0000000 --- a/application/admin/controller/Index.php +++ /dev/null @@ -1,53 +0,0 @@ -buildSuccess([ - 'fileName' => $new_name, - 'fileUrl' => $this->request->domain() . $path . $new_name - ]); - } else { - return $this->buildFailed(ReturnCode::FILE_SAVE_ERROR, '文件上传失败'); - } - } -} diff --git a/application/admin/controller/InterfaceGroup.php b/application/admin/controller/InterfaceGroup.php deleted file mode 100644 index 69357c5..0000000 --- a/application/admin/controller/InterfaceGroup.php +++ /dev/null @@ -1,160 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminApp; -use app\model\AdminGroup; -use app\model\AdminList; -use app\util\ReturnCode; -use app\util\Tools; - -class InterfaceGroup extends Base { - /** - * 获取接口组列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $keywords = $this->request->get('keywords', ''); - $type = $this->request->get('type', ''); - $status = $this->request->get('status', ''); - - $where = []; - if ($status === '1' || $status === '0') { - $where['status'] = $status; - } - if ($type) { - switch ($type) { - case 1: - $where['hash'] = $keywords; - break; - case 2: - $where['name'] = ['like', "%{$keywords}%"]; - break; - } - } - $listObj = (new AdminGroup())->where($where)->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'] - ]); - } - - /** - * 获取全部有效的接口组 - * @author zhaoxiang - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - */ - public function getAll() { - $listInfo = (new AdminGroup())->where(['status' => 1])->select(); - - return $this->buildSuccess([ - 'list' => $listInfo - ]); - } - - /** - * 接口组状态编辑 - * @return array - * @author zhaoxiang - */ - public function changeStatus() { - $id = $this->request->get('id'); - $status = $this->request->get('status'); - $res = AdminGroup::update([ - 'status' => $status - ], [ - 'id' => $id - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 添加接口组 - * @author zhaoxiang - * @return array - */ - public function add() { - $postData = $this->request->post(); - $postData['addTime'] = $postData['updateTime'] = time(); - $res = AdminGroup::create($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 接口组编辑 - * @author zhaoxiang - * @return array - */ - public function edit() { - $postData = $this->request->post(); - $postData['updateTime'] = time(); - $res = AdminGroup::update($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 接口组删除 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function del() { - $hash = $this->request->get('hash'); - if (!$hash) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - if ($hash === 'default') { - return $this->buildFailed(ReturnCode::INVALID, '系统预留关键数据,禁止删除!'); - } - - AdminList::update(['groupHash' => 'default'], ['groupHash' => $hash]); - - $hashRule = AdminApp::all([ - 'app_api_show' => ['like', "%$hash%"] - ]); - if ($hashRule) { - foreach ($hashRule as $rule) { - $appApiShowArr = json_decode($rule->app_api_show, true); - if (!empty($appApiShowArr[$hash])) { - if (isset($appApiShowArr['default'])) { - $appApiShowArr['default'] = array_merge($appApiShowArr['default'], $appApiShowArr[$hash]); - } else { - $appApiShowArr['default'] = $appApiShowArr[$hash]; - } - } - unset($appApiShowArr[$hash]); - $rule->app_api_show = json_encode($appApiShowArr); - $rule->save(); - } - } - - AdminGroup::destroy(['hash' => $hash]); - - return $this->buildSuccess([]); - } -} diff --git a/application/admin/controller/InterfaceList.php b/application/admin/controller/InterfaceList.php deleted file mode 100644 index d8a7dc4..0000000 --- a/application/admin/controller/InterfaceList.php +++ /dev/null @@ -1,194 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminApp; -use app\model\AdminFields; -use app\model\AdminList; -use app\util\ReturnCode; -use app\util\Tools; - -class InterfaceList extends Base { - /** - * 获取接口列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $keywords = $this->request->get('keywords', ''); - $type = $this->request->get('type', ''); - $status = $this->request->get('status', ''); - - $where = []; - if ($status === '1' || $status === '0') { - $where['status'] = $status; - } - if ($type) { - switch ($type) { - case 1: - $where['hash'] = $keywords; - break; - case 2: - $where['info'] = ['like', "%{$keywords}%"]; - break; - case 3: - $where['apiClass'] = ['like', "%{$keywords}%"]; - break; - } - } - $listObj = (new AdminList())->where($where)->order('id', 'DESC') - ->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'] - ]); - } - - /** - * 获取接口唯一标识 - * @author zhaoxiang - * @return array - */ - public function getHash() { - $res['hash'] = uniqid(); - - return $this->buildSuccess($res); - } - - /** - * 新增接口 - * @return array - * @author zhaoxiang - */ - public function add() { - $postData = $this->request->post(); - if (!preg_match("/^[A-Za-z0-9_\/]+$/", $postData['apiClass'])) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '真实类名只允许填写字母,数字和/'); - } - - $res = AdminList::create($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 接口状态编辑 - * @return array - * @author zhaoxiang - */ - public function changeStatus() { - $hash = $this->request->get('hash'); - $status = $this->request->get('status'); - $res = AdminList::update([ - 'status' => $status - ], [ - 'hash' => $hash - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - cache('ApiInfo:' . $hash, null); - - return $this->buildSuccess([]); - } - } - - /** - * 编辑接口 - * @return array - * @author zhaoxiang - */ - public function edit() { - $postData = $this->request->post(); - if (!preg_match("/^[A-Za-z0-9_\/]+$/", $postData['apiClass'])) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '真实类名只允许填写字母,数字和/'); - } - - $res = AdminList::update($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - cache('ApiInfo:' . $postData['hash'], null); - - return $this->buildSuccess([]); - } - } - - /** - * 删除接口 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function del() { - $hash = $this->request->get('hash'); - if (!$hash) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - - $hashRule = AdminApp::all([ - 'app_api' => ['like', "%$hash%"] - ]); - if ($hashRule) { - $oldInfo = AdminList::get(['hash' => $hash]); - foreach ($hashRule as $rule) { - $appApiArr = explode(',', $rule->app_api); - $appApiIndex = array_search($hash, $appApiArr); - array_splice($appApiArr, $appApiIndex, 1); - $rule->app_api = implode(',', $appApiArr); - - $appApiShowArrOld = json_decode($rule->app_api_show, true); - $appApiShowArr = $appApiShowArrOld[$oldInfo->groupHash]; - $appApiShowIndex = array_search($hash, $appApiShowArr); - array_splice($appApiShowArr, $appApiShowIndex, 1); - $appApiShowArrOld[$oldInfo->groupHash] = $appApiShowArr; - $rule->app_api_show = json_encode($appApiShowArrOld); - - $rule->save(); - } - } - - AdminList::destroy(['hash' => $hash]); - AdminFields::destroy(['hash' => $hash]); - - cache('ApiInfo:' . $hash, null); - - return $this->buildSuccess([]); - } - - /** - * 刷新接口路由 - * @author zhaoxiang - * @return array - * @throws \think\exception\DbException - */ - public function refresh() { - $apiRoutePath = ROOT_PATH . 'application/apiRoute.php'; - $tplPath = ROOT_PATH . 'data/apiRoute.tpl'; - $methodArr = ['*', 'POST', 'GET']; - - $tplStr = file_get_contents($tplPath); - $listInfo = AdminList::all(['status' => 1]); - foreach ($listInfo as $value) { - $tplStr .= 'Route::rule(\'api/' . addslashes($value->hash) . '\',\'api/' . addslashes($value->apiClass) . '\', \'' . $methodArr[$value->method] . '\', [\'after_behavior\' => $afterBehavior]);'; - } - - file_put_contents($apiRoutePath, $tplStr); - - return $this->buildSuccess([]); - } -} diff --git a/application/admin/controller/Log.php b/application/admin/controller/Log.php deleted file mode 100644 index 8f03461..0000000 --- a/application/admin/controller/Log.php +++ /dev/null @@ -1,72 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminAuthGroupAccess; -use app\model\AdminUser; -use app\model\AdminUserAction; -use app\model\AdminUserData; -use app\util\ReturnCode; -use app\util\Tools; - -class Log extends Base { - - /** - * 获取操作日志列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $type = $this->request->get('type', ''); - $keywords = $this->request->get('keywords', ''); - - $where = []; - if ($type) { - switch ($type) { - case 1: - $where['url'] = ['like', "%{$keywords}%"]; - break; - case 2: - $where['nickname'] = ['like', "%{$keywords}%"]; - break; - case 3: - $where['uid'] = $keywords; - break; - } - } - $listObj = (new AdminUserAction())->where($where)->order('addTime DESC') - ->paginate($limit, false, ['page' => $start])->toArray(); - - return $this->buildSuccess([ - 'list' => $listObj['data'], - 'count' => $listObj['total'] - ]); - } - - /** - * 删除日志 - * @return array - * @author zhaoxiang - */ - public function del() { - $id = $this->request->get('id'); - if (!$id) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - AdminUserAction::destroy($id); - - return $this->buildSuccess([]); - - } - -} diff --git a/application/admin/controller/Login.php b/application/admin/controller/Login.php deleted file mode 100644 index d9a557c..0000000 --- a/application/admin/controller/Login.php +++ /dev/null @@ -1,101 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminAuthGroupAccess; -use app\model\AdminAuthRule; -use app\model\AdminMenu; -use app\model\AdminUser; -use app\model\AdminUserData; -use app\util\ReturnCode; -use app\util\Tools; - -class Login extends Base { - - /** - * 用户登录 - * @return array - * @throws \think\Exception - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - $username = $this->request->post('username'); - $password = $this->request->post('password'); - if (!$username) { - return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少用户名!'); - } - if (!$password) { - return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少密码!'); - } else { - $password = Tools::userMd5($password); - } - $userInfo = AdminUser::get(['username' => $username, 'password' => $password]); - if (!empty($userInfo)) { - if ($userInfo['status']) { - //更新用户数据 - $userData = AdminUserData::get(['uid' => $userInfo['id']]); - $data = []; - if ($userData) { - $userData->loginTimes ++; - $userData->lastLoginIp = $this->request->ip(1); - $userData->lastLoginTime = time(); - $return['headImg'] = $userData['headImg']; - $userData->save(); - } else { - $data['loginTimes'] = 1; - $data['uid'] = $userInfo['id']; - $data['lastLoginIp'] = $this->request->ip(1); - $data['lastLoginTime'] = time(); - $data['headImg'] = ''; - $return['headImg'] = ''; - AdminUserData::create($data); - } - } else { - return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户已被封禁,请联系管理员'); - } - } else { - return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户名密码不正确'); - } - $apiAuth = md5(uniqid() . time()); - cache('Login:' . $apiAuth, json_encode($userInfo), config('apiAdmin.ONLINE_TIME')); - cache('Login:' . $userInfo['id'], $apiAuth, config('apiAdmin.ONLINE_TIME')); - - $return['access'] = []; - $isSupper = Tools::isAdministrator($userInfo['id']); - if ($isSupper) { - $access = AdminMenu::all(['hide' => 0]); - $access = Tools::buildArrFromObj($access); - $return['access'] = array_values(array_filter(array_column($access, 'url'))); - } else { - $groups = AdminAuthGroupAccess::get(['uid' => $userInfo['id']]); - if (isset($groups) || $groups->groupId) { - $access = (new AdminAuthRule())->whereIn('groupId', $groups->groupId)->select(); - $access = Tools::buildArrFromObj($access); - $return['access'] = array_values(array_unique(array_column($access, 'url'))); - } - } - - $return['id'] = $userInfo['id']; - $return['username'] = $userInfo['username']; - $return['nickname'] = $userInfo['nickname']; - $return['apiAuth'] = $apiAuth; - - return $this->buildSuccess($return, '登录成功'); - } - - public function logout() { - $ApiAuth = $this->request->header('ApiAuth'); - cache('Login:' . $ApiAuth, null); - cache('Login:' . $this->userInfo['id'], null); - - return $this->buildSuccess([], '登出成功'); - } - -} diff --git a/application/admin/controller/Menu.php b/application/admin/controller/Menu.php deleted file mode 100644 index 938b2ec..0000000 --- a/application/admin/controller/Menu.php +++ /dev/null @@ -1,108 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminMenu; -use app\util\ReturnCode; -use app\util\Tools; - -class Menu extends Base { - - /** - * 获取菜单列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - $list = (new AdminMenu)->where([])->order('sort', 'ASC')->select(); - $list = Tools::buildArrFromObj($list); - $list = formatTree(listToTree($list)); - - return $this->buildSuccess([ - 'list' => $list - ], '登录成功'); - } - - /** - * 新增菜单 - * @return array - * @author zhaoxiang - */ - public function add() { - $postData = $this->request->post(); - if ($postData['url']) { - $postData['url'] = 'admin/' . $postData['url']; - } - $res = AdminMenu::create($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 菜单状态编辑 - * @return array - * @author zhaoxiang - */ - public function changeStatus() { - $id = $this->request->get('id'); - $status = $this->request->get('status'); - $res = AdminMenu::update([ - 'id' => $id, - 'hide' => $status - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 编辑菜单 - * @return array - * @author zhaoxiang - */ - public function edit() { - $postData = $this->request->post(); - if ($postData['url']) { - $postData['url'] = 'admin/' . $postData['url']; - } - $res = AdminMenu::update($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 删除菜单 - * @return array - * @author zhaoxiang - */ - public function del() { - $id = $this->request->get('id'); - if (!$id) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - $childNum = AdminMenu::where(['fid' => $id])->count(); - if ($childNum) { - return $this->buildFailed(ReturnCode::INVALID, '当前菜单存在子菜单,不可以被删除!'); - } else { - AdminMenu::destroy($id); - - return $this->buildSuccess([]); - } - } - -} diff --git a/application/admin/controller/Miss.php b/application/admin/controller/Miss.php deleted file mode 100644 index 4215390..0000000 --- a/application/admin/controller/Miss.php +++ /dev/null @@ -1,15 +0,0 @@ -isOptions()) { - return $this->buildSuccess([]); - } else { - return $this->buildFailed(ReturnCode::INVALID, '接口地址异常', []); - } - } -} diff --git a/application/admin/controller/User.php b/application/admin/controller/User.php deleted file mode 100644 index 867b31b..0000000 --- a/application/admin/controller/User.php +++ /dev/null @@ -1,269 +0,0 @@ - - */ - -namespace app\admin\controller; - - -use app\model\AdminAuthGroupAccess; -use app\model\AdminUser; -use app\model\AdminUserData; -use app\util\ReturnCode; -use app\util\Tools; -use think\Db; - -class User extends Base { - - /** - * 获取用户列表 - * @return array - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $start = $this->request->get('page', 1); - $type = $this->request->get('type', ''); - $keywords = $this->request->get('keywords', ''); - $status = $this->request->get('status', ''); - - $where = []; - if ($status === '1' || $status === '0') { - $where['status'] = $status; - } - if ($type) { - switch ($type) { - case 1: - $where['username'] = ['like', "%{$keywords}%"]; - break; - case 2: - $where['nickname'] = ['like', "%{$keywords}%"]; - break; - } - } - - $listObj = (new AdminUser())->where($where)->order('regTime DESC') - ->paginate($limit, false, ['page' => $start])->toArray(); - $listInfo = $listObj['data']; - $idArr = array_column($listInfo, 'id'); - - $userData = AdminUserData::all(function($query) use ($idArr) { - $query->whereIn('uid', $idArr); - }); - $userData = Tools::buildArrFromObj($userData); - $userData = Tools::buildArrByNewKey($userData, 'uid'); - - $userGroup = AdminAuthGroupAccess::all(function($query) use ($idArr) { - $query->whereIn('uid', $idArr); - }); - $userGroup = Tools::buildArrFromObj($userGroup); - $userGroup = Tools::buildArrByNewKey($userGroup, 'uid'); - - foreach ($listInfo as $key => $value) { - if (isset($userData[$value['id']])) { - $listInfo[$key]['lastLoginIp'] = long2ip($userData[$value['id']]['lastLoginIp']); - $listInfo[$key]['loginTimes'] = $userData[$value['id']]['loginTimes']; - $listInfo[$key]['lastLoginTime'] = date('Y-m-d H:i:s', $userData[$value['id']]['lastLoginTime']); - } - $listInfo[$key]['regIp'] = long2ip($listInfo[$key]['regIp']); - if (isset($userGroup[$value['id']])) { - $listInfo[$key]['groupId'] = explode(',', $userGroup[$value['id']]['groupId']); - } else { - $listInfo[$key]['groupId'] = []; - } - } - - return $this->buildSuccess([ - 'list' => $listInfo, - 'count' => $listObj['total'] - ]); - } - - /** - * 新增用户 - * @return array - * @author zhaoxiang - */ - public function add() { - $groups = ''; - $postData = $this->request->post(); - $postData['regIp'] = request()->ip(1); - $postData['regTime'] = time(); - $postData['password'] = Tools::userMd5($postData['password']); - if ($postData['groupId']) { - $groups = trim(implode(',', $postData['groupId']), ','); - } - unset($postData['groupId']); - $res = AdminUser::create($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - AdminAuthGroupAccess::create([ - 'uid' => $res->id, - 'groupId' => $groups - ]); - - return $this->buildSuccess([]); - } - } - - /** - * 获取当前组的全部用户 - * @return array - * @throws \think\Exception - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function getUsers() { - $limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT')); - $page = $this->request->get('page', 1); - $gid = $this->request->get('gid', 0); - if (!$gid) { - return $this->buildFailed(ReturnCode::PARAM_INVALID, '非法操作'); - } - - $totalNum = (new AdminAuthGroupAccess())->where('find_in_set("' . $gid . '", `groupId`)')->count(); - $start = $limit * ($page - 1); - $sql = "SELECT au.* FROM admin_user as au LEFT JOIN admin_auth_group_access as aaga " . - " ON aaga.`uid` = au.`id` WHERE find_in_set('{$gid}', aaga.`groupId`) " . - " ORDER BY au.regTime DESC LIMIT {$start}, {$limit}"; - $userInfo = Db::query($sql); - - $uidArr = array_column($userInfo, 'id'); - $userData = (new AdminUserData())->whereIn('uid', $uidArr)->select(); - $userData = Tools::buildArrByNewKey($userData, 'uid'); - - foreach ($userInfo as $key => $value) { - if (isset($userData[$value['id']])) { - $userInfo[$key]['lastLoginIp'] = long2ip($userData[$value['id']]['lastLoginIp']); - $userInfo[$key]['loginTimes'] = $userData[$value['id']]['loginTimes']; - $userInfo[$key]['lastLoginTime'] = date('Y-m-d H:i:s', $userData[$value['id']]['lastLoginTime']); - } - $userInfo[$key]['regIp'] = long2ip($userInfo[$key]['regIp']); - } - - return $this->buildSuccess([ - 'list' => $userInfo, - 'count' => $totalNum - ]); - } - - /** - * 用户状态编辑 - * @return array - * @author zhaoxiang - */ - public function changeStatus() { - $id = $this->request->get('id'); - $status = $this->request->get('status'); - $res = AdminUser::update([ - 'id' => $id, - 'status' => $status, - 'updateTime' => time() - ]); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - return $this->buildSuccess([]); - } - } - - /** - * 编辑用户 - * @author zhaoxiang - * @return array - * @throws \think\exception\DbException - */ - public function edit() { - $groups = ''; - $postData = $this->request->post(); - if ($postData['password'] === 'ApiAdmin') { - unset($postData['password']); - } else { - $postData['password'] = Tools::userMd5($postData['password']); - } - if ($postData['groupId']) { - $groups = trim(implode(',', $postData['groupId']), ','); - } - $postData['updateTime'] = time(); - unset($postData['groupId']); - $res = AdminUser::update($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - $has = AdminAuthGroupAccess::get(['uid' => $postData['id']]); - if ($has) { - AdminAuthGroupAccess::update([ - 'groupId' => $groups - ], [ - 'uid' => $postData['id'], - ]); - } else { - AdminAuthGroupAccess::create([ - 'uid' => $postData['id'], - 'groupId' => $groups - ]); - } - - return $this->buildSuccess([]); - } - } - - /** - * 修改自己的信息 - * @author zhaoxiang - * @return array - * @throws \think\exception\DbException - */ - public function own() { - $postData = $this->request->post(); - $headImg = $postData['headImg']; - if ($postData['password'] && $postData['oldPassword']) { - $oldPass = Tools::userMd5($postData['oldPassword']); - unset($postData['oldPassword']); - if ($oldPass === $this->userInfo['password']) { - $postData['password'] = Tools::userMd5($postData['password']); - } else { - return $this->buildFailed(ReturnCode::INVALID, '原始密码不正确'); - } - } else { - unset($postData['password']); - unset($postData['oldPassword']); - } - $postData['id'] = $this->userInfo['id']; - $postData['updateTime'] = time(); - unset($postData['headImg']); - $res = AdminUser::update($postData); - if ($res === false) { - return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败'); - } else { - $userData = AdminUserData::get(['uid' => $postData['id']]); - $userData->headImg = $headImg; - $userData->save(); - - return $this->buildSuccess([]); - } - } - - /** - * 删除用户 - * @return array - * @author zhaoxiang - */ - public function del() { - $id = $this->request->get('id'); - if (!$id) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数'); - } - AdminUser::destroy($id); - AdminAuthGroupAccess::destroy(['uid' => $id]); - - return $this->buildSuccess([]); - - } - -} diff --git a/application/admin/tags.php b/application/admin/tags.php deleted file mode 100644 index 95ee5cb..0000000 --- a/application/admin/tags.php +++ /dev/null @@ -1,18 +0,0 @@ - -// +---------------------------------------------------------------------- - -// 应用行为扩展定义文件 -return [ - // 输出结束 - 'response_send' => [ - 'app\\admin\\behavior\\BuildResponse', - ], -]; diff --git a/application/adminRoute.php b/application/adminRoute.php deleted file mode 100644 index 86046e5..0000000 --- a/application/adminRoute.php +++ /dev/null @@ -1,279 +0,0 @@ - [ - 'admin/Login/index', - ['method' => 'post'] - ], - 'Index/upload' => [ - 'admin/Index/upload', - [ - 'method' => 'post', - 'after_behavior' => [ - '\app\admin\behavior\ApiAuth', - '\app\admin\behavior\AdminLog' - ] - ] - ], - 'Login/logout' => [ - 'admin/Login/logout', - [ - 'method' => 'get', - 'after_behavior' => [ - '\app\admin\behavior\ApiAuth', - '\app\admin\behavior\AdminLog' - ] - ] - ] - ]); - //大部分控制器的路由都以分组的形式写到这里 - Route::group('Menu', [ - 'index' => [ - 'admin/Menu/index', - ['method' => 'get'] - ], - 'changeStatus' => [ - 'admin/Menu/changeStatus', - ['method' => 'get'] - ], - 'add' => [ - 'admin/Menu/add', - ['method' => 'post'] - ], - 'edit' => [ - 'admin/Menu/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/Menu/del', - ['method' => 'get'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::group('User', [ - 'index' => [ - 'admin/User/index', - ['method' => 'get'] - ], - 'getUsers' => [ - 'admin/User/getUsers', - ['method' => 'get'] - ], - 'changeStatus' => [ - 'admin/User/changeStatus', - ['method' => 'get'] - ], - 'add' => [ - 'admin/User/add', - ['method' => 'post'] - ], - 'own' => [ - 'admin/User/own', - ['method' => 'post'] - ], - 'edit' => [ - 'admin/User/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/User/del', - ['method' => 'get'] - ], - ], ['after_behavior' => $afterBehavior]); - Route::group('Auth', [ - 'index' => [ - 'admin/Auth/index', - ['method' => 'get'] - ], - 'changeStatus' => [ - 'admin/Auth/changeStatus', - ['method' => 'get'] - ], - 'add' => [ - 'admin/Auth/add', - ['method' => 'post'] - ], - 'delMember' => [ - 'admin/Auth/delMember', - ['method' => 'get'] - ], - 'edit' => [ - 'admin/Auth/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/Auth/del', - ['method' => 'get'] - ], - 'getGroups' => [ - 'admin/Auth/getGroups', - ['method' => 'get'] - ], - 'getRuleList' => [ - 'admin/Auth/getRuleList', - ['method' => 'get'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::group('App', [ - 'index' => [ - 'admin/App/index', - ['method' => 'get'] - ], - 'refreshAppSecret' => [ - 'admin/App/refreshAppSecret', - ['method' => 'get'] - ], - 'changeStatus' => [ - 'admin/App/changeStatus', - ['method' => 'get'] - ], - 'add' => [ - 'admin/App/add', - ['method' => 'post'] - ], - 'getAppInfo' => [ - 'admin/App/getAppInfo', - ['method' => 'get'] - ], - 'edit' => [ - 'admin/App/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/App/del', - ['method' => 'get'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::group('InterfaceList', [ - 'index' => [ - 'admin/InterfaceList/index', - ['method' => 'get'] - ], - 'changeStatus' => [ - 'admin/InterfaceList/changeStatus', - ['method' => 'get'] - ], - 'add' => [ - 'admin/InterfaceList/add', - ['method' => 'post'] - ], - 'refresh' => [ - 'admin/InterfaceList/refresh', - ['method' => 'get'] - ], - 'edit' => [ - 'admin/InterfaceList/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/InterfaceList/del', - ['method' => 'get'] - ], - 'getHash' => [ - 'admin/InterfaceList/getHash', - ['method' => 'get'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::group('Fields', [ - 'index' => [ - 'admin/Fields/index', - ['method' => 'get'] - ], - 'request' => [ - 'admin/Fields/request', - ['method' => 'get'] - ], - 'add' => [ - 'admin/Fields/add', - ['method' => 'post'] - ], - 'response' => [ - 'admin/Fields/response', - ['method' => 'get'] - ], - 'edit' => [ - 'admin/Fields/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/Fields/del', - ['method' => 'get'] - ], - 'upload' => [ - 'admin/Fields/upload', - ['method' => 'post'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::group('InterfaceGroup', [ - 'index' => [ - 'admin/InterfaceGroup/index', - ['method' => 'get'] - ], - 'getAll' => [ - 'admin/InterfaceGroup/getAll', - ['method' => 'get'] - ], - 'add' => [ - 'admin/InterfaceGroup/add', - ['method' => 'post'] - ], - 'changeStatus' => [ - 'admin/InterfaceGroup/changeStatus', - ['method' => 'get'] - ], - 'edit' => [ - 'admin/InterfaceGroup/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/InterfaceGroup/del', - ['method' => 'get'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::group('AppGroup', [ - 'index' => [ - 'admin/AppGroup/index', - ['method' => 'get'] - ], - 'getAll' => [ - 'admin/AppGroup/getAll', - ['method' => 'get'] - ], - 'add' => [ - 'admin/AppGroup/add', - ['method' => 'post'] - ], - 'changeStatus' => [ - 'admin/AppGroup/changeStatus', - ['method' => 'get'] - ], - 'edit' => [ - 'admin/AppGroup/edit', - ['method' => 'post'] - ], - 'del' => [ - 'admin/AppGroup/del', - ['method' => 'get'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::group('Log', [ - 'index' => [ - 'admin/Log/index', - ['method' => 'get'] - ], - 'del' => [ - 'admin/Log/del', - ['method' => 'get'] - ] - ], ['after_behavior' => $afterBehavior]); - Route::miss('admin/Miss/index'); -}); diff --git a/application/api/behavior/ApiAuth.php b/application/api/behavior/ApiAuth.php deleted file mode 100644 index 72ddc46..0000000 --- a/application/api/behavior/ApiAuth.php +++ /dev/null @@ -1,124 +0,0 @@ - - */ - -namespace app\api\behavior; - - -use app\model\AdminList; -use app\util\ApiLog; -use app\util\ReturnCode; -use think\Cache; -use think\Request; - -class ApiAuth { - - /** - * @var Request - */ - private $request; - private $apiInfo; - private $header; - - /** - * 默认行为函数 - * @author zhaoxiang - * @return \think\response\Json - * @throws \think\Exception - * @throws \think\exception\DbException - */ - public function run() { - $this->request = Request::instance(); - $hash = $this->request->routeInfo(); - $this->header = config('apiAdmin.CROSS_DOMAIN'); - if (isset($hash['rule'][1])) { - $hash = $hash['rule'][1]; - - $cached = Cache::has('ApiInfo:' . $hash); - if ($cached) { - $this->apiInfo = Cache::get('ApiInfo:' . $hash); - } else { - $apiInfo = AdminList::get(['hash' => $hash]); - if ($apiInfo) { - $this->apiInfo = $apiInfo->toArray(); - Cache::set('ApiInfo:' . $hash, $this->apiInfo); - } else { - return json(['code' => ReturnCode::DB_READ_ERROR, 'msg' => '获取接口配置数据失败', 'data' => []], 200, $this->header); - } - } - - if ($this->apiInfo['accessToken'] && !$this->apiInfo['isTest']) { - $accessRes = $this->checkAccessToken(); - if ($accessRes) { - return $accessRes; - } - } - if (!$this->apiInfo['isTest']) { - $versionRes = $this->checkVersion(); - if ($versionRes) { - return $versionRes; - } - } - $loginRes = $this->checkLogin(); - if ($loginRes) { - return $loginRes; - } - - ApiLog::setApiInfo($this->apiInfo); - } - } - - /** - * Api接口合法性检测 - */ - private function checkAccessToken() { - $access_token = $this->request->header('access-token'); - if (!isset($access_token) || !$access_token) { - return json(['code' => ReturnCode::ACCESS_TOKEN_TIMEOUT, 'msg' => '缺少参数access-token', 'data' => []], 200, $this->header); - } else { - $appInfo = cache('AccessToken:' . $access_token); - if (!$appInfo) { - return json(['code' => ReturnCode::ACCESS_TOKEN_TIMEOUT, 'msg' => 'access-token已过期', 'data' => []], 200, $this->header); - } - ApiLog::setAppInfo($appInfo); - } - } - - /** - * Api版本参数校验 - */ - private function checkVersion() { - $version = $this->request->header('version'); - if (!isset($version) || !$version) { - return json(['code' => ReturnCode::EMPTY_PARAMS, 'msg' => '缺少参数version', 'data' => []], 200, $this->header); - } else { - if ($version != config('apiAdmin.APP_VERSION')) { - return json(['code' => ReturnCode::VERSION_INVALID, 'msg' => 'API版本不匹配', 'data' => []], 200, $this->header); - } - } - } - - /** - * TODO::需要根据实际情况另外改写 - * 检测用户登录情况 检测通过请赋予USER_INFO值 - */ - private function checkLogin() { - $userToken = $this->request->header('user-token', ''); - if ($this->apiInfo['needLogin']) { - if (!$userToken) { - return json(['code' => ReturnCode::AUTH_ERROR, 'msg' => '缺少user-token', 'data' => []], 200, $this->header); - } - } - if ($userToken) { - $userInfo = cache('wx:openId:' . $userToken); - if (!is_array($userInfo) || !isset($userInfo['openId'])) { - return json(['code' => ReturnCode::AUTH_ERROR, 'msg' => 'user-token不匹配', 'data' => []], 200, $this->header); - } - ApiLog::setUserInfo($userInfo); - } - } - -} diff --git a/application/api/behavior/ApiPermission.php b/application/api/behavior/ApiPermission.php deleted file mode 100644 index f64c7a4..0000000 --- a/application/api/behavior/ApiPermission.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ - -namespace app\api\behavior; - - -use app\util\ReturnCode; -use think\Request; - -class ApiPermission { - - /** - * @var Request - */ - private $request; - - /** - * 接口鉴权 - * @return \think\response\Json - * @author zhaoxiang - */ - public function run() { - $this->request = Request::instance(); - $header = config('apiAdmin.CROSS_DOMAIN'); - $hash = $this->request->routeInfo(); - if (isset($hash['rule'][1])) { - $hash = $hash['rule'][1]; - $access_token = $this->request->header('access-token'); - if ($access_token) { - $appInfo = cache('AccessToken:' . $access_token); - $allRules = explode(',', $appInfo['app_api']); - if (!in_array($hash, $allRules)) { - return json(['code' => ReturnCode::INVALID, 'msg' => '非常抱歉,您没有权限这么做!', 'data' => []], 200, $header); - } - } - } - } - - -} diff --git a/application/api/behavior/BuildResponse.php b/application/api/behavior/BuildResponse.php deleted file mode 100644 index 2e2cc1f..0000000 --- a/application/api/behavior/BuildResponse.php +++ /dev/null @@ -1,99 +0,0 @@ - - */ - -namespace app\api\behavior; - - -use app\model\AdminFields; -use app\util\ApiLog; -use app\util\DataType; -use think\Cache; -use think\Request; - -class BuildResponse { - - /** - * 返回参数过滤(主要是将返回参数的数据类型给规范) - * @param $response \think\Response - * @author zhaoxiang - * @throws \think\exception\DbException - */ - public function run($response) { - $header = config('apiAdmin.CROSS_DOMAIN'); - $response->header($header); - $data = $response->getData(); - $request = Request::instance(); - $hash = $request->routeInfo(); - if (isset($hash['rule'][1])) { - $hash = $hash['rule'][1]; - - $has = Cache::has('ResponseFieldsRule:' . $hash); - if ($has) { - $rule = cache('ResponseFieldsRule:' . $hash); - } else { - $rule = AdminFields::all(['hash' => $hash, 'type' => 1]); - cache('ResponseFieldsRule:' . $hash, $rule); - } - - if ($rule) { - $rule = json_decode(json_encode($rule), true); - $newRule = array_column($rule, 'dataType', 'showName'); - if (is_array($data)) { - $this->handle($data['data'], $newRule); - } elseif (empty($data)) { - if ($newRule['data'] == DataType::TYPE_OBJECT) { - $data = (object)[]; - } elseif ($newRule['data'] == DataType::TYPE_ARRAY) { - $data = []; - } - } - $response->data($data); - } - } - ApiLog::setResponse($data); - ApiLog::save(); - } - - private function handle(&$data, $rule, $prefix = 'data') { - if (empty($data)) { - if ($rule[$prefix] == DataType::TYPE_OBJECT) { - $data = (object)[]; - } - } else { - if ($rule[$prefix] == DataType::TYPE_OBJECT) { - $prefix .= '{}'; - foreach ($data as $index => &$datum) { - $myPre = $prefix . $index; - if (isset($rule[$myPre])) { - switch ($rule[$myPre]) { - case DataType::TYPE_INTEGER: - $datum = intval($datum); - break; - case DataType::TYPE_FLOAT: - $datum = floatval($datum); - break; - case DataType::TYPE_STRING: - $datum = strval($datum); - break; - default: - $this->handle($datum, $rule, $myPre); - break; - } - } - } - } else { - $prefix .= '[]'; - if (is_array($data[0])) { - foreach ($data as &$datum) { - $this->handle($datum, $rule, $prefix); - } - } - } - } - } - -} diff --git a/application/api/behavior/RequestFilter.php b/application/api/behavior/RequestFilter.php deleted file mode 100644 index c14433c..0000000 --- a/application/api/behavior/RequestFilter.php +++ /dev/null @@ -1,179 +0,0 @@ - - */ - -namespace app\api\behavior; - - -use app\model\AdminFields; -use app\util\ApiLog; -use app\util\ReturnCode; -use app\util\DataType; -use think\Cache; -use think\Request; -use think\Validate; - -class RequestFilter { - - /** - * 默认行为函数 - * @throws \think\Exception - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function run() { - $request = Request::instance(); - $method = strtoupper($request->method()); - switch ($method) { - case 'GET': - $data = $request->get(); - break; - case 'POST': - $data = $request->post(); - break; - case 'DELETE': - $data = $request->delete(); - break; - case 'PUT': - $data = $request->put(); - break; - default : - $data = []; - break; - } - ApiLog::setRequest($data); - $hash = $request->routeInfo(); - if (isset($hash['rule'][1])) { - $hash = $hash['rule'][1]; - - $has = Cache::has('RequestFields:NewRule:' . $hash); - if ($has) { - $newRule = cache('RequestFields:NewRule:' . $hash); - $rule = cache('RequestFields:Rule:' . $hash); - } else { - $rule = AdminFields::all(['hash' => $hash, 'type' => 0]); - $newRule = $this->buildValidateRule($rule); - cache('RequestFields:NewRule:' . $hash, $newRule); - cache('RequestFields:Rule:' . $hash, $rule); - } - - if ($newRule) { - $validate = new Validate($newRule); - if (!$validate->check($data)) { - $header = config('apiAdmin.CROSS_DOMAIN'); - return json(['code' => ReturnCode::PARAM_INVALID, 'msg' => $validate->getError(), 'data' => []], 200, $header); - } - } - - $newData = []; - foreach ($rule as $item) { - $newData[$item['fieldName']] = isset($data[$item['fieldName']])? $data[$item['fieldName']] : ''; - if (!$item['isMust'] && $item['default'] !== '' && !isset($data[$item['fieldName']])) { - $newData[$item['fieldName']] = $item['default']; - } - } - - switch ($method) { - case 'GET': - $request->forceGet($newData); - break; - case 'POST': - $request->forcePost($newData); - break; - case 'DELETE': - $request->forceDelete($newData); - break; - case 'PUT': - $request->forcePut($newData); - break; - } - ApiLog::setRequestAfterFilter($newData); - } - ApiLog::setHeader($request->header()); - } - - /** - * 将数据库中的规则转换成TP_Validate使用的规则数组 - * @param array $rule - * @author zhaoxiang - * @return array - */ - public function buildValidateRule($rule = array()) { - $newRule = []; - if ($rule) { - foreach ($rule as $value) { - if ($value['isMust']) { - $newRule[$value['fieldName']][] = 'require'; - } - switch ($value['dataType']) { - case DataType::TYPE_INTEGER: - $newRule[$value['fieldName']][] = 'number'; - if ($value['range']) { - $range = htmlspecialchars_decode($value['range']); - $range = json_decode($range, true); - if (isset($range['min'])) { - $newRule[$value['fieldName']]['egt'] = $range['min']; - } - if (isset($range['max'])) { - $newRule[$value['fieldName']]['elt'] = $range['max']; - } - } - break; - case DataType::TYPE_STRING: - if ($value['range']) { - $range = htmlspecialchars_decode($value['range']); - $range = json_decode($range, true); - if (isset($range['min'])) { - $newRule[$value['fieldName']]['min'] = $range['min']; - } - if (isset($range['max'])) { - $newRule[$value['fieldName']]['max'] = $range['max']; - } - } - break; - case DataType::TYPE_ENUM: - if ($value['range']) { - $range = htmlspecialchars_decode($value['range']); - $range = json_decode($range, true); - $newRule[$value['fieldName']]['in'] = implode(',', $range); - } - break; - case DataType::TYPE_FLOAT: - $newRule[$value['fieldName']][] = 'float'; - if ($value['range']) { - $range = htmlspecialchars_decode($value['range']); - $range = json_decode($range, true); - if (isset($range['min'])) { - $newRule[$value['fieldName']]['egt'] = $range['min']; - } - if (isset($range['max'])) { - $newRule[$value['fieldName']]['elt'] = $range['max']; - } - } - break; - case DataType::TYPE_ARRAY: - $newRule[$value['fieldName']][] = 'array'; - if ($value['range']) { - $range = htmlspecialchars_decode($value['range']); - $range = json_decode($range, true); - if (isset($range['min'])) { - $newRule[$value['fieldName']]['min'] = $range['min']; - } - if (isset($range['max'])) { - $newRule[$value['fieldName']]['max'] = $range['max']; - } - } - break; - case DataType::TYPE_MOBILE: - $newRule[$value['fieldName']]['regex'] = '/^1[34578]\d{9}$/'; - break; - } - } - } - - return $newRule; - } -} diff --git a/application/api/controller/Base.php b/application/api/controller/Base.php deleted file mode 100644 index 9fde9cd..0000000 --- a/application/api/controller/Base.php +++ /dev/null @@ -1,56 +0,0 @@ - - */ - -namespace app\api\controller; - - -use app\util\ApiLog; -use app\util\ReturnCode; -use think\Controller; - -class Base extends Controller { - - private $debug = []; - protected $userInfo = []; - - public function _initialize() { - $this->userInfo = ApiLog::getUserInfo(); - } - - public function buildSuccess($data, $msg = '操作成功', $code = ReturnCode::SUCCESS) { - $return = [ - 'code' => $code, - 'msg' => $msg, - 'data' => $data - ]; - if ($this->debug) { - $return['debug'] = $this->debug; - } - - return json($return); - } - - public function buildFailed($code, $msg, $data = []) { - $return = [ - 'code' => $code, - 'msg' => $msg, - 'data' => $data - ]; - if ($this->debug) { - $return['debug'] = $this->debug; - } - - return json($return); - } - - protected function debug($data) { - if ($data) { - $this->debug[] = $data; - } - } - -} \ No newline at end of file diff --git a/application/api/controller/BuildToken.php b/application/api/controller/BuildToken.php deleted file mode 100644 index 73bd5c3..0000000 --- a/application/api/controller/BuildToken.php +++ /dev/null @@ -1,90 +0,0 @@ - - */ - -namespace app\api\controller; - - -use app\model\AdminApp; -use app\util\ApiLog; -use app\util\ReturnCode; -use app\util\Strs; - -class BuildToken extends Base { - - /** - * 构建AccessToken - * @return \think\response\Json - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\ModelNotFoundException - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function getAccessToken() { - $param = $this->request->param(); - if (empty($param['app_id'])) { - return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少app_id'); - } - $appInfo = (new AdminApp())->where(['app_id' => $param['app_id'], 'app_status' => 1])->find(); - if (empty($appInfo)) { - return $this->buildFailed(ReturnCode::INVALID, '应用ID非法'); - } - - $signature = $param['signature']; - unset($param['signature']); - $sign = $this->getAuthToken($appInfo['app_secret'], $param); - $this->debug($sign); - if ($sign !== $signature) { - return $this->buildFailed(ReturnCode::INVALID, '身份令牌验证失败'); - } - $expires = config('apiAdmin.ACCESS_TOKEN_TIME_OUT'); - $accessToken = cache('AccessToken:' . $param['device_id']); - if ($accessToken) { - cache('AccessToken:' . $accessToken, null); - cache('AccessToken:' . $param['device_id'], null); - } - $accessToken = $this->buildAccessToken($appInfo['app_id'], $appInfo['app_secret']); - $appInfo['device_id'] = $param['device_id']; - ApiLog::setAppInfo($appInfo); - cache('AccessToken:' . $accessToken, $appInfo, $expires); - cache('AccessToken:' . $param['device_id'], $accessToken, $expires); - $return['access_token'] = $accessToken; - $return['expires_in'] = $expires; - - return $this->buildSuccess($return); - } - - /** - * 根据AppSecret和数据生成相对应的身份认证秘钥 - * @param $appSecret - * @param $data - * @return string - */ - private function getAuthToken($appSecret, $data) { - if (empty($data)) { - return ''; - } else { - $preArr = array_merge($data, ['app_secret' => $appSecret]); - ksort($preArr); - $preStr = http_build_query($preArr); - - return md5($preStr); - } - } - - /** - * 计算出唯一的身份令牌 - * @param $appId - * @param $appSecret - * @return string - */ - private function buildAccessToken($appId, $appSecret) { - $preStr = $appSecret . $appId . time() . Strs::keyGen(); - - return md5($preStr); - } - -} diff --git a/application/api/controller/Index.php b/application/api/controller/Index.php deleted file mode 100644 index 3404a4c..0000000 --- a/application/api/controller/Index.php +++ /dev/null @@ -1,19 +0,0 @@ -debug([ - 'TpVersion' => THINK_VERSION - ]); - - return $this->buildSuccess([ - 'Product' => config('apiAdmin.APP_NAME'), - 'Version' => config('apiAdmin.APP_VERSION'), - 'Company' => config('apiAdmin.COMPANY_NAME'), - 'ToYou' => "I'm glad to meet you(终于等到你!)" - ]); - } -} diff --git a/application/api/controller/Miss.php b/application/api/controller/Miss.php deleted file mode 100644 index 0d2836b..0000000 --- a/application/api/controller/Miss.php +++ /dev/null @@ -1,22 +0,0 @@ -debug([ - 'TpVersion' => THINK_VERSION, - 'Float' => StrRandom::randomPhone() - ]); - - return $this->buildSuccess([ - 'Product' => config('apiAdmin.APP_NAME'), - 'Version' => config('apiAdmin.APP_VERSION'), - 'Company' => config('apiAdmin.COMPANY_NAME'), - 'ToYou' => "I'm glad to meet you(终于等到你!)" - ]); - } -} diff --git a/application/api/tags.php b/application/api/tags.php deleted file mode 100644 index 718a5f2..0000000 --- a/application/api/tags.php +++ /dev/null @@ -1,18 +0,0 @@ - -// +---------------------------------------------------------------------- - -// 应用行为扩展定义文件 -return [ - // 输出结束 - 'response_send' => [ - 'app\\api\\behavior\\BuildResponse', - ], -]; diff --git a/application/apiRoute.php b/application/apiRoute.php deleted file mode 100644 index 0d99995..0000000 --- a/application/apiRoute.php +++ /dev/null @@ -1,13 +0,0 @@ - -// +---------------------------------------------------------------------- - -return []; diff --git a/application/common.php b/application/common.php deleted file mode 100644 index 90de30f..0000000 --- a/application/common.php +++ /dev/null @@ -1,65 +0,0 @@ - -// +---------------------------------------------------------------------- - -// 应用公共文件 -/** - * 把返回的数据集转换成Tree - * @param $list - * @param string $pk - * @param string $pid - * @param string $child - * @param string $root - * @return array - */ -function listToTree($list, $pk='id', $pid = 'fid', $child = '_child', $root = '0') { - $tree = array(); - if(is_array($list)) { - $refer = array(); - foreach ($list as $key => $data) { - $refer[$data[$pk]] = &$list[$key]; - } - foreach ($list as $key => $data) { - $parentId = $data[$pid]; - if ($root == $parentId) { - $tree[] = &$list[$key]; - }else{ - if (isset($refer[$parentId])) { - $parent = &$refer[$parentId]; - $parent[$child][] = &$list[$key]; - } - } - } - } - return $tree; -} - -function formatTree($list, $lv = 0, $title = 'name'){ - $formatTree = array(); - foreach($list as $key => $val){ - $title_prefix = ''; - for( $i=0;$i<$lv;$i++ ){ - $title_prefix .= "|---"; - } - $val['lv'] = $lv; - $val['namePrefix'] = $lv == 0 ? '' : $title_prefix; - $val['showName'] = $lv == 0 ? $val[$title] : $title_prefix.$val[$title]; - if(!array_key_exists('_child', $val)){ - array_push($formatTree, $val); - }else{ - $child = $val['_child']; - unset($val['_child']); - array_push($formatTree, $val); - $middle = formatTree($child, $lv+1, $title); //进行下一层递归 - $formatTree = array_merge($formatTree, $middle); - } - } - return $formatTree; -} \ No newline at end of file diff --git a/application/config.php b/application/config.php deleted file mode 100644 index 3b54aee..0000000 --- a/application/config.php +++ /dev/null @@ -1,241 +0,0 @@ - -// +---------------------------------------------------------------------- - -return [ - // +---------------------------------------------------------------------- - // | 应用设置 - // +---------------------------------------------------------------------- - - // 应用命名空间 - 'app_namespace' => 'app', - // 应用调试模式 - 'app_debug' => true, - // 应用Trace - 'app_trace' => false, - // 应用模式状态 - 'app_status' => '', - // 是否支持多模块 - 'app_multi_module' => true, - // 入口自动绑定模块 - 'auto_bind_module' => false, - // 注册的根命名空间 - 'root_namespace' => [], - // 扩展函数文件 - 'extra_file_list' => [THINK_PATH . 'helper' . EXT], - // 默认输出类型 - 'default_return_type' => 'json', - // 默认AJAX 数据返回格式,可选json xml ... - 'default_ajax_return' => 'json', - // 默认JSONP格式返回的处理方法 - 'default_jsonp_handler' => 'jsonpReturn', - // 默认JSONP处理方法 - 'var_jsonp_handler' => 'callback', - // 默认时区 - 'default_timezone' => 'PRC', - // 是否开启多语言 - 'lang_switch_on' => false, - // 默认全局过滤方法 用逗号分隔多个 - 'default_filter' => '', - // 默认语言 - 'default_lang' => 'zh-cn', - // 应用类库后缀 - 'class_suffix' => false, - // 控制器类后缀 - 'controller_suffix' => false, - - // +---------------------------------------------------------------------- - // | 模块设置 - // +---------------------------------------------------------------------- - - // 默认模块名 - 'default_module' => 'api', - // 禁止访问模块 - 'deny_module_list' => ['common'], - // 默认控制器名 - 'default_controller' => 'Index', - // 默认操作名 - 'default_action' => 'index', - // 默认验证器 - 'default_validate' => '', - // 默认的空控制器名 - 'empty_controller' => 'Error', - // 操作方法后缀 - 'action_suffix' => '', - // 自动搜索控制器 - 'controller_auto_search' => false, - - // +---------------------------------------------------------------------- - // | URL设置 - // +---------------------------------------------------------------------- - - // PATHINFO变量名 用于兼容模式 - 'var_pathinfo' => 's', - // 兼容PATH_INFO获取 - 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], - // pathinfo分隔符 - 'pathinfo_depr' => '/', - // URL伪静态后缀 - 'url_html_suffix' => 'html', - // URL普通方式参数 用于自动生成 - 'url_common_param' => false, - // URL参数方式 0 按名称成对解析 1 按顺序解析 - 'url_param_type' => 0, - // 是否开启路由 - 'url_route_on' => true, - // 路由使用完整匹配 - 'route_complete_match' => false, - // 路由配置文件(支持配置多个) - 'route_config_file' => ['adminRoute', 'apiRoute', 'wikiRoute'], - // 是否强制使用路由 - 'url_route_must' => true, - // 域名部署 - 'url_domain_deploy' => false, - // 域名根,如thinkphp.cn - 'url_domain_root' => '', - // 是否自动转换URL中的控制器和操作名 - 'url_convert' => true, - // 默认的访问控制器层 - 'url_controller_layer' => 'controller', - // 表单请求类型伪装变量 - 'var_method' => '_method', - // 表单ajax伪装变量 - 'var_ajax' => '_ajax', - // 表单pjax伪装变量 - 'var_pjax' => '_pjax', - // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 - 'request_cache' => false, - // 请求缓存有效期 - 'request_cache_expire' => null, - // 全局请求缓存排除规则 - 'request_cache_except' => [], - - // +---------------------------------------------------------------------- - // | 模板设置 - // +---------------------------------------------------------------------- - - 'template' => [ - // 模板引擎类型 支持 php think 支持扩展 - 'type' => 'Think', - // 模板路径 - 'view_path' => '', - // 模板后缀 - 'view_suffix' => 'html', - // 模板文件名分隔符 - 'view_depr' => DS, - // 模板引擎普通标签开始标记 - 'tpl_begin' => '{', - // 模板引擎普通标签结束标记 - 'tpl_end' => '}', - // 标签库标签开始标记 - 'taglib_begin' => '{', - // 标签库标签结束标记 - 'taglib_end' => '}', - ], - - // 视图输出字符串内容替换 - 'view_replace_str' => [], - // 默认跳转页面对应的模板文件 - 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', - 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', - - // +---------------------------------------------------------------------- - // | 异常及错误设置 - // +---------------------------------------------------------------------- - - // 异常页面的模板文件 - 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl', - - // 错误显示信息,非调试模式有效 - 'error_message' => '页面错误!请稍后再试~', - // 显示错误信息 - 'show_error_msg' => false, - // 异常处理handle类 留空使用 \think\exception\Handle - 'exception_handle' => '', - - // +---------------------------------------------------------------------- - // | 日志设置 - // +---------------------------------------------------------------------- - - 'log' => [ - // 日志记录方式,内置 file socket 支持扩展 - 'type' => 'File', - // 日志保存目录 - 'path' => LOG_PATH, - // 日志记录级别 - 'level' => [], - ], - - // +---------------------------------------------------------------------- - // | Trace设置 开启 app_trace 后 有效 - // +---------------------------------------------------------------------- - 'trace' => [ - // 内置Html Console 支持扩展 - 'type' => 'Html', - ], - - // +---------------------------------------------------------------------- - // | 缓存设置 - // +---------------------------------------------------------------------- - - 'cache' => [ - // 驱动方式 - 'type' => 'Redis', - // 缓存保存目录 - 'path' => CACHE_PATH, - // 缓存前缀 - 'prefix' => 'ApiAdmin_', - // 缓存有效期 0表示永久缓存 - 'expire' => 0, - ], - - // +---------------------------------------------------------------------- - // | 会话设置 - // +---------------------------------------------------------------------- - - 'session' => [ - 'id' => '', - // SESSION_ID的提交变量,解决flash上传跨域 - 'var_session_id' => '', - // SESSION 前缀 - 'prefix' => 'think', - // 驱动方式 支持redis memcache memcached - 'type' => '', - // 是否自动开启 SESSION - 'auto_start' => true, - ], - - // +---------------------------------------------------------------------- - // | Cookie设置 - // +---------------------------------------------------------------------- - 'cookie' => [ - // cookie 名称前缀 - 'prefix' => '', - // cookie 保存时间 - 'expire' => 0, - // cookie 保存路径 - 'path' => '/', - // cookie 有效域名 - 'domain' => '', - // cookie 启用安全传输 - 'secure' => false, - // httponly设置 - 'httponly' => '', - // 是否使用 setcookie - 'setcookie' => true, - ], - - //分页配置 - 'paginate' => [ - 'type' => 'bootstrap', - 'var_page' => 'page', - 'list_rows' => 15, - ], -]; diff --git a/application/database.php b/application/database.php deleted file mode 100755 index e65bbca..0000000 --- a/application/database.php +++ /dev/null @@ -1,53 +0,0 @@ - -// +---------------------------------------------------------------------- - -return [ - // 数据库类型 - 'type' => 'mysql', - // 服务器地址 - 'hostname' => '127.0.0.1', - // 数据库名 - 'database' => 'apiadmin', - // 用户名 - 'username' => 'root', - // 密码 - 'password' => '123456', - // 端口 - 'hostport' => '', - // 连接dsn - 'dsn' => '', - // 数据库连接参数 - 'params' => [], - // 数据库编码默认采用utf8 - 'charset' => 'utf8', - // 数据库表前缀 - 'prefix' => '', - // 数据库调试模式 - 'debug' => true, - // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'deploy' => 0, - // 数据库读写是否分离 主从式有效 - 'rw_separate' => false, - // 读写分离后 主服务器数量 - 'master_num' => 1, - // 指定从服务器序号 - 'slave_no' => '', - // 是否严格检查字段是否存在 - 'fields_strict' => true, - // 数据集返回类型 - 'resultset_type' => 'array', - // 自动写入时间戳字段 - 'auto_timestamp' => false, - // 时间字段取出后的默认时间格式 - 'datetime_format' => 'Y-m-d H:i:s', - // 是否需要进行SQL性能分析 - 'sql_explain' => false, -]; diff --git a/application/extra/apiAdmin.php b/application/extra/apiAdmin.php deleted file mode 100644 index a50f612..0000000 --- a/application/extra/apiAdmin.php +++ /dev/null @@ -1,38 +0,0 @@ - -// +---------------------------------------------------------------------- - -return [ - 'APP_VERSION' => 'v3.0', - 'APP_NAME' => 'ApiAdmin', - - //鉴权相关 - 'USER_ADMINISTRATOR' => [1], - - //安全秘钥 - 'AUTH_KEY' => 'I&TC{pft>L,C`wFQ>&#ROW>k{Kxlt1>ryW(>r<#R', - - //后台登录状态维持时间[目前只有登录和解锁会重置登录时间] - 'ONLINE_TIME' => 7200, - //AccessToken失效时间 - 'ACCESS_TOKEN_TIME_OUT' => 7200, - 'COMPANY_NAME' => 'ApiAdmin开发维护团队', - - //跨域配置 - 'CROSS_DOMAIN' => [ - 'Access-Control-Allow-Origin' => '*', - 'Access-Control-Allow-Methods' => 'POST,PUT,GET,DELETE', - 'Access-Control-Allow-Headers' => 'version, access-token, user-token, ApiAuth, User-Agent, Keep-Alive, Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With', - 'Access-Control-Allow-Credentials' => 'true' - ], - - //后台列表默认一页显示数量 - 'ADMIN_LIST_DEFAULT' => 20, -]; diff --git a/application/model/AdminApp.php b/application/model/AdminApp.php deleted file mode 100644 index 5895748..0000000 --- a/application/model/AdminApp.php +++ /dev/null @@ -1,8 +0,0 @@ - - */ - -namespace app\model; - - -class AdminAppGroup extends Base { - -} diff --git a/application/model/AdminAuthGroup.php b/application/model/AdminAuthGroup.php deleted file mode 100644 index 285ce74..0000000 --- a/application/model/AdminAuthGroup.php +++ /dev/null @@ -1,17 +0,0 @@ - - */ - -namespace app\model; - - -class AdminAuthGroup extends Base { - - public function rules() { - return $this->hasMany('AdminAuthRule', 'groupId', 'id'); - } - -} diff --git a/application/model/AdminAuthGroupAccess.php b/application/model/AdminAuthGroupAccess.php deleted file mode 100644 index 94848fd..0000000 --- a/application/model/AdminAuthGroupAccess.php +++ /dev/null @@ -1,13 +0,0 @@ - - */ - -namespace app\model; - - -class AdminAuthGroupAccess extends Base { - -} diff --git a/application/model/AdminAuthRule.php b/application/model/AdminAuthRule.php deleted file mode 100644 index 81220ae..0000000 --- a/application/model/AdminAuthRule.php +++ /dev/null @@ -1,13 +0,0 @@ - - */ - -namespace app\model; - - -class AdminAuthRule extends Base { - -} diff --git a/application/model/AdminFields.php b/application/model/AdminFields.php deleted file mode 100644 index fb35e66..0000000 --- a/application/model/AdminFields.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ - -namespace app\model; - -class AdminFields extends Base { - -} diff --git a/application/model/AdminGroup.php b/application/model/AdminGroup.php deleted file mode 100644 index 59789f0..0000000 --- a/application/model/AdminGroup.php +++ /dev/null @@ -1,13 +0,0 @@ - - */ - -namespace app\model; - - -class AdminGroup extends Base { - -} diff --git a/application/model/AdminList.php b/application/model/AdminList.php deleted file mode 100644 index 8f78daf..0000000 --- a/application/model/AdminList.php +++ /dev/null @@ -1,11 +0,0 @@ - - */ - -namespace app\model; - -class AdminList extends Base { - -} diff --git a/application/model/AdminMenu.php b/application/model/AdminMenu.php deleted file mode 100644 index 1f384b1..0000000 --- a/application/model/AdminMenu.php +++ /dev/null @@ -1,8 +0,0 @@ - - */ - -namespace app\model; - - -class AdminUser extends Base { - -} diff --git a/application/model/AdminUserAction.php b/application/model/AdminUserAction.php deleted file mode 100644 index 5dc193c..0000000 --- a/application/model/AdminUserAction.php +++ /dev/null @@ -1,13 +0,0 @@ - - */ - -namespace app\model; - - -class AdminUserAction extends Base { - -} diff --git a/application/model/AdminUserData.php b/application/model/AdminUserData.php deleted file mode 100644 index 31a02c9..0000000 --- a/application/model/AdminUserData.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ - -namespace app\model; - - -class AdminUserData extends Base { - -} diff --git a/application/model/Base.php b/application/model/Base.php deleted file mode 100644 index fa6b123..0000000 --- a/application/model/Base.php +++ /dev/null @@ -1,15 +0,0 @@ - - */ - -namespace app\model; - - -use think\Model; - -class Base extends Model { - -} \ No newline at end of file diff --git a/application/tags.php b/application/tags.php deleted file mode 100755 index 4b18d10..0000000 --- a/application/tags.php +++ /dev/null @@ -1,28 +0,0 @@ - -// +---------------------------------------------------------------------- - -// 应用行为扩展定义文件 -return [ - // 应用初始化 - 'app_init' => [], - // 应用开始 - 'app_begin' => [], - // 模块初始化 - 'module_init' => [], - // 操作开始执行 - 'action_begin' => [], - // 视图内容过滤 - 'view_filter' => [], - // 日志写入 - 'log_write' => [], - // 应用结束 - 'app_end' => [], -]; diff --git a/application/util/ApiLog.php b/application/util/ApiLog.php deleted file mode 100644 index 65c214a..0000000 --- a/application/util/ApiLog.php +++ /dev/null @@ -1,109 +0,0 @@ - - */ - -namespace app\util; - - -class ApiLog { - - private static $appInfo = 'null'; - private static $apiInfo = 'null'; - private static $request = 'null'; - private static $requestAfterFilter = 'null'; - private static $response = 'null'; - private static $header = 'null'; - private static $userInfo = 'null'; - private static $separator = '###'; - - public static function setAppInfo($data) { - self::$appInfo = - (isset($data['app_id']) ? $data['app_id'] : '') . self::$separator . - (isset($data['app_name']) ? $data['app_name'] : '') . self::$separator . - (isset($data['device_id']) ? $data['device_id'] : ''); - } - - public static function setHeader($data) { - $userToken = (isset($data['user-token']) && !empty($data['user-token'])) ? $data['user-token'] : 'null'; - $accessToken = (isset($data['access-token']) && !empty($data['access-token'])) ? $data['access-token'] : 'null'; - $version = (isset($data['version']) && !empty($data['version'])) ? $data['version'] : 'null'; - self::$header = $accessToken . self::$separator . $userToken . self::$separator . $version; - } - - public static function setApiInfo($data) { - self::$apiInfo = isset($data['apiClass']) ? $data['apiClass'] : '' . self::$separator . isset($data['hash']) ? $data['hash'] : ''; - } - - public static function setUserInfo($data) { - if (is_array($data) || is_object($data)) { - $data = json_encode($data); - } - self::$userInfo = $data; - } - - public static function getUserInfo() { - return json_decode(self::$userInfo, true); - } - - public static function setRequest($data) { - if (is_array($data) || is_object($data)) { - $data = json_encode($data); - } - self::$request = $data; - } - - public static function setRequestAfterFilter($data) { - if (is_array($data) || is_object($data)) { - $data = json_encode($data); - } - self::$requestAfterFilter = $data; - } - - public static function setResponse($data, $code = '') { - if (is_array($data) || is_object($data)) { - $data = json_encode($data); - } - self::$response = $code . self::$separator . $data; - } - - public static function save() { - $logPath = RUNTIME_PATH . 'ApiLog' . DS; - if (self::$appInfo == 'null') { - self::$appInfo = 'null' . self::$separator . 'null' . self::$separator . 'null'; - } - $logStr = implode(self::$separator, array( - self::$apiInfo, - date('Y-m-d H:i:s'), - self::$request, - self::$header, - self::$response, - self::$requestAfterFilter, - self::$appInfo, - self::$userInfo - )); - if (!file_exists($logPath)) { - mkdir($logPath, 0755, true); - } - @file_put_contents($logPath . date('YmdH') . '.log', $logStr . "\n", FILE_APPEND); - } - - - /** - * @param string $log 被记录的内容 - * @param string $type 日志文件名称 - * @param string $filePath - */ - public static function writeLog($log, $type = 'sql', $filePath = '') { - if(!$filePath) { - $filePath = '.' . DS . 'runtime' . DS; - } - $filename = $filePath . date("Ymd") . '_' . $type . ".log"; - @$handle = fopen($filename, "a+"); - @fwrite($handle, date('Y-m-d H:i:s') . "\t" . $log . "\r\n"); - @fclose($handle); - } - - -} diff --git a/application/util/DataType.php b/application/util/DataType.php deleted file mode 100644 index e558302..0000000 --- a/application/util/DataType.php +++ /dev/null @@ -1,24 +0,0 @@ - - */ - -namespace app\util; - - -class DataType { - - const TYPE_INTEGER = 1; - const TYPE_STRING = 2; - const TYPE_ARRAY = 3; - const TYPE_FLOAT = 4; - const TYPE_BOOLEAN = 5; - const TYPE_FILE = 6; - const TYPE_ENUM = 7; - const TYPE_MOBILE = 8; - const TYPE_OBJECT = 9; - -} diff --git a/application/util/MockConf.php b/application/util/MockConf.php deleted file mode 100644 index d2364bc..0000000 --- a/application/util/MockConf.php +++ /dev/null @@ -1,21 +0,0 @@ - - */ - -namespace app\util; - - -class MockConf { - - public function mockToApiAdmin() { - - } - - public function apiAdminToMock() { - - } - -} diff --git a/application/util/ReturnCode.php b/application/util/ReturnCode.php deleted file mode 100644 index 781ddda..0000000 --- a/application/util/ReturnCode.php +++ /dev/null @@ -1,49 +0,0 @@ - - */ - -namespace app\util; - -class ReturnCode { - - const SUCCESS = 1; - const INVALID = -1; - const DB_SAVE_ERROR = -2; - const DB_READ_ERROR = -3; - const CACHE_SAVE_ERROR = -4; - const CACHE_READ_ERROR = -5; - const FILE_SAVE_ERROR = -6; - const LOGIN_ERROR = -7; - const NOT_EXISTS = -8; - const JSON_PARSE_FAIL = -9; - const TYPE_ERROR = -10; - const NUMBER_MATCH_ERROR = -11; - const EMPTY_PARAMS = -12; - const DATA_EXISTS = -13; - const AUTH_ERROR = -14; - - const OTHER_LOGIN = -16; - const VERSION_INVALID = -17; - - const CURL_ERROR = -18; - - const RECORD_NOT_FOUND = -19; // 记录未找到 - const DELETE_FAILED = -20; // 删除失败 - const ADD_FAILED = -21; // 添加记录失败 - const UPDATE_FAILED = -22; // 添加记录失败 - - const PARAM_INVALID = -995; // 参数无效 - const ACCESS_TOKEN_TIMEOUT = -996; - const SESSION_TIMEOUT = -997; - const UNKNOWN = -998; - const EXCEPTION = -999; - - static public function getConstants() { - $oClass = new \ReflectionClass(__CLASS__); - return $oClass->getConstants(); - } - -} \ No newline at end of file diff --git a/application/util/StrRandom.php b/application/util/StrRandom.php deleted file mode 100644 index 97c1d71..0000000 --- a/application/util/StrRandom.php +++ /dev/null @@ -1,186 +0,0 @@ - - */ - -namespace app\util; - - -class StrRandom { - - /** - * 构建一个随机浮点数 - * @param int $min 整数部分的最小值,默认值为-999999999 - * @param int $max 整数部分的最大值,默认值为999999999 - * @param int $dmin 小数部分位数的最小值,默认值为 0 - * @param int $dmax 小数部分位数的最大值,默认值为 8 - * @return float - * @author zhaoxiang - */ - public static function randomFloat($min = -999999999, $max = 999999999, $dmin = 0, $dmax = 8) { - $rand = ''; - $intNum = mt_rand($min, $max); - $floatLength = mt_rand($dmin, $dmax); - if ($floatLength > 1) { - $rand = Strs::randString($floatLength - 1, 1); - } - $floatEnd = mt_rand(1, 9); - - return floatval($intNum . '.' . $rand . $floatEnd); - } - - /** - * 获取随机的时间 - * @param string $format PHP的时间日期格式化字符 - * @return false|string - * @author zhaoxiang - */ - public static function randomDate($format = 'Y-m-d H:i:s') { - $timestamp = time() - mt_rand(0, 86400 * 3650); - - return date($format, $timestamp); - } - - /** - * 构建随机IP地址 - * @return string - * @author zhaoxiang - */ - public static function randomIp() { - $ipLong = [ - ['607649792', '608174079'], // 36.56.0.0-36.63.255.255 - ['1038614528', '1039007743'], // 61.232.0.0-61.237.255.255 - ['1783627776', '1784676351'], // 106.80.0.0-106.95.255.255 - ['2035023872', '2035154943'], // 121.76.0.0-121.77.255.255 - ['2078801920', '2079064063'], // 123.232.0.0-123.235.255.255 - ['-1950089216', '-1948778497'], // 139.196.0.0-139.215.255.255 - ['-1425539072', '-1425014785'], // 171.8.0.0-171.15.255.255 - ['-1236271104', '-1235419137'], // 182.80.0.0-182.92.255.255 - ['-770113536', '-768606209'], // 210.25.0.0-210.47.255.255 - ['-569376768', '-564133889'], // 222.16.0.0-222.95.255.255 - ]; - $randKey = mt_rand(0, 9); - - return $ip = long2ip(mt_rand($ipLong[$randKey][0], $ipLong[$randKey][1])); - } - - /** - * 随机生成一个 URL 协议 - * @return mixed - * @author zhaoxiang - */ - public static function randomProtocol() { - $proArr = [ - 'http', - 'ftp', - 'gopher', - 'mailto', - 'mid', - 'cid', - 'news', - 'nntp', - 'prospero', - 'telnet', - 'rlogin', - 'tn3270', - 'wais' - ]; - shuffle($proArr); - - return $proArr[0]; - } - - /** - * 随机生成一个顶级域名 - * @author zhaoxiang - */ - public static function randomTld() { - $tldArr = [ - 'com', 'cn', 'xin', 'net', 'top', '在线', - 'xyz', 'wang', 'shop', 'site', 'club', 'cc', - 'fun', 'online', 'biz', 'red', 'link', 'ltd', - 'mobi', 'info', 'org', 'edu', 'com.cn', 'net.cn', - 'org.cn', 'gov.cn', 'name', 'vip', 'pro', 'work', - 'tv', 'co', 'kim', 'group', 'tech', 'store', 'ren', - 'ink', 'pub', 'live', 'wiki', 'design', '中文网', - '我爱你', '中国', '网址', '网店', '公司', '网络', '集团', 'app' - ]; - shuffle($tldArr); - - return $tldArr[0]; - } - - /** - * 获取一个随机的域名 - * @return string - * @author zhaoxiang - */ - public static function randomDomain() { - $len = mt_rand(6, 16); - - return strtolower(Strs::randString($len)) . '.' . self::randomTld(); - } - - /** - * 随机生成一个URL - * @param string $protocol 协议名称,可以不用指定 - * @return string - * @author zhaoxiang - */ - public static function randomUrl($protocol = '') { - $protocol = $protocol ? $protocol : self::randomProtocol(); - - return $protocol . '://' . self::randomDomain(); - } - - /** - * 随机生成一个邮箱地址 - * @param string $domain 可以指定邮箱域名 - * @return string - * @author zhaoxiang - */ - public static function randomEmail($domain = '') { - $len = mt_rand(6, 16); - $domain = $domain ? $domain : self::randomDomain(); - - return Strs::randString($len) . '@' . $domain; - - } - - - public static function randomPhone() { - $prefixArr = [133, 153, 173, 177, 180, 181, 189, 199, 134, 135, - 136, 137, 138, 139, 150, 151, 152, 157, 158, 159, 172, 178, - 182, 183, 184, 187, 188, 198, 130, 131, 132, 155, 156, 166, - 175, 176, 185, 186, 145, 147, 149, 170, 171]; - shuffle($prefixArr); - - return $prefixArr[0] . Strs::randString(8, 1); - } - - /** - * 随机创建一个身份证号码 - * @return string - * @author zhaoxiang - */ - public static function randomId() { - $prefixArr = [ - 11, 12, 13, 14, 15, - 21, 22, 23, - 31, 32, 33, 34, 35, 36, 37, - 41, 42, 43, 44, 45, 46, - 50, 51, 52, 53, 54, - 61, 62, 63, 64, 65, - 71, 81, 82 - ]; - shuffle($prefixArr); - - $suffixArr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'X']; - shuffle($suffixArr); - - return $prefixArr[0] . '0000' . self::randomDate('Ymd') . Strs::randString(3, 1) . $suffixArr[0]; - } - -} diff --git a/application/util/Strs.php b/application/util/Strs.php deleted file mode 100644 index 46b600c..0000000 --- a/application/util/Strs.php +++ /dev/null @@ -1,252 +0,0 @@ - -// +---------------------------------------------------------------------- -namespace app\util; - -class Strs { - - /** - * 生成UUID 单机使用 - * @access public - * @return string - */ - static public function uuid() { - $charId = md5(uniqid(mt_rand(), true)); - $hyphen = chr(45); - $uuid = chr(123) - . substr($charId, 0, 8) . $hyphen - . substr($charId, 8, 4) . $hyphen - . substr($charId, 12, 4) . $hyphen - . substr($charId, 16, 4) . $hyphen - . substr($charId, 20, 12) - . chr(125); - - return $uuid; - } - - /** - * 生成Guid主键 - * @return Boolean - */ - static public function keyGen() { - return str_replace('-', '', substr(self::uuid(), 1, -1)); - } - - /** - * 检查字符串是否是UTF8编码 - * @param string $string 字符串 - * @return Boolean - */ - static public function isUtf8($string) { - $len = strlen($string); - for ($i = 0; $i < $len; $i++) { - $c = ord($string[$i]); - if ($c > 128) { - if (($c >= 254)) return false; - elseif ($c >= 252) $bits = 6; - elseif ($c >= 248) $bits = 5; - elseif ($c >= 240) $bits = 4; - elseif ($c >= 224) $bits = 3; - elseif ($c >= 192) $bits = 2; - else return false; - if (($i + $bits) > $len) return false; - while ($bits > 1) { - $i++; - $b = ord($string[$i]); - if ($b < 128 || $b > 191) return false; - $bits--; - } - } - } - - return true; - } - - /** - * 字符串截取,支持中文和其他编码 - * @access public - * @param string $str 需要转换的字符串 - * @param integer $start 开始位置 - * @param string $length 截取长度 - * @param string $charset 编码格式 - * @param bool $suffix 截断显示字符 - * @return string - */ - static public function mSubStr($str, $start = 0, $length, $charset = "utf-8", $suffix = true) { - if (function_exists("mb_substr")) - $slice = mb_substr($str, $start, $length, $charset); - elseif (function_exists('iconv_substr')) { - $slice = iconv_substr($str, $start, $length, $charset); - } else { - $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; - $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; - $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; - $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; - preg_match_all($re[$charset], $str, $match); - $slice = join("", array_slice($match[0], $start, $length)); - } - - return $suffix ? $slice . '...' : $slice; - } - - /** - * 产生随机字串,可用来自动生成密码 - * 默认长度6位 字母和数字混合 支持中文 - * @param integer $len 长度 - * @param string $type 字串类型 - * 0 字母 1 数字 其它 混合 - * @param string $addChars 额外字符 - * @return string - */ - static public function randString($len = 6, $type = '', $addChars = '') { - $str = ''; - switch ($type) { - case 0: - $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' . $addChars; - break; - case 1: - $chars = str_repeat('0123456789', 3); - break; - case 2: - $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . $addChars; - break; - case 3: - $chars = 'abcdefghijklmnopqrstuvwxyz' . $addChars; - break; - case 4: - $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借" . $addChars; - break; - default : - // 默认去掉了容易混淆的字符oOLl和数字01,要添加请使用addChars参数 - $chars = 'ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789' . $addChars; - break; - } - if ($len > 10) {//位数过长重复字符串一定次数 - $chars = $type == 1 ? str_repeat($chars, $len) : str_repeat($chars, 5); - } - if ($type != 4) { - $chars = str_shuffle($chars); - $str = substr($chars, 0, $len); - } else { - // 中文随机字 - for ($i = 0; $i < $len; $i++) { - $str .= self::msubstr($chars, floor(mt_rand(0, mb_strlen($chars, 'utf-8') - 1)), 1, 'utf-8', false); - } - } - - return $str; - } - - /** - * 生成一定数量的随机数,并且不重复 - * @param integer $number 数量 - * @param integer $length 长度 - * @param integer $mode 字串类型 - * 0 字母 1 数字 其它 混合 - * @return string - */ - static public function buildCountRand($number, $length = 4, $mode = 1) { - if ($mode == 1 && $length < strlen($number)) { - //不足以生成一定数量的不重复数字 - return false; - } - $rand = array(); - for ($i = 0; $i < $number; $i++) { - $rand[] = self::randString($length, $mode); - } - $unique = array_unique($rand); - if (count($unique) == count($rand)) { - return $rand; - } - $count = count($rand) - count($unique); - for ($i = 0; $i < $count * 3; $i++) { - $rand[] = self::randString($length, $mode); - } - $rand = array_slice(array_unique($rand), 0, $number); - - return $rand; - } - - /** - * 带格式生成随机字符 支持批量生成 - * 但可能存在重复 - * @param string $format 字符格式 - * # 表示数字 * 表示字母和数字 $ 表示字母 - * @param integer $number 生成数量 - * @return string | array - */ - static public function buildFormatRand($format, $number = 1) { - $str = array(); - $length = strlen($format); - for ($j = 0; $j < $number; $j++) { - $strTemp = ''; - for ($i = 0; $i < $length; $i++) { - $char = substr($format, $i, 1); - switch ($char) { - case "*"://字母和数字混合 - $strTemp .= self::randString(1); - break; - case "#"://数字 - $strTemp .= self::randString(1, 1); - break; - case "$"://大写字母 - $strTemp .= self::randString(1, 2); - break; - default://其他格式均不转换 - $strTemp .= $char; - break; - } - } - $str[] = $strTemp; - } - - return $number == 1 ? $strTemp : $str; - } - - /** - * 获取一定范围内的随机数字 位数不足补零 - * @param integer $min 最小值 - * @param integer $max 最大值 - * @return string - */ - static public function randNumber($min, $max) { - return sprintf("%0" . strlen($max) . "d", mt_rand($min, $max)); - } - - // 自动转换字符集 支持数组转换 - static public function autoCharset($string, $from = 'gbk', $to = 'utf-8') { - $from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from; - $to = strtoupper($to) == 'UTF8' ? 'utf-8' : $to; - if (strtoupper($from) === strtoupper($to) || empty($string) || (is_scalar($string) && !is_string($string))) { - //如果编码相同或者非字符串标量则不转换 - return $string; - } - if (is_string($string)) { - if (function_exists('mb_convert_encoding')) { - return mb_convert_encoding($string, $to, $from); - } elseif (function_exists('iconv')) { - return iconv($from, $to, $string); - } else { - return $string; - } - } elseif (is_array($string)) { - foreach ($string as $key => $val) { - $_key = self::autoCharset($key, $from, $to); - $string[$_key] = self::autoCharset($val, $from, $to); - if ($key != $_key) - unset($string[$key]); - } - - return $string; - } else { - return $string; - } - } -} \ No newline at end of file diff --git a/application/util/Tools.php b/application/util/Tools.php deleted file mode 100644 index 2b62a69..0000000 --- a/application/util/Tools.php +++ /dev/null @@ -1,115 +0,0 @@ - - */ - -namespace app\util; - - -class Tools { - - public static function getDate($timestamp) { - $now = time(); - $diff = $now - $timestamp; - if ($diff <= 60) { - return $diff . '秒前'; - } elseif ($diff <= 3600) { - return floor($diff / 60) . '分钟前'; - } elseif ($diff <= 86400) { - return floor($diff / 3600) . '小时前'; - } elseif ($diff <= 2592000) { - return floor($diff / 86400) . '天前'; - } else { - return '一个月前'; - } - } - - /** - * 二次封装的密码加密 - * @param $str - * @param string $auth_key - * @return string - * @author zhaoxiang - */ - public static function userMd5($str, $auth_key = '') { - if (!$auth_key) { - $auth_key = config('apiAdmin.AUTH_KEY'); - } - - return '' === $str ? '' : md5(sha1($str) . $auth_key); - } - - /** - * 判断当前用户是否是超级管理员 - * @param string $uid - * @return bool - * @author zhaoxiang - */ - public static function isAdministrator($uid = '') { - if (!empty($uid)) { - $adminConf = config('apiAdmin.USER_ADMINISTRATOR'); - if (is_array($adminConf)) { - if (is_array($uid)) { - $m = array_intersect($adminConf, $uid); - if (count($m)) { - return true; - } - } else { - if (in_array($uid, $adminConf)) { - return true; - } - } - } else { - if (is_array($uid)) { - if (in_array($adminConf, $uid)) { - return true; - } - } else { - if ($uid == $adminConf) { - return true; - } - } - } - } - - return false; - } - - /** - * 将查询的二维对象转换成二维数组 - * @param array $res - * @param string $key 允许指定索引值 - * @return array - * @author zhaoxiang - */ - public static function buildArrFromObj($res, $key = '') { - $arr = []; - foreach ($res as $value) { - $value = $value->toArray(); - if ($key) { - $arr[$value[$key]] = $value; - } else { - $arr[] = $value; - } - } - - return $arr; - } - - /** - * 将二维数组变成指定key - * @param $array - * @param $keyName - * @author zhaoxiang - * @return array - */ - public static function buildArrByNewKey($array, $keyName = 'id') { - $list = array(); - foreach ($array as $item) { - $list[$item[$keyName]] = $item; - } - return $list; - } -} diff --git a/application/wiki/controller/Base.php b/application/wiki/controller/Base.php deleted file mode 100644 index 8eb1a00..0000000 --- a/application/wiki/controller/Base.php +++ /dev/null @@ -1,90 +0,0 @@ - - */ - -namespace app\wiki\controller; - - -use think\Config; -use think\Controller; -use think\exception\HttpResponseException; -use think\Request; -use think\Response; -use think\View as ViewTemplate; -use think\Url; - -class Base extends Controller { - - protected $appInfo; - - public function checkLogin() { - $appInfo = session('app_info'); - if ($appInfo) { - $this->appInfo = json_decode($appInfo, true); - } else { - $this->redirect(url('/wiki/login')); - } - } - - public function error($msg = '', $url = null, $data = '', $wait = 3, array $header = []) { - if (is_null($url)) { - $url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);'; - } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { - $url = Url::build($url); - } - - $type = 'html'; - $result = [ - 'code' => 0, - 'msg' => $msg, - 'data' => $data, - 'url' => $url, - 'wait' => $wait, - ]; - - if ('html' == strtolower($type)) { - $template = Config::get('template'); - $view = Config::get('view_replace_str'); - - $result = ViewTemplate::instance($template, $view) - ->fetch(Config::get('dispatch_error_tmpl'), $result); - } - - $response = Response::create($result, $type)->header($header); - - throw new HttpResponseException($response); - } - - public function success($msg = '', $url = null, $data = '', $wait = 3, array $header = []) { - if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) { - $url = Request::instance()->server('HTTP_REFERER'); - } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { - $url = Url::build($url); - } - - $type = 'html'; - $result = [ - 'code' => 1, - 'msg' => $msg, - 'data' => $data, - 'url' => $url, - 'wait' => $wait, - ]; - - if ('html' == strtolower($type)) { - $template = Config::get('template'); - $view = Config::get('view_replace_str'); - - $result = ViewTemplate::instance($template, $view) - ->fetch(Config::get('dispatch_success_tmpl'), $result); - } - - $response = Response::create($result, $type)->header($header); - - throw new HttpResponseException($response); - } - -} diff --git a/application/wiki/controller/Index.php b/application/wiki/controller/Index.php deleted file mode 100644 index 671da98..0000000 --- a/application/wiki/controller/Index.php +++ /dev/null @@ -1,178 +0,0 @@ - - */ - -namespace app\wiki\controller; - - -use app\model\AdminApp; -use app\model\AdminFields; -use app\model\AdminGroup; -use app\model\AdminList; -use app\util\DataType; -use app\util\ReturnCode; -use app\util\Tools; - -class Index extends Base { - - /** - * 获取应用列表 - * @return \think\response\View - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - $this->checkLogin(); - - $groupInfo = AdminGroup::all(); - $groupInfo = Tools::buildArrFromObj($groupInfo); - $groupInfo = Tools::buildArrByNewKey($groupInfo, 'hash'); - - $this->appInfo = AdminApp::get(['app_id' => $this->appInfo['app_id']]); - $this->appInfo['app_api_show'] = json_decode($this->appInfo['app_api_show'], true); - - return view('', [ - 'groupInfo' => $groupInfo, - 'appInfo' => $this->appInfo - ]); - } - - public function detail() { - $this->checkLogin(); - - $groupHash = $this->request->route('groupHash'); - $hash = $this->request->route('hash', ''); - $this->appInfo['app_api_show'] = json_decode($this->appInfo['app_api_show'], true); - if (!isset($this->appInfo['app_api_show'][$groupHash]) || empty($this->appInfo['app_api_show'][$groupHash])) { - $this->error('请求非法', url('/wiki/index')); - } - - if (!$hash) { - $hash = $this->appInfo['app_api_show'][$groupHash][0]; - } else { - if (!in_array($hash, $this->appInfo['app_api_show'][$groupHash])) { - $this->error('请求非法', url('/wiki/index')); - } - } - - $apiList = (new AdminList())->whereIn('hash', $this->appInfo['app_api_show'][$groupHash])->where(['groupHash' => $groupHash])->select(); - $apiList = Tools::buildArrFromObj($apiList); - $apiList = Tools::buildArrByNewKey($apiList, 'hash'); - - if (!$hash) { - $hash = $this->appInfo['app_api_show'][$groupHash][0]; - } - $detail = $apiList[$hash]; - - $request = AdminFields::all(['hash' => $hash, 'type' => 0]); - $response = AdminFields::all(['hash' => $hash, 'type' => 1]); - $dataType = array( - DataType::TYPE_INTEGER => 'Integer', - DataType::TYPE_STRING => 'String', - DataType::TYPE_BOOLEAN => 'Boolean', - DataType::TYPE_ENUM => 'Enum', - DataType::TYPE_FLOAT => 'Float', - DataType::TYPE_FILE => 'File', - DataType::TYPE_ARRAY => 'Array', - DataType::TYPE_OBJECT => 'Object', - DataType::TYPE_MOBILE => 'Mobile' - ); - - $groupInfo = AdminGroup::get(['hash' => $groupHash]); - $groupInfo->hot = $groupInfo->hot + 1; - $groupInfo->save(); - - return view('', [ - 'groupInfo' => $groupInfo->toArray(), - 'request' => $request, - 'response' => $response, - 'dataType' => $dataType, - 'apiList' => $apiList, - 'detail' => $detail, - 'hash' => $hash, - 'groupHash' => $groupHash - ]); - } - - public function calculation() { - $this->checkLogin(); - - return view(); - } - - public function errorCode() { - $this->checkLogin(); - $codeArr = ReturnCode::getConstants(); - $errorInfo = array( - ReturnCode::SUCCESS => '请求成功', - ReturnCode::INVALID => '非法操作', - ReturnCode::DB_SAVE_ERROR => '数据存储失败', - ReturnCode::DB_READ_ERROR => '数据读取失败', - ReturnCode::CACHE_SAVE_ERROR => '缓存存储失败', - ReturnCode::CACHE_READ_ERROR => '缓存读取失败', - ReturnCode::FILE_SAVE_ERROR => '文件读取失败', - ReturnCode::LOGIN_ERROR => '登录失败', - ReturnCode::NOT_EXISTS => '不存在', - ReturnCode::JSON_PARSE_FAIL => 'JSON数据格式错误', - ReturnCode::TYPE_ERROR => '类型错误', - ReturnCode::NUMBER_MATCH_ERROR => '数字匹配失败', - ReturnCode::EMPTY_PARAMS => '丢失必要数据', - ReturnCode::DATA_EXISTS => '数据已经存在', - ReturnCode::AUTH_ERROR => '权限认证失败', - ReturnCode::OTHER_LOGIN => '别的终端登录', - ReturnCode::VERSION_INVALID => 'API版本非法', - ReturnCode::CURL_ERROR => 'CURL操作异常', - ReturnCode::RECORD_NOT_FOUND => '记录未找到', - ReturnCode::DELETE_FAILED => '删除失败', - ReturnCode::ADD_FAILED => '添加记录失败', - ReturnCode::UPDATE_FAILED => '更新记录失败', - ReturnCode::PARAM_INVALID => '数据类型非法', - ReturnCode::ACCESS_TOKEN_TIMEOUT => '身份令牌过期', - ReturnCode::SESSION_TIMEOUT => 'SESSION过期', - ReturnCode::UNKNOWN => '未知错误', - ReturnCode::EXCEPTION => '系统异常', - ); - - return view('', [ - 'errorInfo' => $errorInfo, - 'codeArr' => $codeArr - ]); - } - - public function login() { - return view(); - } - - /** - * 处理wiki登录 - * @throws \think\Exception - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function doLogin() { - $appId = $this->request->post('appId'); - $appSecret = $this->request->post('appSecret'); - - $appInfo = AdminApp::get(['app_id' => $appId, 'app_secret' => $appSecret]); - if (!empty($appInfo)) { - if ($appInfo->app_status) { - //保存用户信息和登录凭证 - session('app_info', json_encode($appInfo)); - $this->success('登录成功', url('/wiki/index')); - } else { - $this->error('当前应用已被封禁,请联系管理员'); - } - } else { - $this->error('AppId或AppSecret错误'); - } - } - - public function logout() { - session('app_info', null); - $this->success('退出成功', url('/wiki/login')); - } - -} diff --git a/application/wiki/view/index/calculation.html b/application/wiki/view/index/calculation.html deleted file mode 100644 index 1eab796..0000000 --- a/application/wiki/view/index/calculation.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - {:config('apiAdmin.APP_NAME')} - 算法说明 - - - -
-
-
-

{:config('apiAdmin.APP_NAME')} - 算法说明

- - - -
- 特别说明: 此算法文档会根据业务发展需求发生变更,为了服务的稳定运行,请及时关注此文档! -
-
-
简介
-

当前算法主要服务于获取身份令牌(AccessToken)所进行的身份认证秘钥(signature)的计算。在请求高级接口的时候,系统会验证应用的合法性,也就是验证AccessToken。所以AccessToken是请求API的必要参数。

-

在请求获取AccessToken的接口时候,服务器会对用户合法性(signature)进行核验,具体的接口请求字段,请参看具体的接口文档。

-
一、获取app_id和app_secret
-

目前获取应用ID和应用秘钥是由系统管理员发放,如果你还没有请联系管理员。请注意:app_secret非常重要请妥善保管

-
二、准备加密对象,并且根据字段名降序排序
-
//排序好后应当是如下所示的数据
-{
-    "app_id":"服务器颁发的应用ID",
-    "app_secret":"服务器颁发的应用秘钥",   //请注意,此字段只是在计算加密串的时候在被加入,API请求请勿传递此字段值
-    "device_id":"设备唯一ID",
-    "rand_str":"随机字符串",
-    "timestamp":当前系统时间戳
-}
-
三、生成原始串
-

将上面的数据构建成HTTP查询字符串,如下所示:

-

app_id=服务器颁发的应用ID&app_secret=服务器颁发的应用秘钥&device_id=设备唯一ID&rand_str=随机字符串&timestamp=当前系统时间戳

-
四、计算秘钥
-

将第三步生成的字符串进行哈希计算(md5)获得最终身份认证秘钥。

-
-

© Powered By {:config('apiAdmin.APP_NAME')} {:config('apiAdmin.APP_VERSION')}

-

-
- - diff --git a/application/wiki/view/index/detail.html b/application/wiki/view/index/detail.html deleted file mode 100644 index afa09b9..0000000 --- a/application/wiki/view/index/detail.html +++ /dev/null @@ -1,199 +0,0 @@ - - - - - {:config('apiAdmin.APP_NAME')} - 在线接口列表 - - - - - - - -
-
-
-
-
-
- -
-
- {$groupInfo['name']} -
-

{$groupInfo['description']}

-
-
- 额外的细节 -
-
-
-
-
- {php}$http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';{/php} -
接口访问地址:{$http_type}{$_SERVER['HTTP_HOST']}/api/{$hash}
-
-
- -
-
-
-

接口唯一标识:{$hash}{if condition="$detail['isTest'] == 1"}({$detail['apiClass']}){/if}


-
- 接口说明 - {if condition="$detail['status'] eq 0 "} - 禁用 - {else /} - {if condition="$detail['isTest'] eq 1 "} - 测试 - {else /} - 启用 - {/if} - {/if} - {:config('apiAdmin.APP_VERSION')} - - {switch name="detail['method']"} - {case value="1" break="1"}POST{/case} - {case value="2" break="1"}GET{/case} - {default /}不限 - {/switch} - -
-

{$detail['info']}

-
-
- -
-

公共请求参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
参数名字类型是否必须默认值其他说明
versionString必填{:config('apiAdmin.APP_VERSION')}API版本号【请在Header头里面传递】
access-tokenString{$detail['accessToken']==1?'必填':'勿填'}APP认证秘钥【请在Header头里面传递】
user-tokenString{$detail['needLogin']==1?'必填':'勿填'}用户认证秘钥【请在Header头里面传递】
-

请求参数

- - - - - - {volist name="request" id="vo"} - - - - - - - - - {/volist} - -
参数名字类型是否必须默认值其他说明
{$vo['fieldName']}{$dataType[$vo['dataType']]}{$vo['isMust']==1?'必填':'可选'}{$vo['default']}{$vo['range']}{$vo['info']}
-
-
-

公共返回参数

- - - - - - - - - - - - - - - - - - - - - -
返回字段类型说明
codeInteger返回码,详情请参阅错误码说明
msgString错误描述,当请求成功时可能为空
debugString调试字段,如果没有调试信息会没有此字段
-

返回参数

- - - - - - {volist name="response" id="vo"} - - - - - - {/volist} - -
返回字段类型说明
{$vo['showName']}{$dataType[$vo['dataType']]}{$vo['info']}
-
-
-

-                
-
- 温馨提示: 此接口参数列表根据后台代码自动生成,如有疑问请咨询后端开发 -
-

© Powered By {:config('apiAdmin.APP_NAME')} {:config('apiAdmin.APP_VERSION')}

-

-
-
-
- - - diff --git a/application/wiki/view/index/error_code.html b/application/wiki/view/index/error_code.html deleted file mode 100644 index 0f40e15..0000000 --- a/application/wiki/view/index/error_code.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - {:config('apiAdmin.APP_NAME')} - 错误码说明 - - - -
-
-
-

{:config('apiAdmin.APP_NAME')} - 错误码说明

- - - - - - - - - - - {volist name="codeArr" id="vo"} - - - - - - - {/volist} - -
#英文标识错误码中文说明
- {$i} - - {$key} - - {$vo} - - {$errorInfo[$vo]} -
-

© Powered By {:config('apiAdmin.APP_NAME')} {:config('apiAdmin.APP_VERSION')}

-

-
- - diff --git a/application/wiki/view/index/index.html b/application/wiki/view/index/index.html deleted file mode 100644 index 78db05a..0000000 --- a/application/wiki/view/index/index.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - {:config('apiAdmin.APP_NAME')} - 在线接口文档 - - - -
-
-
-

{:config('apiAdmin.APP_NAME')} - 接口文档

- - - - - - -
-
-
接口状态说明:
-

测试 系统将不过滤任何字段,也不进行AccessToken的认证,但在必要的情况下会进行UserToken的认证!

-

启用 系统将严格过滤请求字段,并且进行全部必要认证!

-

禁用 系统将拒绝所有请求,一般应用于危机处理!

-
-
- -

© Powered By {:config('apiAdmin.APP_NAME')} {:config('apiAdmin.APP_VERSION')}

-

-
- - diff --git a/application/wiki/view/index/login.html b/application/wiki/view/index/login.html deleted file mode 100644 index 86d04eb..0000000 --- a/application/wiki/view/index/login.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - {:config('apiAdmin.APP_NAME')} - 在线接口文档 - - - - - - - - - - - -
-
-

-
- 欢迎使用{:config('apiAdmin.APP_NAME')}在线文档 -
-

-
-
-
-
- - -
-
-
-
- - -
-
-
提 交
-
-
-
-
- 如果您没有AppId和AppSecret,请联系服务供应商获取! -
-
-
- - diff --git a/application/wikiRoute.php b/application/wikiRoute.php deleted file mode 100644 index 95db9ff..0000000 --- a/application/wikiRoute.php +++ /dev/null @@ -1,38 +0,0 @@ - [ - 'login' => [ - 'wiki/index/login', - ['method' => 'get'] - ], - 'doLogin' => [ - 'wiki/index/doLogin', - ['method' => 'post'] - ], - 'index' => [ - 'wiki/index/index', - ['method' => 'get'] - ], - 'calculation' => [ - 'wiki/index/calculation', - ['method' => 'get'] - ], - 'errorCode' => [ - 'wiki/index/errorCode', - ['method' => 'get'] - ], - 'detail/:groupHash/[:hash]' => [ - 'wiki/index/detail', - ['method' => 'get'] - ], - 'logout' => [ - 'wiki/index/logout', - ['method' => 'get'] - ], - '__miss__' => ['wiki/index/index'], - ], -]; diff --git a/build.php b/build.php deleted file mode 100644 index b37d3ab..0000000 --- a/build.php +++ /dev/null @@ -1,25 +0,0 @@ - -// +---------------------------------------------------------------------- - -return [ - // 生成应用公共文件 - '__file__' => ['common.php', 'config.php', 'database.php'], - - // 定义demo模块的自动生成 (按照实际定义的文件名生成) - 'demo' => [ - '__file__' => ['common.php'], - '__dir__' => ['behavior', 'controller', 'model', 'view'], - 'controller' => ['Index', 'Test', 'UserType'], - 'model' => ['User', 'UserType'], - 'view' => ['index/index'], - ], - // 其他更多的模块定义 -]; diff --git a/composer.json b/composer.json deleted file mode 100644 index 5477dc4..0000000 --- a/composer.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "apiadmin/apiadmin3", - "description": "the api manager", - "type": "project", - "keywords": [ - "api", - "apiadmin", - "tp5" - ], - "homepage": "http://www.apiadmin.org/", - "license": "Apache-2.0", - "authors": [ - { - "name": "zhao", - "email": "756958008@qq.com" - } - ], - "autoload": { - "psr-4": { - "app\\": "application" - } - }, - "require": { - "php": ">=5.6.0", - "php-curl-class/php-curl-class": "^8.0" - }, - "extra": { - "think-path": "thinkphp" - }, - "config": { - "preferred-install": "dist" - } -} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index f75684d..0000000 --- a/composer.lock +++ /dev/null @@ -1,77 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "content-hash": "c38a84a081b633a51738b670cdfef2fd", - "packages": [ - { - "name": "php-curl-class/php-curl-class", - "version": "8.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-curl-class/php-curl-class.git", - "reference": "75597b28c454acd9767e6182371376916cdb8531" - }, - "dist": { - "type": "zip", - "url": "https://files.phpcomposer.com/files/php-curl-class/php-curl-class/75597b28c454acd9767e6182371376916cdb8531.zip", - "reference": "75597b28c454acd9767e6182371376916cdb8531", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "*", - "squizlabs/php_codesniffer": "*" - }, - "type": "library", - "autoload": { - "psr-4": { - "Curl\\": "src/Curl/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Unlicense" - ], - "authors": [ - { - "name": "Zach Borboa" - } - ], - "description": "PHP Curl Class makes it easy to send HTTP requests and integrate with web APIs.", - "homepage": "https://github.com/php-curl-class/php-curl-class", - "keywords": [ - "api", - "class", - "client", - "curl", - "framework", - "http", - "http client", - "json", - "php", - "requests", - "rest", - "restful", - "web service", - "xml" - ], - "time": "2018-04-09T08:28:13+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.6.0" - }, - "platform-dev": [] -} diff --git a/data/apiRoute.tpl b/data/apiRoute.tpl deleted file mode 100644 index 3200188..0000000 --- a/data/apiRoute.tpl +++ /dev/null @@ -1,15 +0,0 @@ - - Options +FollowSymlinks -Multiviews - RewriteEngine On - - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L] - diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index e71815a6618c6ef19c78d27840b8995fb2521499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbVMSx8i26uv?4_SAEaJq7BFqqJE;Q9TBc5JYcLIgSmPnyr-jk`K{>ZB(>aLWVXo z*9E63a&I$RrZR03EEi&&_1^#9`}O_*AViPd;mm*e&-u>z&UX%1)0XhJY?;RY723X~ znzmfiw3Reo@g{fAL(}N{_i=@Ma0M%r6$X8HFcE zpG~1@_%Y6ow1ksJIN%eE0)m_g-8Gd#K%-r;7XvI$t0gLrlUMS(*o zV$Y+$Ct(SJ+L5c+)7OmI%nVG$!vbteaep>7ij6%r*#F`@;?!a~HIJfDIkr7LrT7TO z8Pus^>>;*w*WwO!6s7@#wJgVkVE+^G7)ra2;Ldm_p8Ob6`0br_NQk8JTkP3k{J^jG z*cCa8vT!3JGaq0ucb3{&JkLiTVfXWMD5q9ZyH%ZD)V;jPIT^6ouVd%VG`X~V*0H+F zhl^v6kP#Mn+6Yg-!rHDH>fs|^>X)1U?nncMSj%CIp#G9el3d=+e!&L43iV_6ITI5d zQv>h>y$V~X^k*JwD7m;pl{iR^$K%uN!-g$vq?qse=KxBm_3+$BoO#pw7gpx+aR#|L z%6Dm{!D`%_jIeKm8ajyn9!EZFoOpW+Tl5oZR|^>D;?7A9ZiV-%JuQ#*owco@x{a zD-|ENtov7tOFzK5r}KRMSHhkEb!7aa$$nhqBKuHtV!cJ5I+?Si!w-Hm{`)ye -// +---------------------------------------------------------------------- - -// [ 应用入口文件 ] - -// 定义应用目录 -define('APP_PATH', __DIR__ . '/../application/'); -// 加载框架引导文件 -require __DIR__ . '/../thinkphp/start.php'; diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index eb05362..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: diff --git a/public/router.php b/public/router.php deleted file mode 100644 index f8e424e..0000000 --- a/public/router.php +++ /dev/null @@ -1,20 +0,0 @@ - -// +---------------------------------------------------------------------- -// $Id$ - -if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["REQUEST_URI"])) { - return false; -} else { - if (!isset($_SERVER['PATH_INFO'])) { - $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI']; - } - require __DIR__ . "/index.php"; -} diff --git a/public/static/defaultImg.jpg b/public/static/defaultImg.jpg deleted file mode 100644 index 8142bacd85ed2b365e16ecbe4c4ed14671e91df8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15839 zcmeHubzD`=*Y7?-N}NN3#GxAwNavv&LAuMJQ=~&$8U>_FTBSt5=d}qzf-ZT4roBXx_z*H4g6af$j06^#u@NE(3 zQ}DLC4geY&00#g7*Z?Mo2!Noe@8uvW0OLCi0Q#Vdf6?Y3wx2R!000yJEgxwIK!3`k zb$(CEKl4Anu@V6Q3(bKd`T6;hKtE^@7y{(|;`1Sqd7!^F=7E1{gskU5{-z5tf69C} za(?+X1IPiGPz+2AC?+NbCKeVZHZBYo7Y7HIgn$qaMovOOK~6$OMn%I+M|F{rnv4v= zg9Q$7h0}G0Y4FR8*lA{a$S%ek=gCO6g0Xzu08VmwM_ee$8!LOQs zzW*Tb2Z28b{7*$7AeS;#^DITp&kRqiO6X9|5brlnK@zBXnt+zu!NA$+7oqw7B0+i7 z$45rPP7n1SVg4rhR|Y&)aRTAo9$&3jlD68O_9Scxw?zI`iY7pbM&sl?vnFb9u`UJn zDa-@Zd`G$HqK_6;1S#TgKAM7jSh#8K zMDM83|9N2?^I?=Jn#a8v@oKR8^tq1ztK*~u|JL6s{K|m4>Nfi|xrfg{!(S4Y3ejwc zxTlkM6LYQ4;VY3fX`TSd47sf}SI}J>?%eLNEgLPt8%4ne4&yq)+1a4Vzqw2_AJr|*egj6RzX8t(I8Xo}wVmy| z)3^7DB^bcJm9jo4ncUEztkf%905xu^mNLSU5CEhcOprr2Tzr{(`9Dm1Iu&!{U&7M@ zFQ7rSeKQ{K6wh+pLdQsZ9Q?bjpE=gS_Ls5uVmx*Zhx~G^(G3OpXxBP5JM6G<3R&|G z*50ePQ~ap!De2k;@%hB+KI%*a-^Y^2t}Z7sCJ0~Cd7`qe(SPEQ`9Y*?WR}2pL)GHO zWm4h5(T7fawsvXO!Q^N&7ldlw);iM*4{N8sv(SkULj9W~G~`3sI4SIVpE626irW`8 zoCgwZ>axS*f;XBI6yu>niQ{6%jP6-4%KdDB@*t%-0l%;?|J$#?-1^gc&hOkg0B5mV z9=>b}4`b+5u8HyRoR#QLTaSz)y8xbZRXIN49Z$McyB?ZwRC2nx{+kQH;Xe7mnbnQ1 zxdnc4%#Bw^i&XOqG}>%V&NBLK2~1VE|V6#!t( zyPg?@{Y1w>Up%F>6zqFaP-&FcSMo7nS?N3uXkZL)o+PadIT=o44BuWK7IzjJ%s8P` zO`TYKo7Se|wIfzPN*0kG!3H{Sa-IE_l28w^|9ry#dEf{5$44a=J1e(5lIXCPG|4xS zII1xPvzS1n*>L~S4O|W^gUg5O@@rQCC_CixyCqY|e{=y^oSE(F4$DQ3`KDA2ahi*@5%}s~ItOmASs6-7D6B5M` z3gt7Zk7vW4_WT!KRSQ6 zk0vlcm@q&PfxM&zCn6>hAfx9;kybH?O`qmQBvdMk)@`OsPF5HXURqTd zGcV3!onX|`D5fuN$yTBE3LKG71?G$CducmdybSwcQn*qvPgz7#RQnY zJL8@p*Bs!NRNA;qfFrN{j8@wHYpL2vTsFe%qOqBa0c>vR(u--Fy~M8WL$lN!Ha)Fs za}_)*2Q^#vdD9%d;zQGf*P{w0X9h2fp8Ko6&n_o3LXG)=l+}9h23c0^uZiArQG$?@gnQ3p@U83#SeNQ`VPnX;lD%y&3XG2HLMnZmn>F<%D% z5LTSoj%Vc=+^~#q@vrs$oc2~!Swp|H->*Z1o|`dVlkeUPmlrgM?;9X3jHn>Hdes9V z*d>g0nHQtB*4o1H-PCg~_{4`)7YpKxB^=Ytkly_Ygycec!twF$mwg`F4>Gee;zG=y zhRiZwx6uS1-w-wyzGMIS<^Dq4QNF}Jh2z$}_R5zTU(1U)H4+bu!3*>m(Q;R7)Ac3m z;u*gNfnGzx?m8RjS*)!{C_YoxKqXSItaKA859Mo!$K1Hy`C_WS*5RwjJ?BTgUeyfh zEO~f|U86(V#aU*iUiXOtP)r9of^!$O%Ilq-3y-h4(H$I!GjCJ4bu~7}AA~j$*=rID ztI;N>a%X1}eYwFi8Z?^Nd8!&)29Xf-8?hkNs|;r?W|I}o?@Be#sHb@>bzdoD$I~{A zF}>iPE(g}F!TD#_(rc^xo37KHZ_=sfxIfqabjr!zuJ?}quqLl`&vRgjjD?4-POOK! zj=ih1t&ZPY1L~nQV3KrT)O5t9bb2~xrU}zq5f*lmu;Fvup1eOJY878_2dWr)gWNC5 z!q2X&uE9of*I19OoM^s4iDM$+WBP)T%~M^X_Pxb6ulI&%teYFN7mrY=iShE83H8p2}dvwrw_ z_ukiuz{xe&5%xU=cm3?#mIwlathwXshkJaD?v{4TyqRs&U*fU3XM_XaMSTNuGoOc- zNeESuTE)Ko;1m6;);~gmg)~q_{q6F@!8VurCw;3QW~=EA_6uLx-Fup{>RCc*o+&%4 zD}muZ_1K@CNvTPgY-sRKK<)kOAFGrsz7G-StmN@BEheUX*DuOGwL24uMZv}#Q3vGt z+^!zl}8wfjXAQeDAi%Vld7>8{4JopdOL?U`lB*k#jtJPm2euHsK>SU>&67MvtIfI zc@i;CcwPc^=R4H`9Y$AV7Y_YvvxWLw{%Sk^O~OTyUq5*DtMsv`k)z&RS4vCKQ>D4A=yoLg?Pw#h&DK&@*;j}oiJ;GOGu!jd>n}T5Kiz#&gd^syz3x*<_2DCv z)TZDEoY92FrC$nqnpw@av)NS*4p%rz4fabMj&+`#mQ5q>-}wgQG@<8kdN_LD699wJ zm!Am)2Ve+3EhNec)L7?lQnxpl1g34N#3`nnQqTcjXrks^+* zpw3#1278HytNh|pL=P%2Qr2H9B$nbjcztAYEsyjdpOg(FHkJ@rhl+u85+IBao18E= z0wqy0ZVqr9emt5E59Binb&lwf6^WD;SAzmLvWJBg#T&V%P=b_paG(H@=t_$OYDw+of4#PJ zi8`pB%UYyIri4+IlZ29SVmbi0F}g zGTLtL9@Px|T2^<7884w^uUOws%5M{}B(Vu;eYMLZx2N-SJ;js;e_i4o5O}f;k1H&( z54-Nt1?t&Fs0AnA8<>ygxb~6`=aDulwDfBm4vIs20E)$`NOd*{MqU9Rs3$Mj zR{U5>tqjH9L~|H2`Lk5dCu+{5@z#^h7s|Minm+f~xEN%KQ=*h*VX#PUvJ|gW0~bVQ zG(57!nj$M3*HO8hK>h?>qllAKWe8CuxUbqB`gv#7Sn`V7cC?XsZTV&~$FoQwhzxD| zFg%*OtJEu}#|eu+8EXBEKY8_nD53gVR8NUlrzK7}`)b{UNZ4b{GJT|@>uBM;dZ3?A zm%Yn@Lu1k_n&cF`g?1X3@@f;^C+K^Emyu>iV|w>=uAT^5Pg&o+89$f)mTb_C@Y;e1 z?xdJNT;c_nydz>cXyX@~HH>uMqBy2C{VNXkPF~)hwujd19sECy4UJ8&?(Ixvzj7Qu z?t2xH{6gF4eu!UEJYRi@@EaOReSfgD=5Vm0sD7Yw;Z36Y;r7Y{40Se%Y@=9`QkY_> zXYml?3ACr!Ylk*_zRuSxaAd^EUZ2Ky1U9Xj>;VGl#I$}U&f!xlGC5=G;u#KBQq{}7 zYe##vEG0mmlwHK>%SQ7|zh`HP0c?gg9j)L-;K)J#1dgmqPjdQnrsTk-OJOUe!4VlCwg`&Ow^cVQ+}_`WtM0uikKbEu&k!`{8#DW}`tbAC^^@IaLi2~JxY$XL({mqao0%>h`6#@mn0Z|(RqSY)(aq?Xzo}D@G zP{dL`&wZ_UY929VCe-l(<#DO~ZaPCd7Uq&TlmkKCc5GA=u|37KaN2-65%ESAj=sIv z4biS1O7m;cvY8e}ED__k9%k2?UP{im*phi&OM$I+CKTgta;}|s7=7vit7a3~Qe!D8 zvgn~$oO{ldaAk&Q&4zYQ!#bwxZvA2?jn*>JJ@|f)0+nM?F2Ri zPv5hZu%7CK7QZNQZBnAMV|{KdMp*winmlun;QEv^htF)vq>F%Hsp;2hho7+^vGIvm z=HMI9ul|689%pM*<;_g3@>`)nHv*O7$ojlA9OVL3-jmDXX}05*i(L6FZlaHARo+>C ziSA~E#$xrK8}deJGW#9_ZEkrxLmP4Dmif28m}FGdfiK* z)?|&D`?*_09dt3MMXhFL;^HsQuB}Aplj6Q_E{nv{n5%Sm<{$Y)Y*G33S6AK>*Kx?~ z`K5v*P|WnY<@I7vW1Ff9j-ceRhBZ>LgXAV@tTX7N1<(ae{aA zn)z-T=GCIY0Ch`bh6AhUUr}*Lt*R^DY4BN50?al|bbB}2Y#&?7bH1wKXCVIOJ&UpT zarnlOrcC{KMP|eu^1mRsFZbe3-`HlbOsVkhte|#h@>aOmMtO=`cKMp)1l~KATg4N? z3C;uWW3E3P(h@kzvU#8OsHx22R%V)-ma6AH4E`L?z@r-aNLqcOz6#-X>cR8D@{F^p z)ydN>&RDVcfB+ouRv1Scz-Pg|=6{fJmW0tW5%$3IFa0s-$*Hk0*9m$-t!`b6^Puky zQ|KcFVq}4oRPqg%4%$qpKRetY%XqlcAt`mKB>SaVL|?2TTY5Nr@8*NAEqK0K*>~Uu z*~Xu8^)alYT^A>pqX&{Fo@RLa;XYz^$|#b}n>6;4$M zvh~-qvNS#VS(%&ZeOOvT{v21EZS|=mWR>`x))_4eHr|w2&t4UEqmB|&8C~QaW@ya< zhj`0pB3{@fDuD(67<$Q*lQr<&XmF};SPND^UJBP=NXDVDBjSDPR?#~i9hL+;xjZaZ^P%US z8;6oyZq6=%YE=U)iHfB(6E#2IcwK;b+`96b02F1!dAP9fvHdOr{T6^zn7NILD6>!p zEZx#o9+sD++*x=PUqQ=bYYB_O5*pP?Kwl<*!s{$qu9bRK+7$`D$7LEhy;~+zK$h3W zlNjL9i2|6e0^yV17|hR|$4RDZ5G~#!hDeFL5Y%;CRvz)O(_&1rz8o@BD|VeHC%&N_ z3F{aOG{#K#MkMeaLlH0e$!7Xf2)I-&=$Gq_vs~Ut*zd^2H8$Vs*NHnR@ik3PC-O}E zfNfKkGW#?tCtPJW1k(!|ffGW))kg&32ERw#4PlaIgGkCr#Q3~}Dt3~BpjY1u$vZFM zgwyW|?^@Y>48v#UON^EerdItNb~k2llR1pQt#Wb%4!rxQ6fEB?Q#~5?DPa~1lQ<*W zZc1=krkYZbBUasNViOk2+}xzK>|9AxGqxO9_O@0I4K7j!w~P9T%Y(5Qu;oI-dMrwuZgG(=I~DK$qjk5! zM5;vN;_EI}A!QJR>H8ZM%TQ&irwk4Sn6>-Dk}(+GGj=~c@V7}va&B8CGwOaJ+t!FJ zl*clyx&AzG$up2s_JIyV_jH?Ln>(#~H-RK)8PjnnRh^~3tl)J7=uO&Tu>0VaT!knK zgET3T6*9hz$v56;f%N8galZ;j4qkjw71BJ=wsWB{@&07_5oKsna8%@lB*u&1jnf!1 zJEt|GS_POA1H6{w(#JxF0`iTcSO|==Slu=9;G&LpW#XL;5pa2vw&P*W1XkNLGB_&S zjMC8&AISB%B854Jt=DQ2cDYy4EmGkVwjK%AW2^8~(Tlj2PWiH7hx0$oP`3i_t#i|$ z*tpB)t|B_=fss7Ife%25vEVdbXxD01NCVY|$_E)xa?|J#IhL)(&D(tC;6x+`iQ22r zA$dI2+ghI^^7(L}RN_%gnw5xcf*EgPd!bn9rzmLXw&@Y`;NoZT}TOEy*bc#Gbh zrVmP`DUNBI9a#`j46(%w@`6HEV#90Pi?d|+Fx-O)EC+-_lyY7(+(il-6Y_KmDU^yg zookHem7WwL(KF}!u5H<@_{v6Qg95@Mz62JYLW&>LJ=BvH?l0$+jC*Nw68gk4I?ByM zPKfmu&PCMzfw1H~^&zl-ySH#f>+Q6A?{^mMN~bmUWdsq9h>V1`?lyCwX%`w;LMiXN zXqDQ5=Nl{&nqupw3DS@FgF$zASKi+d;qahe6b}O>QY1nU(2WaySa+lNs3YprlCkmH z<6wOkI=yw54rR)qAtrkq_^!wCiO77pmmKV+ zQk6KAyKqz4Eag+AmkZcPw|M1jYFf4mfJjfijcBbU@$WOIm^=sX-E`zdPw$=7VodVQ z?APgOM?&oi+AC&CwKG?HgI$?`7VbCAP~61Q1vo^Er<|4VaFw8TA=rPwQurPgk)H&( zAJcDNSp8rKK!q5Fb)u--^f+{teSbK{GbS?g@TXHs3Ix~;_IQh|Nv@Q&G!w825Dp`# z^9B^Sng0QbS{RgBjHOYzlSIfS(d|tF+IhEDC{Q)PZtqpU`|2>NODjgUkxnCtv_M9) zY>Vd$8SY;FsL!qZ?ziUR*UGxjbeh;)Rf_aChOl9I^|Q}u2j1^2-?}>dsI2a-;H4 zP(HV+l$;CZycnzOwDWoA-iZ-CDL>qV;Pt9R7I#cdCIQhHQtfLlm_A1IMVNyH&5m_* zU^=E#Y89>0Mk4PGs=FLASnn~xIG6cRvXZn-ujr=+ptszp04DPL2LR&!m2Uu@)|h~d zpW7T%?h3P#kBe*Fn57jdIG+XIMp=S!O8EmAi?!^egQA5Mq=4 zAVJOQ(?=ZrWpq(|&^Pn^CH<3K1{<+qWzy9C!3d>jwyDDfGIXc~Ds(qVU3bjDzOeqN zamXcT0Socy!A+l5*oVwT>1>w^8cHjs4tEm2+J=$XzCO5DN6ydLY4??oo}Eq7Qqg%3 z#R02mJUVUW)uT&f>H63jVi^uek|lUP7Jd8;kjUS}rl`(oZNJq0<(1KC(6AYL>HYpz z*Y`KrV0g%mKYxD^_=CV71pY@Oz}G7j{QFFGNe)loZR~$Af6Zq25m_lI z_y&Cbo%>gtc@uxvj{Gu*mK5ZQ{df6x({p|=a9a+KPX*C|gNFp6RpDQT{H5@B;{JKI zN8+F>)TAAC(AA13cy3Oo^*@aM%wodNiF??)#jRxfxFEm54t!TMXKer9TiaTdh%W7g z?k?}AG=D^n98`6jyC=B#2z~vpe*!PhnZlpB{UnN9B=L|EkB}2+4n85`Uxd%ApO@+k z$q@#zn+$7E2VMH#JCDbFZj_+k@1T!t?X3e$pnxazADG`ceO`{I6Q) zL_6%a?0=*GkIWwg{vhxNf&W(s5TZBM=-|MQv%tT8y#WGXa6a^&nhc6Q@B3cb`3WZM zYdl2(;!L?N9xzwWO~jVJhN(>?A{c0SjhNCR+yKcelobr54jXc}KTL$&NyTmrlVfY{ zn}wl8N%QIf)9PpiOQ4taX5Q^$_e`# zH(MEIP?nb zV(qTln!6D@8Ee{->@I)WYicy>f)r*-wUr58>hhhq9}k|H!i$uM$1C#R zUqq6ez3--RSW*H}1a%T3kMMItyqHk~&3la6%6<{UZKC5Zy@yO3Xsih=@InmcPGK=i zB~L4z_FT9=vstt6Y<(~elHvWn9g2P#2n@kGe|hLfQ}-8=ps)n?mVX9|4p0YHm5)fa=n$&eG`@ z$~u{r)@PBsFc=)SxRsBC-1G=+vv`)QYEFa?bj(l-$iwhN5M3h4SA=6G`$9QkkSIyQ z=xGi_YjwPwM=B}zR=Oi`HP;^2E+`0BB#nUOp!CfY?f8N_HZ3Y9t9eDyL%XVqN2=4c zD=ride{au3L7-Gjy}UPhgh?ihWh>1OlG_5mxM%9c4w4HK0fPD23Z8P%M2PObFSWld z!jEmsrxY8wX_0|jcj4j}aUwT!uFG%fP{EiW4I2$=S4haPx?FEh&ohibXXj`|cbUVVg@6csz?P$7+?m;%=mUQ^D z3?Pi1Gq(MP%ABt=Bx3~->+p@{)dxwp=hv#Rq0Y7u@!nUKjz(A}K|4_hhP}>0>*GhB zjhcCuYFRHB)=-q@m0>}(KbhDuu*$Zd$OtF ze(>w0EhkY~=;;|N4Sv0UU)NZ6Jc5I9P^lVJ#`cVH6cSG4o_4d0Tt$>kU^gu|CT=|H zaTq1Fi^XD)>TbfDpg0tM@(_#xvo5}yg!Q%p84l%~O0Ul=SOrT-;TPQSr!pkorq)LY zDyvbDl0Z&-ZI?K4B<%|uADsfIYt*xppzt%!Q{D|3|G9KUEvv0p2UKS#pv_*VQ&<(s zRIeOfcUpV2AR*s1pW_|Bs7ms3qPSx8p}eLwnlw*&_J)^HDzT1L53nUuPT@I(gJS4_FpnC2rWn=N;p)6vyhP1mC{gw~x%-4=7 z)Dy=LrO|3q6nH(F+bMXTs*$2jhMqsGmGPxdw0qeZS;CdnQl^L492O@v+5SXWBcI5{ zlI2y~U#9U>rlh`_g9XX73muz@S4VY57WTTybQe9d!llL*HE*`cD!$ME^eRnYXtqG| zZO@1saE+HFCRilYio_|ddY9S!Gwakj2kZ|ik2LwvZ_%rK3FDlH@Ai>Y;zTJ%XFD{4 zjWq4|5q%kE9d}w=^hjn0>5l_6g`y0xS7OyvE|uyaQ8%eJpL*SmLBKUF3F>F1o0sxG z-kLMeTmfeA*i;@F3f?T{aS!v(ekl+0d%zeXWKTUYp6u!-x+$*CW|c*n;q&OJ?spI9 zD3-DldM0c~f5Y|Tp}x~r_MsTkyW);#$B+u*lQAUH^E?b6p?9aE zD{$yT=;CiJ45kdH1aBY#E5E7Je5d=Ti1hm>Z~oe`PIiyKx5Dgpu*%;6)xH|t#qOW zkT!KH{sowz#_k&-87*!3z6H%tIzht_~lpl+n6*kg_M~>;wn}QRPzPDg5wZhHC|#slGZ-~O2{NYG-Wumxs0(Fp!MS86PsmYT~B^K7Iw>_qf!pmnNXj+%3$Syt^Ptlx!m+~Ga zY~8vO?h|L8U*y_N=pDSdi&SHFko=P#MpWQQ(PwFG1uZiyA;wy2Z^8#4ryN?R&I zK_fE)7*gsTaW@jP%AS>B#$(Kr=gp+SRhG;;C2VUoc}ugX()Mg#g!XMryF4~>@0Nu~ zkW5o$jarTcJ)iz=FK;WozV)(AGe~=LK3Km2;V5NRSC!+fx?(1` zf+4ec;wHU#sz8}7qw)8z)<+hk&e2kG0&vcYDjX7lCfQ0(5|A*YOTB^?P@f=>uu%o9S+61yi` znnv3xtr2A6@;VdS`I8r`67G_x5;xro_5F^^^B*(gquUXM8o)=QVa61!^s7-*)4JMK zWAKcxoK%>8=N;H9%C$U?eP@C#&wa&Kgt7QEh7o%-1EYkM0)K{R6k&_;Pj$NZ6Dui4 zRqX2W70YAo(pzKZ9j}mu3eZFF)Qks)e2GLo$KnA7zWaKcT8JOj1)!A@MtM360#l0pJSM&d@;YuG45hw zi!MhxT>!^RSgc8DIH*(yP~K)d%Ew9rGdC@IYn&)_dEBqgItsmCNDO^eo_d-sVO z3_o%LN)9O`H{=jSP){;UIBHw7wdbZ%6 ztkucSe7ZZNBDN8YkLMSzfyA)hnoE8u=uy`|f*UWk(4eDRnh940fwWtmZ@jw7ptf2x f9o3S6udRpbC17y&%P~k#8L+zHa=exMZR&pkbrAx( diff --git a/public/static/jsonFormater/Collapsed.gif b/public/static/jsonFormater/Collapsed.gif deleted file mode 100644 index 17cbc27b321c010dc7f8e118c3a9fdddd26aec9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215 zcmZ?wbhEHblwsgzIKsg2|NsAg|9=1Z^XJ>Quiw6Y`1tYd`wy=_et7xz&9j#;AHR5Z z<*?;Ebt__E-?BBcL(2nJ`vv(L98#90n0g_mO;!hSvb_Q_< z9gr-@P6pPH2daH3ne)P3*6N5Z+~C1j!W&@d!@1|E@Qyp3MjBCU?XCe4iv)B6G?Fz} yg{->XJ=H~1L}1#HMUGd~wx_LIba8`)+ytY~PK_RF6?^8a%vu{)+}NbZU=09HV`3Qq diff --git a/public/static/jsonFormater/Expanded.gif b/public/static/jsonFormater/Expanded.gif deleted file mode 100644 index 2aa74410fc1d4b5ff2eddf807c2fea896858e81a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206 zcmZ?wbhEHblwsgzIKsg2|NsAg|9=1Z^XJ>Quiw6Y`1tYd`wy=_et7xz&9j#;A3u0- z@9wROH*Q?KdG+-5%SWzVICkmG{xc_cZ8&sg|K1IUb}X-*y@LU42#~}I6o0ZXvNMP? z=zwHFb~3PfKTz#U$(%PmWNnV>!VM9OCA=YqF`SO~g?HRpX`~^>-?d;vh+@RN^Q}de pt32+|j2UHq`XK`Aba)o9_4yDyin+FDin{)zyDH2~alU^@T+ diff --git a/public/static/jsonFormater/jsonFormater.css b/public/static/jsonFormater/jsonFormater.css deleted file mode 100644 index 79c6909..0000000 --- a/public/static/jsonFormater/jsonFormater.css +++ /dev/null @@ -1,35 +0,0 @@ -@charset "utf-8"; -/* CSS Document */ -.jf-ObjectBrace { - color: #00AA00; - font-weight: bold; -} -.jf-ArrayBrace { - color: #0033FF; - font-weight: bold; -} -.jf-PropertyName { - color: #CC0000; - font-weight: bold; -} -.jf-String { - color: #007777; -} -.jf-Number { - color: #AA00AA; -} -.jf-Boolean { - color: #0000FF; -} -.jf-Null { - color: #0000FF; -} -.jf-Comma { - color: #000000; - font-weight: bold; -} -pre.jf-CodeContainer { - margin-top: 0; - margin-bottom: 0; - text-align: left; -} diff --git a/public/static/jsonFormater/jsonFormater.js b/public/static/jsonFormater/jsonFormater.js deleted file mode 100644 index f6995b3..0000000 --- a/public/static/jsonFormater/jsonFormater.js +++ /dev/null @@ -1,202 +0,0 @@ -function JsonFormater(opt) { - this.options = $.extend({ - dom: '', - tabSize: 2, - singleTab: " ", - quoteKeys: true, - imgCollapsed: "images/Collapsed.gif", - imgExpanded: "images/Expanded.gif", - isCollapsible: true - }, opt || {}); - this.isFormated = false; - this.obj = { - _dateObj: new Date(), - _regexpObj: new RegExp() - }; - this.init(); -} -JsonFormater.prototype = { - init: function () { - this.tab = this.multiplyString(this.options.tabSize, this.options.singleTab); - this.bindEvent(); - }, - doFormat: function (json) { - var html; - var obj; - try { - if(typeof json == 'object'){ - obj = [json]; - }else{ - if (json == ""){ - json = "\"\""; - } - obj = eval("[" + json + "]"); - } - html = this.ProcessObject(obj[0], 0, false, false, false); - $(this.options.dom).addClass('jf-CodeContainer'); - $(this.options.dom).html(html); - this.isFormated = true; - } catch (e) { - alert("JSON数据格式不正确:\n" + e.message); - $(this.options.dom).html(""); - this.isFormated = false; - } - }, - bindEvent: function () { - var that = this; - $(this.options.dom).off('click','.imgToggle'); - $(this.options.dom).on('click', '.imgToggle', function () { - if (that.isFormated == false) { - return; - } - that.makeContentVisible($(this).parent().next(), !$(this).data('status')); - }); - }, - expandAll: function () { - if (this.isFormated == false) { - return; - } - var that = this; - this.traverseChildren($(this.options.dom), function(element){ - if(element.hasClass('jf-collapsible')){ - that.makeContentVisible(element, true); - } - }, 0); - }, - collapseAll: function () { - if (this.isFormated == false) { - return; - } - var that = this; - this.traverseChildren($(this.options.dom), function(element){ - if(element.hasClass('jf-collapsible')){ - that.makeContentVisible(element, false); - } - }, 0); - }, - collapseLevel: function(level){ - if (this.isFormated == false) { - return; - } - var that = this; - this.traverseChildren($(this.options.dom), function(element, depth){ - if(element.hasClass('jf-collapsible')){ - if(depth >= level){ - that.makeContentVisible(element, false); - }else{ - that.makeContentVisible(element, true); - } - } - }, 0); - - }, - isArray: function (obj) { - return obj && - typeof obj === 'object' && - typeof obj.length === 'number' && !(obj.propertyIsEnumerable('length')); - }, - getRow: function (indent, data, isPropertyContent) { - var tabs = ""; - if (!isPropertyContent) { - tabs = this.multiplyString(indent, this.tab); - } - if (data != null && data.length > 0 && data.charAt(data.length - 1) != "\n") { - data = data + "\n"; - } - return tabs + data; - }, - formatLiteral: function (literal, quote, comma, indent, isArray, style) { - if (typeof literal == 'string') { - literal = literal.split("<").join("<").split(">").join(">"); - } - var str = "" + quote + literal + quote + comma + ""; - if (isArray) str = this.getRow(indent, str); - return str; - }, - formatFunction: function (indent, obj) { - var tabs; - var i; - var funcStrArray = obj.toString().split("\n"); - var str = ""; - tabs = this.multiplyString(indent, this.tab); - for (i = 0; i < funcStrArray.length; i++) { - str += ((i == 0) ? "" : tabs) + funcStrArray[i] + "\n"; - } - return str; - }, - multiplyString: function (num, str) { - var result = ''; - for (var i = 0; i < num; i++) { - result += str; - } - return result; - }, - traverseChildren: function (element, func, depth) { - var length = element.children().length; - for (var i = 0; i < length; i++) { - this.traverseChildren(element.children().eq(i), func, depth + 1); - } - func(element, depth); - }, - makeContentVisible : function(element, visible){ - var img = element.prev().find('img'); - if(visible){ - element.show(); - img.attr('src', this.options.imgExpanded); - img.data('status', 1); - }else{ - element.hide(); - img.attr('src', this.options.imgCollapsed); - img.data('status', 0); - } - }, - ProcessObject: function (obj, indent, addComma, isArray, isPropertyContent) { - var html = ""; - var comma = (addComma) ? ", " : ""; - var type = typeof obj; - var clpsHtml = ""; - var prop; - if (this.isArray(obj)) { - if (obj.length == 0) { - html += this.getRow(indent, "[ ]" + comma, isPropertyContent); - } else { - clpsHtml = this.options.isCollapsible ? "" : ""; - html += this.getRow(indent, "[" + clpsHtml, isPropertyContent); - for (var i = 0; i < obj.length; i++) { - html += this.ProcessObject(obj[i], indent + 1, i < (obj.length - 1), true, false); - } - clpsHtml = this.options.isCollapsible ? "" : ""; - html += this.getRow(indent, clpsHtml + "]" + comma); - } - } else if (type == 'object') { - if (obj == null) { - html += this.formatLiteral("null", "", comma, indent, isArray, "Null"); - } else { - var numProps = 0; - for (prop in obj) numProps++; - if (numProps == 0) { - html += this.getRow(indent, "{ }" + comma, isPropertyContent); - } else { - clpsHtml = this.options.isCollapsible ? "" : ""; - html += this.getRow(indent, "{" + clpsHtml, isPropertyContent); - var j = 0; - for (prop in obj) { - var quote = this.options.quoteKeys ? "\"" : ""; - html += this.getRow(indent + 1, "" + quote + prop + quote + ": " + this.ProcessObject(obj[prop], indent + 1, ++j < numProps, false, true)); - } - clpsHtml = this.options.isCollapsible ? "" : ""; - html += this.getRow(indent, clpsHtml + "}" + comma); - } - } - } else if (type == 'number') { - html += this.formatLiteral(obj, "", comma, indent, isArray, "Number"); - } else if (type == 'boolean') { - html += this.formatLiteral(obj, "", comma, indent, isArray, "Boolean"); - }else if (type == 'undefined') { - html += this.formatLiteral("undefined", "", comma, indent, isArray, "Null"); - } else { - html += this.formatLiteral(obj.toString().split("\\").join("\\\\").split('"').join('\\"'), "\"", comma, indent, isArray, "String"); - } - return html; - } -}; diff --git a/runtime/index.html b/runtime/index.html deleted file mode 100644 index e69de29..0000000 diff --git a/think b/think deleted file mode 100644 index 4e2688f..0000000 --- a/think +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env php - -// +---------------------------------------------------------------------- - -// 定义项目路径 -define('APP_PATH', __DIR__ . '/application/'); - -// 加载框架引导文件 -require __DIR__.'/thinkphp/console.php'; diff --git a/thinkphp/.gitignore b/thinkphp/.gitignore deleted file mode 100755 index 7e31ef5..0000000 --- a/thinkphp/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/composer.lock -/vendor -.idea -.DS_Store diff --git a/thinkphp/.htaccess b/thinkphp/.htaccess deleted file mode 100755 index 3418e55..0000000 --- a/thinkphp/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all \ No newline at end of file diff --git a/thinkphp/.travis.yml b/thinkphp/.travis.yml deleted file mode 100755 index f74ffca..0000000 --- a/thinkphp/.travis.yml +++ /dev/null @@ -1,47 +0,0 @@ -sudo: false - -language: php - -services: - - memcached - - mongodb - - mysql - - postgresql - - redis-server - -matrix: - fast_finish: true - include: - - php: 5.4 - - php: 5.5 - - php: 5.6 - - php: 7.0 - - php: hhvm - allow_failures: - - php: hhvm - -cache: - directories: - - $HOME/.composer/cache - -before_install: - - composer self-update - - mysql -e "create database IF NOT EXISTS test;" -uroot - - psql -c 'DROP DATABASE IF EXISTS test;' -U postgres - - psql -c 'create database test;' -U postgres - -install: - - ./tests/script/install.sh - -script: - ## LINT - - find . -path ./vendor -prune -o -type f -name \*.php -exec php -l {} \; - ## PHP Copy/Paste Detector - - vendor/bin/phpcpd --verbose --exclude vendor ./ || true - ## PHPLOC - - vendor/bin/phploc --exclude vendor ./ - ## PHPUNIT - - vendor/bin/phpunit --coverage-clover=coverage.xml --configuration=phpunit.xml - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/thinkphp/CONTRIBUTING.md b/thinkphp/CONTRIBUTING.md deleted file mode 100755 index dc8e91c..0000000 --- a/thinkphp/CONTRIBUTING.md +++ /dev/null @@ -1,119 +0,0 @@ -如何贡献我的源代码 -=== - -此文档介绍了 ThinkPHP 团队的组成以及运转机制,您提交的代码将给 ThinkPHP 项目带来什么好处,以及如何才能加入我们的行列。 - -## 通过 Github 贡献代码 - -ThinkPHP 目前使用 Git 来控制程序版本,如果你想为 ThinkPHP 贡献源代码,请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上,任何 GitHub 用户都可以向我们贡献代码。 - -参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。 - -我们希望你贡献的代码符合: - -* ThinkPHP 的编码规范 -* 适当的注释,能让其他人读懂 -* 遵循 Apache2 开源协议 - -**如果想要了解更多细节或有任何疑问,请继续阅读下面的内容** - -### 注意事项 - -* 本项目代码格式化标准选用 [**PSR-2**](http://www.kancloud.cn/thinkphp/php-fig-psr/3141); -* 类名和类文件名遵循 [**PSR-4**](http://www.kancloud.cn/thinkphp/php-fig-psr/3144); -* 对于 Issues 的处理,请使用诸如 `fix #xxx(Issue ID)` 的 commit title 直接关闭 issue。 -* 系统会自动在 PHP 5.4 5.5 5.6 7.0 和 HHVM 上测试修改,其中 HHVM 下的测试容许报错,请确保你的修改符合 PHP 5.4 ~ 5.6 和 PHP 7.0 的语法规范; -* 管理员不会合并造成 CI faild 的修改,若出现 CI faild 请检查自己的源代码或修改相应的[单元测试文件](tests); - -## GitHub Issue - -GitHub 提供了 Issue 功能,该功能可以用于: - -* 提出 bug -* 提出功能改进 -* 反馈使用体验 - -该功能不应该用于: - - * 提出修改意见(涉及代码署名和修订追溯问题) - * 不友善的言论 - -## 快速修改 - -**GitHub 提供了快速编辑文件的功能** - -1. 登录 GitHub 帐号; -2. 浏览项目文件,找到要进行修改的文件; -3. 点击右上角铅笔图标进行修改; -4. 填写 `Commit changes` 相关内容(Title 必填); -5. 提交修改,等待 CI 验证和管理员合并。 - -**若您需要一次提交大量修改,请继续阅读下面的内容** - -## 完整流程 - -1. `fork`本项目; -2. 克隆(`clone`)你 `fork` 的项目到本地; -3. 新建分支(`branch`)并检出(`checkout`)新分支; -4. 添加本项目到你的本地 git 仓库作为上游(`upstream`); -5. 进行修改,若你的修改包含方法或函数的增减,请记得修改[单元测试文件](tests); -6. 变基(衍合 `rebase`)你的分支到上游 master 分支; -7. `push` 你的本地仓库到 GitHub; -8. 提交 `pull request`; -9. 等待 CI 验证(若不通过则重复 5~7,不需要重新提交 `pull request`,GitHub 会自动更新你的 `pull request`); -10. 等待管理员处理,并及时 `rebase` 你的分支到上游 master 分支(若上游 master 分支有修改)。 - -*若有必要,可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`* - -*绝对不可以使用 `git push -f` 强行推送修改到上游* - -### 注意事项 - -* 若对上述流程有任何不清楚的地方,请查阅 GIT 教程,如 [这个](http://backlogtool.com/git-guide/cn/); -* 对于代码**不同方面**的修改,请在自己 `fork` 的项目中**创建不同的分支**(原因参见`完整流程`第9条备注部分); -* 变基及交互式变基操作参见 [Git 交互式变基](http://pakchoi.me/2015/03/17/git-interactive-rebase/) - -## 推荐资源 - -### 开发环境 - -* XAMPP for Windows 5.5.x -* WampServer (for Windows) -* upupw Apache PHP5.4 ( for Windows) - -或自行安装 - -- Apache / Nginx -- PHP 5.4 ~ 5.6 -- MySQL / MariaDB - -*Windows 用户推荐添加 PHP bin 目录到 PATH,方便使用 composer* - -*Linux 用户自行配置环境, Mac 用户推荐使用内置 Apache 配合 Homebrew 安装 PHP 和 MariaDB* - -### 编辑器 - -Sublime Text 3 + phpfmt 插件 - -phpfmt 插件参数 - -```json -{ - "autocomplete": true, - "enable_auto_align": true, - "format_on_save": true, - "indent_with_space": true, - "psr1_naming": false, - "psr2": true, - "version": 4 -} -``` - -或其他 编辑器 / IDE 配合 PSR2 自动格式化工具 - -### Git GUI - -* SourceTree -* GitHub Desktop - -或其他 Git 图形界面客户端 diff --git a/thinkphp/LICENSE.txt b/thinkphp/LICENSE.txt deleted file mode 100755 index 2cb9a8a..0000000 --- a/thinkphp/LICENSE.txt +++ /dev/null @@ -1,32 +0,0 @@ - -ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 -版权所有Copyright © 2006-2017 by ThinkPHP (http://thinkphp.cn) -All rights reserved。 -ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 - -Apache Licence是著名的非盈利开源组织Apache采用的协议。 -该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, -允许代码修改,再作为开源或商业软件发布。需要满足 -的条件: -1. 需要给代码的用户一份Apache Licence ; -2. 如果你修改了代码,需要在被修改的文件中说明; -3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 -带有原来代码中的协议,商标,专利声明和其他原来作者规 -定需要包含的说明; -4. 如果再发布的产品中包含一个Notice文件,则在Notice文 -件中需要带有本协议内容。你可以在Notice中增加自己的 -许可,但不可以表现为对Apache Licence构成更改。 -具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/thinkphp/README.md b/thinkphp/README.md deleted file mode 100755 index f01fd2b..0000000 --- a/thinkphp/README.md +++ /dev/null @@ -1,114 +0,0 @@ -ThinkPHP 5.0 -=============== - -[![StyleCI](https://styleci.io/repos/48530411/shield?style=flat&branch=master)](https://styleci.io/repos/48530411) -[![Build Status](https://travis-ci.org/top-think/framework.svg?branch=master)](https://travis-ci.org/top-think/framework) -[![codecov.io](http://codecov.io/github/top-think/framework/coverage.svg?branch=master)](http://codecov.io/github/github/top-think/framework?branch=master) -[![Total Downloads](https://poser.pugx.org/topthink/framework/downloads)](https://packagist.org/packages/topthink/framework) -[![Latest Stable Version](https://poser.pugx.org/topthink/framework/v/stable)](https://packagist.org/packages/topthink/framework) -[![Latest Unstable Version](https://poser.pugx.org/topthink/framework/v/unstable)](https://packagist.org/packages/topthink/framework) -[![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework) - -ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PHP版本要求提升到5.4,优化核心,减少依赖,基于全新的架构思想和命名空间实现,是ThinkPHP突破原有框架思路的颠覆之作,其主要特性包括: - - + 基于命名空间和众多PHP新特性 - + 核心功能组件化 - + 强化路由功能 - + 更灵活的控制器 - + 重构的模型和数据库类 - + 配置文件可分离 - + 重写的自动验证和完成 - + 简化扩展机制 - + API支持完善 - + 改进的Log类 - + 命令行访问支持 - + REST支持 - + 引导文件支持 - + 方便的自动生成定义 - + 真正惰性加载 - + 分布式环境支持 - + 支持Composer - + 支持MongoDb - -> ThinkPHP5的运行环境要求PHP5.4以上。 - -详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) 以及[ThinkPHP5入门系列教程](http://www.kancloud.cn/special/thinkphp5_quickstart) - -## 目录结构 - -初始的目录结构如下: - -~~~ -www WEB部署目录(或者子目录) -├─application 应用目录 -│ ├─common 公共模块目录(可以更改) -│ ├─module_name 模块目录 -│ │ ├─config.php 模块配置文件 -│ │ ├─common.php 模块函数文件 -│ │ ├─controller 控制器目录 -│ │ ├─model 模型目录 -│ │ ├─view 视图目录 -│ │ └─ ... 更多类库目录 -│ │ -│ ├─command.php 命令行工具配置文件 -│ ├─common.php 公共函数文件 -│ ├─config.php 公共配置文件 -│ ├─route.php 路由配置文件 -│ ├─tags.php 应用行为扩展定义文件 -│ └─database.php 数据库配置文件 -│ -├─public WEB目录(对外访问目录) -│ ├─index.php 入口文件 -│ ├─router.php 快速测试文件 -│ └─.htaccess 用于apache的重写 -│ -├─thinkphp 框架系统目录 -│ ├─lang 语言文件目录 -│ ├─library 框架类库目录 -│ │ ├─think Think类库包目录 -│ │ └─traits 系统Trait目录 -│ │ -│ ├─tpl 系统模板目录 -│ ├─base.php 基础定义文件 -│ ├─console.php 控制台入口文件 -│ ├─convention.php 框架惯例配置文件 -│ ├─helper.php 助手函数文件 -│ ├─phpunit.xml phpunit配置文件 -│ └─start.php 框架入口文件 -│ -├─extend 扩展类库目录 -├─runtime 应用的运行时目录(可写,可定制) -├─vendor 第三方类库目录(Composer依赖库) -├─build.php 自动生成定义文件(参考) -├─composer.json composer 定义文件 -├─LICENSE.txt 授权说明文件 -├─README.md README 文件 -├─think 命令行入口文件 -~~~ - -> router.php用于php自带webserver支持,可用于快速测试 -> 切换到public目录后,启动命令:php -S localhost:8888 router.php -> 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。 - -## 命名规范 - -ThinkPHP5的命名规范遵循`PSR-2`规范以及`PSR-4`自动加载规范。 - -## 参与开发 -注册并登录 Github 帐号, fork 本项目并进行改动。 - -更多细节参阅 [CONTRIBUTING.md](CONTRIBUTING.md) - -## 版权信息 - -ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 - -本项目包含的第三方源码和二进制文件之版权信息另行标注。 - -版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn) - -All rights reserved。 - -ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 - -更多细节参阅 [LICENSE.txt](LICENSE.txt) diff --git a/thinkphp/base.php b/thinkphp/base.php deleted file mode 100755 index 86c585b..0000000 --- a/thinkphp/base.php +++ /dev/null @@ -1,65 +0,0 @@ - -// +---------------------------------------------------------------------- - -define('THINK_VERSION', '5.0.23'); -define('THINK_START_TIME', microtime(true)); -define('THINK_START_MEM', memory_get_usage()); -define('EXT', '.php'); -define('DS', DIRECTORY_SEPARATOR); -defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS); -define('LIB_PATH', THINK_PATH . 'library' . DS); -define('CORE_PATH', LIB_PATH . 'think' . DS); -define('TRAIT_PATH', LIB_PATH . 'traits' . DS); -defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS); -defined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS); -defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS); -defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS); -defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS); -defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS); -defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS); -defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS); -defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录 -defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀 -defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀 - -// 环境常量 -define('IS_CLI', PHP_SAPI == 'cli' ? true : false); -define('IS_WIN', strpos(PHP_OS, 'WIN') !== false); - -// 载入Loader类 -require CORE_PATH . 'Loader.php'; - -// 加载环境变量配置文件 -if (is_file(ROOT_PATH . '.env')) { - $env = parse_ini_file(ROOT_PATH . '.env', true); - - foreach ($env as $key => $val) { - $name = ENV_PREFIX . strtoupper($key); - - if (is_array($val)) { - foreach ($val as $k => $v) { - $item = $name . '_' . strtoupper($k); - putenv("$item=$v"); - } - } else { - putenv("$name=$val"); - } - } -} - -// 注册自动加载 -\think\Loader::register(); - -// 注册错误和异常处理机制 -\think\Error::register(); - -// 加载惯例配置文件 -\think\Config::set(include THINK_PATH . 'convention' . EXT); diff --git a/thinkphp/codecov.yml b/thinkphp/codecov.yml deleted file mode 100755 index bef9d64..0000000 --- a/thinkphp/codecov.yml +++ /dev/null @@ -1,12 +0,0 @@ -comment: - layout: header, changes, diff -coverage: - ignore: - - base.php - - helper.php - - convention.php - - lang/zh-cn.php - - start.php - - console.php - status: - patch: false diff --git a/thinkphp/composer.json b/thinkphp/composer.json deleted file mode 100755 index c546e11..0000000 --- a/thinkphp/composer.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "topthink/framework", - "description": "the new thinkphp framework", - "type": "think-framework", - "keywords": [ - "framework", - "thinkphp", - "ORM" - ], - "homepage": "http://thinkphp.cn/", - "license": "Apache-2.0", - "authors": [ - { - "name": "liu21st", - "email": "liu21st@gmail.com" - } - ], - "require": { - "php": ">=5.4.0", - "topthink/think-installer": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "4.8.*", - "johnkary/phpunit-speedtrap": "^1.0", - "mikey179/vfsStream": "~1.6", - "phploc/phploc": "2.*", - "sebastian/phpcpd": "2.*", - "phpdocumentor/reflection-docblock": "^2.0" - }, - "autoload": { - "psr-4": { - "think\\": "library/think" - } - } -} diff --git a/thinkphp/console.php b/thinkphp/console.php deleted file mode 100755 index 578e4a7..0000000 --- a/thinkphp/console.php +++ /dev/null @@ -1,20 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -// ThinkPHP 引导文件 -// 加载基础文件 -require __DIR__ . '/base.php'; - -// 执行应用 -App::initCommon(); -Console::init(); diff --git a/thinkphp/convention.php b/thinkphp/convention.php deleted file mode 100755 index 31a0a0c..0000000 --- a/thinkphp/convention.php +++ /dev/null @@ -1,298 +0,0 @@ - '', - // 应用调试模式 - 'app_debug' => false, - // 应用Trace - 'app_trace' => false, - // 应用模式状态 - 'app_status' => '', - // 是否支持多模块 - 'app_multi_module' => true, - // 入口自动绑定模块 - 'auto_bind_module' => false, - // 注册的根命名空间 - 'root_namespace' => [], - // 扩展函数文件 - 'extra_file_list' => [THINK_PATH . 'helper' . EXT], - // 默认输出类型 - 'default_return_type' => 'html', - // 默认AJAX 数据返回格式,可选json xml ... - 'default_ajax_return' => 'json', - // 默认JSONP格式返回的处理方法 - 'default_jsonp_handler' => 'jsonpReturn', - // 默认JSONP处理方法 - 'var_jsonp_handler' => 'callback', - // 默认时区 - 'default_timezone' => 'PRC', - // 是否开启多语言 - 'lang_switch_on' => false, - // 默认全局过滤方法 用逗号分隔多个 - 'default_filter' => '', - // 默认语言 - 'default_lang' => 'zh-cn', - // 应用类库后缀 - 'class_suffix' => false, - // 控制器类后缀 - 'controller_suffix' => false, - - // +---------------------------------------------------------------------- - // | 模块设置 - // +---------------------------------------------------------------------- - - // 默认模块名 - 'default_module' => 'index', - // 禁止访问模块 - 'deny_module_list' => ['common'], - // 默认控制器名 - 'default_controller' => 'Index', - // 默认操作名 - 'default_action' => 'index', - // 默认验证器 - 'default_validate' => '', - // 默认的空控制器名 - 'empty_controller' => 'Error', - // 操作方法前缀 - 'use_action_prefix' => false, - // 操作方法后缀 - 'action_suffix' => '', - // 自动搜索控制器 - 'controller_auto_search' => false, - - // +---------------------------------------------------------------------- - // | URL设置 - // +---------------------------------------------------------------------- - - // PATHINFO变量名 用于兼容模式 - 'var_pathinfo' => 's', - // 兼容PATH_INFO获取 - 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], - // pathinfo分隔符 - 'pathinfo_depr' => '/', - // HTTPS代理标识 - 'https_agent_name' => '', - // URL伪静态后缀 - 'url_html_suffix' => 'html', - // URL普通方式参数 用于自动生成 - 'url_common_param' => false, - // URL参数方式 0 按名称成对解析 1 按顺序解析 - 'url_param_type' => 0, - // 是否开启路由 - 'url_route_on' => true, - // 路由配置文件(支持配置多个) - 'route_config_file' => ['route'], - // 路由使用完整匹配 - 'route_complete_match' => false, - // 是否强制使用路由 - 'url_route_must' => false, - // 域名部署 - 'url_domain_deploy' => false, - // 域名根,如thinkphp.cn - 'url_domain_root' => '', - // 是否自动转换URL中的控制器和操作名 - 'url_convert' => true, - // 默认的访问控制器层 - 'url_controller_layer' => 'controller', - // 表单请求类型伪装变量 - 'var_method' => '_method', - // 表单ajax伪装变量 - 'var_ajax' => '_ajax', - // 表单pjax伪装变量 - 'var_pjax' => '_pjax', - // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 - 'request_cache' => false, - // 请求缓存有效期 - 'request_cache_expire' => null, - // 全局请求缓存排除规则 - 'request_cache_except' => [], - - // +---------------------------------------------------------------------- - // | 模板设置 - // +---------------------------------------------------------------------- - - 'template' => [ - // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 - 'auto_rule' => 1, - // 模板引擎类型 支持 php think 支持扩展 - 'type' => 'Think', - // 视图基础目录,配置目录为所有模块的视图起始目录 - 'view_base' => '', - // 当前模板的视图目录 留空为自动获取 - 'view_path' => '', - // 模板后缀 - 'view_suffix' => 'html', - // 模板文件名分隔符 - 'view_depr' => DS, - // 模板引擎普通标签开始标记 - 'tpl_begin' => '{', - // 模板引擎普通标签结束标记 - 'tpl_end' => '}', - // 标签库标签开始标记 - 'taglib_begin' => '{', - // 标签库标签结束标记 - 'taglib_end' => '}', - ], - - // 视图输出字符串内容替换 - 'view_replace_str' => [], - // 默认跳转页面对应的模板文件 - 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', - 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', - - // +---------------------------------------------------------------------- - // | 异常及错误设置 - // +---------------------------------------------------------------------- - - // 异常页面的模板文件 - 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl', - - // 错误显示信息,非调试模式有效 - 'error_message' => '页面错误!请稍后再试~', - // 显示错误信息 - 'show_error_msg' => false, - // 异常处理handle类 留空使用 \think\exception\Handle - 'exception_handle' => '', - // 是否记录trace信息到日志 - 'record_trace' => false, - - // +---------------------------------------------------------------------- - // | 日志设置 - // +---------------------------------------------------------------------- - - 'log' => [ - // 日志记录方式,内置 file socket 支持扩展 - 'type' => 'File', - // 日志保存目录 - 'path' => LOG_PATH, - // 日志记录级别 - 'level' => [], - ], - - // +---------------------------------------------------------------------- - // | Trace设置 开启 app_trace 后 有效 - // +---------------------------------------------------------------------- - 'trace' => [ - // 内置Html Console 支持扩展 - 'type' => 'Html', - ], - - // +---------------------------------------------------------------------- - // | 缓存设置 - // +---------------------------------------------------------------------- - - 'cache' => [ - // 驱动方式 - 'type' => 'File', - // 缓存保存目录 - 'path' => CACHE_PATH, - // 缓存前缀 - 'prefix' => '', - // 缓存有效期 0表示永久缓存 - 'expire' => 0, - ], - - // +---------------------------------------------------------------------- - // | 会话设置 - // +---------------------------------------------------------------------- - - 'session' => [ - 'id' => '', - // SESSION_ID的提交变量,解决flash上传跨域 - 'var_session_id' => '', - // SESSION 前缀 - 'prefix' => 'think', - // 驱动方式 支持redis memcache memcached - 'type' => '', - // 是否自动开启 SESSION - 'auto_start' => true, - 'httponly' => true, - 'secure' => false, - ], - - // +---------------------------------------------------------------------- - // | Cookie设置 - // +---------------------------------------------------------------------- - 'cookie' => [ - // cookie 名称前缀 - 'prefix' => '', - // cookie 保存时间 - 'expire' => 0, - // cookie 保存路径 - 'path' => '/', - // cookie 有效域名 - 'domain' => '', - // cookie 启用安全传输 - 'secure' => false, - // httponly设置 - 'httponly' => '', - // 是否使用 setcookie - 'setcookie' => true, - ], - - // +---------------------------------------------------------------------- - // | 数据库设置 - // +---------------------------------------------------------------------- - - 'database' => [ - // 数据库类型 - 'type' => 'mysql', - // 数据库连接DSN配置 - 'dsn' => '', - // 服务器地址 - 'hostname' => '127.0.0.1', - // 数据库名 - 'database' => '', - // 数据库用户名 - 'username' => 'root', - // 数据库密码 - 'password' => '', - // 数据库连接端口 - 'hostport' => '', - // 数据库连接参数 - 'params' => [], - // 数据库编码默认采用utf8 - 'charset' => 'utf8', - // 数据库表前缀 - 'prefix' => '', - // 数据库调试模式 - 'debug' => false, - // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'deploy' => 0, - // 数据库读写是否分离 主从式有效 - 'rw_separate' => false, - // 读写分离后 主服务器数量 - 'master_num' => 1, - // 指定从服务器序号 - 'slave_no' => '', - // 是否严格检查字段是否存在 - 'fields_strict' => true, - // 数据集返回类型 - 'resultset_type' => 'array', - // 自动写入时间戳字段 - 'auto_timestamp' => false, - // 时间字段取出后的默认时间格式 - 'datetime_format' => 'Y-m-d H:i:s', - // 是否需要进行SQL性能分析 - 'sql_explain' => false, - ], - - //分页配置 - 'paginate' => [ - 'type' => 'bootstrap', - 'var_page' => 'page', - 'list_rows' => 15, - ], - - //控制台配置 - 'console' => [ - 'name' => 'Think Console', - 'version' => '0.1', - 'user' => null, - ], - -]; diff --git a/thinkphp/helper.php b/thinkphp/helper.php deleted file mode 100755 index 12683cf..0000000 --- a/thinkphp/helper.php +++ /dev/null @@ -1,589 +0,0 @@ - -// +---------------------------------------------------------------------- - -//------------------------ -// ThinkPHP 助手函数 -//------------------------- - -use think\Cache; -use think\Config; -use think\Cookie; -use think\Db; -use think\Debug; -use think\exception\HttpException; -use think\exception\HttpResponseException; -use think\Lang; -use think\Loader; -use think\Log; -use think\Model; -use think\Request; -use think\Response; -use think\Session; -use think\Url; -use think\View; - -if (!function_exists('load_trait')) { - /** - * 快速导入Traits PHP5.5以上无需调用 - * @param string $class trait库 - * @param string $ext 类库后缀 - * @return boolean - */ - function load_trait($class, $ext = EXT) - { - return Loader::import($class, TRAIT_PATH, $ext); - } -} - -if (!function_exists('exception')) { - /** - * 抛出异常处理 - * - * @param string $msg 异常消息 - * @param integer $code 异常代码 默认为0 - * @param string $exception 异常类 - * - * @throws Exception - */ - function exception($msg, $code = 0, $exception = '') - { - $e = $exception ?: '\think\Exception'; - throw new $e($msg, $code); - } -} - -if (!function_exists('debug')) { - /** - * 记录时间(微秒)和内存使用情况 - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer|string $dec 小数位 如果是m 表示统计内存占用 - * @return mixed - */ - function debug($start, $end = '', $dec = 6) - { - if ('' == $end) { - Debug::remark($start); - } else { - return 'm' == $dec ? Debug::getRangeMem($start, $end) : Debug::getRangeTime($start, $end, $dec); - } - } -} - -if (!function_exists('lang')) { - /** - * 获取语言变量值 - * @param string $name 语言变量名 - * @param array $vars 动态变量值 - * @param string $lang 语言 - * @return mixed - */ - function lang($name, $vars = [], $lang = '') - { - return Lang::get($name, $vars, $lang); - } -} - -if (!function_exists('config')) { - /** - * 获取和设置配置参数 - * @param string|array $name 参数名 - * @param mixed $value 参数值 - * @param string $range 作用域 - * @return mixed - */ - function config($name = '', $value = null, $range = '') - { - if (is_null($value) && is_string($name)) { - return 0 === strpos($name, '?') ? Config::has(substr($name, 1), $range) : Config::get($name, $range); - } else { - return Config::set($name, $value, $range); - } - } -} - -if (!function_exists('input')) { - /** - * 获取输入数据 支持默认值和过滤 - * @param string $key 获取的变量名 - * @param mixed $default 默认值 - * @param string $filter 过滤方法 - * @return mixed - */ - function input($key = '', $default = null, $filter = '') - { - if (0 === strpos($key, '?')) { - $key = substr($key, 1); - $has = true; - } - if ($pos = strpos($key, '.')) { - // 指定参数来源 - list($method, $key) = explode('.', $key, 2); - if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) { - $key = $method . '.' . $key; - $method = 'param'; - } - } else { - // 默认为自动判断 - $method = 'param'; - } - if (isset($has)) { - return request()->has($key, $method, $default); - } else { - return request()->$method($key, $default, $filter); - } - } -} - -if (!function_exists('widget')) { - /** - * 渲染输出Widget - * @param string $name Widget名称 - * @param array $data 传入的参数 - * @return mixed - */ - function widget($name, $data = []) - { - return Loader::action($name, $data, 'widget'); - } -} - -if (!function_exists('model')) { - /** - * 实例化Model - * @param string $name Model名称 - * @param string $layer 业务层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @return \think\Model - */ - function model($name = '', $layer = 'model', $appendSuffix = false) - { - return Loader::model($name, $layer, $appendSuffix); - } -} - -if (!function_exists('validate')) { - /** - * 实例化验证器 - * @param string $name 验证器名称 - * @param string $layer 业务层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @return \think\Validate - */ - function validate($name = '', $layer = 'validate', $appendSuffix = false) - { - return Loader::validate($name, $layer, $appendSuffix); - } -} - -if (!function_exists('db')) { - /** - * 实例化数据库类 - * @param string $name 操作的数据表名称(不含前缀) - * @param array|string $config 数据库配置参数 - * @param bool $force 是否强制重新连接 - * @return \think\db\Query - */ - function db($name = '', $config = [], $force = false) - { - return Db::connect($config, $force)->name($name); - } -} - -if (!function_exists('controller')) { - /** - * 实例化控制器 格式:[模块/]控制器 - * @param string $name 资源地址 - * @param string $layer 控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @return \think\Controller - */ - function controller($name, $layer = 'controller', $appendSuffix = false) - { - return Loader::controller($name, $layer, $appendSuffix); - } -} - -if (!function_exists('action')) { - /** - * 调用模块的操作方法 参数格式 [模块/控制器/]操作 - * @param string $url 调用地址 - * @param string|array $vars 调用参数 支持字符串和数组 - * @param string $layer 要调用的控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @return mixed - */ - function action($url, $vars = [], $layer = 'controller', $appendSuffix = false) - { - return Loader::action($url, $vars, $layer, $appendSuffix); - } -} - -if (!function_exists('import')) { - /** - * 导入所需的类库 同java的Import 本函数有缓存功能 - * @param string $class 类库命名空间字符串 - * @param string $baseUrl 起始路径 - * @param string $ext 导入的文件扩展名 - * @return boolean - */ - function import($class, $baseUrl = '', $ext = EXT) - { - return Loader::import($class, $baseUrl, $ext); - } -} - -if (!function_exists('vendor')) { - /** - * 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面 - * @param string $class 类库 - * @param string $ext 类库后缀 - * @return boolean - */ - function vendor($class, $ext = EXT) - { - return Loader::import($class, VENDOR_PATH, $ext); - } -} - -if (!function_exists('dump')) { - /** - * 浏览器友好的变量输出 - * @param mixed $var 变量 - * @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串 - * @param string $label 标签 默认为空 - * @return void|string - */ - function dump($var, $echo = true, $label = null) - { - return Debug::dump($var, $echo, $label); - } -} - -if (!function_exists('url')) { - /** - * Url生成 - * @param string $url 路由地址 - * @param string|array $vars 变量 - * @param bool|string $suffix 生成的URL后缀 - * @param bool|string $domain 域名 - * @return string - */ - function url($url = '', $vars = '', $suffix = true, $domain = false) - { - return Url::build($url, $vars, $suffix, $domain); - } -} - -if (!function_exists('session')) { - /** - * Session管理 - * @param string|array $name session名称,如果为数组表示进行session设置 - * @param mixed $value session值 - * @param string $prefix 前缀 - * @return mixed - */ - function session($name, $value = '', $prefix = null) - { - if (is_array($name)) { - // 初始化 - Session::init($name); - } elseif (is_null($name)) { - // 清除 - Session::clear('' === $value ? null : $value); - } elseif ('' === $value) { - // 判断或获取 - return 0 === strpos($name, '?') ? Session::has(substr($name, 1), $prefix) : Session::get($name, $prefix); - } elseif (is_null($value)) { - // 删除 - return Session::delete($name, $prefix); - } else { - // 设置 - return Session::set($name, $value, $prefix); - } - } -} - -if (!function_exists('cookie')) { - /** - * Cookie管理 - * @param string|array $name cookie名称,如果为数组表示进行cookie设置 - * @param mixed $value cookie值 - * @param mixed $option 参数 - * @return mixed - */ - function cookie($name, $value = '', $option = null) - { - if (is_array($name)) { - // 初始化 - Cookie::init($name); - } elseif (is_null($name)) { - // 清除 - Cookie::clear($value); - } elseif ('' === $value) { - // 获取 - return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1), $option) : Cookie::get($name, $option); - } elseif (is_null($value)) { - // 删除 - return Cookie::delete($name); - } else { - // 设置 - return Cookie::set($name, $value, $option); - } - } -} - -if (!function_exists('cache')) { - /** - * 缓存管理 - * @param mixed $name 缓存名称,如果为数组表示进行缓存设置 - * @param mixed $value 缓存值 - * @param mixed $options 缓存参数 - * @param string $tag 缓存标签 - * @return mixed - */ - function cache($name, $value = '', $options = null, $tag = null) - { - if (is_array($options)) { - // 缓存操作的同时初始化 - $cache = Cache::connect($options); - } elseif (is_array($name)) { - // 缓存初始化 - return Cache::connect($name); - } else { - $cache = Cache::init(); - } - - if (is_null($name)) { - return $cache->clear($value); - } elseif ('' === $value) { - // 获取缓存 - return 0 === strpos($name, '?') ? $cache->has(substr($name, 1)) : $cache->get($name); - } elseif (is_null($value)) { - // 删除缓存 - return $cache->rm($name); - } elseif (0 === strpos($name, '?') && '' !== $value) { - $expire = is_numeric($options) ? $options : null; - return $cache->remember(substr($name, 1), $value, $expire); - } else { - // 缓存数据 - if (is_array($options)) { - $expire = isset($options['expire']) ? $options['expire'] : null; //修复查询缓存无法设置过期时间 - } else { - $expire = is_numeric($options) ? $options : null; //默认快捷缓存设置过期时间 - } - if (is_null($tag)) { - return $cache->set($name, $value, $expire); - } else { - return $cache->tag($tag)->set($name, $value, $expire); - } - } - } -} - -if (!function_exists('trace')) { - /** - * 记录日志信息 - * @param mixed $log log信息 支持字符串和数组 - * @param string $level 日志级别 - * @return void|array - */ - function trace($log = '[think]', $level = 'log') - { - if ('[think]' === $log) { - return Log::getLog(); - } else { - Log::record($log, $level); - } - } -} - -if (!function_exists('request')) { - /** - * 获取当前Request对象实例 - * @return Request - */ - function request() - { - return Request::instance(); - } -} - -if (!function_exists('response')) { - /** - * 创建普通 Response 对象实例 - * @param mixed $data 输出数据 - * @param int|string $code 状态码 - * @param array $header 头信息 - * @param string $type - * @return Response - */ - function response($data = [], $code = 200, $header = [], $type = 'html') - { - return Response::create($data, $type, $code, $header); - } -} - -if (!function_exists('view')) { - /** - * 渲染模板输出 - * @param string $template 模板文件 - * @param array $vars 模板变量 - * @param array $replace 模板替换 - * @param integer $code 状态码 - * @return \think\response\View - */ - function view($template = '', $vars = [], $replace = [], $code = 200) - { - return Response::create($template, 'view', $code)->replace($replace)->assign($vars); - } -} - -if (!function_exists('json')) { - /** - * 获取\think\response\Json对象实例 - * @param mixed $data 返回的数据 - * @param integer $code 状态码 - * @param array $header 头部 - * @param array $options 参数 - * @return \think\response\Json - */ - function json($data = [], $code = 200, $header = [], $options = []) - { - return Response::create($data, 'json', $code, $header, $options); - } -} - -if (!function_exists('jsonp')) { - /** - * 获取\think\response\Jsonp对象实例 - * @param mixed $data 返回的数据 - * @param integer $code 状态码 - * @param array $header 头部 - * @param array $options 参数 - * @return \think\response\Jsonp - */ - function jsonp($data = [], $code = 200, $header = [], $options = []) - { - return Response::create($data, 'jsonp', $code, $header, $options); - } -} - -if (!function_exists('xml')) { - /** - * 获取\think\response\Xml对象实例 - * @param mixed $data 返回的数据 - * @param integer $code 状态码 - * @param array $header 头部 - * @param array $options 参数 - * @return \think\response\Xml - */ - function xml($data = [], $code = 200, $header = [], $options = []) - { - return Response::create($data, 'xml', $code, $header, $options); - } -} - -if (!function_exists('redirect')) { - /** - * 获取\think\response\Redirect对象实例 - * @param mixed $url 重定向地址 支持Url::build方法的地址 - * @param array|integer $params 额外参数 - * @param integer $code 状态码 - * @param array $with 隐式传参 - * @return \think\response\Redirect - */ - function redirect($url = [], $params = [], $code = 302, $with = []) - { - if (is_integer($params)) { - $code = $params; - $params = []; - } - return Response::create($url, 'redirect', $code)->params($params)->with($with); - } -} - -if (!function_exists('abort')) { - /** - * 抛出HTTP异常 - * @param integer|Response $code 状态码 或者 Response对象实例 - * @param string $message 错误信息 - * @param array $header 参数 - */ - function abort($code, $message = null, $header = []) - { - if ($code instanceof Response) { - throw new HttpResponseException($code); - } else { - throw new HttpException($code, $message, null, $header); - } - } -} - -if (!function_exists('halt')) { - /** - * 调试变量并且中断输出 - * @param mixed $var 调试变量或者信息 - */ - function halt($var) - { - dump($var); - throw new HttpResponseException(new Response); - } -} - -if (!function_exists('token')) { - /** - * 生成表单令牌 - * @param string $name 令牌名称 - * @param mixed $type 令牌生成方法 - * @return string - */ - function token($name = '__token__', $type = 'md5') - { - $token = Request::instance()->token($name, $type); - return ''; - } -} - -if (!function_exists('load_relation')) { - /** - * 延迟预载入关联查询 - * @param mixed $resultSet 数据集 - * @param mixed $relation 关联 - * @return array - */ - function load_relation($resultSet, $relation) - { - $item = current($resultSet); - if ($item instanceof Model) { - $item->eagerlyResultSet($resultSet, $relation); - } - return $resultSet; - } -} - -if (!function_exists('collection')) { - /** - * 数组转换为数据集对象 - * @param array $resultSet 数据集数组 - * @return \think\model\Collection|\think\Collection - */ - function collection($resultSet) - { - $item = current($resultSet); - if ($item instanceof Model) { - return \think\model\Collection::make($resultSet); - } else { - return \think\Collection::make($resultSet); - } - } -} diff --git a/thinkphp/lang/zh-cn.php b/thinkphp/lang/zh-cn.php deleted file mode 100755 index eb7a914..0000000 --- a/thinkphp/lang/zh-cn.php +++ /dev/null @@ -1,136 +0,0 @@ - -// +---------------------------------------------------------------------- - -// 核心中文语言包 -return [ - // 系统错误提示 - 'Undefined variable' => '未定义变量', - 'Undefined index' => '未定义数组索引', - 'Undefined offset' => '未定义数组下标', - 'Parse error' => '语法解析错误', - 'Type error' => '类型错误', - 'Fatal error' => '致命错误', - 'syntax error' => '语法错误', - - // 框架核心错误提示 - 'dispatch type not support' => '不支持的调度类型', - 'method param miss' => '方法参数错误', - 'method not exists' => '方法不存在', - 'module not exists' => '模块不存在', - 'controller not exists' => '控制器不存在', - 'class not exists' => '类不存在', - 'property not exists' => '类的属性不存在', - 'template not exists' => '模板文件不存在', - 'illegal controller name' => '非法的控制器名称', - 'illegal action name' => '非法的操作名称', - 'url suffix deny' => '禁止的URL后缀访问', - 'Route Not Found' => '当前访问路由未定义', - 'Undefined db type' => '未定义数据库类型', - 'variable type error' => '变量类型错误', - 'PSR-4 error' => 'PSR-4 规范错误', - 'not support total' => '简洁模式下不能获取数据总数', - 'not support last' => '简洁模式下不能获取最后一页', - 'error session handler' => '错误的SESSION处理器类', - 'not allow php tag' => '模板不允许使用PHP语法', - 'not support' => '不支持', - 'redisd master' => 'Redisd 主服务器错误', - 'redisd slave' => 'Redisd 从服务器错误', - 'must run at sae' => '必须在SAE运行', - 'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务', - 'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务', - 'fields not exists' => '数据表字段不存在', - 'where express error' => '查询表达式错误', - 'not support data' => '不支持的数据表达式', - 'no data to update' => '没有任何数据需要更新', - 'miss data to insert' => '缺少需要写入的数据', - 'miss complex primary data' => '缺少复合主键数据', - 'miss update condition' => '缺少更新条件', - 'model data Not Found' => '模型数据不存在', - 'table data not Found' => '表数据不存在', - 'delete without condition' => '没有条件不会执行删除操作', - 'miss relation data' => '缺少关联表数据', - 'tag attr must' => '模板标签属性必须', - 'tag error' => '模板标签错误', - 'cache write error' => '缓存写入失败', - 'sae mc write error' => 'SAE mc 写入错误', - 'route name not exists' => '路由标识不存在(或参数不够)', - 'invalid request' => '非法请求', - 'bind attr has exists' => '模型的属性已经存在', - 'relation data not exists' => '关联数据不存在', - 'relation not support' => '关联不支持', - 'chunk not support order' => 'Chunk不支持调用order方法', - 'closure not support cache(true)' => '使用闭包查询不支持cache(true),请指定缓存Key', - - // 上传错误信息 - 'unknown upload error' => '未知上传错误!', - 'file write error' => '文件写入失败!', - 'upload temp dir not found' => '找不到临时文件夹!', - 'no file to uploaded' => '没有文件被上传!', - 'only the portion of file is uploaded' => '文件只有部分被上传!', - 'upload File size exceeds the maximum value' => '上传文件大小超过了最大值!', - 'upload write error' => '文件上传保存错误!', - 'has the same filename: {:filename}' => '存在同名文件:{:filename}', - 'upload illegal files' => '非法上传文件', - 'illegal image files' => '非法图片文件', - 'extensions to upload is not allowed' => '上传文件后缀不允许', - 'mimetype to upload is not allowed' => '上传文件MIME类型不允许!', - 'filesize not match' => '上传文件大小不符!', - 'directory {:path} creation failed' => '目录 {:path} 创建失败!', - - // Validate Error Message - ':attribute require' => ':attribute不能为空', - ':attribute must be numeric' => ':attribute必须是数字', - ':attribute must be integer' => ':attribute必须是整数', - ':attribute must be float' => ':attribute必须是浮点数', - ':attribute must be bool' => ':attribute必须是布尔值', - ':attribute not a valid email address' => ':attribute格式不符', - ':attribute not a valid mobile' => ':attribute格式不符', - ':attribute must be a array' => ':attribute必须是数组', - ':attribute must be yes,on or 1' => ':attribute必须是yes、on或者1', - ':attribute not a valid datetime' => ':attribute不是一个有效的日期或时间格式', - ':attribute not a valid file' => ':attribute不是有效的上传文件', - ':attribute not a valid image' => ':attribute不是有效的图像文件', - ':attribute must be alpha' => ':attribute只能是字母', - ':attribute must be alpha-numeric' => ':attribute只能是字母和数字', - ':attribute must be alpha-numeric, dash, underscore' => ':attribute只能是字母、数字和下划线_及破折号-', - ':attribute not a valid domain or ip' => ':attribute不是有效的域名或者IP', - ':attribute must be chinese' => ':attribute只能是汉字', - ':attribute must be chinese or alpha' => ':attribute只能是汉字、字母', - ':attribute must be chinese,alpha-numeric' => ':attribute只能是汉字、字母和数字', - ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', - ':attribute not a valid url' => ':attribute不是有效的URL地址', - ':attribute not a valid ip' => ':attribute不是有效的IP地址', - ':attribute must be dateFormat of :rule' => ':attribute必须使用日期格式 :rule', - ':attribute must be in :rule' => ':attribute必须在 :rule 范围内', - ':attribute be notin :rule' => ':attribute不能在 :rule 范围内', - ':attribute must between :1 - :2' => ':attribute只能在 :1 - :2 之间', - ':attribute not between :1 - :2' => ':attribute不能在 :1 - :2 之间', - 'size of :attribute must be :rule' => ':attribute长度不符合要求 :rule', - 'max size of :attribute must be :rule' => ':attribute长度不能超过 :rule', - 'min size of :attribute must be :rule' => ':attribute长度不能小于 :rule', - ':attribute cannot be less than :rule' => ':attribute日期不能小于 :rule', - ':attribute cannot exceed :rule' => ':attribute日期不能超过 :rule', - ':attribute not within :rule' => '不在有效期内 :rule', - 'access IP is not allowed' => '不允许的IP访问', - 'access IP denied' => '禁止的IP访问', - ':attribute out of accord with :2' => ':attribute和确认字段:2不一致', - ':attribute cannot be same with :2' => ':attribute和比较字段:2不能相同', - ':attribute must greater than or equal :rule' => ':attribute必须大于等于 :rule', - ':attribute must greater than :rule' => ':attribute必须大于 :rule', - ':attribute must less than or equal :rule' => ':attribute必须小于等于 :rule', - ':attribute must less than :rule' => ':attribute必须小于 :rule', - ':attribute must equal :rule' => ':attribute必须等于 :rule', - ':attribute has exists' => ':attribute已存在', - ':attribute not conform to the rules' => ':attribute不符合指定规则', - 'invalid Request method' => '无效的请求类型', - 'invalid token' => '令牌数据无效', - 'not conform to the rules' => '规则错误', -]; diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php deleted file mode 100755 index f572b90..0000000 --- a/thinkphp/library/think/App.php +++ /dev/null @@ -1,677 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\ClassNotFoundException; -use think\exception\HttpException; -use think\exception\HttpResponseException; -use think\exception\RouteNotFoundException; - -/** - * App 应用管理 - * @author liu21st - */ -class App -{ - /** - * @var bool 是否初始化过 - */ - protected static $init = false; - - /** - * @var string 当前模块路径 - */ - public static $modulePath; - - /** - * @var bool 应用调试模式 - */ - public static $debug = true; - - /** - * @var string 应用类库命名空间 - */ - public static $namespace = 'app'; - - /** - * @var bool 应用类库后缀 - */ - public static $suffix = false; - - /** - * @var bool 应用路由检测 - */ - protected static $routeCheck; - - /** - * @var bool 严格路由检测 - */ - protected static $routeMust; - - /** - * @var array 请求调度分发 - */ - protected static $dispatch; - - /** - * @var array 额外加载文件 - */ - protected static $file = []; - - /** - * 执行应用程序 - * @access public - * @param Request $request 请求对象 - * @return Response - * @throws Exception - */ - public static function run(Request $request = null) - { - $request = is_null($request) ? Request::instance() : $request; - - try { - $config = self::initCommon(); - - // 模块/控制器绑定 - if (defined('BIND_MODULE')) { - BIND_MODULE && Route::bind(BIND_MODULE); - } elseif ($config['auto_bind_module']) { - // 入口自动绑定 - $name = pathinfo($request->baseFile(), PATHINFO_FILENAME); - if ($name && 'index' != $name && is_dir(APP_PATH . $name)) { - Route::bind($name); - } - } - - $request->filter($config['default_filter']); - - // 默认语言 - Lang::range($config['default_lang']); - // 开启多语言机制 检测当前语言 - $config['lang_switch_on'] && Lang::detect(); - $request->langset(Lang::range()); - - // 加载系统语言包 - Lang::load([ - THINK_PATH . 'lang' . DS . $request->langset() . EXT, - APP_PATH . 'lang' . DS . $request->langset() . EXT, - ]); - - // 监听 app_dispatch - Hook::listen('app_dispatch', self::$dispatch); - // 获取应用调度信息 - $dispatch = self::$dispatch; - - // 未设置调度信息则进行 URL 路由检测 - if (empty($dispatch)) { - $dispatch = self::routeCheck($request, $config); - } - - // 记录当前调度信息 - $request->dispatch($dispatch); - - // 记录路由和请求信息 - if (self::$debug) { - Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info'); - Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info'); - Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info'); - } - - // 监听 app_begin - Hook::listen('app_begin', $dispatch); - - // 请求缓存检查 - $request->cache( - $config['request_cache'], - $config['request_cache_expire'], - $config['request_cache_except'] - ); - - $data = self::exec($dispatch, $config); - } catch (HttpResponseException $exception) { - $data = $exception->getResponse(); - } - - // 清空类的实例化 - Loader::clearInstance(); - - // 输出数据到客户端 - if ($data instanceof Response) { - $response = $data; - } elseif (!is_null($data)) { - // 默认自动识别响应输出类型 - $type = $request->isAjax() ? - Config::get('default_ajax_return') : - Config::get('default_return_type'); - - $response = Response::create($data, $type); - } else { - $response = Response::create(); - } - - // 监听 app_end - Hook::listen('app_end', $response); - - return $response; - } - - /** - * 初始化应用,并返回配置信息 - * @access public - * @return array - */ - public static function initCommon() - { - if (empty(self::$init)) { - if (defined('APP_NAMESPACE')) { - self::$namespace = APP_NAMESPACE; - } - - Loader::addNamespace(self::$namespace, APP_PATH); - - // 初始化应用 - $config = self::init(); - self::$suffix = $config['class_suffix']; - - // 应用调试模式 - self::$debug = Env::get('app_debug', Config::get('app_debug')); - - if (!self::$debug) { - ini_set('display_errors', 'Off'); - } elseif (!IS_CLI) { - // 重新申请一块比较大的 buffer - if (ob_get_level() > 0) { - $output = ob_get_clean(); - } - - ob_start(); - - if (!empty($output)) { - echo $output; - } - - } - - if (!empty($config['root_namespace'])) { - Loader::addNamespace($config['root_namespace']); - } - - // 加载额外文件 - if (!empty($config['extra_file_list'])) { - foreach ($config['extra_file_list'] as $file) { - $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; - if (is_file($file) && !isset(self::$file[$file])) { - include $file; - self::$file[$file] = true; - } - } - } - - // 设置系统时区 - date_default_timezone_set($config['default_timezone']); - - // 监听 app_init - Hook::listen('app_init'); - - self::$init = true; - } - - return Config::get(); - } - - /** - * 初始化应用或模块 - * @access public - * @param string $module 模块名 - * @return array - */ - private static function init($module = '') - { - // 定位模块目录 - $module = $module ? $module . DS : ''; - - // 加载初始化文件 - if (is_file(APP_PATH . $module . 'init' . EXT)) { - include APP_PATH . $module . 'init' . EXT; - } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) { - include RUNTIME_PATH . $module . 'init' . EXT; - } else { - // 加载模块配置 - $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT); - - // 读取数据库配置文件 - $filename = CONF_PATH . $module . 'database' . CONF_EXT; - Config::load($filename, 'database'); - - // 读取扩展配置文件 - if (is_dir(CONF_PATH . $module . 'extra')) { - $dir = CONF_PATH . $module . 'extra'; - $files = scandir($dir); - foreach ($files as $file) { - if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) { - $filename = $dir . DS . $file; - Config::load($filename, pathinfo($file, PATHINFO_FILENAME)); - } - } - } - - // 加载应用状态配置 - if ($config['app_status']) { - Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); - } - - // 加载行为扩展文件 - if (is_file(CONF_PATH . $module . 'tags' . EXT)) { - Hook::import(include CONF_PATH . $module . 'tags' . EXT); - } - - // 加载公共文件 - $path = APP_PATH . $module; - if (is_file($path . 'common' . EXT)) { - include $path . 'common' . EXT; - } - - // 加载当前模块语言包 - if ($module) { - Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT); - } - } - - return Config::get(); - } - - /** - * 设置当前请求的调度信息 - * @access public - * @param array|string $dispatch 调度信息 - * @param string $type 调度类型 - * @return void - */ - public static function dispatch($dispatch, $type = 'module') - { - self::$dispatch = ['type' => $type, $type => $dispatch]; - } - - /** - * 执行函数或者闭包方法 支持参数调用 - * @access public - * @param string|array|\Closure $function 函数或者闭包 - * @param array $vars 变量 - * @return mixed - */ - public static function invokeFunction($function, $vars = []) - { - $reflect = new \ReflectionFunction($function); - $args = self::bindParams($reflect, $vars); - - // 记录执行信息 - self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'); - - return $reflect->invokeArgs($args); - } - - /** - * 调用反射执行类的方法 支持参数绑定 - * @access public - * @param string|array $method 方法 - * @param array $vars 变量 - * @return mixed - */ - public static function invokeMethod($method, $vars = []) - { - if (is_array($method)) { - $class = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]); - $reflect = new \ReflectionMethod($class, $method[1]); - } else { - // 静态方法 - $reflect = new \ReflectionMethod($method); - } - - $args = self::bindParams($reflect, $vars); - - self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info'); - - return $reflect->invokeArgs(isset($class) ? $class : null, $args); - } - - /** - * 调用反射执行类的实例化 支持依赖注入 - * @access public - * @param string $class 类名 - * @param array $vars 变量 - * @return mixed - */ - public static function invokeClass($class, $vars = []) - { - $reflect = new \ReflectionClass($class); - $constructor = $reflect->getConstructor(); - $args = $constructor ? self::bindParams($constructor, $vars) : []; - - return $reflect->newInstanceArgs($args); - } - - /** - * 绑定参数 - * @access private - * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类 - * @param array $vars 变量 - * @return array - */ - private static function bindParams($reflect, $vars = []) - { - // 自动获取请求变量 - if (empty($vars)) { - $vars = Config::get('url_param_type') ? - Request::instance()->route() : - Request::instance()->param(); - } - - $args = []; - if ($reflect->getNumberOfParameters() > 0) { - // 判断数组类型 数字数组时按顺序绑定参数 - reset($vars); - $type = key($vars) === 0 ? 1 : 0; - - foreach ($reflect->getParameters() as $param) { - $args[] = self::getParamValue($param, $vars, $type); - } - } - - return $args; - } - - /** - * 获取参数值 - * @access private - * @param \ReflectionParameter $param 参数 - * @param array $vars 变量 - * @param string $type 类别 - * @return array - */ - private static function getParamValue($param, &$vars, $type) - { - $name = $param->getName(); - $class = $param->getClass(); - - if ($class) { - $className = $class->getName(); - $bind = Request::instance()->$name; - - if ($bind instanceof $className) { - $result = $bind; - } else { - if (method_exists($className, 'invoke')) { - $method = new \ReflectionMethod($className, 'invoke'); - - if ($method->isPublic() && $method->isStatic()) { - return $className::invoke(Request::instance()); - } - } - - $result = method_exists($className, 'instance') ? - $className::instance() : - new $className; - } - } elseif (1 == $type && !empty($vars)) { - $result = array_shift($vars); - } elseif (0 == $type && isset($vars[$name])) { - $result = $vars[$name]; - } elseif ($param->isDefaultValueAvailable()) { - $result = $param->getDefaultValue(); - } else { - throw new \InvalidArgumentException('method param miss:' . $name); - } - - return $result; - } - - /** - * 执行调用分发 - * @access protected - * @param array $dispatch 调用信息 - * @param array $config 配置信息 - * @return Response|mixed - * @throws \InvalidArgumentException - */ - protected static function exec($dispatch, $config) - { - switch ($dispatch['type']) { - case 'redirect': // 重定向跳转 - $data = Response::create($dispatch['url'], 'redirect') - ->code($dispatch['status']); - break; - case 'module': // 模块/控制器/操作 - $data = self::module( - $dispatch['module'], - $config, - isset($dispatch['convert']) ? $dispatch['convert'] : null - ); - break; - case 'controller': // 执行控制器操作 - $vars = array_merge(Request::instance()->param(), $dispatch['var']); - $data = Loader::action( - $dispatch['controller'], - $vars, - $config['url_controller_layer'], - $config['controller_suffix'] - ); - break; - case 'method': // 回调方法 - $vars = array_merge(Request::instance()->param(), $dispatch['var']); - $data = self::invokeMethod($dispatch['method'], $vars); - break; - case 'function': // 闭包 - $data = self::invokeFunction($dispatch['function']); - break; - case 'response': // Response 实例 - $data = $dispatch['response']; - break; - default: - throw new \InvalidArgumentException('dispatch type not support'); - } - - return $data; - } - - /** - * 执行模块 - * @access public - * @param array $result 模块/控制器/操作 - * @param array $config 配置参数 - * @param bool $convert 是否自动转换控制器和操作名 - * @return mixed - * @throws HttpException - */ - public static function module($result, $config, $convert = null) - { - if (is_string($result)) { - $result = explode('/', $result); - } - - $request = Request::instance(); - - if ($config['app_multi_module']) { - // 多模块部署 - $module = strip_tags(strtolower($result[0] ?: $config['default_module'])); - $bind = Route::getBind('module'); - $available = false; - - if ($bind) { - // 绑定模块 - list($bindModule) = explode('/', $bind); - - if (empty($result[0])) { - $module = $bindModule; - $available = true; - } elseif ($module == $bindModule) { - $available = true; - } - } elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) { - $available = true; - } - - // 模块初始化 - if ($module && $available) { - // 初始化模块 - $request->module($module); - $config = self::init($module); - - // 模块请求缓存检查 - $request->cache( - $config['request_cache'], - $config['request_cache_expire'], - $config['request_cache_except'] - ); - } else { - throw new HttpException(404, 'module not exists:' . $module); - } - } else { - // 单一模块部署 - $module = ''; - $request->module($module); - } - - // 设置默认过滤机制 - $request->filter($config['default_filter']); - - // 当前模块路径 - App::$modulePath = APP_PATH . ($module ? $module . DS : ''); - - // 是否自动转换控制器和操作名 - $convert = is_bool($convert) ? $convert : $config['url_convert']; - - // 获取控制器名 - $controller = strip_tags($result[1] ?: $config['default_controller']); - - if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) { - throw new HttpException(404, 'controller not exists:' . $controller); - } - - $controller = $convert ? strtolower($controller) : $controller; - - // 获取操作名 - $actionName = strip_tags($result[2] ?: $config['default_action']); - if (!empty($config['action_convert'])) { - $actionName = Loader::parseName($actionName, 1); - } else { - $actionName = $convert ? strtolower($actionName) : $actionName; - } - - // 设置当前请求的控制器、操作 - $request->controller(Loader::parseName($controller, 1))->action($actionName); - - // 监听module_init - Hook::listen('module_init', $request); - - try { - $instance = Loader::controller( - $controller, - $config['url_controller_layer'], - $config['controller_suffix'], - $config['empty_controller'] - ); - } catch (ClassNotFoundException $e) { - throw new HttpException(404, 'controller not exists:' . $e->getClass()); - } - - // 获取当前操作名 - $action = $actionName . $config['action_suffix']; - - $vars = []; - if (is_callable([$instance, $action])) { - // 执行操作方法 - $call = [$instance, $action]; - // 严格获取当前操作方法名 - $reflect = new \ReflectionMethod($instance, $action); - $methodName = $reflect->getName(); - $suffix = $config['action_suffix']; - $actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName; - $request->action($actionName); - - } elseif (is_callable([$instance, '_empty'])) { - // 空操作 - $call = [$instance, '_empty']; - $vars = [$actionName]; - } else { - // 操作不存在 - throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()'); - } - - Hook::listen('action_begin', $call); - - return self::invokeMethod($call, $vars); - } - - /** - * URL路由检测(根据PATH_INFO) - * @access public - * @param \think\Request $request 请求实例 - * @param array $config 配置信息 - * @return array - * @throws \think\Exception - */ - public static function routeCheck($request, array $config) - { - $path = $request->path(); - $depr = $config['pathinfo_depr']; - $result = false; - - // 路由检测 - $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; - if ($check) { - // 开启路由 - if (is_file(RUNTIME_PATH . 'route.php')) { - // 读取路由缓存 - $rules = include RUNTIME_PATH . 'route.php'; - is_array($rules) && Route::rules($rules); - } else { - $files = $config['route_config_file']; - foreach ($files as $file) { - if (is_file(CONF_PATH . $file . CONF_EXT)) { - // 导入路由配置 - $rules = include CONF_PATH . $file . CONF_EXT; - is_array($rules) && Route::import($rules); - } - } - } - - // 路由检测(根据路由定义返回不同的URL调度) - $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); - $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; - - if ($must && false === $result) { - // 路由无效 - throw new RouteNotFoundException(); - } - } - - // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 - if (false === $result) { - $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); - } - - return $result; - } - - /** - * 设置应用的路由检测机制 - * @access public - * @param bool $route 是否需要检测路由 - * @param bool $must 是否强制检测路由 - * @return void - */ - public static function route($route, $must = false) - { - self::$routeCheck = $route; - self::$routeMust = $must; - } -} diff --git a/thinkphp/library/think/Build.php b/thinkphp/library/think/Build.php deleted file mode 100755 index de7c327..0000000 --- a/thinkphp/library/think/Build.php +++ /dev/null @@ -1,235 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Build -{ - /** - * 根据传入的 build 资料创建目录和文件 - * @access public - * @param array $build build 列表 - * @param string $namespace 应用类库命名空间 - * @param bool $suffix 类库后缀 - * @return void - * @throws Exception - */ - public static function run(array $build = [], $namespace = 'app', $suffix = false) - { - // 锁定 - $lock = APP_PATH . 'build.lock'; - - // 如果锁定文件不可写(不存在)则进行处理,否则表示已经有程序在处理了 - if (!is_writable($lock)) { - if (!touch($lock)) { - throw new Exception( - '应用目录[' . APP_PATH . ']不可写,目录无法自动生成!
请手动生成项目目录~', - 10006 - ); - } - - foreach ($build as $module => $list) { - if ('__dir__' == $module) { - // 创建目录列表 - self::buildDir($list); - } elseif ('__file__' == $module) { - // 创建文件列表 - self::buildFile($list); - } else { - // 创建模块 - self::module($module, $list, $namespace, $suffix); - } - } - - // 解除锁定 - unlink($lock); - } - } - - /** - * 创建目录 - * @access protected - * @param array $list 目录列表 - * @return void - */ - protected static function buildDir($list) - { - foreach ($list as $dir) { - // 目录不存在则创建目录 - !is_dir(APP_PATH . $dir) && mkdir(APP_PATH . $dir, 0755, true); - } - } - - /** - * 创建文件 - * @access protected - * @param array $list 文件列表 - * @return void - */ - protected static function buildFile($list) - { - foreach ($list as $file) { - // 先创建目录 - if (!is_dir(APP_PATH . dirname($file))) { - mkdir(APP_PATH . dirname($file), 0755, true); - } - - // 再创建文件 - if (!is_file(APP_PATH . $file)) { - file_put_contents( - APP_PATH . $file, - 'php' == pathinfo($file, PATHINFO_EXTENSION) ? " ['config.php', 'common.php'], - '__dir__' => ['controller', 'model', 'view'], - ]; - } - - // 创建子目录和文件 - foreach ($list as $path => $file) { - $modulePath = APP_PATH . $module . DS; - - if ('__dir__' == $path) { - // 生成子目录 - foreach ($file as $dir) { - self::checkDirBuild($modulePath . $dir); - } - } elseif ('__file__' == $path) { - // 生成(空白)文件 - foreach ($file as $name) { - if (!is_file($modulePath . $name)) { - file_put_contents( - $modulePath . $name, - 'php' == pathinfo($name, PATHINFO_EXTENSION) ? " -// +---------------------------------------------------------------------- - -namespace think; - -use think\cache\Driver; - -class Cache -{ - /** - * @var array 缓存的实例 - */ - public static $instance = []; - - /** - * @var int 缓存读取次数 - */ - public static $readTimes = 0; - - /** - * @var int 缓存写入次数 - */ - public static $writeTimes = 0; - - /** - * @var object 操作句柄 - */ - public static $handler; - - /** - * 连接缓存驱动 - * @access public - * @param array $options 配置数组 - * @param bool|string $name 缓存连接标识 true 强制重新连接 - * @return Driver - */ - public static function connect(array $options = [], $name = false) - { - $type = !empty($options['type']) ? $options['type'] : 'File'; - - if (false === $name) { - $name = md5(serialize($options)); - } - - if (true === $name || !isset(self::$instance[$name])) { - $class = false === strpos($type, '\\') ? - '\\think\\cache\\driver\\' . ucwords($type) : - $type; - - // 记录初始化信息 - App::$debug && Log::record('[ CACHE ] INIT ' . $type, 'info'); - - if (true === $name) { - return new $class($options); - } - - self::$instance[$name] = new $class($options); - } - - return self::$instance[$name]; - } - - /** - * 自动初始化缓存 - * @access public - * @param array $options 配置数组 - * @return Driver - */ - public static function init(array $options = []) - { - if (is_null(self::$handler)) { - if (empty($options) && 'complex' == Config::get('cache.type')) { - $default = Config::get('cache.default'); - // 获取默认缓存配置,并连接 - $options = Config::get('cache.' . $default['type']) ?: $default; - } elseif (empty($options)) { - $options = Config::get('cache'); - } - - self::$handler = self::connect($options); - } - - return self::$handler; - } - - /** - * 切换缓存类型 需要配置 cache.type 为 complex - * @access public - * @param string $name 缓存标识 - * @return Driver - */ - public static function store($name = '') - { - if ('' !== $name && 'complex' == Config::get('cache.type')) { - return self::connect(Config::get('cache.' . $name), strtolower($name)); - } - - return self::init(); - } - - /** - * 判断缓存是否存在 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public static function has($name) - { - self::$readTimes++; - - return self::init()->has($name); - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存标识 - * @param mixed $default 默认值 - * @return mixed - */ - public static function get($name, $default = false) - { - self::$readTimes++; - - return self::init()->get($name, $default); - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存标识 - * @param mixed $value 存储数据 - * @param int|null $expire 有效时间 0为永久 - * @return boolean - */ - public static function set($name, $value, $expire = null) - { - self::$writeTimes++; - - return self::init()->set($name, $value, $expire); - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public static function inc($name, $step = 1) - { - self::$writeTimes++; - - return self::init()->inc($name, $step); - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public static function dec($name, $step = 1) - { - self::$writeTimes++; - - return self::init()->dec($name, $step); - } - - /** - * 删除缓存 - * @access public - * @param string $name 缓存标识 - * @return boolean - */ - public static function rm($name) - { - self::$writeTimes++; - - return self::init()->rm($name); - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return boolean - */ - public static function clear($tag = null) - { - self::$writeTimes++; - - return self::init()->clear($tag); - } - - /** - * 读取缓存并删除 - * @access public - * @param string $name 缓存变量名 - * @return mixed - */ - public static function pull($name) - { - self::$readTimes++; - self::$writeTimes++; - - return self::init()->pull($name); - } - - /** - * 如果不存在则写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param int $expire 有效时间 0为永久 - * @return mixed - */ - public static function remember($name, $value, $expire = null) - { - self::$readTimes++; - - return self::init()->remember($name, $value, $expire); - } - - /** - * 缓存标签 - * @access public - * @param string $name 标签名 - * @param string|array $keys 缓存标识 - * @param bool $overlay 是否覆盖 - * @return Driver - */ - public static function tag($name, $keys = null, $overlay = false) - { - return self::init()->tag($name, $keys, $overlay); - } - -} diff --git a/thinkphp/library/think/Collection.php b/thinkphp/library/think/Collection.php deleted file mode 100755 index 8e132b1..0000000 --- a/thinkphp/library/think/Collection.php +++ /dev/null @@ -1,457 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use ArrayAccess; -use ArrayIterator; -use Countable; -use IteratorAggregate; -use JsonSerializable; - -class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable -{ - /** - * @var array 数据 - */ - protected $items = []; - - /** - * Collection constructor. - * @access public - * @param array $items 数据 - */ - public function __construct($items = []) - { - $this->items = $this->convertToArray($items); - } - - /** - * 创建 Collection 实例 - * @access public - * @param array $items 数据 - * @return static - */ - public static function make($items = []) - { - return new static($items); - } - - /** - * 判断数据是否为空 - * @access public - * @return bool - */ - public function isEmpty() - { - return empty($this->items); - } - - /** - * 将数据转成数组 - * @access public - * @return array - */ - public function toArray() - { - return array_map(function ($value) { - return ($value instanceof Model || $value instanceof self) ? - $value->toArray() : - $value; - }, $this->items); - } - - /** - * 获取全部的数据 - * @access public - * @return array - */ - public function all() - { - return $this->items; - } - - /** - * 交换数组中的键和值 - * @access public - * @return static - */ - public function flip() - { - return new static(array_flip($this->items)); - } - - /** - * 返回数组中所有的键名组成的新 Collection 实例 - * @access public - * @return static - */ - public function keys() - { - return new static(array_keys($this->items)); - } - - /** - * 合并数组并返回一个新的 Collection 实例 - * @access public - * @param mixed $items 新的数据 - * @return static - */ - public function merge($items) - { - return new static(array_merge($this->items, $this->convertToArray($items))); - } - - /** - * 比较数组,返回差集生成的新 Collection 实例 - * @access public - * @param mixed $items 做比较的数据 - * @return static - */ - public function diff($items) - { - return new static(array_diff($this->items, $this->convertToArray($items))); - } - - /** - * 比较数组,返回交集组成的 Collection 新实例 - * @access public - * @param mixed $items 比较数据 - * @return static - */ - public function intersect($items) - { - return new static(array_intersect($this->items, $this->convertToArray($items))); - } - - /** - * 返回并删除数据中的的最后一个元素(出栈) - * @access public - * @return mixed - */ - public function pop() - { - return array_pop($this->items); - } - - /** - * 返回并删除数据中首个元素 - * @access public - * @return mixed - */ - public function shift() - { - return array_shift($this->items); - } - - /** - * 在数组开头插入一个元素 - * @access public - * @param mixed $value 值 - * @param mixed $key 键名 - * @return void - */ - public function unshift($value, $key = null) - { - if (is_null($key)) { - array_unshift($this->items, $value); - } else { - $this->items = [$key => $value] + $this->items; - } - } - - /** - * 在数组结尾插入一个元素 - * @access public - * @param mixed $value 值 - * @param mixed $key 键名 - * @return void - */ - public function push($value, $key = null) - { - if (is_null($key)) { - $this->items[] = $value; - } else { - $this->items[$key] = $value; - } - } - - /** - * 通过使用用户自定义函数,以字符串返回数组 - * @access public - * @param callable $callback 回调函数 - * @param mixed $initial 初始值 - * @return mixed - */ - public function reduce(callable $callback, $initial = null) - { - return array_reduce($this->items, $callback, $initial); - } - - /** - * 以相反的顺序创建一个新的 Collection 实例 - * @access public - * @return static - */ - public function reverse() - { - return new static(array_reverse($this->items)); - } - - /** - * 把数据分割为新的数组块 - * @access public - * @param int $size 分隔长度 - * @param bool $preserveKeys 是否保持原数据索引 - * @return static - */ - public function chunk($size, $preserveKeys = false) - { - $chunks = []; - - foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) { - $chunks[] = new static($chunk); - } - - return new static($chunks); - } - - /** - * 给数据中的每个元素执行回调 - * @access public - * @param callable $callback 回调函数 - * @return $this - */ - public function each(callable $callback) - { - foreach ($this->items as $key => $item) { - $result = $callback($item, $key); - - if (false === $result) { - break; - } - - if (!is_object($item)) { - $this->items[$key] = $result; - } - } - - return $this; - } - - /** - * 用回调函数过滤数据中的元素 - * @access public - * @param callable|null $callback 回调函数 - * @return static - */ - public function filter(callable $callback = null) - { - return new static(array_filter($this->items, $callback ?: null)); - } - - /** - * 返回数据中指定的一列 - * @access public - * @param mixed $columnKey 键名 - * @param null $indexKey 作为索引值的列 - * @return array - */ - public function column($columnKey, $indexKey = null) - { - if (function_exists('array_column')) { - return array_column($this->items, $columnKey, $indexKey); - } - - $result = []; - foreach ($this->items as $row) { - $key = $value = null; - $keySet = $valueSet = false; - - if (null !== $indexKey && array_key_exists($indexKey, $row)) { - $key = (string) $row[$indexKey]; - $keySet = true; - } - - if (null === $columnKey) { - $valueSet = true; - $value = $row; - } elseif (is_array($row) && array_key_exists($columnKey, $row)) { - $valueSet = true; - $value = $row[$columnKey]; - } - - if ($valueSet) { - if ($keySet) { - $result[$key] = $value; - } else { - $result[] = $value; - } - } - } - - return $result; - } - - /** - * 对数据排序,并返回排序后的数据组成的新 Collection 实例 - * @access public - * @param callable|null $callback 回调函数 - * @return static - */ - public function sort(callable $callback = null) - { - $items = $this->items; - $callback = $callback ?: function ($a, $b) { - return $a == $b ? 0 : (($a < $b) ? -1 : 1); - }; - - uasort($items, $callback); - return new static($items); - } - - /** - * 将数据打乱后组成新的 Collection 实例 - * @access public - * @return static - */ - public function shuffle() - { - $items = $this->items; - - shuffle($items); - return new static($items); - } - - /** - * 截取数据并返回新的 Collection 实例 - * @access public - * @param int $offset 起始位置 - * @param int $length 截取长度 - * @param bool $preserveKeys 是否保持原先的键名 - * @return static - */ - public function slice($offset, $length = null, $preserveKeys = false) - { - return new static(array_slice($this->items, $offset, $length, $preserveKeys)); - } - - /** - * 指定的键是否存在 - * @access public - * @param mixed $offset 键名 - * @return bool - */ - public function offsetExists($offset) - { - return array_key_exists($offset, $this->items); - } - - /** - * 获取指定键对应的值 - * @access public - * @param mixed $offset 键名 - * @return mixed - */ - public function offsetGet($offset) - { - return $this->items[$offset]; - } - - /** - * 设置键值 - * @access public - * @param mixed $offset 键名 - * @param mixed $value 值 - * @return void - */ - public function offsetSet($offset, $value) - { - if (is_null($offset)) { - $this->items[] = $value; - } else { - $this->items[$offset] = $value; - } - } - - /** - * 删除指定键值 - * @access public - * @param mixed $offset 键名 - * @return void - */ - public function offsetUnset($offset) - { - unset($this->items[$offset]); - } - - /** - * 统计数据的个数 - * @access public - * @return int - */ - public function count() - { - return count($this->items); - } - - /** - * 获取数据的迭代器 - * @access public - * @return ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->items); - } - - /** - * 将数据反序列化成数组 - * @access public - * @return array - */ - public function jsonSerialize() - { - return $this->toArray(); - } - - /** - * 转换当前数据集为 JSON 字符串 - * @access public - * @param integer $options json 参数 - * @return string - */ - public function toJson($options = JSON_UNESCAPED_UNICODE) - { - return json_encode($this->toArray(), $options); - } - - /** - * 将数据转换成字符串 - * @access public - * @return string - */ - public function __toString() - { - return $this->toJson(); - } - - /** - * 将数据转换成数组 - * @access protected - * @param mixed $items 数据 - * @return array - */ - protected function convertToArray($items) - { - return $items instanceof self ? $items->all() : (array) $items; - } -} diff --git a/thinkphp/library/think/Config.php b/thinkphp/library/think/Config.php deleted file mode 100755 index 8fa668d..0000000 --- a/thinkphp/library/think/Config.php +++ /dev/null @@ -1,214 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Config -{ - /** - * @var array 配置参数 - */ - private static $config = []; - - /** - * @var string 参数作用域 - */ - private static $range = '_sys_'; - - /** - * 设定配置参数的作用域 - * @access public - * @param string $range 作用域 - * @return void - */ - public static function range($range) - { - self::$range = $range; - - if (!isset(self::$config[$range])) self::$config[$range] = []; - } - - /** - * 解析配置文件或内容 - * @access public - * @param string $config 配置文件路径或内容 - * @param string $type 配置解析类型 - * @param string $name 配置名(如设置即表示二级配置) - * @param string $range 作用域 - * @return mixed - */ - public static function parse($config, $type = '', $name = '', $range = '') - { - $range = $range ?: self::$range; - - if (empty($type)) $type = pathinfo($config, PATHINFO_EXTENSION); - - $class = false !== strpos($type, '\\') ? - $type : - '\\think\\config\\driver\\' . ucwords($type); - - return self::set((new $class())->parse($config), $name, $range); - } - - /** - * 加载配置文件(PHP格式) - * @access public - * @param string $file 配置文件名 - * @param string $name 配置名(如设置即表示二级配置) - * @param string $range 作用域 - * @return mixed - */ - public static function load($file, $name = '', $range = '') - { - $range = $range ?: self::$range; - - if (!isset(self::$config[$range])) self::$config[$range] = []; - - if (is_file($file)) { - $name = strtolower($name); - $type = pathinfo($file, PATHINFO_EXTENSION); - - if ('php' == $type) { - return self::set(include $file, $name, $range); - } - - if ('yaml' == $type && function_exists('yaml_parse_file')) { - return self::set(yaml_parse_file($file), $name, $range); - } - - return self::parse($file, $type, $name, $range); - } - - return self::$config[$range]; - } - - /** - * 检测配置是否存在 - * @access public - * @param string $name 配置参数名(支持二级配置 . 号分割) - * @param string $range 作用域 - * @return bool - */ - public static function has($name, $range = '') - { - $range = $range ?: self::$range; - - if (!strpos($name, '.')) { - return isset(self::$config[$range][strtolower($name)]); - } - - // 二维数组设置和获取支持 - $name = explode('.', $name, 2); - return isset(self::$config[$range][strtolower($name[0])][$name[1]]); - } - - /** - * 获取配置参数 为空则获取所有配置 - * @access public - * @param string $name 配置参数名(支持二级配置 . 号分割) - * @param string $range 作用域 - * @return mixed - */ - public static function get($name = null, $range = '') - { - $range = $range ?: self::$range; - - // 无参数时获取所有 - if (empty($name) && isset(self::$config[$range])) { - return self::$config[$range]; - } - - // 非二级配置时直接返回 - if (!strpos($name, '.')) { - $name = strtolower($name); - return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null; - } - - // 二维数组设置和获取支持 - $name = explode('.', $name, 2); - $name[0] = strtolower($name[0]); - - if (!isset(self::$config[$range][$name[0]])) { - // 动态载入额外配置 - $module = Request::instance()->module(); - $file = CONF_PATH . ($module ? $module . DS : '') . 'extra' . DS . $name[0] . CONF_EXT; - - is_file($file) && self::load($file, $name[0]); - } - - return isset(self::$config[$range][$name[0]][$name[1]]) ? - self::$config[$range][$name[0]][$name[1]] : - null; - } - - /** - * 设置配置参数 name 为数组则为批量设置 - * @access public - * @param string|array $name 配置参数名(支持二级配置 . 号分割) - * @param mixed $value 配置值 - * @param string $range 作用域 - * @return mixed - */ - public static function set($name, $value = null, $range = '') - { - $range = $range ?: self::$range; - - if (!isset(self::$config[$range])) self::$config[$range] = []; - - // 字符串则表示单个配置设置 - if (is_string($name)) { - if (!strpos($name, '.')) { - self::$config[$range][strtolower($name)] = $value; - } else { - // 二维数组 - $name = explode('.', $name, 2); - self::$config[$range][strtolower($name[0])][$name[1]] = $value; - } - - return $value; - } - - // 数组则表示批量设置 - if (is_array($name)) { - if (!empty($value)) { - self::$config[$range][$value] = isset(self::$config[$range][$value]) ? - array_merge(self::$config[$range][$value], $name) : - $name; - - return self::$config[$range][$value]; - } - - return self::$config[$range] = array_merge( - self::$config[$range], array_change_key_case($name) - ); - } - - // 为空直接返回已有配置 - return self::$config[$range]; - } - - /** - * 重置配置参数 - * @access public - * @param string $range 作用域 - * @return void - */ - public static function reset($range = '') - { - $range = $range ?: self::$range; - - if (true === $range) { - self::$config = []; - } else { - self::$config[$range] = []; - } - } -} diff --git a/thinkphp/library/think/Console.php b/thinkphp/library/think/Console.php deleted file mode 100755 index 32b2572..0000000 --- a/thinkphp/library/think/Console.php +++ /dev/null @@ -1,863 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\console\Command; -use think\console\command\Help as HelpCommand; -use think\console\Input; -use think\console\input\Argument as InputArgument; -use think\console\input\Definition as InputDefinition; -use think\console\input\Option as InputOption; -use think\console\Output; -use think\console\output\driver\Buffer; - -class Console -{ - /** - * @var string 命令名称 - */ - private $name; - - /** - * @var string 命令版本 - */ - private $version; - - /** - * @var Command[] 命令 - */ - private $commands = []; - - /** - * @var bool 是否需要帮助信息 - */ - private $wantHelps = false; - - /** - * @var bool 是否捕获异常 - */ - private $catchExceptions = true; - - /** - * @var bool 是否自动退出执行 - */ - private $autoExit = true; - - /** - * @var InputDefinition 输入定义 - */ - private $definition; - - /** - * @var string 默认执行的命令 - */ - private $defaultCommand; - - /** - * @var array 默认提供的命令 - */ - private static $defaultCommands = [ - "think\\console\\command\\Help", - "think\\console\\command\\Lists", - "think\\console\\command\\Build", - "think\\console\\command\\Clear", - "think\\console\\command\\make\\Controller", - "think\\console\\command\\make\\Model", - "think\\console\\command\\optimize\\Autoload", - "think\\console\\command\\optimize\\Config", - "think\\console\\command\\optimize\\Route", - "think\\console\\command\\optimize\\Schema", - ]; - - /** - * Console constructor. - * @access public - * @param string $name 名称 - * @param string $version 版本 - * @param null|string $user 执行用户 - */ - public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN', $user = null) - { - $this->name = $name; - $this->version = $version; - - if ($user) { - $this->setUser($user); - } - - $this->defaultCommand = 'list'; - $this->definition = $this->getDefaultInputDefinition(); - - foreach ($this->getDefaultCommands() as $command) { - $this->add($command); - } - } - - /** - * 设置执行用户 - * @param $user - */ - public function setUser($user) - { - $user = posix_getpwnam($user); - if ($user) { - posix_setuid($user['uid']); - posix_setgid($user['gid']); - } - } - - /** - * 初始化 Console - * @access public - * @param bool $run 是否运行 Console - * @return int|Console - */ - public static function init($run = true) - { - static $console; - - if (!$console) { - $config = Config::get('console'); - // 实例化 console - $console = new self($config['name'], $config['version'], $config['user']); - - // 读取指令集 - if (is_file(CONF_PATH . 'command' . EXT)) { - $commands = include CONF_PATH . 'command' . EXT; - - if (is_array($commands)) { - foreach ($commands as $command) { - class_exists($command) && - is_subclass_of($command, "\\think\\console\\Command") && - $console->add(new $command()); // 注册指令 - } - } - } - } - - return $run ? $console->run() : $console; - } - - /** - * 调用命令 - * @access public - * @param string $command - * @param array $parameters - * @param string $driver - * @return Output - */ - public static function call($command, array $parameters = [], $driver = 'buffer') - { - $console = self::init(false); - - array_unshift($parameters, $command); - - $input = new Input($parameters); - $output = new Output($driver); - - $console->setCatchExceptions(false); - $console->find($command)->run($input, $output); - - return $output; - } - - /** - * 执行当前的指令 - * @access public - * @return int - * @throws \Exception - */ - public function run() - { - $input = new Input(); - $output = new Output(); - - $this->configureIO($input, $output); - - try { - $exitCode = $this->doRun($input, $output); - } catch (\Exception $e) { - if (!$this->catchExceptions) throw $e; - - $output->renderException($e); - - $exitCode = $e->getCode(); - - if (is_numeric($exitCode)) { - $exitCode = ((int) $exitCode) ?: 1; - } else { - $exitCode = 1; - } - } - - if ($this->autoExit) { - if ($exitCode > 255) $exitCode = 255; - - exit($exitCode); - } - - return $exitCode; - } - - /** - * 执行指令 - * @access public - * @param Input $input 输入 - * @param Output $output 输出 - * @return int - */ - public function doRun(Input $input, Output $output) - { - // 获取版本信息 - if (true === $input->hasParameterOption(['--version', '-V'])) { - $output->writeln($this->getLongVersion()); - - return 0; - } - - $name = $this->getCommandName($input); - - // 获取帮助信息 - if (true === $input->hasParameterOption(['--help', '-h'])) { - if (!$name) { - $name = 'help'; - $input = new Input(['help']); - } else { - $this->wantHelps = true; - } - } - - if (!$name) { - $name = $this->defaultCommand; - $input = new Input([$this->defaultCommand]); - } - - return $this->doRunCommand($this->find($name), $input, $output); - } - - /** - * 设置输入参数定义 - * @access public - * @param InputDefinition $definition 输入定义 - * @return $this; - */ - public function setDefinition(InputDefinition $definition) - { - $this->definition = $definition; - - return $this; - } - - /** - * 获取输入参数定义 - * @access public - * @return InputDefinition - */ - public function getDefinition() - { - return $this->definition; - } - - /** - * 获取帮助信息 - * @access public - * @return string - */ - public function getHelp() - { - return $this->getLongVersion(); - } - - /** - * 设置是否捕获异常 - * @access public - * @param bool $boolean 是否捕获 - * @return $this - */ - public function setCatchExceptions($boolean) - { - $this->catchExceptions = (bool) $boolean; - - return $this; - } - - /** - * 设置是否自动退出 - * @access public - * @param bool $boolean 是否自动退出 - * @return $this - */ - public function setAutoExit($boolean) - { - $this->autoExit = (bool) $boolean; - - return $this; - } - - /** - * 获取名称 - * @access public - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * 设置名称 - * @access public - * @param string $name 名称 - * @return $this - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * 获取版本 - * @access public - * @return string - */ - public function getVersion() - { - return $this->version; - } - - /** - * 设置版本 - * @access public - * @param string $version 版本信息 - * @return $this - */ - public function setVersion($version) - { - $this->version = $version; - - return $this; - } - - /** - * 获取完整的版本号 - * @access public - * @return string - */ - public function getLongVersion() - { - if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) { - return sprintf( - '%s version %s', - $this->getName(), - $this->getVersion() - ); - } - - return 'Console Tool'; - } - - /** - * 注册一个指令 - * @access public - * @param string $name 指令名称 - * @return Command - */ - public function register($name) - { - return $this->add(new Command($name)); - } - - /** - * 批量添加指令 - * @access public - * @param Command[] $commands 指令实例 - * @return $this - */ - public function addCommands(array $commands) - { - foreach ($commands as $command) $this->add($command); - - return $this; - } - - /** - * 添加一个指令 - * @access public - * @param Command $command 命令实例 - * @return Command|bool - */ - public function add(Command $command) - { - if (!$command->isEnabled()) { - $command->setConsole(null); - return false; - } - - $command->setConsole($this); - - if (null === $command->getDefinition()) { - throw new \LogicException( - sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)) - ); - } - - $this->commands[$command->getName()] = $command; - - foreach ($command->getAliases() as $alias) { - $this->commands[$alias] = $command; - } - - return $command; - } - - /** - * 获取指令 - * @access public - * @param string $name 指令名称 - * @return Command - * @throws \InvalidArgumentException - */ - public function get($name) - { - if (!isset($this->commands[$name])) { - throw new \InvalidArgumentException( - sprintf('The command "%s" does not exist.', $name) - ); - } - - $command = $this->commands[$name]; - - if ($this->wantHelps) { - $this->wantHelps = false; - - /** @var HelpCommand $helpCommand */ - $helpCommand = $this->get('help'); - $helpCommand->setCommand($command); - - return $helpCommand; - } - - return $command; - } - - /** - * 某个指令是否存在 - * @access public - * @param string $name 指令名称 - * @return bool - */ - public function has($name) - { - return isset($this->commands[$name]); - } - - /** - * 获取所有的命名空间 - * @access public - * @return array - */ - public function getNamespaces() - { - $namespaces = []; - - foreach ($this->commands as $command) { - $namespaces = array_merge( - $namespaces, $this->extractAllNamespaces($command->getName()) - ); - - foreach ($command->getAliases() as $alias) { - $namespaces = array_merge( - $namespaces, $this->extractAllNamespaces($alias) - ); - } - } - - return array_values(array_unique(array_filter($namespaces))); - } - - /** - * 查找注册命名空间中的名称或缩写 - * @access public - * @param string $namespace - * @return string - * @throws \InvalidArgumentException - */ - public function findNamespace($namespace) - { - $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { - return preg_quote($matches[1]) . '[^:]*'; - }, $namespace); - - $allNamespaces = $this->getNamespaces(); - $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); - - if (empty($namespaces)) { - $message = sprintf( - 'There are no commands defined in the "%s" namespace.', $namespace - ); - - if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { - if (1 == count($alternatives)) { - $message .= "\n\nDid you mean this?\n "; - } else { - $message .= "\n\nDid you mean one of these?\n "; - } - - $message .= implode("\n ", $alternatives); - } - - throw new \InvalidArgumentException($message); - } - - $exact = in_array($namespace, $namespaces, true); - - if (count($namespaces) > 1 && !$exact) { - throw new \InvalidArgumentException( - sprintf( - 'The namespace "%s" is ambiguous (%s).', - $namespace, - $this->getAbbreviationSuggestions(array_values($namespaces))) - ); - } - - return $exact ? $namespace : reset($namespaces); - } - - /** - * 查找指令 - * @access public - * @param string $name 名称或者别名 - * @return Command - * @throws \InvalidArgumentException - */ - public function find($name) - { - $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { - return preg_quote($matches[1]) . '[^:]*'; - }, $name); - - $allCommands = array_keys($this->commands); - $commands = preg_grep('{^' . $expr . '}', $allCommands); - - if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) { - if (false !== ($pos = strrpos($name, ':'))) { - $this->findNamespace(substr($name, 0, $pos)); - } - - $message = sprintf('Command "%s" is not defined.', $name); - - if ($alternatives = $this->findAlternatives($name, $allCommands)) { - if (1 == count($alternatives)) { - $message .= "\n\nDid you mean this?\n "; - } else { - $message .= "\n\nDid you mean one of these?\n "; - } - $message .= implode("\n ", $alternatives); - } - - throw new \InvalidArgumentException($message); - } - - if (count($commands) > 1) { - $commandList = $this->commands; - $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) { - $commandName = $commandList[$nameOrAlias]->getName(); - - return $commandName === $nameOrAlias || !in_array($commandName, $commands); - }); - } - - $exact = in_array($name, $commands, true); - if (count($commands) > 1 && !$exact) { - $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); - - throw new \InvalidArgumentException( - sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions) - ); - } - - return $this->get($exact ? $name : reset($commands)); - } - - /** - * 获取所有的指令 - * @access public - * @param string $namespace 命名空间 - * @return Command[] - */ - public function all($namespace = null) - { - if (null === $namespace) return $this->commands; - - $commands = []; - - foreach ($this->commands as $name => $command) { - $ext = $this->extractNamespace($name, substr_count($namespace, ':') + 1); - - if ($ext === $namespace) $commands[$name] = $command; - } - - return $commands; - } - - /** - * 获取可能的指令名 - * @access public - * @param array $names 指令名 - * @return array - */ - public static function getAbbreviations($names) - { - $abbrevs = []; - foreach ($names as $name) { - for ($len = strlen($name); $len > 0; --$len) { - $abbrev = substr($name, 0, $len); - $abbrevs[$abbrev][] = $name; - } - } - - return $abbrevs; - } - - /** - * 配置基于用户的参数和选项的输入和输出实例 - * @access protected - * @param Input $input 输入实例 - * @param Output $output 输出实例 - * @return void - */ - protected function configureIO(Input $input, Output $output) - { - if (true === $input->hasParameterOption(['--ansi'])) { - $output->setDecorated(true); - } elseif (true === $input->hasParameterOption(['--no-ansi'])) { - $output->setDecorated(false); - } - - if (true === $input->hasParameterOption(['--no-interaction', '-n'])) { - $input->setInteractive(false); - } - - if (true === $input->hasParameterOption(['--quiet', '-q'])) { - $output->setVerbosity(Output::VERBOSITY_QUIET); - } else { - if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) { - $output->setVerbosity(Output::VERBOSITY_DEBUG); - } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) { - $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE); - } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) { - $output->setVerbosity(Output::VERBOSITY_VERBOSE); - } - } - } - - /** - * 执行指令 - * @access protected - * @param Command $command 指令实例 - * @param Input $input 输入实例 - * @param Output $output 输出实例 - * @return int - * @throws \Exception - */ - protected function doRunCommand(Command $command, Input $input, Output $output) - { - return $command->run($input, $output); - } - - /** - * 获取指令的名称 - * @access protected - * @param Input $input 输入实例 - * @return string - */ - protected function getCommandName(Input $input) - { - return $input->getFirstArgument(); - } - - /** - * 获取默认输入定义 - * @access protected - * @return InputDefinition - */ - protected function getDefaultInputDefinition() - { - return new InputDefinition([ - new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), - new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'), - new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this console version'), - new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'), - new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), - new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'), - new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'), - new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'), - ]); - } - - /** - * 获取默认命令 - * @access protected - * @return Command[] - */ - protected function getDefaultCommands() - { - $defaultCommands = []; - - foreach (self::$defaultCommands as $class) { - if (class_exists($class) && is_subclass_of($class, "think\\console\\Command")) { - $defaultCommands[] = new $class(); - } - } - - return $defaultCommands; - } - - /** - * 添加默认指令 - * @access public - * @param array $classes 指令 - * @return void - */ - public static function addDefaultCommands(array $classes) - { - self::$defaultCommands = array_merge(self::$defaultCommands, $classes); - } - - /** - * 获取可能的建议 - * @access private - * @param array $abbrevs - * @return string - */ - private function getAbbreviationSuggestions($abbrevs) - { - return sprintf( - '%s, %s%s', - $abbrevs[0], - $abbrevs[1], - count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '' - ); - } - - /** - * 返回指令的命名空间部分 - * @access public - * @param string $name 指令名称 - * @param string $limit 部分的命名空间的最大数量 - * @return string - */ - public function extractNamespace($name, $limit = null) - { - $parts = explode(':', $name); - array_pop($parts); - - return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit)); - } - - /** - * 查找可替代的建议 - * @access private - * @param string $name 指令名称 - * @param array|\Traversable $collection 建议集合 - * @return array - */ - private function findAlternatives($name, $collection) - { - $threshold = 1e3; - $alternatives = []; - $collectionParts = []; - - foreach ($collection as $item) { - $collectionParts[$item] = explode(':', $item); - } - - foreach (explode(':', $name) as $i => $subname) { - foreach ($collectionParts as $collectionName => $parts) { - $exists = isset($alternatives[$collectionName]); - - if (!isset($parts[$i]) && $exists) { - $alternatives[$collectionName] += $threshold; - continue; - } elseif (!isset($parts[$i])) { - continue; - } - - $lev = levenshtein($subname, $parts[$i]); - - if ($lev <= strlen($subname) / 3 || - '' !== $subname && - false !== strpos($parts[$i], $subname) - ) { - $alternatives[$collectionName] = $exists ? - $alternatives[$collectionName] + $lev : - $lev; - } elseif ($exists) { - $alternatives[$collectionName] += $threshold; - } - } - } - - foreach ($collection as $item) { - $lev = levenshtein($name, $item); - - if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { - $alternatives[$item] = isset($alternatives[$item]) ? - $alternatives[$item] - $lev : - $lev; - } - } - - $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { - return $lev < 2 * $threshold; - }); - - asort($alternatives); - - return array_keys($alternatives); - } - - /** - * 设置默认的指令 - * @access public - * @param string $commandName 指令名称 - * @return $this - */ - public function setDefaultCommand($commandName) - { - $this->defaultCommand = $commandName; - - return $this; - } - - /** - * 返回所有的命名空间 - * @access private - * @param string $name 指令名称 - * @return array - */ - private function extractAllNamespaces($name) - { - $namespaces = []; - - foreach (explode(':', $name, -1) as $part) { - if (count($namespaces)) { - $namespaces[] = end($namespaces) . ':' . $part; - } else { - $namespaces[] = $part; - } - } - - return $namespaces; - } - -} diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php deleted file mode 100755 index 77225b7..0000000 --- a/thinkphp/library/think/Controller.php +++ /dev/null @@ -1,229 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\ValidateException; -use traits\controller\Jump; - -Loader::import('controller/Jump', TRAIT_PATH, EXT); - -class Controller -{ - use Jump; - - /** - * @var \think\View 视图类实例 - */ - protected $view; - - /** - * @var \think\Request Request 实例 - */ - protected $request; - - /** - * @var bool 验证失败是否抛出异常 - */ - protected $failException = false; - - /** - * @var bool 是否批量验证 - */ - protected $batchValidate = false; - - /** - * @var array 前置操作方法列表 - */ - protected $beforeActionList = []; - - /** - * 构造方法 - * @access public - * @param Request $request Request 对象 - */ - public function __construct(Request $request = null) - { - $this->view = View::instance(Config::get('template'), Config::get('view_replace_str')); - $this->request = is_null($request) ? Request::instance() : $request; - - // 控制器初始化 - $this->_initialize(); - - // 前置操作方法 - if ($this->beforeActionList) { - foreach ($this->beforeActionList as $method => $options) { - is_numeric($method) ? - $this->beforeAction($options) : - $this->beforeAction($method, $options); - } - } - } - - /** - * 初始化操作 - * @access protected - */ - protected function _initialize() - { - } - - /** - * 前置操作 - * @access protected - * @param string $method 前置操作方法名 - * @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]] - * @return void - */ - protected function beforeAction($method, $options = []) - { - if (isset($options['only'])) { - if (is_string($options['only'])) { - $options['only'] = explode(',', $options['only']); - } - - if (!in_array($this->request->action(), $options['only'])) { - return; - } - } elseif (isset($options['except'])) { - if (is_string($options['except'])) { - $options['except'] = explode(',', $options['except']); - } - - if (in_array($this->request->action(), $options['except'])) { - return; - } - } - - call_user_func([$this, $method]); - } - - /** - * 加载模板输出 - * @access protected - * @param string $template 模板文件名 - * @param array $vars 模板输出变量 - * @param array $replace 模板替换 - * @param array $config 模板参数 - * @return mixed - */ - protected function fetch($template = '', $vars = [], $replace = [], $config = []) - { - return $this->view->fetch($template, $vars, $replace, $config); - } - - /** - * 渲染内容输出 - * @access protected - * @param string $content 模板内容 - * @param array $vars 模板输出变量 - * @param array $replace 替换内容 - * @param array $config 模板参数 - * @return mixed - */ - protected function display($content = '', $vars = [], $replace = [], $config = []) - { - return $this->view->display($content, $vars, $replace, $config); - } - - /** - * 模板变量赋值 - * @access protected - * @param mixed $name 要显示的模板变量 - * @param mixed $value 变量的值 - * @return $this - */ - protected function assign($name, $value = '') - { - $this->view->assign($name, $value); - - return $this; - } - - /** - * 初始化模板引擎 - * @access protected - * @param array|string $engine 引擎参数 - * @return $this - */ - protected function engine($engine) - { - $this->view->engine($engine); - - return $this; - } - - /** - * 设置验证失败后是否抛出异常 - * @access protected - * @param bool $fail 是否抛出异常 - * @return $this - */ - protected function validateFailException($fail = true) - { - $this->failException = $fail; - - return $this; - } - - /** - * 验证数据 - * @access protected - * @param array $data 数据 - * @param string|array $validate 验证器名或者验证规则数组 - * @param array $message 提示信息 - * @param bool $batch 是否批量验证 - * @param mixed $callback 回调方法(闭包) - * @return array|string|true - * @throws ValidateException - */ - protected function validate($data, $validate, $message = [], $batch = false, $callback = null) - { - if (is_array($validate)) { - $v = Loader::validate(); - $v->rule($validate); - } else { - // 支持场景 - if (strpos($validate, '.')) { - list($validate, $scene) = explode('.', $validate); - } - - $v = Loader::validate($validate); - - !empty($scene) && $v->scene($scene); - } - - // 批量验证 - if ($batch || $this->batchValidate) { - $v->batch(true); - } - - // 设置错误信息 - if (is_array($message)) { - $v->message($message); - } - - // 使用回调验证 - if ($callback && is_callable($callback)) { - call_user_func_array($callback, [$v, &$data]); - } - - if (!$v->check($data)) { - if ($this->failException) { - throw new ValidateException($v->getError()); - } - - return $v->getError(); - } - - return true; - } -} diff --git a/thinkphp/library/think/Cookie.php b/thinkphp/library/think/Cookie.php deleted file mode 100755 index 61b47cc..0000000 --- a/thinkphp/library/think/Cookie.php +++ /dev/null @@ -1,268 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Cookie -{ - /** - * @var array cookie 设置参数 - */ - protected static $config = [ - 'prefix' => '', // cookie 名称前缀 - 'expire' => 0, // cookie 保存时间 - 'path' => '/', // cookie 保存路径 - 'domain' => '', // cookie 有效域名 - 'secure' => false, // cookie 启用安全传输 - 'httponly' => false, // httponly 设置 - 'setcookie' => true, // 是否使用 setcookie - ]; - - /** - * @var bool 是否完成初始化了 - */ - protected static $init; - - /** - * Cookie初始化 - * @access public - * @param array $config 配置参数 - * @return void - */ - public static function init(array $config = []) - { - if (empty($config)) { - $config = Config::get('cookie'); - } - - self::$config = array_merge(self::$config, array_change_key_case($config)); - - if (!empty(self::$config['httponly'])) { - ini_set('session.cookie_httponly', 1); - } - - self::$init = true; - } - - /** - * 设置或者获取 cookie 作用域(前缀) - * @access public - * @param string $prefix 前缀 - * @return string| - */ - public static function prefix($prefix = '') - { - if (empty($prefix)) { - return self::$config['prefix']; - } - - return self::$config['prefix'] = $prefix; - } - - /** - * Cookie 设置、获取、删除 - * @access public - * @param string $name cookie 名称 - * @param mixed $value cookie 值 - * @param mixed $option 可选参数 可能会是 null|integer|string - * @return void - */ - public static function set($name, $value = '', $option = null) - { - !isset(self::$init) && self::init(); - - // 参数设置(会覆盖黙认设置) - if (!is_null($option)) { - if (is_numeric($option)) { - $option = ['expire' => $option]; - } elseif (is_string($option)) { - parse_str($option, $option); - } - - $config = array_merge(self::$config, array_change_key_case($option)); - } else { - $config = self::$config; - } - - $name = $config['prefix'] . $name; - - // 设置 cookie - if (is_array($value)) { - array_walk_recursive($value, 'self::jsonFormatProtect', 'encode'); - $value = 'think:' . json_encode($value); - } - - $expire = !empty($config['expire']) ? - $_SERVER['REQUEST_TIME'] + intval($config['expire']) : - 0; - - if ($config['setcookie']) { - setcookie( - $name, $value, $expire, $config['path'], $config['domain'], - $config['secure'], $config['httponly'] - ); - } - - $_COOKIE[$name] = $value; - } - - /** - * 永久保存 Cookie 数据 - * @access public - * @param string $name cookie 名称 - * @param mixed $value cookie 值 - * @param mixed $option 可选参数 可能会是 null|integer|string - * @return void - */ - public static function forever($name, $value = '', $option = null) - { - if (is_null($option) || is_numeric($option)) { - $option = []; - } - - $option['expire'] = 315360000; - - self::set($name, $value, $option); - } - - /** - * 判断是否有 Cookie 数据 - * @access public - * @param string $name cookie 名称 - * @param string|null $prefix cookie 前缀 - * @return bool - */ - public static function has($name, $prefix = null) - { - !isset(self::$init) && self::init(); - - $prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; - - return isset($_COOKIE[$prefix . $name]); - } - - /** - * 获取 Cookie 的值 - * @access public - * @param string $name cookie 名称 - * @param string|null $prefix cookie 前缀 - * @return mixed - */ - public static function get($name = '', $prefix = null) - { - !isset(self::$init) && self::init(); - - $prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; - $key = $prefix . $name; - - if ('' == $name) { - // 获取全部 - if ($prefix) { - $value = []; - - foreach ($_COOKIE as $k => $val) { - if (0 === strpos($k, $prefix)) { - $value[$k] = $val; - } - - } - } else { - $value = $_COOKIE; - } - } elseif (isset($_COOKIE[$key])) { - $value = $_COOKIE[$key]; - - if (0 === strpos($value, 'think:')) { - $value = json_decode(substr($value, 6), true); - array_walk_recursive($value, 'self::jsonFormatProtect', 'decode'); - } - } else { - $value = null; - } - - return $value; - } - - /** - * 删除 Cookie - * @access public - * @param string $name cookie 名称 - * @param string|null $prefix cookie 前缀 - * @return void - */ - public static function delete($name, $prefix = null) - { - !isset(self::$init) && self::init(); - - $config = self::$config; - $prefix = !is_null($prefix) ? $prefix : $config['prefix']; - $name = $prefix . $name; - - if ($config['setcookie']) { - setcookie( - $name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], - $config['domain'], $config['secure'], $config['httponly'] - ); - } - - // 删除指定 cookie - unset($_COOKIE[$name]); - } - - /** - * 清除指定前缀的所有 cookie - * @access public - * @param string|null $prefix cookie 前缀 - * @return void - */ - public static function clear($prefix = null) - { - if (empty($_COOKIE)) { - return; - } - - !isset(self::$init) && self::init(); - - // 要删除的 cookie 前缀,不指定则删除 config 设置的指定前缀 - $config = self::$config; - $prefix = !is_null($prefix) ? $prefix : $config['prefix']; - - if ($prefix) { - foreach ($_COOKIE as $key => $val) { - if (0 === strpos($key, $prefix)) { - if ($config['setcookie']) { - setcookie( - $key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], - $config['domain'], $config['secure'], $config['httponly'] - ); - } - - unset($_COOKIE[$key]); - } - } - } - } - - /** - * json 转换时的格式保护 - * @access protected - * @param mixed $val 要转换的值 - * @param string $key 键名 - * @param string $type 转换类别 - * @return void - */ - protected static function jsonFormatProtect(&$val, $key, $type = 'encode') - { - if (!empty($val) && true !== $val) { - $val = 'decode' == $type ? urldecode($val) : urlencode($val); - } - } -} diff --git a/thinkphp/library/think/Db.php b/thinkphp/library/think/Db.php deleted file mode 100755 index 80f08d2..0000000 --- a/thinkphp/library/think/Db.php +++ /dev/null @@ -1,180 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\db\Connection; -use think\db\Query; - -/** - * Class Db - * @package think - * @method Query table(string $table) static 指定数据表(含前缀) - * @method Query name(string $name) static 指定数据表(不含前缀) - * @method Query where(mixed $field, string $op = null, mixed $condition = null) static 查询条件 - * @method Query join(mixed $join, mixed $condition = null, string $type = 'INNER') static JOIN查询 - * @method Query union(mixed $union, boolean $all = false) static UNION查询 - * @method Query limit(mixed $offset, integer $length = null) static 查询LIMIT - * @method Query order(mixed $field, string $order = null) static 查询ORDER - * @method Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存 - * @method mixed value(string $field) static 获取某个字段的值 - * @method array column(string $field, string $key = '') static 获取某个列的值 - * @method Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询 - * @method mixed find(mixed $data = null) static 查询单个记录 - * @method mixed select(mixed $data = null) static 查询多个记录 - * @method integer insert(array $data, boolean $replace = false, boolean $getLastInsID = false, string $sequence = null) static 插入一条记录 - * @method integer insertGetId(array $data, boolean $replace = false, string $sequence = null) static 插入一条记录并返回自增ID - * @method integer insertAll(array $dataSet) static 插入多条记录 - * @method integer update(array $data) static 更新记录 - * @method integer delete(mixed $data = null) static 删除记录 - * @method boolean chunk(integer $count, callable $callback, string $column = null) static 分块获取数据 - * @method mixed query(string $sql, array $bind = [], boolean $master = false, bool $pdo = false) static SQL查询 - * @method integer execute(string $sql, array $bind = [], boolean $fetch = false, boolean $getLastInsID = false, string $sequence = null) static SQL执行 - * @method Paginator paginate(integer $listRows = 15, mixed $simple = null, array $config = []) static 分页查询 - * @method mixed transaction(callable $callback) static 执行数据库事务 - * @method void startTrans() static 启动事务 - * @method void commit() static 用于非自动提交状态下面的查询提交 - * @method void rollback() static 事务回滚 - * @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句 - * @method string quote(string $str) static SQL指令安全过滤 - * @method string getLastInsID($sequence = null) static 获取最近插入的ID - */ -class Db -{ - /** - * @var Connection[] 数据库连接实例 - */ - private static $instance = []; - - /** - * @var int 查询次数 - */ - public static $queryTimes = 0; - - /** - * @var int 执行次数 - */ - public static $executeTimes = 0; - - /** - * 数据库初始化,并取得数据库类实例 - * @access public - * @param mixed $config 连接配置 - * @param bool|string $name 连接标识 true 强制重新连接 - * @return Connection - * @throws Exception - */ - public static function connect($config = [], $name = false) - { - if (false === $name) { - $name = md5(serialize($config)); - } - - if (true === $name || !isset(self::$instance[$name])) { - // 解析连接参数 支持数组和字符串 - $options = self::parseConfig($config); - - if (empty($options['type'])) { - throw new \InvalidArgumentException('Undefined db type'); - } - - $class = false !== strpos($options['type'], '\\') ? - $options['type'] : - '\\think\\db\\connector\\' . ucwords($options['type']); - - // 记录初始化信息 - if (App::$debug) { - Log::record('[ DB ] INIT ' . $options['type'], 'info'); - } - - if (true === $name) { - $name = md5(serialize($config)); - } - - self::$instance[$name] = new $class($options); - } - - return self::$instance[$name]; - } - - /** - * 清除连接实例 - * @access public - * @return void - */ - public static function clear() - { - self::$instance = []; - } - - /** - * 数据库连接参数解析 - * @access private - * @param mixed $config 连接参数 - * @return array - */ - private static function parseConfig($config) - { - if (empty($config)) { - $config = Config::get('database'); - } elseif (is_string($config) && false === strpos($config, '/')) { - $config = Config::get($config); // 支持读取配置参数 - } - - return is_string($config) ? self::parseDsn($config) : $config; - } - - /** - * DSN 解析 - * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1¶m2=val2#utf8 - * @access private - * @param string $dsnStr 数据库 DSN 字符串解析 - * @return array - */ - private static function parseDsn($dsnStr) - { - $info = parse_url($dsnStr); - - if (!$info) { - return []; - } - - $dsn = [ - 'type' => $info['scheme'], - 'username' => isset($info['user']) ? $info['user'] : '', - 'password' => isset($info['pass']) ? $info['pass'] : '', - 'hostname' => isset($info['host']) ? $info['host'] : '', - 'hostport' => isset($info['port']) ? $info['port'] : '', - 'database' => !empty($info['path']) ? ltrim($info['path'], '/') : '', - 'charset' => isset($info['fragment']) ? $info['fragment'] : 'utf8', - ]; - - if (isset($info['query'])) { - parse_str($info['query'], $dsn['params']); - } else { - $dsn['params'] = []; - } - - return $dsn; - } - - /** - * 调用驱动类的方法 - * @access public - * @param string $method 方法名 - * @param array $params 参数 - * @return mixed - */ - public static function __callStatic($method, $params) - { - return call_user_func_array([self::connect(), $method], $params); - } -} diff --git a/thinkphp/library/think/Debug.php b/thinkphp/library/think/Debug.php deleted file mode 100755 index df48748..0000000 --- a/thinkphp/library/think/Debug.php +++ /dev/null @@ -1,252 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\ClassNotFoundException; -use think\response\Redirect; - -class Debug -{ - /** - * @var array 区间时间信息 - */ - protected static $info = []; - - /** - * @var array 区间内存信息 - */ - protected static $mem = []; - - /** - * 记录时间(微秒)和内存使用情况 - * @access public - * @param string $name 标记位置 - * @param mixed $value 标记值(留空则取当前 time 表示仅记录时间 否则同时记录时间和内存) - * @return void - */ - public static function remark($name, $value = '') - { - self::$info[$name] = is_float($value) ? $value : microtime(true); - - if ('time' != $value) { - self::$mem['mem'][$name] = is_float($value) ? $value : memory_get_usage(); - self::$mem['peak'][$name] = memory_get_peak_usage(); - } - } - - /** - * 统计某个区间的时间(微秒)使用情况 返回值以秒为单位 - * @access public - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer $dec 小数位 - * @return string - */ - public static function getRangeTime($start, $end, $dec = 6) - { - if (!isset(self::$info[$end])) { - self::$info[$end] = microtime(true); - } - - return number_format((self::$info[$end] - self::$info[$start]), $dec); - } - - /** - * 统计从开始到统计时的时间(微秒)使用情况 返回值以秒为单位 - * @access public - * @param integer $dec 小数位 - * @return string - */ - public static function getUseTime($dec = 6) - { - return number_format((microtime(true) - THINK_START_TIME), $dec); - } - - /** - * 获取当前访问的吞吐率情况 - * @access public - * @return string - */ - public static function getThroughputRate() - { - return number_format(1 / self::getUseTime(), 2) . 'req/s'; - } - - /** - * 记录区间的内存使用情况 - * @access public - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer $dec 小数位 - * @return string - */ - public static function getRangeMem($start, $end, $dec = 2) - { - if (!isset(self::$mem['mem'][$end])) { - self::$mem['mem'][$end] = memory_get_usage(); - } - - $size = self::$mem['mem'][$end] - self::$mem['mem'][$start]; - $a = ['B', 'KB', 'MB', 'GB', 'TB']; - $pos = 0; - - while ($size >= 1024) { - $size /= 1024; - $pos++; - } - - return round($size, $dec) . " " . $a[$pos]; - } - - /** - * 统计从开始到统计时的内存使用情况 - * @access public - * @param integer $dec 小数位 - * @return string - */ - public static function getUseMem($dec = 2) - { - $size = memory_get_usage() - THINK_START_MEM; - $a = ['B', 'KB', 'MB', 'GB', 'TB']; - $pos = 0; - - while ($size >= 1024) { - $size /= 1024; - $pos++; - } - - return round($size, $dec) . " " . $a[$pos]; - } - - /** - * 统计区间的内存峰值情况 - * @access public - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer $dec 小数位 - * @return string - */ - public static function getMemPeak($start, $end, $dec = 2) - { - if (!isset(self::$mem['peak'][$end])) { - self::$mem['peak'][$end] = memory_get_peak_usage(); - } - - $size = self::$mem['peak'][$end] - self::$mem['peak'][$start]; - $a = ['B', 'KB', 'MB', 'GB', 'TB']; - $pos = 0; - - while ($size >= 1024) { - $size /= 1024; - $pos++; - } - - return round($size, $dec) . " " . $a[$pos]; - } - - /** - * 获取文件加载信息 - * @access public - * @param bool $detail 是否显示详细 - * @return integer|array - */ - public static function getFile($detail = false) - { - $files = get_included_files(); - - if ($detail) { - $info = []; - - foreach ($files as $file) { - $info[] = $file . ' ( ' . number_format(filesize($file) / 1024, 2) . ' KB )'; - } - - return $info; - } - - return count($files); - } - - /** - * 浏览器友好的变量输出 - * @access public - * @param mixed $var 变量 - * @param boolean $echo 是否输出(默认为 true,为 false 则返回输出字符串) - * @param string|null $label 标签(默认为空) - * @param integer $flags htmlspecialchars 的标志 - * @return null|string - */ - public static function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE) - { - $label = (null === $label) ? '' : rtrim($label) . ':'; - - ob_start(); - var_dump($var); - $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', ob_get_clean()); - - if (IS_CLI) { - $output = PHP_EOL . $label . $output . PHP_EOL; - } else { - if (!extension_loaded('xdebug')) { - $output = htmlspecialchars($output, $flags); - } - - $output = '
' . $label . $output . '
'; - } - - if ($echo) { - echo($output); - return; - } - - return $output; - } - - /** - * 调试信息注入到响应中 - * @access public - * @param Response $response 响应实例 - * @param string $content 返回的字符串 - * @return void - */ - public static function inject(Response $response, &$content) - { - $config = Config::get('trace'); - $type = isset($config['type']) ? $config['type'] : 'Html'; - $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); - - unset($config['type']); - - if (!class_exists($class)) { - throw new ClassNotFoundException('class not exists:' . $class, $class); - } - - /** @var \think\debug\Console|\think\debug\Html $trace */ - $trace = new $class($config); - - if ($response instanceof Redirect) { - // TODO 记录 - } else { - $output = $trace->output($response, Log::getLog()); - - if (is_string($output)) { - // trace 调试信息注入 - $pos = strripos($content, ''); - if (false !== $pos) { - $content = substr($content, 0, $pos) . $output . substr($content, $pos); - } else { - $content = $content . $output; - } - } - } - } -} diff --git a/thinkphp/library/think/Env.php b/thinkphp/library/think/Env.php deleted file mode 100755 index 0a8b250..0000000 --- a/thinkphp/library/think/Env.php +++ /dev/null @@ -1,39 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Env -{ - /** - * 获取环境变量值 - * @access public - * @param string $name 环境变量名(支持二级 . 号分割) - * @param string $default 默认值 - * @return mixed - */ - public static function get($name, $default = null) - { - $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', $name))); - - if (false !== $result) { - if ('false' === $result) { - $result = false; - } elseif ('true' === $result) { - $result = true; - } - - return $result; - } - - return $default; - } -} diff --git a/thinkphp/library/think/Error.php b/thinkphp/library/think/Error.php deleted file mode 100755 index 5f361d5..0000000 --- a/thinkphp/library/think/Error.php +++ /dev/null @@ -1,136 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\console\Output as ConsoleOutput; -use think\exception\ErrorException; -use think\exception\Handle; -use think\exception\ThrowableError; - -class Error -{ - /** - * 注册异常处理 - * @access public - * @return void - */ - public static function register() - { - error_reporting(E_ALL); - set_error_handler([__CLASS__, 'appError']); - set_exception_handler([__CLASS__, 'appException']); - register_shutdown_function([__CLASS__, 'appShutdown']); - } - - /** - * 异常处理 - * @access public - * @param \Exception|\Throwable $e 异常 - * @return void - */ - public static function appException($e) - { - if (!$e instanceof \Exception) { - $e = new ThrowableError($e); - } - - $handler = self::getExceptionHandler(); - $handler->report($e); - - if (IS_CLI) { - $handler->renderForConsole(new ConsoleOutput, $e); - } else { - $handler->render($e)->send(); - } - } - - /** - * 错误处理 - * @access public - * @param integer $errno 错误编号 - * @param integer $errstr 详细错误信息 - * @param string $errfile 出错的文件 - * @param integer $errline 出错行号 - * @return void - * @throws ErrorException - */ - public static function appError($errno, $errstr, $errfile = '', $errline = 0) - { - $exception = new ErrorException($errno, $errstr, $errfile, $errline); - - // 符合异常处理的则将错误信息托管至 think\exception\ErrorException - if (error_reporting() & $errno) { - throw $exception; - } - - self::getExceptionHandler()->report($exception); - } - - /** - * 异常中止处理 - * @access public - * @return void - */ - public static function appShutdown() - { - // 将错误信息托管至 think\ErrorException - if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) { - self::appException(new ErrorException( - $error['type'], $error['message'], $error['file'], $error['line'] - )); - } - - // 写入日志 - Log::save(); - } - - /** - * 确定错误类型是否致命 - * @access protected - * @param int $type 错误类型 - * @return bool - */ - protected static function isFatal($type) - { - return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]); - } - - /** - * 获取异常处理的实例 - * @access public - * @return Handle - */ - public static function getExceptionHandler() - { - static $handle; - - if (!$handle) { - // 异常处理 handle - $class = Config::get('exception_handle'); - - if ($class && is_string($class) && class_exists($class) && - is_subclass_of($class, "\\think\\exception\\Handle") - ) { - $handle = new $class; - } else { - $handle = new Handle; - - if ($class instanceof \Closure) { - $handle->setRender($class); - } - - } - } - - return $handle; - } -} diff --git a/thinkphp/library/think/Exception.php b/thinkphp/library/think/Exception.php deleted file mode 100755 index 1ef06bd..0000000 --- a/thinkphp/library/think/Exception.php +++ /dev/null @@ -1,55 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Exception extends \Exception -{ - /** - * @var array 保存异常页面显示的额外 Debug 数据 - */ - protected $data = []; - - /** - * 设置异常额外的 Debug 数据 - * 数据将会显示为下面的格式 - * - * Exception Data - * -------------------------------------------------- - * Label 1 - * key1 value1 - * key2 value2 - * Label 2 - * key1 value1 - * key2 value2 - * - * @access protected - * @param string $label 数据分类,用于异常页面显示 - * @param array $data 需要显示的数据,必须为关联数组 - * @return void - */ - final protected function setData($label, array $data) - { - $this->data[$label] = $data; - } - - /** - * 获取异常额外 Debug 数据 - * 主要用于输出到异常页面便于调试 - * @access public - * @return array - */ - final public function getData() - { - return $this->data; - } - -} diff --git a/thinkphp/library/think/File.php b/thinkphp/library/think/File.php deleted file mode 100755 index d2ed220..0000000 --- a/thinkphp/library/think/File.php +++ /dev/null @@ -1,478 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use SplFileObject; - -class File extends SplFileObject -{ - /** - * @var string 错误信息 - */ - private $error = ''; - - /** - * @var string 当前完整文件名 - */ - protected $filename; - - /** - * @var string 上传文件名 - */ - protected $saveName; - - /** - * @var string 文件上传命名规则 - */ - protected $rule = 'date'; - - /** - * @var array 文件上传验证规则 - */ - protected $validate = []; - - /** - * @var bool 单元测试 - */ - protected $isTest; - - /** - * @var array 上传文件信息 - */ - protected $info; - - /** - * @var array 文件 hash 信息 - */ - protected $hash = []; - - /** - * File constructor. - * @access public - * @param string $filename 文件名称 - * @param string $mode 访问模式 - */ - public function __construct($filename, $mode = 'r') - { - parent::__construct($filename, $mode); - $this->filename = $this->getRealPath() ?: $this->getPathname(); - } - - /** - * 设置是否是单元测试 - * @access public - * @param bool $test 是否是测试 - * @return $this - */ - public function isTest($test = false) - { - $this->isTest = $test; - - return $this; - } - - /** - * 设置上传信息 - * @access public - * @param array $info 上传文件信息 - * @return $this - */ - public function setUploadInfo($info) - { - $this->info = $info; - - return $this; - } - - /** - * 获取上传文件的信息 - * @access public - * @param string $name 信息名称 - * @return array|string - */ - public function getInfo($name = '') - { - return isset($this->info[$name]) ? $this->info[$name] : $this->info; - } - - /** - * 获取上传文件的文件名 - * @access public - * @return string - */ - public function getSaveName() - { - return $this->saveName; - } - - /** - * 设置上传文件的保存文件名 - * @access public - * @param string $saveName 保存名称 - * @return $this - */ - public function setSaveName($saveName) - { - $this->saveName = $saveName; - - return $this; - } - - /** - * 获取文件的哈希散列值 - * @access public - * @param string $type 类型 - * @return string - */ - public function hash($type = 'sha1') - { - if (!isset($this->hash[$type])) { - $this->hash[$type] = hash_file($type, $this->filename); - } - - return $this->hash[$type]; - } - - /** - * 检查目录是否可写 - * @access protected - * @param string $path 目录 - * @return boolean - */ - protected function checkPath($path) - { - if (is_dir($path) || mkdir($path, 0755, true)) { - return true; - } - - $this->error = ['directory {:path} creation failed', ['path' => $path]]; - - return false; - } - - /** - * 获取文件类型信息 - * @access public - * @return string - */ - public function getMime() - { - $finfo = finfo_open(FILEINFO_MIME_TYPE); - - return finfo_file($finfo, $this->filename); - } - - /** - * 设置文件的命名规则 - * @access public - * @param string $rule 文件命名规则 - * @return $this - */ - public function rule($rule) - { - $this->rule = $rule; - - return $this; - } - - /** - * 设置上传文件的验证规则 - * @access public - * @param array $rule 验证规则 - * @return $this - */ - public function validate(array $rule = []) - { - $this->validate = $rule; - - return $this; - } - - /** - * 检测是否合法的上传文件 - * @access public - * @return bool - */ - public function isValid() - { - return $this->isTest ? is_file($this->filename) : is_uploaded_file($this->filename); - } - - /** - * 检测上传文件 - * @access public - * @param array $rule 验证规则 - * @return bool - */ - public function check($rule = []) - { - $rule = $rule ?: $this->validate; - - /* 检查文件大小 */ - if (isset($rule['size']) && !$this->checkSize($rule['size'])) { - $this->error = 'filesize not match'; - return false; - } - - /* 检查文件 Mime 类型 */ - if (isset($rule['type']) && !$this->checkMime($rule['type'])) { - $this->error = 'mimetype to upload is not allowed'; - return false; - } - - /* 检查文件后缀 */ - if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) { - $this->error = 'extensions to upload is not allowed'; - return false; - } - - /* 检查图像文件 */ - if (!$this->checkImg()) { - $this->error = 'illegal image files'; - return false; - } - - return true; - } - - /** - * 检测上传文件后缀 - * @access public - * @param array|string $ext 允许后缀 - * @return bool - */ - public function checkExt($ext) - { - if (is_string($ext)) { - $ext = explode(',', $ext); - } - - $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); - - return in_array($extension, $ext); - } - - /** - * 检测图像文件 - * @access public - * @return bool - */ - public function checkImg() - { - $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); - - // 如果上传的不是图片,或者是图片而且后缀确实符合图片类型则返回 true - return !in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) || in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6, 13]); - } - - /** - * 判断图像类型 - * @access protected - * @param string $image 图片名称 - * @return bool|int - */ - protected function getImageType($image) - { - if (function_exists('exif_imagetype')) { - return exif_imagetype($image); - } - - try { - $info = getimagesize($image); - return $info ? $info[2] : false; - } catch (\Exception $e) { - return false; - } - } - - /** - * 检测上传文件大小 - * @access public - * @param integer $size 最大大小 - * @return bool - */ - public function checkSize($size) - { - return $this->getSize() <= $size; - } - - /** - * 检测上传文件类型 - * @access public - * @param array|string $mime 允许类型 - * @return bool - */ - public function checkMime($mime) - { - $mime = is_string($mime) ? explode(',', $mime) : $mime; - - return in_array(strtolower($this->getMime()), $mime); - } - - /** - * 移动文件 - * @access public - * @param string $path 保存路径 - * @param string|bool $savename 保存的文件名 默认自动生成 - * @param boolean $replace 同名文件是否覆盖 - * @return false|File - */ - public function move($path, $savename = true, $replace = true) - { - // 文件上传失败,捕获错误代码 - if (!empty($this->info['error'])) { - $this->error($this->info['error']); - return false; - } - - // 检测合法性 - if (!$this->isValid()) { - $this->error = 'upload illegal files'; - return false; - } - - // 验证上传 - if (!$this->check()) { - return false; - } - - $path = rtrim($path, DS) . DS; - // 文件保存命名规则 - $saveName = $this->buildSaveName($savename); - $filename = $path . $saveName; - - // 检测目录 - if (false === $this->checkPath(dirname($filename))) { - return false; - } - - // 不覆盖同名文件 - if (!$replace && is_file($filename)) { - $this->error = ['has the same filename: {:filename}', ['filename' => $filename]]; - return false; - } - - /* 移动文件 */ - if ($this->isTest) { - rename($this->filename, $filename); - } elseif (!move_uploaded_file($this->filename, $filename)) { - $this->error = 'upload write error'; - return false; - } - - // 返回 File 对象实例 - $file = new self($filename); - $file->setSaveName($saveName)->setUploadInfo($this->info); - - return $file; - } - - /** - * 获取保存文件名 - * @access protected - * @param string|bool $savename 保存的文件名 默认自动生成 - * @return string - */ - protected function buildSaveName($savename) - { - // 自动生成文件名 - if (true === $savename) { - if ($this->rule instanceof \Closure) { - $savename = call_user_func_array($this->rule, [$this]); - } else { - switch ($this->rule) { - case 'date': - $savename = date('Ymd') . DS . md5(microtime(true)); - break; - default: - if (in_array($this->rule, hash_algos())) { - $hash = $this->hash($this->rule); - $savename = substr($hash, 0, 2) . DS . substr($hash, 2); - } elseif (is_callable($this->rule)) { - $savename = call_user_func($this->rule); - } else { - $savename = date('Ymd') . DS . md5(microtime(true)); - } - } - } - } elseif ('' === $savename || false === $savename) { - $savename = $this->getInfo('name'); - } - - if (!strpos($savename, '.')) { - $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION); - } - - return $savename; - } - - /** - * 获取错误代码信息 - * @access private - * @param int $errorNo 错误号 - * @return $this - */ - private function error($errorNo) - { - switch ($errorNo) { - case 1: - case 2: - $this->error = 'upload File size exceeds the maximum value'; - break; - case 3: - $this->error = 'only the portion of file is uploaded'; - break; - case 4: - $this->error = 'no file to uploaded'; - break; - case 6: - $this->error = 'upload temp dir not found'; - break; - case 7: - $this->error = 'file write error'; - break; - default: - $this->error = 'unknown upload error'; - } - - return $this; - } - - /** - * 获取错误信息(支持多语言) - * @access public - * @return string - */ - public function getError() - { - if (is_array($this->error)) { - list($msg, $vars) = $this->error; - } else { - $msg = $this->error; - $vars = []; - } - - return Lang::has($msg) ? Lang::get($msg, $vars) : $msg; - } - - /** - * 魔法方法,获取文件的 hash 值 - * @access public - * @param string $method 方法名 - * @param mixed $args 调用参数 - * @return string - */ - public function __call($method, $args) - { - return $this->hash($method); - } -} diff --git a/thinkphp/library/think/Hook.php b/thinkphp/library/think/Hook.php deleted file mode 100755 index a69ce54..0000000 --- a/thinkphp/library/think/Hook.php +++ /dev/null @@ -1,148 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Hook -{ - /** - * @var array 标签 - */ - private static $tags = []; - - /** - * 动态添加行为扩展到某个标签 - * @access public - * @param string $tag 标签名称 - * @param mixed $behavior 行为名称 - * @param bool $first 是否放到开头执行 - * @return void - */ - public static function add($tag, $behavior, $first = false) - { - isset(self::$tags[$tag]) || self::$tags[$tag] = []; - - if (is_array($behavior) && !is_callable($behavior)) { - if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) { - unset($behavior['_overlay']); - self::$tags[$tag] = array_merge(self::$tags[$tag], $behavior); - } else { - unset($behavior['_overlay']); - self::$tags[$tag] = $behavior; - } - } elseif ($first) { - array_unshift(self::$tags[$tag], $behavior); - } else { - self::$tags[$tag][] = $behavior; - } - } - - /** - * 批量导入插件 - * @access public - * @param array $tags 插件信息 - * @param boolean $recursive 是否递归合并 - * @return void - */ - public static function import(array $tags, $recursive = true) - { - if ($recursive) { - foreach ($tags as $tag => $behavior) { - self::add($tag, $behavior); - } - } else { - self::$tags = $tags + self::$tags; - } - } - - /** - * 获取插件信息 - * @access public - * @param string $tag 插件位置(留空获取全部) - * @return array - */ - public static function get($tag = '') - { - if (empty($tag)) { - return self::$tags; - } - - return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : []; - } - - /** - * 监听标签的行为 - * @access public - * @param string $tag 标签名称 - * @param mixed $params 传入参数 - * @param mixed $extra 额外参数 - * @param bool $once 只获取一个有效返回值 - * @return mixed - */ - public static function listen($tag, &$params = null, $extra = null, $once = false) - { - $results = []; - - foreach (static::get($tag) as $key => $name) { - $results[$key] = self::exec($name, $tag, $params, $extra); - - // 如果返回 false,或者仅获取一个有效返回则中断行为执行 - if (false === $results[$key] || (!is_null($results[$key]) && $once)) { - break; - } - } - - return $once ? end($results) : $results; - } - - /** - * 执行某个行为 - * @access public - * @param mixed $class 要执行的行为 - * @param string $tag 方法名(标签名) - * @param mixed $params 传人的参数 - * @param mixed $extra 额外参数 - * @return mixed - */ - public static function exec($class, $tag = '', &$params = null, $extra = null) - { - App::$debug && Debug::remark('behavior_start', 'time'); - - $method = Loader::parseName($tag, 1, false); - - if ($class instanceof \Closure) { - $result = call_user_func_array($class, [ & $params, $extra]); - $class = 'Closure'; - } elseif (is_array($class)) { - list($class, $method) = $class; - - $result = (new $class())->$method($params, $extra); - $class = $class . '->' . $method; - } elseif (is_object($class)) { - $result = $class->$method($params, $extra); - $class = get_class($class); - } elseif (strpos($class, '::')) { - $result = call_user_func_array($class, [ & $params, $extra]); - } else { - $obj = new $class(); - $method = ($tag && is_callable([$obj, $method])) ? $method : 'run'; - $result = $obj->$method($params, $extra); - } - - if (App::$debug) { - Debug::remark('behavior_end', 'time'); - Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info'); - } - - return $result; - } - -} diff --git a/thinkphp/library/think/Lang.php b/thinkphp/library/think/Lang.php deleted file mode 100755 index a50d838..0000000 --- a/thinkphp/library/think/Lang.php +++ /dev/null @@ -1,265 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Lang -{ - /** - * @var array 语言数据 - */ - private static $lang = []; - - /** - * @var string 语言作用域 - */ - private static $range = 'zh-cn'; - - /** - * @var string 语言自动侦测的变量 - */ - protected static $langDetectVar = 'lang'; - - /** - * @var string 语言 Cookie 变量 - */ - protected static $langCookieVar = 'think_var'; - - /** - * @var int 语言 Cookie 的过期时间 - */ - protected static $langCookieExpire = 3600; - - /** - * @var array 允许语言列表 - */ - protected static $allowLangList = []; - - /** - * @var array Accept-Language 转义为对应语言包名称 系统默认配置 - */ - protected static $acceptLanguage = ['zh-hans-cn' => 'zh-cn']; - - /** - * 设定当前的语言 - * @access public - * @param string $range 语言作用域 - * @return string - */ - public static function range($range = '') - { - if ($range) { - self::$range = $range; - } - - return self::$range; - } - - /** - * 设置语言定义(不区分大小写) - * @access public - * @param string|array $name 语言变量 - * @param string $value 语言值 - * @param string $range 语言作用域 - * @return mixed - */ - public static function set($name, $value = null, $range = '') - { - $range = $range ?: self::$range; - - if (!isset(self::$lang[$range])) { - self::$lang[$range] = []; - } - - if (is_array($name)) { - return self::$lang[$range] = array_change_key_case($name) + self::$lang[$range]; - } - - return self::$lang[$range][strtolower($name)] = $value; - } - - /** - * 加载语言定义(不区分大小写) - * @access public - * @param array|string $file 语言文件 - * @param string $range 语言作用域 - * @return mixed - */ - public static function load($file, $range = '') - { - $range = $range ?: self::$range; - $file = is_string($file) ? [$file] : $file; - - if (!isset(self::$lang[$range])) { - self::$lang[$range] = []; - } - - $lang = []; - - foreach ($file as $_file) { - if (is_file($_file)) { - // 记录加载信息 - App::$debug && Log::record('[ LANG ] ' . $_file, 'info'); - - $_lang = include $_file; - - if (is_array($_lang)) { - $lang = array_change_key_case($_lang) + $lang; - } - } - } - - if (!empty($lang)) { - self::$lang[$range] = $lang + self::$lang[$range]; - } - - return self::$lang[$range]; - } - - /** - * 获取语言定义(不区分大小写) - * @access public - * @param string|null $name 语言变量 - * @param string $range 语言作用域 - * @return mixed - */ - public static function has($name, $range = '') - { - $range = $range ?: self::$range; - - return isset(self::$lang[$range][strtolower($name)]); - } - - /** - * 获取语言定义(不区分大小写) - * @access public - * @param string|null $name 语言变量 - * @param array $vars 变量替换 - * @param string $range 语言作用域 - * @return mixed - */ - public static function get($name = null, $vars = [], $range = '') - { - $range = $range ?: self::$range; - - // 空参数返回所有定义 - if (empty($name)) { - return self::$lang[$range]; - } - - $key = strtolower($name); - $value = isset(self::$lang[$range][$key]) ? self::$lang[$range][$key] : $name; - - // 变量解析 - if (!empty($vars) && is_array($vars)) { - /** - * Notes: - * 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0 - * 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数 - */ - if (key($vars) === 0) { - // 数字索引解析 - array_unshift($vars, $value); - $value = call_user_func_array('sprintf', $vars); - } else { - // 关联索引解析 - $replace = array_keys($vars); - foreach ($replace as &$v) { - $v = "{:{$v}}"; - } - $value = str_replace($replace, $vars, $value); - } - - } - - return $value; - } - - /** - * 自动侦测设置获取语言选择 - * @access public - * @return string - */ - public static function detect() - { - $langSet = ''; - - if (isset($_GET[self::$langDetectVar])) { - // url 中设置了语言变量 - $langSet = strtolower($_GET[self::$langDetectVar]); - } elseif (isset($_COOKIE[self::$langCookieVar])) { - // Cookie 中设置了语言变量 - $langSet = strtolower($_COOKIE[self::$langCookieVar]); - } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - // 自动侦测浏览器语言 - preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches); - $langSet = strtolower($matches[1]); - $acceptLangs = Config::get('header_accept_lang'); - - if (isset($acceptLangs[$langSet])) { - $langSet = $acceptLangs[$langSet]; - } elseif (isset(self::$acceptLanguage[$langSet])) { - $langSet = self::$acceptLanguage[$langSet]; - } - } - - // 合法的语言 - if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) { - self::$range = $langSet ?: self::$range; - } - - return self::$range; - } - - /** - * 设置语言自动侦测的变量 - * @access public - * @param string $var 变量名称 - * @return void - */ - public static function setLangDetectVar($var) - { - self::$langDetectVar = $var; - } - - /** - * 设置语言的 cookie 保存变量 - * @access public - * @param string $var 变量名称 - * @return void - */ - public static function setLangCookieVar($var) - { - self::$langCookieVar = $var; - } - - /** - * 设置语言的 cookie 的过期时间 - * @access public - * @param string $expire 过期时间 - * @return void - */ - public static function setLangCookieExpire($expire) - { - self::$langCookieExpire = $expire; - } - - /** - * 设置允许的语言列表 - * @access public - * @param array $list 语言列表 - * @return void - */ - public static function setAllowLangList($list) - { - self::$allowLangList = $list; - } -} diff --git a/thinkphp/library/think/Loader.php b/thinkphp/library/think/Loader.php deleted file mode 100755 index d813a5d..0000000 --- a/thinkphp/library/think/Loader.php +++ /dev/null @@ -1,677 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\ClassNotFoundException; - -class Loader -{ - /** - * @var array 实例数组 - */ - protected static $instance = []; - - /** - * @var array 类名映射 - */ - protected static $classMap = []; - - /** - * @var array 命名空间别名 - */ - protected static $namespaceAlias = []; - - /** - * @var array PSR-4 命名空间前缀长度映射 - */ - private static $prefixLengthsPsr4 = []; - - /** - * @var array PSR-4 的加载目录 - */ - private static $prefixDirsPsr4 = []; - - /** - * @var array PSR-4 加载失败的回退目录 - */ - private static $fallbackDirsPsr4 = []; - - /** - * @var array PSR-0 命名空间前缀映射 - */ - private static $prefixesPsr0 = []; - - /** - * @var array PSR-0 加载失败的回退目录 - */ - private static $fallbackDirsPsr0 = []; - - /** - * @var array 需要加载的文件 - */ - private static $files = []; - - /** - * 自动加载 - * @access public - * @param string $class 类名 - * @return bool - */ - public static function autoload($class) - { - // 检测命名空间别名 - if (!empty(self::$namespaceAlias)) { - $namespace = dirname($class); - if (isset(self::$namespaceAlias[$namespace])) { - $original = self::$namespaceAlias[$namespace] . '\\' . basename($class); - if (class_exists($original)) { - return class_alias($original, $class, false); - } - } - } - - if ($file = self::findFile($class)) { - // 非 Win 环境不严格区分大小写 - if (!IS_WIN || pathinfo($file, PATHINFO_FILENAME) == pathinfo(realpath($file), PATHINFO_FILENAME)) { - __include_file($file); - return true; - } - } - - return false; - } - - /** - * 查找文件 - * @access private - * @param string $class 类名 - * @return bool|string - */ - private static function findFile($class) - { - // 类库映射 - if (!empty(self::$classMap[$class])) { - return self::$classMap[$class]; - } - - // 查找 PSR-4 - $logicalPathPsr4 = strtr($class, '\\', DS) . EXT; - $first = $class[0]; - - if (isset(self::$prefixLengthsPsr4[$first])) { - foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) { - if (0 === strpos($class, $prefix)) { - foreach (self::$prefixDirsPsr4[$prefix] as $dir) { - if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) { - return $file; - } - } - } - } - } - - // 查找 PSR-4 fallback dirs - foreach (self::$fallbackDirsPsr4 as $dir) { - if (is_file($file = $dir . DS . $logicalPathPsr4)) { - return $file; - } - } - - // 查找 PSR-0 - if (false !== $pos = strrpos($class, '\\')) { - // namespace class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DS); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DS) . EXT; - } - - if (isset(self::$prefixesPsr0[$first])) { - foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (is_file($file = $dir . DS . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // 查找 PSR-0 fallback dirs - foreach (self::$fallbackDirsPsr0 as $dir) { - if (is_file($file = $dir . DS . $logicalPathPsr0)) { - return $file; - } - } - - // 找不到则设置映射为 false 并返回 - return self::$classMap[$class] = false; - } - - /** - * 注册 classmap - * @access public - * @param string|array $class 类名 - * @param string $map 映射 - * @return void - */ - public static function addClassMap($class, $map = '') - { - if (is_array($class)) { - self::$classMap = array_merge(self::$classMap, $class); - } else { - self::$classMap[$class] = $map; - } - } - - /** - * 注册命名空间 - * @access public - * @param string|array $namespace 命名空间 - * @param string $path 路径 - * @return void - */ - public static function addNamespace($namespace, $path = '') - { - if (is_array($namespace)) { - foreach ($namespace as $prefix => $paths) { - self::addPsr4($prefix . '\\', rtrim($paths, DS), true); - } - } else { - self::addPsr4($namespace . '\\', rtrim($path, DS), true); - } - } - - /** - * 添加 PSR-0 命名空间 - * @access private - * @param array|string $prefix 空间前缀 - * @param array $paths 路径 - * @param bool $prepend 预先设置的优先级更高 - * @return void - */ - private static function addPsr0($prefix, $paths, $prepend = false) - { - if (!$prefix) { - self::$fallbackDirsPsr0 = $prepend ? - array_merge((array) $paths, self::$fallbackDirsPsr0) : - array_merge(self::$fallbackDirsPsr0, (array) $paths); - } else { - $first = $prefix[0]; - - if (!isset(self::$prefixesPsr0[$first][$prefix])) { - self::$prefixesPsr0[$first][$prefix] = (array) $paths; - } else { - self::$prefixesPsr0[$first][$prefix] = $prepend ? - array_merge((array) $paths, self::$prefixesPsr0[$first][$prefix]) : - array_merge(self::$prefixesPsr0[$first][$prefix], (array) $paths); - } - } - } - - /** - * 添加 PSR-4 空间 - * @access private - * @param array|string $prefix 空间前缀 - * @param string $paths 路径 - * @param bool $prepend 预先设置的优先级更高 - * @return void - */ - private static function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - self::$fallbackDirsPsr4 = $prepend ? - array_merge((array) $paths, self::$fallbackDirsPsr4) : - array_merge(self::$fallbackDirsPsr4, (array) $paths); - - } elseif (!isset(self::$prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException( - "A non-empty PSR-4 prefix must end with a namespace separator." - ); - } - - self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - self::$prefixDirsPsr4[$prefix] = (array) $paths; - - } else { - self::$prefixDirsPsr4[$prefix] = $prepend ? - // Prepend directories for an already registered namespace. - array_merge((array) $paths, self::$prefixDirsPsr4[$prefix]) : - // Append directories for an already registered namespace. - array_merge(self::$prefixDirsPsr4[$prefix], (array) $paths); - } - } - - /** - * 注册命名空间别名 - * @access public - * @param array|string $namespace 命名空间 - * @param string $original 源文件 - * @return void - */ - public static function addNamespaceAlias($namespace, $original = '') - { - if (is_array($namespace)) { - self::$namespaceAlias = array_merge(self::$namespaceAlias, $namespace); - } else { - self::$namespaceAlias[$namespace] = $original; - } - } - - /** - * 注册自动加载机制 - * @access public - * @param callable $autoload 自动加载处理方法 - * @return void - */ - public static function register($autoload = null) - { - // 注册系统自动加载 - spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); - - // Composer 自动加载支持 - if (is_dir(VENDOR_PATH . 'composer')) { - if (PHP_VERSION_ID >= 50600 && is_file(VENDOR_PATH . 'composer' . DS . 'autoload_static.php')) { - require VENDOR_PATH . 'composer' . DS . 'autoload_static.php'; - - $declaredClass = get_declared_classes(); - $composerClass = array_pop($declaredClass); - - foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) { - if (property_exists($composerClass, $attr)) { - self::${$attr} = $composerClass::${$attr}; - } - } - } else { - self::registerComposerLoader(); - } - } - - // 注册命名空间定义 - self::addNamespace([ - 'think' => LIB_PATH . 'think' . DS, - 'behavior' => LIB_PATH . 'behavior' . DS, - 'traits' => LIB_PATH . 'traits' . DS, - ]); - - // 加载类库映射文件 - if (is_file(RUNTIME_PATH . 'classmap' . EXT)) { - self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT)); - } - - self::loadComposerAutoloadFiles(); - - // 自动加载 extend 目录 - self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS); - } - - /** - * 注册 composer 自动加载 - * @access private - * @return void - */ - private static function registerComposerLoader() - { - if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) { - $map = require VENDOR_PATH . 'composer/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - self::addPsr0($namespace, $path); - } - } - - if (is_file(VENDOR_PATH . 'composer/autoload_psr4.php')) { - $map = require VENDOR_PATH . 'composer/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - self::addPsr4($namespace, $path); - } - } - - if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) { - $classMap = require VENDOR_PATH . 'composer/autoload_classmap.php'; - if ($classMap) { - self::addClassMap($classMap); - } - } - - if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) { - self::$files = require VENDOR_PATH . 'composer/autoload_files.php'; - } - } - - // 加载composer autofile文件 - public static function loadComposerAutoloadFiles() - { - foreach (self::$files as $fileIdentifier => $file) { - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - __require_file($file); - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } - } - } - - /** - * 导入所需的类库 同 Java 的 Import 本函数有缓存功能 - * @access public - * @param string $class 类库命名空间字符串 - * @param string $baseUrl 起始路径 - * @param string $ext 导入的文件扩展名 - * @return bool - */ - public static function import($class, $baseUrl = '', $ext = EXT) - { - static $_file = []; - $key = $class . $baseUrl; - $class = str_replace(['.', '#'], [DS, '.'], $class); - - if (isset($_file[$key])) { - return true; - } - - if (empty($baseUrl)) { - list($name, $class) = explode(DS, $class, 2); - - if (isset(self::$prefixDirsPsr4[$name . '\\'])) { - // 注册的命名空间 - $baseUrl = self::$prefixDirsPsr4[$name . '\\']; - } elseif ('@' == $name) { - // 加载当前模块应用类库 - $baseUrl = App::$modulePath; - } elseif (is_dir(EXTEND_PATH . $name)) { - $baseUrl = EXTEND_PATH . $name . DS; - } else { - // 加载其它模块的类库 - $baseUrl = APP_PATH . $name . DS; - } - } elseif (substr($baseUrl, -1) != DS) { - $baseUrl .= DS; - } - - // 如果类存在则导入类库文件 - if (is_array($baseUrl)) { - foreach ($baseUrl as $path) { - if (is_file($filename = $path . DS . $class . $ext)) { - break; - } - } - } else { - $filename = $baseUrl . $class . $ext; - } - - if (!empty($filename) && - is_file($filename) && - (!IS_WIN || pathinfo($filename, PATHINFO_FILENAME) == pathinfo(realpath($filename), PATHINFO_FILENAME)) - ) { - __include_file($filename); - $_file[$key] = true; - - return true; - } - - return false; - } - - /** - * 实例化(分层)模型 - * @access public - * @param string $name Model名称 - * @param string $layer 业务层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $common 公共模块名 - * @return object - * @throws ClassNotFoundException - */ - public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common') - { - $uid = $name . $layer; - - if (isset(self::$instance[$uid])) { - return self::$instance[$uid]; - } - - list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); - - if (class_exists($class)) { - $model = new $class(); - } else { - $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class); - - if (class_exists($class)) { - $model = new $class(); - } else { - throw new ClassNotFoundException('class not exists:' . $class, $class); - } - } - - return self::$instance[$uid] = $model; - } - - /** - * 实例化(分层)控制器 格式:[模块名/]控制器名 - * @access public - * @param string $name 资源地址 - * @param string $layer 控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $empty 空控制器名称 - * @return object - * @throws ClassNotFoundException - */ - public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '') - { - list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); - - if (class_exists($class)) { - return App::invokeClass($class); - } - - if ($empty) { - $emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix); - - if (class_exists($emptyClass)) { - return new $emptyClass(Request::instance()); - } - } - - throw new ClassNotFoundException('class not exists:' . $class, $class); - } - - /** - * 实例化验证类 格式:[模块名/]验证器名 - * @access public - * @param string $name 资源地址 - * @param string $layer 验证层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $common 公共模块名 - * @return object|false - * @throws ClassNotFoundException - */ - public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common') - { - $name = $name ?: Config::get('default_validate'); - - if (empty($name)) { - return new Validate; - } - - $uid = $name . $layer; - if (isset(self::$instance[$uid])) { - return self::$instance[$uid]; - } - - list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); - - if (class_exists($class)) { - $validate = new $class; - } else { - $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class); - - if (class_exists($class)) { - $validate = new $class; - } else { - throw new ClassNotFoundException('class not exists:' . $class, $class); - } - } - - return self::$instance[$uid] = $validate; - } - - /** - * 解析模块和类名 - * @access protected - * @param string $name 资源地址 - * @param string $layer 验证层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @return array - */ - protected static function getModuleAndClass($name, $layer, $appendSuffix) - { - if (false !== strpos($name, '\\')) { - $module = Request::instance()->module(); - $class = $name; - } else { - if (strpos($name, '/')) { - list($module, $name) = explode('/', $name, 2); - } else { - $module = Request::instance()->module(); - } - - $class = self::parseClass($module, $layer, $name, $appendSuffix); - } - - return [$module, $class]; - } - - /** - * 数据库初始化 并取得数据库类实例 - * @access public - * @param mixed $config 数据库配置 - * @param bool|string $name 连接标识 true 强制重新连接 - * @return \think\db\Connection - */ - public static function db($config = [], $name = false) - { - return Db::connect($config, $name); - } - - /** - * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作 - * @access public - * @param string $url 调用地址 - * @param string|array $vars 调用参数 支持字符串和数组 - * @param string $layer 要调用的控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @return mixed - */ - public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false) - { - $info = pathinfo($url); - $action = $info['basename']; - $module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller(); - $class = self::controller($module, $layer, $appendSuffix); - - if ($class) { - if (is_scalar($vars)) { - if (strpos($vars, '=')) { - parse_str($vars, $vars); - } else { - $vars = [$vars]; - } - } - - return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars); - } - - return false; - } - - /** - * 字符串命名风格转换 - * type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格 - * @access public - * @param string $name 字符串 - * @param integer $type 转换类型 - * @param bool $ucfirst 首字母是否大写(驼峰规则) - * @return string - */ - public static function parseName($name, $type = 0, $ucfirst = true) - { - if ($type) { - $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) { - return strtoupper($match[1]); - }, $name); - - return $ucfirst ? ucfirst($name) : lcfirst($name); - } - - return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); - } - - /** - * 解析应用类的类名 - * @access public - * @param string $module 模块名 - * @param string $layer 层名 controller model ... - * @param string $name 类名 - * @param bool $appendSuffix 是否添加类名后缀 - * @return string - */ - public static function parseClass($module, $layer, $name, $appendSuffix = false) - { - - $array = explode('\\', str_replace(['/', '.'], '\\', $name)); - $class = self::parseName(array_pop($array), 1); - $class = $class . (App::$suffix || $appendSuffix ? ucfirst($layer) : ''); - $path = $array ? implode('\\', $array) . '\\' : ''; - - return App::$namespace . '\\' . - ($module ? $module . '\\' : '') . - $layer . '\\' . $path . $class; - } - - /** - * 初始化类的实例 - * @access public - * @return void - */ - public static function clearInstance() - { - self::$instance = []; - } -} - -// 作用范围隔离 - -/** - * include - * @param string $file 文件路径 - * @return mixed - */ -function __include_file($file) -{ - return include $file; -} - -/** - * require - * @param string $file 文件路径 - * @return mixed - */ -function __require_file($file) -{ - return require $file; -} diff --git a/thinkphp/library/think/Log.php b/thinkphp/library/think/Log.php deleted file mode 100755 index c064306..0000000 --- a/thinkphp/library/think/Log.php +++ /dev/null @@ -1,237 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\ClassNotFoundException; - -/** - * Class Log - * @package think - * - * @method void log($msg) static 记录一般日志 - * @method void error($msg) static 记录错误日志 - * @method void info($msg) static 记录一般信息日志 - * @method void sql($msg) static 记录 SQL 查询日志 - * @method void notice($msg) static 记录提示日志 - * @method void alert($msg) static 记录报警日志 - */ -class Log -{ - const LOG = 'log'; - const ERROR = 'error'; - const INFO = 'info'; - const SQL = 'sql'; - const NOTICE = 'notice'; - const ALERT = 'alert'; - const DEBUG = 'debug'; - - /** - * @var array 日志信息 - */ - protected static $log = []; - - /** - * @var array 配置参数 - */ - protected static $config = []; - - /** - * @var array 日志类型 - */ - protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert', 'debug']; - - /** - * @var log\driver\File|log\driver\Test|log\driver\Socket 日志写入驱动 - */ - protected static $driver; - - /** - * @var string 当前日志授权 key - */ - protected static $key; - - /** - * 日志初始化 - * @access public - * @param array $config 配置参数 - * @return void - */ - public static function init($config = []) - { - $type = isset($config['type']) ? $config['type'] : 'File'; - $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type); - - self::$config = $config; - unset($config['type']); - - if (class_exists($class)) { - self::$driver = new $class($config); - } else { - throw new ClassNotFoundException('class not exists:' . $class, $class); - } - - // 记录初始化信息 - App::$debug && Log::record('[ LOG ] INIT ' . $type, 'info'); - } - - /** - * 获取日志信息 - * @access public - * @param string $type 信息类型 - * @return array|string - */ - public static function getLog($type = '') - { - return $type ? self::$log[$type] : self::$log; - } - - /** - * 记录调试信息 - * @access public - * @param mixed $msg 调试信息 - * @param string $type 信息类型 - * @return void - */ - public static function record($msg, $type = 'log') - { - self::$log[$type][] = $msg; - - // 命令行下面日志写入改进 - IS_CLI && self::save(); - } - - /** - * 清空日志信息 - * @access public - * @return void - */ - public static function clear() - { - self::$log = []; - } - - /** - * 设置当前日志记录的授权 key - * @access public - * @param string $key 授权 key - * @return void - */ - public static function key($key) - { - self::$key = $key; - } - - /** - * 检查日志写入权限 - * @access public - * @param array $config 当前日志配置参数 - * @return bool - */ - public static function check($config) - { - return !self::$key || empty($config['allow_key']) || in_array(self::$key, $config['allow_key']); - } - - /** - * 保存调试信息 - * @access public - * @return bool - */ - public static function save() - { - // 没有需要保存的记录则直接返回 - if (empty(self::$log)) { - return true; - } - - is_null(self::$driver) && self::init(Config::get('log')); - - // 检测日志写入权限 - if (!self::check(self::$config)) { - return false; - } - - if (empty(self::$config['level'])) { - // 获取全部日志 - $log = self::$log; - if (!App::$debug && isset($log['debug'])) { - unset($log['debug']); - } - } else { - // 记录允许级别 - $log = []; - foreach (self::$config['level'] as $level) { - if (isset(self::$log[$level])) { - $log[$level] = self::$log[$level]; - } - } - } - - if ($result = self::$driver->save($log, true)) { - self::$log = []; - } - - Hook::listen('log_write_done', $log); - - return $result; - } - - /** - * 实时写入日志信息 并支持行为 - * @access public - * @param mixed $msg 调试信息 - * @param string $type 信息类型 - * @param bool $force 是否强制写入 - * @return bool - */ - public static function write($msg, $type = 'log', $force = false) - { - $log = self::$log; - - // 如果不是强制写入,而且信息类型不在可记录的类别中则直接返回 false 不做记录 - if (true !== $force && !empty(self::$config['level']) && !in_array($type, self::$config['level'])) { - return false; - } - - // 封装日志信息 - $log[$type][] = $msg; - - // 监听 log_write - Hook::listen('log_write', $log); - - is_null(self::$driver) && self::init(Config::get('log')); - - // 写入日志 - if ($result = self::$driver->save($log, false)) { - self::$log = []; - } - - return $result; - } - - /** - * 静态方法调用 - * @access public - * @param string $method 调用方法 - * @param mixed $args 参数 - * @return void - */ - public static function __callStatic($method, $args) - { - if (in_array($method, self::$type)) { - array_push($args, $method); - - call_user_func_array('\\think\\Log::record', $args); - } - } - -} diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php deleted file mode 100755 index 2190e34..0000000 --- a/thinkphp/library/think/Model.php +++ /dev/null @@ -1,2348 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use BadMethodCallException; -use InvalidArgumentException; -use think\db\Query; -use think\exception\ValidateException; -use think\model\Collection as ModelCollection; -use think\model\Relation; -use think\model\relation\BelongsTo; -use think\model\relation\BelongsToMany; -use think\model\relation\HasMany; -use think\model\relation\HasManyThrough; -use think\model\relation\HasOne; -use think\model\relation\MorphMany; -use think\model\relation\MorphOne; -use think\model\relation\MorphTo; - -/** - * Class Model - * @package think - * @mixin Query - */ -abstract class Model implements \JsonSerializable, \ArrayAccess -{ - // 数据库查询对象池 - protected static $links = []; - // 数据库配置 - protected $connection = []; - // 父关联模型对象 - protected $parent; - // 数据库查询对象 - protected $query; - // 当前模型名称 - protected $name; - // 数据表名称 - protected $table; - // 当前类名称 - protected $class; - // 回调事件 - private static $event = []; - // 错误信息 - protected $error; - // 字段验证规则 - protected $validate; - // 数据表主键 复合主键使用数组定义 不设置则自动获取 - protected $pk; - // 数据表字段信息 留空则自动获取 - protected $field = []; - // 数据排除字段 - protected $except = []; - // 数据废弃字段 - protected $disuse = []; - // 只读字段 - protected $readonly = []; - // 显示属性 - protected $visible = []; - // 隐藏属性 - protected $hidden = []; - // 追加属性 - protected $append = []; - // 数据信息 - protected $data = []; - // 原始数据 - protected $origin = []; - // 关联模型 - protected $relation = []; - - // 保存自动完成列表 - protected $auto = []; - // 新增自动完成列表 - protected $insert = []; - // 更新自动完成列表 - protected $update = []; - // 是否需要自动写入时间戳 如果设置为字符串 则表示时间字段的类型 - protected $autoWriteTimestamp; - // 创建时间字段 - protected $createTime = 'create_time'; - // 更新时间字段 - protected $updateTime = 'update_time'; - // 时间字段取出后的默认时间格式 - protected $dateFormat; - // 字段类型或者格式转换 - protected $type = []; - // 是否为更新数据 - protected $isUpdate = false; - // 是否使用Replace - protected $replace = false; - // 是否强制更新所有数据 - protected $force = false; - // 更新条件 - protected $updateWhere; - // 验证失败是否抛出异常 - protected $failException = false; - // 全局查询范围 - protected $useGlobalScope = true; - // 是否采用批量验证 - protected $batchValidate = false; - // 查询数据集对象 - protected $resultSetType; - // 关联自动写入 - protected $relationWrite; - - /** - * 初始化过的模型. - * - * @var array - */ - protected static $initialized = []; - - /** - * 是否从主库读取(主从分布式有效) - * @var array - */ - protected static $readMaster; - - /** - * 构造方法 - * @access public - * @param array|object $data 数据 - */ - public function __construct($data = []) - { - if (is_object($data)) { - $this->data = get_object_vars($data); - } else { - $this->data = $data; - } - - if ($this->disuse) { - // 废弃字段 - foreach ((array) $this->disuse as $key) { - if (array_key_exists($key, $this->data)) { - unset($this->data[$key]); - } - } - } - - // 记录原始数据 - $this->origin = $this->data; - - // 当前类名 - $this->class = get_called_class(); - - if (empty($this->name)) { - // 当前模型名 - $name = str_replace('\\', '/', $this->class); - $this->name = basename($name); - if (Config::get('class_suffix')) { - $suffix = basename(dirname($name)); - $this->name = substr($this->name, 0, -strlen($suffix)); - } - } - - if (is_null($this->autoWriteTimestamp)) { - // 自动写入时间戳 - $this->autoWriteTimestamp = $this->getQuery()->getConfig('auto_timestamp'); - } - - if (is_null($this->dateFormat)) { - // 设置时间戳格式 - $this->dateFormat = $this->getQuery()->getConfig('datetime_format'); - } - - if (is_null($this->resultSetType)) { - $this->resultSetType = $this->getQuery()->getConfig('resultset_type'); - } - // 执行初始化操作 - $this->initialize(); - } - - /** - * 是否从主库读取数据(主从分布有效) - * @access public - * @param bool $all 是否所有模型生效 - * @return $this - */ - public function readMaster($all = false) - { - $model = $all ? '*' : $this->class; - - static::$readMaster[$model] = true; - return $this; - } - - /** - * 创建模型的查询对象 - * @access protected - * @return Query - */ - protected function buildQuery() - { - // 合并数据库配置 - if (!empty($this->connection)) { - if (is_array($this->connection)) { - $connection = array_merge(Config::get('database'), $this->connection); - } else { - $connection = $this->connection; - } - } else { - $connection = []; - } - - $con = Db::connect($connection); - // 设置当前模型 确保查询返回模型对象 - $queryClass = $this->query ?: $con->getConfig('query'); - $query = new $queryClass($con, $this); - - if (isset(static::$readMaster['*']) || isset(static::$readMaster[$this->class])) { - $query->master(true); - } - - // 设置当前数据表和模型名 - if (!empty($this->table)) { - $query->setTable($this->table); - } else { - $query->name($this->name); - } - - if (!empty($this->pk)) { - $query->pk($this->pk); - } - - return $query; - } - - /** - * 创建新的模型实例 - * @access public - * @param array|object $data 数据 - * @param bool $isUpdate 是否为更新 - * @param mixed $where 更新条件 - * @return Model - */ - public function newInstance($data = [], $isUpdate = false, $where = null) - { - return (new static($data))->isUpdate($isUpdate, $where); - } - - /** - * 获取当前模型的查询对象 - * @access public - * @param bool $buildNewQuery 创建新的查询对象 - * @return Query - */ - public function getQuery($buildNewQuery = false) - { - if ($buildNewQuery) { - return $this->buildQuery(); - } elseif (!isset(self::$links[$this->class])) { - // 创建模型查询对象 - self::$links[$this->class] = $this->buildQuery(); - } - - return self::$links[$this->class]; - } - - /** - * 获取当前模型的数据库查询对象 - * @access public - * @param bool $useBaseQuery 是否调用全局查询范围 - * @param bool $buildNewQuery 创建新的查询对象 - * @return Query - */ - public function db($useBaseQuery = true, $buildNewQuery = true) - { - $query = $this->getQuery($buildNewQuery); - - // 全局作用域 - if ($useBaseQuery && method_exists($this, 'base')) { - call_user_func_array([$this, 'base'], [ & $query]); - } - - // 返回当前模型的数据库查询对象 - return $query; - } - - /** - * 初始化模型 - * @access protected - * @return void - */ - protected function initialize() - { - $class = get_class($this); - if (!isset(static::$initialized[$class])) { - static::$initialized[$class] = true; - static::init(); - } - } - - /** - * 初始化处理 - * @access protected - * @return void - */ - protected static function init() - { - } - - /** - * 设置父关联对象 - * @access public - * @param Model $model 模型对象 - * @return $this - */ - public function setParent($model) - { - $this->parent = $model; - return $this; - } - - /** - * 获取父关联对象 - * @access public - * @return Model - */ - public function getParent() - { - return $this->parent; - } - - /** - * 设置数据对象值 - * @access public - * @param mixed $data 数据或者属性名 - * @param mixed $value 值 - * @return $this - */ - public function data($data, $value = null) - { - if (is_string($data)) { - $this->data[$data] = $value; - } else { - // 清空数据 - $this->data = []; - if (is_object($data)) { - $data = get_object_vars($data); - } - if (true === $value) { - // 数据对象赋值 - foreach ($data as $key => $value) { - $this->setAttr($key, $value, $data); - } - } else { - $this->data = $data; - } - } - return $this; - } - - /** - * 获取对象原始数据 如果不存在指定字段返回false - * @access public - * @param string $name 字段名 留空获取全部 - * @return mixed - * @throws InvalidArgumentException - */ - public function getData($name = null) - { - if (is_null($name)) { - return $this->data; - } elseif (array_key_exists($name, $this->data)) { - return $this->data[$name]; - } elseif (array_key_exists($name, $this->relation)) { - return $this->relation[$name]; - } else { - throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name); - } - } - - /** - * 是否需要自动写入时间字段 - * @access public - * @param bool $auto - * @return $this - */ - public function isAutoWriteTimestamp($auto) - { - $this->autoWriteTimestamp = $auto; - return $this; - } - - /** - * 更新是否强制写入数据 而不做比较 - * @access public - * @param bool $force - * @return $this - */ - public function force($force = true) - { - $this->force = $force; - return $this; - } - - /** - * 修改器 设置数据对象值 - * @access public - * @param string $name 属性名 - * @param mixed $value 属性值 - * @param array $data 数据 - * @return $this - */ - public function setAttr($name, $value, $data = []) - { - if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) { - // 自动写入的时间戳字段 - $value = $this->autoWriteTimestamp($name); - } else { - // 检测修改器 - $method = 'set' . Loader::parseName($name, 1) . 'Attr'; - if (method_exists($this, $method)) { - $value = $this->$method($value, array_merge($this->data, $data), $this->relation); - } elseif (isset($this->type[$name])) { - // 类型转换 - $value = $this->writeTransform($value, $this->type[$name]); - } - } - - // 设置数据对象属性 - $this->data[$name] = $value; - return $this; - } - - /** - * 获取当前模型的关联模型数据 - * @access public - * @param string $name 关联方法名 - * @return mixed - */ - public function getRelation($name = null) - { - if (is_null($name)) { - return $this->relation; - } elseif (array_key_exists($name, $this->relation)) { - return $this->relation[$name]; - } else { - return; - } - } - - /** - * 设置关联数据对象值 - * @access public - * @param string $name 属性名 - * @param mixed $value 属性值 - * @return $this - */ - public function setRelation($name, $value) - { - $this->relation[$name] = $value; - return $this; - } - - /** - * 自动写入时间戳 - * @access public - * @param string $name 时间戳字段 - * @return mixed - */ - protected function autoWriteTimestamp($name) - { - if (isset($this->type[$name])) { - $type = $this->type[$name]; - if (strpos($type, ':')) { - list($type, $param) = explode(':', $type, 2); - } - switch ($type) { - case 'datetime': - case 'date': - $format = !empty($param) ? $param : $this->dateFormat; - $value = $this->formatDateTime(time(), $format); - break; - case 'timestamp': - case 'integer': - default: - $value = time(); - break; - } - } elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [ - 'datetime', - 'date', - 'timestamp', - ]) - ) { - $value = $this->formatDateTime(time(), $this->dateFormat); - } else { - $value = $this->formatDateTime(time(), $this->dateFormat, true); - } - return $value; - } - - /** - * 时间日期字段格式化处理 - * @access public - * @param mixed $time 时间日期表达式 - * @param mixed $format 日期格式 - * @param bool $timestamp 是否进行时间戳转换 - * @return mixed - */ - protected function formatDateTime($time, $format, $timestamp = false) - { - if (false !== strpos($format, '\\')) { - $time = new $format($time); - } elseif (!$timestamp && false !== $format) { - $time = date($format, $time); - } - return $time; - } - - /** - * 数据写入 类型转换 - * @access public - * @param mixed $value 值 - * @param string|array $type 要转换的类型 - * @return mixed - */ - protected function writeTransform($value, $type) - { - if (is_null($value)) { - return; - } - - if (is_array($type)) { - list($type, $param) = $type; - } elseif (strpos($type, ':')) { - list($type, $param) = explode(':', $type, 2); - } - switch ($type) { - case 'integer': - $value = (int) $value; - break; - case 'float': - if (empty($param)) { - $value = (float) $value; - } else { - $value = (float) number_format($value, $param, '.', ''); - } - break; - case 'boolean': - $value = (bool) $value; - break; - case 'timestamp': - if (!is_numeric($value)) { - $value = strtotime($value); - } - break; - case 'datetime': - $format = !empty($param) ? $param : $this->dateFormat; - $value = is_numeric($value) ? $value : strtotime($value); - $value = $this->formatDateTime($value, $format); - break; - case 'object': - if (is_object($value)) { - $value = json_encode($value, JSON_FORCE_OBJECT); - } - break; - case 'array': - $value = (array) $value; - case 'json': - $option = !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE; - $value = json_encode($value, $option); - break; - case 'serialize': - $value = serialize($value); - break; - - } - return $value; - } - - /** - * 获取器 获取数据对象的值 - * @access public - * @param string $name 名称 - * @return mixed - * @throws InvalidArgumentException - */ - public function getAttr($name) - { - try { - $notFound = false; - $value = $this->getData($name); - } catch (InvalidArgumentException $e) { - $notFound = true; - $value = null; - } - - // 检测属性获取器 - $method = 'get' . Loader::parseName($name, 1) . 'Attr'; - if (method_exists($this, $method)) { - $value = $this->$method($value, $this->data, $this->relation); - } elseif (isset($this->type[$name])) { - // 类型转换 - $value = $this->readTransform($value, $this->type[$name]); - } elseif (in_array($name, [$this->createTime, $this->updateTime])) { - if (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [ - 'datetime', - 'date', - 'timestamp', - ]) - ) { - $value = $this->formatDateTime(strtotime($value), $this->dateFormat); - } else { - $value = $this->formatDateTime($value, $this->dateFormat); - } - } elseif ($notFound) { - $relation = Loader::parseName($name, 1, false); - if (method_exists($this, $relation)) { - $modelRelation = $this->$relation(); - // 不存在该字段 获取关联数据 - $value = $this->getRelationData($modelRelation); - // 保存关联对象值 - $this->relation[$name] = $value; - } else { - throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name); - } - } - return $value; - } - - /** - * 获取关联模型数据 - * @access public - * @param Relation $modelRelation 模型关联对象 - * @return mixed - * @throws BadMethodCallException - */ - protected function getRelationData(Relation $modelRelation) - { - if ($this->parent && !$modelRelation->isSelfRelation() && get_class($modelRelation->getModel()) == get_class($this->parent)) { - $value = $this->parent; - } else { - // 首先获取关联数据 - if (method_exists($modelRelation, 'getRelation')) { - $value = $modelRelation->getRelation(); - } else { - throw new BadMethodCallException('method not exists:' . get_class($modelRelation) . '-> getRelation'); - } - } - return $value; - } - - /** - * 数据读取 类型转换 - * @access public - * @param mixed $value 值 - * @param string|array $type 要转换的类型 - * @return mixed - */ - protected function readTransform($value, $type) - { - if (is_null($value)) { - return; - } - - if (is_array($type)) { - list($type, $param) = $type; - } elseif (strpos($type, ':')) { - list($type, $param) = explode(':', $type, 2); - } - switch ($type) { - case 'integer': - $value = (int) $value; - break; - case 'float': - if (empty($param)) { - $value = (float) $value; - } else { - $value = (float) number_format($value, $param, '.', ''); - } - break; - case 'boolean': - $value = (bool) $value; - break; - case 'timestamp': - if (!is_null($value)) { - $format = !empty($param) ? $param : $this->dateFormat; - $value = $this->formatDateTime($value, $format); - } - break; - case 'datetime': - if (!is_null($value)) { - $format = !empty($param) ? $param : $this->dateFormat; - $value = $this->formatDateTime(strtotime($value), $format); - } - break; - case 'json': - $value = json_decode($value, true); - break; - case 'array': - $value = empty($value) ? [] : json_decode($value, true); - break; - case 'object': - $value = empty($value) ? new \stdClass() : json_decode($value); - break; - case 'serialize': - try { - $value = unserialize($value); - } catch (\Exception $e) { - $value = null; - } - break; - default: - if (false !== strpos($type, '\\')) { - // 对象类型 - $value = new $type($value); - } - } - return $value; - } - - /** - * 设置需要追加的输出属性 - * @access public - * @param array $append 属性列表 - * @param bool $override 是否覆盖 - * @return $this - */ - public function append($append = [], $override = false) - { - $this->append = $override ? $append : array_merge($this->append, $append); - return $this; - } - - /** - * 设置附加关联对象的属性 - * @access public - * @param string $relation 关联方法 - * @param string|array $append 追加属性名 - * @return $this - * @throws Exception - */ - public function appendRelationAttr($relation, $append) - { - if (is_string($append)) { - $append = explode(',', $append); - } - - $relation = Loader::parseName($relation, 1, false); - - // 获取关联数据 - if (isset($this->relation[$relation])) { - $model = $this->relation[$relation]; - } else { - $model = $this->getRelationData($this->$relation()); - } - - if ($model instanceof Model) { - foreach ($append as $key => $attr) { - $key = is_numeric($key) ? $attr : $key; - if (isset($this->data[$key])) { - throw new Exception('bind attr has exists:' . $key); - } else { - $this->data[$key] = $model->getAttr($attr); - } - } - } - return $this; - } - - /** - * 设置需要隐藏的输出属性 - * @access public - * @param array $hidden 属性列表 - * @param bool $override 是否覆盖 - * @return $this - */ - public function hidden($hidden = [], $override = false) - { - $this->hidden = $override ? $hidden : array_merge($this->hidden, $hidden); - return $this; - } - - /** - * 设置需要输出的属性 - * @access public - * @param array $visible - * @param bool $override 是否覆盖 - * @return $this - */ - public function visible($visible = [], $override = false) - { - $this->visible = $override ? $visible : array_merge($this->visible, $visible); - return $this; - } - - /** - * 解析隐藏及显示属性 - * @access protected - * @param array $attrs 属性 - * @param array $result 结果集 - * @param bool $visible - * @return array - */ - protected function parseAttr($attrs, &$result, $visible = true) - { - $array = []; - foreach ($attrs as $key => $val) { - if (is_array($val)) { - if ($visible) { - $array[] = $key; - } - $result[$key] = $val; - } elseif (strpos($val, '.')) { - list($key, $name) = explode('.', $val); - if ($visible) { - $array[] = $key; - } - $result[$key][] = $name; - } else { - $array[] = $val; - } - } - return $array; - } - - /** - * 转换子模型对象 - * @access protected - * @param Model|ModelCollection $model - * @param $visible - * @param $hidden - * @param $key - * @return array - */ - protected function subToArray($model, $visible, $hidden, $key) - { - // 关联模型对象 - if (isset($visible[$key])) { - $model->visible($visible[$key]); - } elseif (isset($hidden[$key])) { - $model->hidden($hidden[$key]); - } - return $model->toArray(); - } - - /** - * 转换当前模型对象为数组 - * @access public - * @return array - */ - public function toArray() - { - $item = []; - $visible = []; - $hidden = []; - - $data = array_merge($this->data, $this->relation); - - // 过滤属性 - if (!empty($this->visible)) { - $array = $this->parseAttr($this->visible, $visible); - $data = array_intersect_key($data, array_flip($array)); - } elseif (!empty($this->hidden)) { - $array = $this->parseAttr($this->hidden, $hidden, false); - $data = array_diff_key($data, array_flip($array)); - } - - foreach ($data as $key => $val) { - if ($val instanceof Model || $val instanceof ModelCollection) { - // 关联模型对象 - $item[$key] = $this->subToArray($val, $visible, $hidden, $key); - } elseif (is_array($val) && reset($val) instanceof Model) { - // 关联模型数据集 - $arr = []; - foreach ($val as $k => $value) { - $arr[$k] = $this->subToArray($value, $visible, $hidden, $key); - } - $item[$key] = $arr; - } else { - // 模型属性 - $item[$key] = $this->getAttr($key); - } - } - // 追加属性(必须定义获取器) - if (!empty($this->append)) { - foreach ($this->append as $key => $name) { - if (is_array($name)) { - // 追加关联对象属性 - $relation = $this->getAttr($key); - $item[$key] = $relation->append($name)->toArray(); - } elseif (strpos($name, '.')) { - list($key, $attr) = explode('.', $name); - // 追加关联对象属性 - $relation = $this->getAttr($key); - $item[$key] = $relation->append([$attr])->toArray(); - } else { - $relation = Loader::parseName($name, 1, false); - if (method_exists($this, $relation)) { - $modelRelation = $this->$relation(); - $value = $this->getRelationData($modelRelation); - - if (method_exists($modelRelation, 'getBindAttr')) { - $bindAttr = $modelRelation->getBindAttr(); - if ($bindAttr) { - foreach ($bindAttr as $key => $attr) { - $key = is_numeric($key) ? $attr : $key; - if (isset($this->data[$key])) { - throw new Exception('bind attr has exists:' . $key); - } else { - $item[$key] = $value ? $value->getAttr($attr) : null; - } - } - continue; - } - } - $item[$name] = $value; - } else { - $item[$name] = $this->getAttr($name); - } - } - } - } - return !empty($item) ? $item : []; - } - - /** - * 转换当前模型对象为JSON字符串 - * @access public - * @param integer $options json参数 - * @return string - */ - public function toJson($options = JSON_UNESCAPED_UNICODE) - { - return json_encode($this->toArray(), $options); - } - - /** - * 移除当前模型的关联属性 - * @access public - * @return $this - */ - public function removeRelation() - { - $this->relation = []; - return $this; - } - - /** - * 转换当前模型数据集为数据集对象 - * @access public - * @param array|\think\Collection $collection 数据集 - * @return \think\Collection - */ - public function toCollection($collection) - { - if ($this->resultSetType) { - if ('collection' == $this->resultSetType) { - $collection = new ModelCollection($collection); - } elseif (false !== strpos($this->resultSetType, '\\')) { - $class = $this->resultSetType; - $collection = new $class($collection); - } - } - return $collection; - } - - /** - * 关联数据一起更新 - * @access public - * @param mixed $relation 关联 - * @return $this - */ - public function together($relation) - { - if (is_string($relation)) { - $relation = explode(',', $relation); - } - $this->relationWrite = $relation; - return $this; - } - - /** - * 获取模型对象的主键 - * @access public - * @param string $name 模型名 - * @return mixed - */ - public function getPk($name = '') - { - if (!empty($name)) { - $table = $this->getQuery()->getTable($name); - return $this->getQuery()->getPk($table); - } elseif (empty($this->pk)) { - $this->pk = $this->getQuery()->getPk(); - } - return $this->pk; - } - - /** - * 判断一个字段名是否为主键字段 - * @access public - * @param string $key 名称 - * @return bool - */ - protected function isPk($key) - { - $pk = $this->getPk(); - if (is_string($pk) && $pk == $key) { - return true; - } elseif (is_array($pk) && in_array($key, $pk)) { - return true; - } - return false; - } - - /** - * 新增数据是否使用Replace - * @access public - * @param bool $replace - * @return $this - */ - public function replace($replace = true) - { - $this->replace = $replace; - return $this; - } - - /** - * 保存当前数据对象 - * @access public - * @param array $data 数据 - * @param array $where 更新条件 - * @param string $sequence 自增序列名 - * @return integer|false - */ - public function save($data = [], $where = [], $sequence = null) - { - if (is_string($data)) { - $sequence = $data; - $data = []; - } - - // 数据自动验证 - if (!$this->validateData($data)) { - return false; - } - - // 数据对象赋值 - foreach ($data as $key => $value) { - $this->setAttr($key, $value, $data); - } - - if (!empty($where)) { - $this->isUpdate = true; - $this->updateWhere = $where; - } - - // 自动关联写入 - if (!empty($this->relationWrite)) { - $relation = []; - foreach ($this->relationWrite as $key => $name) { - if (is_array($name)) { - if (key($name) === 0) { - $relation[$key] = []; - foreach ($name as $val) { - if (isset($this->data[$val])) { - $relation[$key][$val] = $this->data[$val]; - unset($this->data[$val]); - } - } - } else { - $relation[$key] = $name; - } - } elseif (isset($this->relation[$name])) { - $relation[$name] = $this->relation[$name]; - } elseif (isset($this->data[$name])) { - $relation[$name] = $this->data[$name]; - unset($this->data[$name]); - } - } - } - - // 数据自动完成 - $this->autoCompleteData($this->auto); - - // 事件回调 - if (false === $this->trigger('before_write', $this)) { - return false; - } - $pk = $this->getPk(); - if ($this->isUpdate) { - // 自动更新 - $this->autoCompleteData($this->update); - - // 事件回调 - if (false === $this->trigger('before_update', $this)) { - return false; - } - - // 获取有更新的数据 - $data = $this->getChangedData(); - - if (empty($data) || (count($data) == 1 && is_string($pk) && isset($data[$pk]))) { - // 关联更新 - if (isset($relation)) { - $this->autoRelationUpdate($relation); - } - return 0; - } elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) { - // 自动写入更新时间 - $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime); - $this->data[$this->updateTime] = $data[$this->updateTime]; - } - - if (empty($where) && !empty($this->updateWhere)) { - $where = $this->updateWhere; - } - - // 保留主键数据 - foreach ($this->data as $key => $val) { - if ($this->isPk($key)) { - $data[$key] = $val; - } - } - - $array = []; - - foreach ((array) $pk as $key) { - if (isset($data[$key])) { - $array[$key] = $data[$key]; - unset($data[$key]); - } - } - - if (!empty($array)) { - $where = $array; - } - - // 检测字段 - $allowFields = $this->checkAllowField(array_merge($this->auto, $this->update)); - - // 模型更新 - if (!empty($allowFields)) { - $result = $this->getQuery()->where($where)->strict(false)->field($allowFields)->update($data); - } else { - $result = $this->getQuery()->where($where)->update($data); - } - - // 关联更新 - if (isset($relation)) { - $this->autoRelationUpdate($relation); - } - - // 更新回调 - $this->trigger('after_update', $this); - - } else { - // 自动写入 - $this->autoCompleteData($this->insert); - - // 自动写入创建时间和更新时间 - if ($this->autoWriteTimestamp) { - if ($this->createTime && !isset($this->data[$this->createTime])) { - $this->data[$this->createTime] = $this->autoWriteTimestamp($this->createTime); - } - if ($this->updateTime && !isset($this->data[$this->updateTime])) { - $this->data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime); - } - } - - if (false === $this->trigger('before_insert', $this)) { - return false; - } - - // 检测字段 - $allowFields = $this->checkAllowField(array_merge($this->auto, $this->insert)); - if (!empty($allowFields)) { - $result = $this->getQuery()->strict(false)->field($allowFields)->insert($this->data, $this->replace, false, $sequence); - } else { - $result = $this->getQuery()->insert($this->data, $this->replace, false, $sequence); - } - - // 获取自动增长主键 - if ($result && $insertId = $this->getQuery()->getLastInsID($sequence)) { - foreach ((array) $pk as $key) { - if (!isset($this->data[$key]) || '' == $this->data[$key]) { - $this->data[$key] = $insertId; - } - } - } - - // 关联写入 - if (isset($relation)) { - foreach ($relation as $name => $val) { - $method = Loader::parseName($name, 1, false); - $this->$method()->save($val); - } - } - - // 标记为更新 - $this->isUpdate = true; - - // 新增回调 - $this->trigger('after_insert', $this); - } - // 写入回调 - $this->trigger('after_write', $this); - - // 重新记录原始数据 - $this->origin = $this->data; - - return $result; - } - - protected function checkAllowField($auto = []) - { - if (true === $this->field) { - $this->field = $this->getQuery()->getTableInfo('', 'fields'); - $field = $this->field; - } elseif (!empty($this->field)) { - $field = array_merge($this->field, $auto); - if ($this->autoWriteTimestamp) { - array_push($field, $this->createTime, $this->updateTime); - } - } elseif (!empty($this->except)) { - $fields = $this->getQuery()->getTableInfo('', 'fields'); - $field = array_diff($fields, (array) $this->except); - $this->field = $field; - } else { - $field = []; - } - - if ($this->disuse) { - // 废弃字段 - $field = array_diff($field, (array) $this->disuse); - } - return $field; - } - - protected function autoRelationUpdate($relation) - { - foreach ($relation as $name => $val) { - if ($val instanceof Model) { - $val->save(); - } else { - unset($this->data[$name]); - $model = $this->getAttr($name); - if ($model instanceof Model) { - $model->save($val); - } - } - } - } - - /** - * 获取变化的数据 并排除只读数据 - * @access public - * @return array - */ - public function getChangedData() - { - if ($this->force) { - $data = $this->data; - } else { - $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) { - if ((empty($a) || empty($b)) && $a !== $b) { - return 1; - } - return is_object($a) || $a != $b ? 1 : 0; - }); - } - - if (!empty($this->readonly)) { - // 只读字段不允许更新 - foreach ($this->readonly as $key => $field) { - if (isset($data[$field])) { - unset($data[$field]); - } - } - } - - return $data; - } - - /** - * 字段值(延迟)增长 - * @access public - * @param string $field 字段名 - * @param integer $step 增长值 - * @param integer $lazyTime 延时时间(s) - * @return integer|true - * @throws Exception - */ - public function setInc($field, $step = 1, $lazyTime = 0) - { - // 更新条件 - $where = $this->getWhere(); - - $result = $this->getQuery()->where($where)->setInc($field, $step, $lazyTime); - if (true !== $result) { - $this->data[$field] += $step; - } - - return $result; - } - - /** - * 字段值(延迟)增长 - * @access public - * @param string $field 字段名 - * @param integer $step 增长值 - * @param integer $lazyTime 延时时间(s) - * @return integer|true - * @throws Exception - */ - public function setDec($field, $step = 1, $lazyTime = 0) - { - // 更新条件 - $where = $this->getWhere(); - $result = $this->getQuery()->where($where)->setDec($field, $step, $lazyTime); - if (true !== $result) { - $this->data[$field] -= $step; - } - - return $result; - } - - /** - * 获取更新条件 - * @access protected - * @return mixed - */ - protected function getWhere() - { - // 删除条件 - $pk = $this->getPk(); - - if (is_string($pk) && isset($this->data[$pk])) { - $where = [$pk => $this->data[$pk]]; - } elseif (!empty($this->updateWhere)) { - $where = $this->updateWhere; - } else { - $where = null; - } - return $where; - } - - /** - * 保存多个数据到当前数据对象 - * @access public - * @param array $dataSet 数据 - * @param boolean $replace 是否自动识别更新和写入 - * @return array|false - * @throws \Exception - */ - public function saveAll($dataSet, $replace = true) - { - if ($this->validate) { - // 数据批量验证 - $validate = $this->validate; - foreach ($dataSet as $data) { - if (!$this->validateData($data, $validate)) { - return false; - } - } - } - - $result = []; - $db = $this->getQuery(); - $db->startTrans(); - try { - $pk = $this->getPk(); - if (is_string($pk) && $replace) { - $auto = true; - } - foreach ($dataSet as $key => $data) { - if ($this->isUpdate || (!empty($auto) && isset($data[$pk]))) { - $result[$key] = self::update($data, [], $this->field); - } else { - $result[$key] = self::create($data, $this->field); - } - } - $db->commit(); - return $this->toCollection($result); - } catch (\Exception $e) { - $db->rollback(); - throw $e; - } - } - - /** - * 设置允许写入的字段 - * @access public - * @param string|array $field 允许写入的字段 如果为true只允许写入数据表字段 - * @return $this - */ - public function allowField($field) - { - if (is_string($field)) { - $field = explode(',', $field); - } - $this->field = $field; - return $this; - } - - /** - * 设置排除写入的字段 - * @access public - * @param string|array $field 排除允许写入的字段 - * @return $this - */ - public function except($field) - { - if (is_string($field)) { - $field = explode(',', $field); - } - $this->except = $field; - return $this; - } - - /** - * 设置只读字段 - * @access public - * @param mixed $field 只读字段 - * @return $this - */ - public function readonly($field) - { - if (is_string($field)) { - $field = explode(',', $field); - } - $this->readonly = $field; - return $this; - } - - /** - * 是否为更新数据 - * @access public - * @param bool $update - * @param mixed $where - * @return $this - */ - public function isUpdate($update = true, $where = null) - { - $this->isUpdate = $update; - if (!empty($where)) { - $this->updateWhere = $where; - } - return $this; - } - - /** - * 数据自动完成 - * @access public - * @param array $auto 要自动更新的字段列表 - * @return void - */ - protected function autoCompleteData($auto = []) - { - foreach ($auto as $field => $value) { - if (is_integer($field)) { - $field = $value; - $value = null; - } - - if (!isset($this->data[$field])) { - $default = null; - } else { - $default = $this->data[$field]; - } - - $this->setAttr($field, !is_null($value) ? $value : $default); - } - } - - /** - * 删除当前的记录 - * @access public - * @return integer - */ - public function delete() - { - if (false === $this->trigger('before_delete', $this)) { - return false; - } - - // 删除条件 - $where = $this->getWhere(); - - // 删除当前模型数据 - $result = $this->getQuery()->where($where)->delete(); - - // 关联删除 - if (!empty($this->relationWrite)) { - foreach ($this->relationWrite as $key => $name) { - $name = is_numeric($key) ? $name : $key; - $model = $this->getAttr($name); - if ($model instanceof Model) { - $model->delete(); - } - } - } - - $this->trigger('after_delete', $this); - // 清空原始数据 - $this->origin = []; - - return $result; - } - - /** - * 设置自动完成的字段( 规则通过修改器定义) - * @access public - * @param array $fields 需要自动完成的字段 - * @return $this - */ - public function auto($fields) - { - $this->auto = $fields; - return $this; - } - - /** - * 设置字段验证 - * @access public - * @param array|string|bool $rule 验证规则 true表示自动读取验证器类 - * @param array $msg 提示信息 - * @param bool $batch 批量验证 - * @return $this - */ - public function validate($rule = true, $msg = [], $batch = false) - { - if (is_array($rule)) { - $this->validate = [ - 'rule' => $rule, - 'msg' => $msg, - ]; - } else { - $this->validate = true === $rule ? $this->name : $rule; - } - $this->batchValidate = $batch; - return $this; - } - - /** - * 设置验证失败后是否抛出异常 - * @access public - * @param bool $fail 是否抛出异常 - * @return $this - */ - public function validateFailException($fail = true) - { - $this->failException = $fail; - return $this; - } - - /** - * 自动验证数据 - * @access protected - * @param array $data 验证数据 - * @param mixed $rule 验证规则 - * @param bool $batch 批量验证 - * @return bool - */ - protected function validateData($data, $rule = null, $batch = null) - { - $info = is_null($rule) ? $this->validate : $rule; - - if (!empty($info)) { - if (is_array($info)) { - $validate = Loader::validate(); - $validate->rule($info['rule']); - $validate->message($info['msg']); - } else { - $name = is_string($info) ? $info : $this->name; - if (strpos($name, '.')) { - list($name, $scene) = explode('.', $name); - } - $validate = Loader::validate($name); - if (!empty($scene)) { - $validate->scene($scene); - } - } - $batch = is_null($batch) ? $this->batchValidate : $batch; - - if (!$validate->batch($batch)->check($data)) { - $this->error = $validate->getError(); - if ($this->failException) { - throw new ValidateException($this->error); - } else { - return false; - } - } - $this->validate = null; - } - return true; - } - - /** - * 返回模型的错误信息 - * @access public - * @return string|array - */ - public function getError() - { - return $this->error; - } - - /** - * 注册回调方法 - * @access public - * @param string $event 事件名 - * @param callable $callback 回调方法 - * @param bool $override 是否覆盖 - * @return void - */ - public static function event($event, $callback, $override = false) - { - $class = get_called_class(); - if ($override) { - self::$event[$class][$event] = []; - } - self::$event[$class][$event][] = $callback; - } - - /** - * 触发事件 - * @access protected - * @param string $event 事件名 - * @param mixed $params 传入参数(引用) - * @return bool - */ - protected function trigger($event, &$params) - { - if (isset(self::$event[$this->class][$event])) { - foreach (self::$event[$this->class][$event] as $callback) { - if (is_callable($callback)) { - $result = call_user_func_array($callback, [ & $params]); - if (false === $result) { - return false; - } - } - } - } - return true; - } - - /** - * 写入数据 - * @access public - * @param array $data 数据数组 - * @param array|true $field 允许字段 - * @return $this - */ - public static function create($data = [], $field = null) - { - $model = new static(); - if (!empty($field)) { - $model->allowField($field); - } - $model->isUpdate(false)->save($data, []); - return $model; - } - - /** - * 更新数据 - * @access public - * @param array $data 数据数组 - * @param array $where 更新条件 - * @param array|true $field 允许字段 - * @return $this - */ - public static function update($data = [], $where = [], $field = null) - { - $model = new static(); - if (!empty($field)) { - $model->allowField($field); - } - $result = $model->isUpdate(true)->save($data, $where); - return $model; - } - - /** - * 查找单条记录 - * @access public - * @param mixed $data 主键值或者查询条件(闭包) - * @param array|string $with 关联预查询 - * @param bool $cache 是否缓存 - * @return static|null - * @throws exception\DbException - */ - public static function get($data, $with = [], $cache = false) - { - if (is_null($data)) { - return; - } - - if (true === $with || is_int($with)) { - $cache = $with; - $with = []; - } - $query = static::parseQuery($data, $with, $cache); - return $query->find($data); - } - - /** - * 查找所有记录 - * @access public - * @param mixed $data 主键列表或者查询条件(闭包) - * @param array|string $with 关联预查询 - * @param bool $cache 是否缓存 - * @return static[]|false - * @throws exception\DbException - */ - public static function all($data = null, $with = [], $cache = false) - { - if (true === $with || is_int($with)) { - $cache = $with; - $with = []; - } - $query = static::parseQuery($data, $with, $cache); - return $query->select($data); - } - - /** - * 分析查询表达式 - * @access public - * @param mixed $data 主键列表或者查询条件(闭包) - * @param string $with 关联预查询 - * @param bool $cache 是否缓存 - * @return Query - */ - protected static function parseQuery(&$data, $with, $cache) - { - $result = self::with($with)->cache($cache); - if (is_array($data) && key($data) !== 0) { - $result = $result->where($data); - $data = null; - } elseif ($data instanceof \Closure) { - call_user_func_array($data, [ & $result]); - $data = null; - } elseif ($data instanceof Query) { - $result = $data->with($with)->cache($cache); - $data = null; - } - return $result; - } - - /** - * 删除记录 - * @access public - * @param mixed $data 主键列表 支持闭包查询条件 - * @return integer 成功删除的记录数 - */ - public static function destroy($data) - { - $model = new static(); - $query = $model->db(); - if (empty($data) && 0 !== $data) { - return 0; - } elseif (is_array($data) && key($data) !== 0) { - $query->where($data); - $data = null; - } elseif ($data instanceof \Closure) { - call_user_func_array($data, [ & $query]); - $data = null; - } - $resultSet = $query->select($data); - $count = 0; - if ($resultSet) { - foreach ($resultSet as $data) { - $result = $data->delete(); - $count += $result; - } - } - return $count; - } - - /** - * 命名范围 - * @access public - * @param string|array|\Closure $name 命名范围名称 逗号分隔 - * @internal mixed ...$params 参数调用 - * @return Query - */ - public static function scope($name) - { - $model = new static(); - $query = $model->db(); - $params = func_get_args(); - array_shift($params); - array_unshift($params, $query); - if ($name instanceof \Closure) { - call_user_func_array($name, $params); - } elseif (is_string($name)) { - $name = explode(',', $name); - } - if (is_array($name)) { - foreach ($name as $scope) { - $method = 'scope' . trim($scope); - if (method_exists($model, $method)) { - call_user_func_array([$model, $method], $params); - } - } - } - return $query; - } - - /** - * 设置是否使用全局查询范围 - * @param bool $use 是否启用全局查询范围 - * @access public - * @return Query - */ - public static function useGlobalScope($use) - { - $model = new static(); - return $model->db($use); - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $relation 关联方法名 - * @param mixed $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @return Relation|Query - */ - public static function has($relation, $operator = '>=', $count = 1, $id = '*') - { - $relation = (new static())->$relation(); - if (is_array($operator) || $operator instanceof \Closure) { - return $relation->hasWhere($operator); - } - return $relation->has($operator, $count, $id); - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $relation 关联方法名 - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Relation|Query - */ - public static function hasWhere($relation, $where = [], $fields = null) - { - return (new static())->$relation()->hasWhere($where, $fields); - } - - /** - * 解析模型的完整命名空间 - * @access public - * @param string $model 模型名(或者完整类名) - * @return string - */ - protected function parseModel($model) - { - if (false === strpos($model, '\\')) { - $path = explode('\\', get_called_class()); - array_pop($path); - array_push($path, Loader::parseName($model, 1)); - $model = implode('\\', $path); - } - return $model; - } - - /** - * 查询当前模型的关联数据 - * @access public - * @param string|array $relations 关联名 - * @return $this - */ - public function relationQuery($relations) - { - if (is_string($relations)) { - $relations = explode(',', $relations); - } - - foreach ($relations as $key => $relation) { - $subRelation = ''; - $closure = null; - if ($relation instanceof \Closure) { - // 支持闭包查询过滤关联条件 - $closure = $relation; - $relation = $key; - } - if (is_array($relation)) { - $subRelation = $relation; - $relation = $key; - } elseif (strpos($relation, '.')) { - list($relation, $subRelation) = explode('.', $relation, 2); - } - $method = Loader::parseName($relation, 1, false); - $this->data[$relation] = $this->$method()->getRelation($subRelation, $closure); - } - return $this; - } - - /** - * 预载入关联查询 返回数据集 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 关联名 - * @return array - */ - public function eagerlyResultSet(&$resultSet, $relation) - { - $relations = is_string($relation) ? explode(',', $relation) : $relation; - foreach ($relations as $key => $relation) { - $subRelation = ''; - $closure = false; - if ($relation instanceof \Closure) { - $closure = $relation; - $relation = $key; - } - if (is_array($relation)) { - $subRelation = $relation; - $relation = $key; - } elseif (strpos($relation, '.')) { - list($relation, $subRelation) = explode('.', $relation, 2); - } - $relation = Loader::parseName($relation, 1, false); - $this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure); - } - } - - /** - * 预载入关联查询 返回模型对象 - * @access public - * @param Model $result 数据对象 - * @param string $relation 关联名 - * @return Model - */ - public function eagerlyResult(&$result, $relation) - { - $relations = is_string($relation) ? explode(',', $relation) : $relation; - - foreach ($relations as $key => $relation) { - $subRelation = ''; - $closure = false; - if ($relation instanceof \Closure) { - $closure = $relation; - $relation = $key; - } - if (is_array($relation)) { - $subRelation = $relation; - $relation = $key; - } elseif (strpos($relation, '.')) { - list($relation, $subRelation) = explode('.', $relation, 2); - } - $relation = Loader::parseName($relation, 1, false); - $this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure); - } - } - - /** - * 关联统计 - * @access public - * @param Model $result 数据对象 - * @param string|array $relation 关联名 - * @return void - */ - public function relationCount(&$result, $relation) - { - $relations = is_string($relation) ? explode(',', $relation) : $relation; - - foreach ($relations as $key => $relation) { - $closure = false; - if ($relation instanceof \Closure) { - $closure = $relation; - $relation = $key; - } elseif (is_string($key)) { - $name = $relation; - $relation = $key; - } - $relation = Loader::parseName($relation, 1, false); - $count = $this->$relation()->relationCount($result, $closure); - if (!isset($name)) { - $name = Loader::parseName($relation) . '_count'; - } - $result->setAttr($name, $count); - } - } - - /** - * 获取模型的默认外键名 - * @access public - * @param string $name 模型名 - * @return string - */ - protected function getForeignKey($name) - { - if (strpos($name, '\\')) { - $name = basename(str_replace('\\', '/', $name)); - } - return Loader::parseName($name) . '_id'; - } - - /** - * HAS ONE 关联定义 - * @access public - * @param string $model 模型名 - * @param string $foreignKey 关联外键 - * @param string $localKey 当前模型主键 - * @param array $alias 别名定义(已经废弃) - * @param string $joinType JOIN类型 - * @return HasOne - */ - public function hasOne($model, $foreignKey = '', $localKey = '', $alias = [], $joinType = 'INNER') - { - // 记录当前关联信息 - $model = $this->parseModel($model); - $localKey = $localKey ?: $this->getPk(); - $foreignKey = $foreignKey ?: $this->getForeignKey($this->name); - return new HasOne($this, $model, $foreignKey, $localKey, $joinType); - } - - /** - * BELONGS TO 关联定义 - * @access public - * @param string $model 模型名 - * @param string $foreignKey 关联外键 - * @param string $localKey 关联主键 - * @param array $alias 别名定义(已经废弃) - * @param string $joinType JOIN类型 - * @return BelongsTo - */ - public function belongsTo($model, $foreignKey = '', $localKey = '', $alias = [], $joinType = 'INNER') - { - // 记录当前关联信息 - $model = $this->parseModel($model); - $foreignKey = $foreignKey ?: $this->getForeignKey($model); - $localKey = $localKey ?: (new $model)->getPk(); - $trace = debug_backtrace(false, 2); - $relation = Loader::parseName($trace[1]['function']); - return new BelongsTo($this, $model, $foreignKey, $localKey, $joinType, $relation); - } - - /** - * HAS MANY 关联定义 - * @access public - * @param string $model 模型名 - * @param string $foreignKey 关联外键 - * @param string $localKey 当前模型主键 - * @return HasMany - */ - public function hasMany($model, $foreignKey = '', $localKey = '') - { - // 记录当前关联信息 - $model = $this->parseModel($model); - $localKey = $localKey ?: $this->getPk(); - $foreignKey = $foreignKey ?: $this->getForeignKey($this->name); - return new HasMany($this, $model, $foreignKey, $localKey); - } - - /** - * HAS MANY 远程关联定义 - * @access public - * @param string $model 模型名 - * @param string $through 中间模型名 - * @param string $foreignKey 关联外键 - * @param string $throughKey 关联外键 - * @param string $localKey 当前模型主键 - * @return HasManyThrough - */ - public function hasManyThrough($model, $through, $foreignKey = '', $throughKey = '', $localKey = '') - { - // 记录当前关联信息 - $model = $this->parseModel($model); - $through = $this->parseModel($through); - $localKey = $localKey ?: $this->getPk(); - $foreignKey = $foreignKey ?: $this->getForeignKey($this->name); - $throughKey = $throughKey ?: $this->getForeignKey($through); - return new HasManyThrough($this, $model, $through, $foreignKey, $throughKey, $localKey); - } - - /** - * BELONGS TO MANY 关联定义 - * @access public - * @param string $model 模型名 - * @param string $table 中间表名 - * @param string $foreignKey 关联外键 - * @param string $localKey 当前模型关联键 - * @return BelongsToMany - */ - public function belongsToMany($model, $table = '', $foreignKey = '', $localKey = '') - { - // 记录当前关联信息 - $model = $this->parseModel($model); - $name = Loader::parseName(basename(str_replace('\\', '/', $model))); - $table = $table ?: Loader::parseName($this->name) . '_' . $name; - $foreignKey = $foreignKey ?: $name . '_id'; - $localKey = $localKey ?: $this->getForeignKey($this->name); - return new BelongsToMany($this, $model, $table, $foreignKey, $localKey); - } - - /** - * MORPH MANY 关联定义 - * @access public - * @param string $model 模型名 - * @param string|array $morph 多态字段信息 - * @param string $type 多态类型 - * @return MorphMany - */ - public function morphMany($model, $morph = null, $type = '') - { - // 记录当前关联信息 - $model = $this->parseModel($model); - if (is_null($morph)) { - $trace = debug_backtrace(false, 2); - $morph = Loader::parseName($trace[1]['function']); - } - $type = $type ?: get_class($this); - if (is_array($morph)) { - list($morphType, $foreignKey) = $morph; - } else { - $morphType = $morph . '_type'; - $foreignKey = $morph . '_id'; - } - return new MorphMany($this, $model, $foreignKey, $morphType, $type); - } - - /** - * MORPH One 关联定义 - * @access public - * @param string $model 模型名 - * @param string|array $morph 多态字段信息 - * @param string $type 多态类型 - * @return MorphOne - */ - public function morphOne($model, $morph = null, $type = '') - { - // 记录当前关联信息 - $model = $this->parseModel($model); - if (is_null($morph)) { - $trace = debug_backtrace(false, 2); - $morph = Loader::parseName($trace[1]['function']); - } - $type = $type ?: get_class($this); - if (is_array($morph)) { - list($morphType, $foreignKey) = $morph; - } else { - $morphType = $morph . '_type'; - $foreignKey = $morph . '_id'; - } - return new MorphOne($this, $model, $foreignKey, $morphType, $type); - } - - /** - * MORPH TO 关联定义 - * @access public - * @param string|array $morph 多态字段信息 - * @param array $alias 多态别名定义 - * @return MorphTo - */ - public function morphTo($morph = null, $alias = []) - { - $trace = debug_backtrace(false, 2); - $relation = Loader::parseName($trace[1]['function']); - - if (is_null($morph)) { - $morph = $relation; - } - // 记录当前关联信息 - if (is_array($morph)) { - list($morphType, $foreignKey) = $morph; - } else { - $morphType = $morph . '_type'; - $foreignKey = $morph . '_id'; - } - return new MorphTo($this, $morphType, $foreignKey, $alias, $relation); - } - - public function __call($method, $args) - { - $query = $this->db(true, false); - if (method_exists($this, 'scope' . $method)) { - // 动态调用命名范围 - $method = 'scope' . $method; - array_unshift($args, $query); - call_user_func_array([$this, $method], $args); - return $this; - } else { - return call_user_func_array([$query, $method], $args); - } - } - - public static function __callStatic($method, $args) - { - $model = new static(); - $query = $model->db(); - if (method_exists($model, 'scope' . $method)) { - // 动态调用命名范围 - $method = 'scope' . $method; - array_unshift($args, $query); - - call_user_func_array([$model, $method], $args); - return $query; - } else { - return call_user_func_array([$query, $method], $args); - } - } - - /** - * 修改器 设置数据对象的值 - * @access public - * @param string $name 名称 - * @param mixed $value 值 - * @return void - */ - public function __set($name, $value) - { - $this->setAttr($name, $value); - } - - /** - * 获取器 获取数据对象的值 - * @access public - * @param string $name 名称 - * @return mixed - */ - public function __get($name) - { - return $this->getAttr($name); - } - - /** - * 检测数据对象的值 - * @access public - * @param string $name 名称 - * @return boolean - */ - public function __isset($name) - { - try { - if (array_key_exists($name, $this->data) || array_key_exists($name, $this->relation)) { - return true; - } else { - $this->getAttr($name); - return true; - } - } catch (InvalidArgumentException $e) { - return false; - } - - } - - /** - * 销毁数据对象的值 - * @access public - * @param string $name 名称 - * @return void - */ - public function __unset($name) - { - unset($this->data[$name], $this->relation[$name]); - } - - public function __toString() - { - return $this->toJson(); - } - - // JsonSerializable - public function jsonSerialize() - { - return $this->toArray(); - } - - // ArrayAccess - public function offsetSet($name, $value) - { - $this->setAttr($name, $value); - } - - public function offsetExists($name) - { - return $this->__isset($name); - } - - public function offsetUnset($name) - { - $this->__unset($name); - } - - public function offsetGet($name) - { - return $this->getAttr($name); - } - - /** - * 解序列化后处理 - */ - public function __wakeup() - { - $this->initialize(); - } - - /** - * 模型事件快捷方法 - * @param $callback - * @param bool $override - */ - protected static function beforeInsert($callback, $override = false) - { - self::event('before_insert', $callback, $override); - } - - protected static function afterInsert($callback, $override = false) - { - self::event('after_insert', $callback, $override); - } - - protected static function beforeUpdate($callback, $override = false) - { - self::event('before_update', $callback, $override); - } - - protected static function afterUpdate($callback, $override = false) - { - self::event('after_update', $callback, $override); - } - - protected static function beforeWrite($callback, $override = false) - { - self::event('before_write', $callback, $override); - } - - protected static function afterWrite($callback, $override = false) - { - self::event('after_write', $callback, $override); - } - - protected static function beforeDelete($callback, $override = false) - { - self::event('before_delete', $callback, $override); - } - - protected static function afterDelete($callback, $override = false) - { - self::event('after_delete', $callback, $override); - } - -} diff --git a/thinkphp/library/think/Paginator.php b/thinkphp/library/think/Paginator.php deleted file mode 100755 index 3655567..0000000 --- a/thinkphp/library/think/Paginator.php +++ /dev/null @@ -1,409 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use ArrayAccess; -use ArrayIterator; -use Countable; -use IteratorAggregate; -use JsonSerializable; -use Traversable; - -abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable -{ - /** @var bool 是否为简洁模式 */ - protected $simple = false; - - /** @var Collection 数据集 */ - protected $items; - - /** @var integer 当前页 */ - protected $currentPage; - - /** @var integer 最后一页 */ - protected $lastPage; - - /** @var integer|null 数据总数 */ - protected $total; - - /** @var integer 每页的数量 */ - protected $listRows; - - /** @var bool 是否有下一页 */ - protected $hasMore; - - /** @var array 一些配置 */ - protected $options = [ - 'var_page' => 'page', - 'path' => '/', - 'query' => [], - 'fragment' => '', - ]; - - /** @var mixed simple模式下的下个元素 */ - protected $nextItem; - - public function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = []) - { - $this->options = array_merge($this->options, $options); - - $this->options['path'] = '/' != $this->options['path'] ? rtrim($this->options['path'], '/') : $this->options['path']; - - $this->simple = $simple; - $this->listRows = $listRows; - - if (!$items instanceof Collection) { - $items = Collection::make($items); - } - - if ($simple) { - $this->currentPage = $this->setCurrentPage($currentPage); - $this->hasMore = count($items) > ($this->listRows); - if ($this->hasMore) { - $this->nextItem = $items->slice($this->listRows, 1); - } - $items = $items->slice(0, $this->listRows); - } else { - $this->total = $total; - $this->lastPage = (int) ceil($total / $listRows); - $this->currentPage = $this->setCurrentPage($currentPage); - $this->hasMore = $this->currentPage < $this->lastPage; - } - $this->items = $items; - } - - /** - * @param $items - * @param $listRows - * @param null $currentPage - * @param bool $simple - * @param null $total - * @param array $options - * @return Paginator - */ - public static function make($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = []) - { - return new static($items, $listRows, $currentPage, $total, $simple, $options); - } - - protected function setCurrentPage($currentPage) - { - if (!$this->simple && $currentPage > $this->lastPage) { - return $this->lastPage > 0 ? $this->lastPage : 1; - } - - return $currentPage; - } - - /** - * 获取页码对应的链接 - * - * @param $page - * @return string - */ - protected function url($page) - { - if ($page <= 0) { - $page = 1; - } - - if (strpos($this->options['path'], '[PAGE]') === false) { - $parameters = [$this->options['var_page'] => $page]; - $path = $this->options['path']; - } else { - $parameters = []; - $path = str_replace('[PAGE]', $page, $this->options['path']); - } - if (count($this->options['query']) > 0) { - $parameters = array_merge($this->options['query'], $parameters); - } - $url = $path; - if (!empty($parameters)) { - $url .= '?' . http_build_query($parameters, null, '&'); - } - return $url . $this->buildFragment(); - } - - /** - * 自动获取当前页码 - * @param string $varPage - * @param int $default - * @return int - */ - public static function getCurrentPage($varPage = 'page', $default = 1) - { - $page = (int) Request::instance()->param($varPage); - - if (filter_var($page, FILTER_VALIDATE_INT) !== false && $page >= 1) { - return $page; - } - - return $default; - } - - /** - * 自动获取当前的path - * @return string - */ - public static function getCurrentPath() - { - return Request::instance()->baseUrl(); - } - - public function total() - { - if ($this->simple) { - throw new \DomainException('not support total'); - } - return $this->total; - } - - public function listRows() - { - return $this->listRows; - } - - public function currentPage() - { - return $this->currentPage; - } - - public function lastPage() - { - if ($this->simple) { - throw new \DomainException('not support last'); - } - return $this->lastPage; - } - - /** - * 数据是否足够分页 - * @return boolean - */ - public function hasPages() - { - return !(1 == $this->currentPage && !$this->hasMore); - } - - /** - * 创建一组分页链接 - * - * @param int $start - * @param int $end - * @return array - */ - public function getUrlRange($start, $end) - { - $urls = []; - - for ($page = $start; $page <= $end; $page++) { - $urls[$page] = $this->url($page); - } - - return $urls; - } - - /** - * 设置URL锚点 - * - * @param string|null $fragment - * @return $this - */ - public function fragment($fragment) - { - $this->options['fragment'] = $fragment; - return $this; - } - - /** - * 添加URL参数 - * - * @param array|string $key - * @param string|null $value - * @return $this - */ - public function appends($key, $value = null) - { - if (!is_array($key)) { - $queries = [$key => $value]; - } else { - $queries = $key; - } - - foreach ($queries as $k => $v) { - if ($k !== $this->options['var_page']) { - $this->options['query'][$k] = $v; - } - } - - return $this; - } - - /** - * 构造锚点字符串 - * - * @return string - */ - protected function buildFragment() - { - return $this->options['fragment'] ? '#' . $this->options['fragment'] : ''; - } - - /** - * 渲染分页html - * @return mixed - */ - abstract public function render(); - - public function items() - { - return $this->items->all(); - } - - public function getCollection() - { - return $this->items; - } - - public function isEmpty() - { - return $this->items->isEmpty(); - } - - /** - * 给每个元素执行个回调 - * - * @param callable $callback - * @return $this - */ - public function each(callable $callback) - { - foreach ($this->items as $key => $item) { - $result = $callback($item, $key); - if (false === $result) { - break; - } elseif (!is_object($item)) { - $this->items[$key] = $result; - } - } - - return $this; - } - - /** - * Retrieve an external iterator - * @return Traversable An instance of an object implementing Iterator or - * Traversable - */ - public function getIterator() - { - return new ArrayIterator($this->items->all()); - } - - /** - * Whether a offset exists - * @param mixed $offset - * @return bool - */ - public function offsetExists($offset) - { - return $this->items->offsetExists($offset); - } - - /** - * Offset to retrieve - * @param mixed $offset - * @return mixed - */ - public function offsetGet($offset) - { - return $this->items->offsetGet($offset); - } - - /** - * Offset to set - * @param mixed $offset - * @param mixed $value - */ - public function offsetSet($offset, $value) - { - $this->items->offsetSet($offset, $value); - } - - /** - * Offset to unset - * @param mixed $offset - * @return void - * @since 5.0.0 - */ - public function offsetUnset($offset) - { - $this->items->offsetUnset($offset); - } - - /** - * Count elements of an object - */ - public function count() - { - return $this->items->count(); - } - - public function __toString() - { - return (string) $this->render(); - } - - public function toArray() - { - if ($this->simple) { - return [ - 'per_page' => $this->listRows, - 'current_page' => $this->currentPage, - 'has_more' => $this->hasMore, - 'next_item' => $this->nextItem, - 'data' => $this->items->toArray(), - ]; - } else { - return [ - 'total' => $this->total, - 'per_page' => $this->listRows, - 'current_page' => $this->currentPage, - 'last_page' => $this->lastPage, - 'data' => $this->items->toArray(), - ]; - } - - } - - /** - * Specify data which should be serialized to JSON - */ - public function jsonSerialize() - { - return $this->toArray(); - } - - public function __call($name, $arguments) - { - $collection = $this->getCollection(); - - $result = call_user_func_array([$collection, $name], $arguments); - - if ($result === $collection) { - return $this; - } - - return $result; - } - -} diff --git a/thinkphp/library/think/Process.php b/thinkphp/library/think/Process.php deleted file mode 100755 index 6f3faa3..0000000 --- a/thinkphp/library/think/Process.php +++ /dev/null @@ -1,1205 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\process\exception\Failed as ProcessFailedException; -use think\process\exception\Timeout as ProcessTimeoutException; -use think\process\pipes\Pipes; -use think\process\pipes\Unix as UnixPipes; -use think\process\pipes\Windows as WindowsPipes; -use think\process\Utils; - -class Process -{ - - const ERR = 'err'; - const OUT = 'out'; - - const STATUS_READY = 'ready'; - const STATUS_STARTED = 'started'; - const STATUS_TERMINATED = 'terminated'; - - const STDIN = 0; - const STDOUT = 1; - const STDERR = 2; - - const TIMEOUT_PRECISION = 0.2; - - private $callback; - private $commandline; - private $cwd; - private $env; - private $input; - private $starttime; - private $lastOutputTime; - private $timeout; - private $idleTimeout; - private $options; - private $exitcode; - private $fallbackExitcode; - private $processInformation; - private $outputDisabled = false; - private $stdout; - private $stderr; - private $enhanceWindowsCompatibility = true; - private $enhanceSigchildCompatibility; - private $process; - private $status = self::STATUS_READY; - private $incrementalOutputOffset = 0; - private $incrementalErrorOutputOffset = 0; - private $tty; - private $pty; - - private $useFileHandles = false; - - /** @var Pipes */ - private $processPipes; - - private $latestSignal; - - private static $sigchild; - - /** - * @var array - */ - public static $exitCodes = [ - 0 => 'OK', - 1 => 'General error', - 2 => 'Misuse of shell builtins', - 126 => 'Invoked command cannot execute', - 127 => 'Command not found', - 128 => 'Invalid exit argument', - // signals - 129 => 'Hangup', - 130 => 'Interrupt', - 131 => 'Quit and dump core', - 132 => 'Illegal instruction', - 133 => 'Trace/breakpoint trap', - 134 => 'Process aborted', - 135 => 'Bus error: "access to undefined portion of memory object"', - 136 => 'Floating point exception: "erroneous arithmetic operation"', - 137 => 'Kill (terminate immediately)', - 138 => 'User-defined 1', - 139 => 'Segmentation violation', - 140 => 'User-defined 2', - 141 => 'Write to pipe with no one reading', - 142 => 'Signal raised by alarm', - 143 => 'Termination (request to terminate)', - // 144 - not defined - 145 => 'Child process terminated, stopped (or continued*)', - 146 => 'Continue if stopped', - 147 => 'Stop executing temporarily', - 148 => 'Terminal stop signal', - 149 => 'Background process attempting to read from tty ("in")', - 150 => 'Background process attempting to write to tty ("out")', - 151 => 'Urgent data available on socket', - 152 => 'CPU time limit exceeded', - 153 => 'File size limit exceeded', - 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"', - 155 => 'Profiling timer expired', - // 156 - not defined - 157 => 'Pollable event', - // 158 - not defined - 159 => 'Bad syscall', - ]; - - /** - * 构造方法 - * @param string $commandline 指令 - * @param string|null $cwd 工作目录 - * @param array|null $env 环境变量 - * @param string|null $input 输入 - * @param int|float|null $timeout 超时时间 - * @param array $options proc_open的选项 - * @throws \RuntimeException - * @api - */ - public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = []) - { - if (!function_exists('proc_open')) { - throw new \RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); - } - - $this->commandline = $commandline; - $this->cwd = $cwd; - - if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DS)) { - $this->cwd = getcwd(); - } - if (null !== $env) { - $this->setEnv($env); - } - - $this->input = $input; - $this->setTimeout($timeout); - $this->useFileHandles = '\\' === DS; - $this->pty = false; - $this->enhanceWindowsCompatibility = true; - $this->enhanceSigchildCompatibility = '\\' !== DS && $this->isSigchildEnabled(); - $this->options = array_replace([ - 'suppress_errors' => true, - 'binary_pipes' => true, - ], $options); - } - - public function __destruct() - { - $this->stop(); - } - - public function __clone() - { - $this->resetProcessData(); - } - - /** - * 运行指令 - * @param callback|null $callback - * @return int - */ - public function run($callback = null) - { - $this->start($callback); - - return $this->wait(); - } - - /** - * 运行指令 - * @param callable|null $callback - * @return self - * @throws \RuntimeException - * @throws ProcessFailedException - */ - public function mustRun($callback = null) - { - if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { - throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); - } - - if (0 !== $this->run($callback)) { - throw new ProcessFailedException($this); - } - - return $this; - } - - /** - * 启动进程并写到 STDIN 输入后返回。 - * @param callable|null $callback - * @throws \RuntimeException - * @throws \RuntimeException - * @throws \LogicException - */ - public function start($callback = null) - { - if ($this->isRunning()) { - throw new \RuntimeException('Process is already running'); - } - if ($this->outputDisabled && null !== $callback) { - throw new \LogicException('Output has been disabled, enable it to allow the use of a callback.'); - } - - $this->resetProcessData(); - $this->starttime = $this->lastOutputTime = microtime(true); - $this->callback = $this->buildCallback($callback); - $descriptors = $this->getDescriptors(); - - $commandline = $this->commandline; - - if ('\\' === DS && $this->enhanceWindowsCompatibility) { - $commandline = 'cmd /V:ON /E:ON /C "(' . $commandline . ')'; - foreach ($this->processPipes->getFiles() as $offset => $filename) { - $commandline .= ' ' . $offset . '>' . Utils::escapeArgument($filename); - } - $commandline .= '"'; - - if (!isset($this->options['bypass_shell'])) { - $this->options['bypass_shell'] = true; - } - } - - $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); - - if (!is_resource($this->process)) { - throw new \RuntimeException('Unable to launch a new process.'); - } - $this->status = self::STATUS_STARTED; - - if ($this->tty) { - return; - } - - $this->updateStatus(false); - $this->checkTimeout(); - } - - /** - * 重启进程 - * @param callable|null $callback - * @return Process - * @throws \RuntimeException - * @throws \RuntimeException - */ - public function restart($callback = null) - { - if ($this->isRunning()) { - throw new \RuntimeException('Process is already running'); - } - - $process = clone $this; - $process->start($callback); - - return $process; - } - - /** - * 等待要终止的进程 - * @param callable|null $callback - * @return int - */ - public function wait($callback = null) - { - $this->requireProcessIsStarted(__FUNCTION__); - - $this->updateStatus(false); - if (null !== $callback) { - $this->callback = $this->buildCallback($callback); - } - - do { - $this->checkTimeout(); - $running = '\\' === DS ? $this->isRunning() : $this->processPipes->areOpen(); - $close = '\\' !== DS || !$running; - $this->readPipes(true, $close); - } while ($running); - - while ($this->isRunning()) { - usleep(1000); - } - - if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) { - throw new \RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig'])); - } - - return $this->exitcode; - } - - /** - * 获取PID - * @return int|null - * @throws \RuntimeException - */ - public function getPid() - { - if ($this->isSigchildEnabled()) { - throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved.'); - } - - $this->updateStatus(false); - - return $this->isRunning() ? $this->processInformation['pid'] : null; - } - - /** - * 将一个 POSIX 信号发送到进程中 - * @param int $signal - * @return Process - */ - public function signal($signal) - { - $this->doSignal($signal, true); - - return $this; - } - - /** - * 禁用从底层过程获取输出和错误输出。 - * @return Process - */ - public function disableOutput() - { - if ($this->isRunning()) { - throw new \RuntimeException('Disabling output while the process is running is not possible.'); - } - if (null !== $this->idleTimeout) { - throw new \LogicException('Output can not be disabled while an idle timeout is set.'); - } - - $this->outputDisabled = true; - - return $this; - } - - /** - * 开启从底层过程获取输出和错误输出。 - * @return Process - * @throws \RuntimeException - */ - public function enableOutput() - { - if ($this->isRunning()) { - throw new \RuntimeException('Enabling output while the process is running is not possible.'); - } - - $this->outputDisabled = false; - - return $this; - } - - /** - * 输出是否禁用 - * @return bool - */ - public function isOutputDisabled() - { - return $this->outputDisabled; - } - - /** - * 获取当前的输出管道 - * @return string - * @throws \LogicException - * @throws \LogicException - * @api - */ - public function getOutput() - { - if ($this->outputDisabled) { - throw new \LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); - - $this->readPipes(false, '\\' === DS ? !$this->processInformation['running'] : true); - - return $this->stdout; - } - - /** - * 以增量方式返回的输出结果。 - * @return string - */ - public function getIncrementalOutput() - { - $this->requireProcessIsStarted(__FUNCTION__); - - $data = $this->getOutput(); - - $latest = substr($data, $this->incrementalOutputOffset); - - if (false === $latest) { - return ''; - } - - $this->incrementalOutputOffset = strlen($data); - - return $latest; - } - - /** - * 清空输出 - * @return Process - */ - public function clearOutput() - { - $this->stdout = ''; - $this->incrementalOutputOffset = 0; - - return $this; - } - - /** - * 返回当前的错误输出的过程 (STDERR)。 - * @return string - */ - public function getErrorOutput() - { - if ($this->outputDisabled) { - throw new \LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); - - $this->readPipes(false, '\\' === DS ? !$this->processInformation['running'] : true); - - return $this->stderr; - } - - /** - * 以增量方式返回 errorOutput - * @return string - */ - public function getIncrementalErrorOutput() - { - $this->requireProcessIsStarted(__FUNCTION__); - - $data = $this->getErrorOutput(); - - $latest = substr($data, $this->incrementalErrorOutputOffset); - - if (false === $latest) { - return ''; - } - - $this->incrementalErrorOutputOffset = strlen($data); - - return $latest; - } - - /** - * 清空 errorOutput - * @return Process - */ - public function clearErrorOutput() - { - $this->stderr = ''; - $this->incrementalErrorOutputOffset = 0; - - return $this; - } - - /** - * 获取退出码 - * @return null|int - */ - public function getExitCode() - { - if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { - throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); - } - - $this->updateStatus(false); - - return $this->exitcode; - } - - /** - * 获取退出文本 - * @return null|string - */ - public function getExitCodeText() - { - if (null === $exitcode = $this->getExitCode()) { - return; - } - - return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error'; - } - - /** - * 检查是否成功 - * @return bool - */ - public function isSuccessful() - { - return 0 === $this->getExitCode(); - } - - /** - * 是否未捕获的信号已被终止子进程 - * @return bool - */ - public function hasBeenSignaled() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - if ($this->isSigchildEnabled()) { - throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); - } - - $this->updateStatus(false); - - return $this->processInformation['signaled']; - } - - /** - * 返回导致子进程终止其执行的数。 - * @return int - */ - public function getTermSignal() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - if ($this->isSigchildEnabled()) { - throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); - } - - $this->updateStatus(false); - - return $this->processInformation['termsig']; - } - - /** - * 检查子进程信号是否已停止 - * @return bool - */ - public function hasBeenStopped() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - $this->updateStatus(false); - - return $this->processInformation['stopped']; - } - - /** - * 返回导致子进程停止其执行的数。 - * @return int - */ - public function getStopSignal() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - $this->updateStatus(false); - - return $this->processInformation['stopsig']; - } - - /** - * 检查是否正在运行 - * @return bool - */ - public function isRunning() - { - if (self::STATUS_STARTED !== $this->status) { - return false; - } - - $this->updateStatus(false); - - return $this->processInformation['running']; - } - - /** - * 检查是否已开始 - * @return bool - */ - public function isStarted() - { - return self::STATUS_READY != $this->status; - } - - /** - * 检查是否已终止 - * @return bool - */ - public function isTerminated() - { - $this->updateStatus(false); - - return self::STATUS_TERMINATED == $this->status; - } - - /** - * 获取当前的状态 - * @return string - */ - public function getStatus() - { - $this->updateStatus(false); - - return $this->status; - } - - /** - * 终止进程 - */ - public function stop() - { - if ($this->isRunning()) { - if ('\\' === DS && !$this->isSigchildEnabled()) { - exec(sprintf('taskkill /F /T /PID %d 2>&1', $this->getPid()), $output, $exitCode); - if ($exitCode > 0) { - throw new \RuntimeException('Unable to kill the process'); - } - } else { - $pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid {$this->getPid()}`); - foreach ($pids as $pid) { - if (is_numeric($pid)) { - posix_kill($pid, 9); - } - } - } - } - - $this->updateStatus(false); - if ($this->processInformation['running']) { - $this->close(); - } - - return $this->exitcode; - } - - /** - * 添加一行输出 - * @param string $line - */ - public function addOutput($line) -{ - $this->lastOutputTime = microtime(true); - $this->stdout .= $line; - } - - /** - * 添加一行错误输出 - * @param string $line - */ - public function addErrorOutput($line) -{ - $this->lastOutputTime = microtime(true); - $this->stderr .= $line; - } - - /** - * 获取被执行的指令 - * @return string - */ - public function getCommandLine() -{ - return $this->commandline; - } - - /** - * 设置指令 - * @param string $commandline - * @return self - */ - public function setCommandLine($commandline) -{ - $this->commandline = $commandline; - - return $this; - } - - /** - * 获取超时时间 - * @return float|null - */ - public function getTimeout() -{ - return $this->timeout; - } - - /** - * 获取idle超时时间 - * @return float|null - */ - public function getIdleTimeout() -{ - return $this->idleTimeout; - } - - /** - * 设置超时时间 - * @param int|float|null $timeout - * @return self - */ - public function setTimeout($timeout) -{ - $this->timeout = $this->validateTimeout($timeout); - - return $this; - } - - /** - * 设置idle超时时间 - * @param int|float|null $timeout - * @return self - */ - public function setIdleTimeout($timeout) -{ - if (null !== $timeout && $this->outputDisabled) { - throw new \LogicException('Idle timeout can not be set while the output is disabled.'); - } - - $this->idleTimeout = $this->validateTimeout($timeout); - - return $this; - } - - /** - * 设置TTY - * @param bool $tty - * @return self - */ - public function setTty($tty) -{ - if ('\\' === DS && $tty) { - throw new \RuntimeException('TTY mode is not supported on Windows platform.'); - } - if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) { - throw new \RuntimeException('TTY mode requires /dev/tty to be readable.'); - } - - $this->tty = (bool) $tty; - - return $this; - } - - /** - * 检查是否是tty模式 - * @return bool - */ - public function isTty() -{ - return $this->tty; - } - - /** - * 设置pty模式 - * @param bool $bool - * @return self - */ - public function setPty($bool) -{ - $this->pty = (bool) $bool; - - return $this; - } - - /** - * 是否是pty模式 - * @return bool - */ - public function isPty() -{ - return $this->pty; - } - - /** - * 获取工作目录 - * @return string|null - */ - public function getWorkingDirectory() -{ - if (null === $this->cwd) { - return getcwd() ?: null; - } - - return $this->cwd; - } - - /** - * 设置工作目录 - * @param string $cwd - * @return self - */ - public function setWorkingDirectory($cwd) -{ - $this->cwd = $cwd; - - return $this; - } - - /** - * 获取环境变量 - * @return array - */ - public function getEnv() -{ - return $this->env; - } - - /** - * 设置环境变量 - * @param array $env - * @return self - */ - public function setEnv(array $env) -{ - $env = array_filter($env, function ($value) { - return !is_array($value); - }); - - $this->env = []; - foreach ($env as $key => $value) { - $this->env[(binary) $key] = (binary) $value; - } - - return $this; - } - - /** - * 获取输入 - * @return null|string - */ - public function getInput() -{ - return $this->input; - } - - /** - * 设置输入 - * @param mixed $input - * @return self - */ - public function setInput($input) -{ - if ($this->isRunning()) { - throw new \LogicException('Input can not be set while the process is running.'); - } - - $this->input = Utils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input); - - return $this; - } - - /** - * 获取proc_open的选项 - * @return array - */ - public function getOptions() -{ - return $this->options; - } - - /** - * 设置proc_open的选项 - * @param array $options - * @return self - */ - public function setOptions(array $options) -{ - $this->options = $options; - - return $this; - } - - /** - * 是否兼容windows - * @return bool - */ - public function getEnhanceWindowsCompatibility() -{ - return $this->enhanceWindowsCompatibility; - } - - /** - * 设置是否兼容windows - * @param bool $enhance - * @return self - */ - public function setEnhanceWindowsCompatibility($enhance) -{ - $this->enhanceWindowsCompatibility = (bool) $enhance; - - return $this; - } - - /** - * 返回是否 sigchild 兼容模式激活 - * @return bool - */ - public function getEnhanceSigchildCompatibility() -{ - return $this->enhanceSigchildCompatibility; - } - - /** - * 激活 sigchild 兼容性模式。 - * @param bool $enhance - * @return self - */ - public function setEnhanceSigchildCompatibility($enhance) -{ - $this->enhanceSigchildCompatibility = (bool) $enhance; - - return $this; - } - - /** - * 是否超时 - */ - public function checkTimeout() -{ - if (self::STATUS_STARTED !== $this->status) { - return; - } - - if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) { - $this->stop(); - - throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_GENERAL); - } - - if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) { - $this->stop(); - - throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_IDLE); - } - } - - /** - * 是否支持pty - * @return bool - */ - public static function isPtySupported() -{ - static $result; - - if (null !== $result) { - return $result; - } - - if ('\\' === DS) { - return $result = false; - } - - $proc = @proc_open('echo 1', [['pty'], ['pty'], ['pty']], $pipes); - if (is_resource($proc)) { - proc_close($proc); - - return $result = true; - } - - return $result = false; - } - - /** - * 创建所需的 proc_open 的描述符 - * @return array - */ - private function getDescriptors() -{ - if ('\\' === DS) { - $this->processPipes = WindowsPipes::create($this, $this->input); - } else { - $this->processPipes = UnixPipes::create($this, $this->input); - } - $descriptors = $this->processPipes->getDescriptors($this->outputDisabled); - - if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { - - $descriptors = array_merge($descriptors, [['pipe', 'w']]); - - $this->commandline = '(' . $this->commandline . ') 3>/dev/null; code=$?; echo $code >&3; exit $code'; - } - - return $descriptors; - } - - /** - * 建立 wait () 使用的回调。 - * @param callable|null $callback - * @return callable - */ - protected function buildCallback($callback) -{ - $out = self::OUT; - $callback = function ($type, $data) use ($callback, $out) { - if ($out == $type) { - $this->addOutput($data); - } else { - $this->addErrorOutput($data); - } - - if (null !== $callback) { - call_user_func($callback, $type, $data); - } - }; - - return $callback; - } - - /** - * 更新状态 - * @param bool $blocking - */ - protected function updateStatus($blocking) -{ - if (self::STATUS_STARTED !== $this->status) { - return; - } - - $this->processInformation = proc_get_status($this->process); - $this->captureExitCode(); - - $this->readPipes($blocking, '\\' === DS ? !$this->processInformation['running'] : true); - - if (!$this->processInformation['running']) { - $this->close(); - } - } - - /** - * 是否开启 '--enable-sigchild' - * @return bool - */ - protected function isSigchildEnabled() -{ - if (null !== self::$sigchild) { - return self::$sigchild; - } - - if (!function_exists('phpinfo')) { - return self::$sigchild = false; - } - - ob_start(); - phpinfo(INFO_GENERAL); - - return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild'); - } - - /** - * 验证是否超时 - * @param int|float|null $timeout - * @return float|null - */ - private function validateTimeout($timeout) -{ - $timeout = (float) $timeout; - - if (0.0 === $timeout) { - $timeout = null; - } elseif ($timeout < 0) { - throw new \InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); - } - - return $timeout; - } - - /** - * 读取pipes - * @param bool $blocking - * @param bool $close - */ - private function readPipes($blocking, $close) -{ - $result = $this->processPipes->readAndWrite($blocking, $close); - - $callback = $this->callback; - foreach ($result as $type => $data) { - if (3 == $type) { - $this->fallbackExitcode = (int) $data; - } else { - $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data); - } - } - } - - /** - * 捕获退出码 - */ - private function captureExitCode() -{ - if (isset($this->processInformation['exitcode']) && -1 != $this->processInformation['exitcode']) { - $this->exitcode = $this->processInformation['exitcode']; - } - } - - /** - * 关闭资源 - * @return int 退出码 - */ - private function close() -{ - $this->processPipes->close(); - if (is_resource($this->process)) { - $exitcode = proc_close($this->process); - } else { - $exitcode = -1; - } - - $this->exitcode = -1 !== $exitcode ? $exitcode : (null !== $this->exitcode ? $this->exitcode : -1); - $this->status = self::STATUS_TERMINATED; - - if (-1 === $this->exitcode && null !== $this->fallbackExitcode) { - $this->exitcode = $this->fallbackExitcode; - } elseif (-1 === $this->exitcode && $this->processInformation['signaled'] - && 0 < $this->processInformation['termsig'] - ) { - $this->exitcode = 128 + $this->processInformation['termsig']; - } - - return $this->exitcode; - } - - /** - * 重置数据 - */ - private function resetProcessData() -{ - $this->starttime = null; - $this->callback = null; - $this->exitcode = null; - $this->fallbackExitcode = null; - $this->processInformation = null; - $this->stdout = null; - $this->stderr = null; - $this->process = null; - $this->latestSignal = null; - $this->status = self::STATUS_READY; - $this->incrementalOutputOffset = 0; - $this->incrementalErrorOutputOffset = 0; - } - - /** - * 将一个 POSIX 信号发送到进程中。 - * @param int $signal - * @param bool $throwException - * @return bool - */ - private function doSignal($signal, $throwException) -{ - if (!$this->isRunning()) { - if ($throwException) { - throw new \LogicException('Can not send signal on a non running process.'); - } - - return false; - } - - if ($this->isSigchildEnabled()) { - if ($throwException) { - throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - } - - return false; - } - - if (true !== @proc_terminate($this->process, $signal)) { - if ($throwException) { - throw new \RuntimeException(sprintf('Error while sending signal `%s`.', $signal)); - } - - return false; - } - - $this->latestSignal = $signal; - - return true; - } - - /** - * 确保进程已经开启 - * @param string $functionName - */ - private function requireProcessIsStarted($functionName) -{ - if (!$this->isStarted()) { - throw new \LogicException(sprintf('Process must be started before calling %s.', $functionName)); - } - } - - /** - * 确保进程已经终止 - * @param string $functionName - */ - private function requireProcessIsTerminated($functionName) -{ - if (!$this->isTerminated()) { - throw new \LogicException(sprintf('Process must be terminated before calling %s.', $functionName)); - } - } -} diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php deleted file mode 100755 index ac0c177..0000000 --- a/thinkphp/library/think/Request.php +++ /dev/null @@ -1,1768 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Request -{ - /** - * @var object 对象实例 - */ - protected static $instance; - - protected $method; - /** - * @var string 域名(含协议和端口) - */ - protected $domain; - - /** - * @var string URL地址 - */ - protected $url; - - /** - * @var string 基础URL - */ - protected $baseUrl; - - /** - * @var string 当前执行的文件 - */ - protected $baseFile; - - /** - * @var string 访问的ROOT地址 - */ - protected $root; - - /** - * @var string pathinfo - */ - protected $pathinfo; - - /** - * @var string pathinfo(不含后缀) - */ - protected $path; - - /** - * @var array 当前路由信息 - */ - protected $routeInfo = []; - - /** - * @var array 环境变量 - */ - protected $env; - - /** - * @var array 当前调度信息 - */ - protected $dispatch = []; - protected $module; - protected $controller; - protected $action; - // 当前语言集 - protected $langset; - - /** - * @var array 请求参数 - */ - protected $param = []; - protected $get = []; - protected $post = []; - protected $request = []; - protected $route = []; - protected $put; - protected $session = []; - protected $file = []; - protected $cookie = []; - protected $server = []; - protected $header = []; - - /** - * @var array 资源类型 - */ - protected $mimeType = [ - 'xml' => 'application/xml,text/xml,application/x-xml', - 'json' => 'application/json,text/x-json,application/jsonrequest,text/json', - 'js' => 'text/javascript,application/javascript,application/x-javascript', - 'css' => 'text/css', - 'rss' => 'application/rss+xml', - 'yaml' => 'application/x-yaml,text/yaml', - 'atom' => 'application/atom+xml', - 'pdf' => 'application/pdf', - 'text' => 'text/plain', - 'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*', - 'csv' => 'text/csv', - 'html' => 'text/html,application/xhtml+xml,*/*', - ]; - - protected $content; - - // 全局过滤规则 - protected $filter; - // Hook扩展方法 - protected static $hook = []; - // 绑定的属性 - protected $bind = []; - // php://input - protected $input; - // 请求缓存 - protected $cache; - // 缓存是否检查 - protected $isCheckCache; - /** - * 是否合并Param - * @var bool - */ - protected $mergeParam = false; - - /** - * 构造函数 - * @access protected - * @param array $options 参数 - */ - protected function __construct($options = []) - { - foreach ($options as $name => $item) { - if (property_exists($this, $name)) { - $this->$name = $item; - } - } - if (is_null($this->filter)) { - $this->filter = Config::get('default_filter'); - } - - // 保存 php://input - $this->input = file_get_contents('php://input'); - } - - public function __call($method, $args) - { - if (array_key_exists($method, self::$hook)) { - array_unshift($args, $this); - return call_user_func_array(self::$hook[$method], $args); - } else { - throw new Exception('method not exists:' . __CLASS__ . '->' . $method); - } - } - - /** - * Hook 方法注入 - * @access public - * @param string|array $method 方法名 - * @param mixed $callback callable - * @return void - */ - public static function hook($method, $callback = null) - { - if (is_array($method)) { - self::$hook = array_merge(self::$hook, $method); - } else { - self::$hook[$method] = $callback; - } - } - - /** - * 初始化 - * @access public - * @param array $options 参数 - * @return \think\Request - */ - public static function instance($options = []) - { - if (is_null(self::$instance)) { - self::$instance = new static($options); - } - return self::$instance; - } - - /** - * 销毁当前请求对象 - * @access public - * @return void - */ - public static function destroy() - { - if (!is_null(self::$instance)) { - self::$instance = null; - } - } - - /** - * 创建一个URL请求 - * @access public - * @param string $uri URL地址 - * @param string $method 请求类型 - * @param array $params 请求参数 - * @param array $cookie - * @param array $files - * @param array $server - * @param string $content - * @return \think\Request - */ - public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null) - { - $server['PATH_INFO'] = ''; - $server['REQUEST_METHOD'] = strtoupper($method); - $info = parse_url($uri); - if (isset($info['host'])) { - $server['SERVER_NAME'] = $info['host']; - $server['HTTP_HOST'] = $info['host']; - } - if (isset($info['scheme'])) { - if ('https' === $info['scheme']) { - $server['HTTPS'] = 'on'; - $server['SERVER_PORT'] = 443; - } else { - unset($server['HTTPS']); - $server['SERVER_PORT'] = 80; - } - } - if (isset($info['port'])) { - $server['SERVER_PORT'] = $info['port']; - $server['HTTP_HOST'] = $server['HTTP_HOST'] . ':' . $info['port']; - } - if (isset($info['user'])) { - $server['PHP_AUTH_USER'] = $info['user']; - } - if (isset($info['pass'])) { - $server['PHP_AUTH_PW'] = $info['pass']; - } - if (!isset($info['path'])) { - $info['path'] = '/'; - } - $options = []; - $options[strtolower($method)] = $params; - $queryString = ''; - if (isset($info['query'])) { - parse_str(html_entity_decode($info['query']), $query); - if (!empty($params)) { - $params = array_replace($query, $params); - $queryString = http_build_query($params, '', '&'); - } else { - $params = $query; - $queryString = $info['query']; - } - } elseif (!empty($params)) { - $queryString = http_build_query($params, '', '&'); - } - if ($queryString) { - parse_str($queryString, $get); - $options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get; - } - - $server['REQUEST_URI'] = $info['path'] . ('' !== $queryString ? '?' . $queryString : ''); - $server['QUERY_STRING'] = $queryString; - $options['cookie'] = $cookie; - $options['param'] = $params; - $options['file'] = $files; - $options['server'] = $server; - $options['url'] = $server['REQUEST_URI']; - $options['baseUrl'] = $info['path']; - $options['pathinfo'] = '/' == $info['path'] ? '/' : ltrim($info['path'], '/'); - $options['method'] = $server['REQUEST_METHOD']; - $options['domain'] = isset($info['scheme']) ? $info['scheme'] . '://' . $server['HTTP_HOST'] : ''; - $options['content'] = $content; - self::$instance = new self($options); - return self::$instance; - } - - /** - * 设置或获取当前包含协议的域名 - * @access public - * @param string $domain 域名 - * @return string - */ - public function domain($domain = null) - { - if (!is_null($domain)) { - $this->domain = $domain; - return $this; - } elseif (!$this->domain) { - $this->domain = $this->scheme() . '://' . $this->host(); - } - return $this->domain; - } - - /** - * 设置或获取当前完整URL 包括QUERY_STRING - * @access public - * @param string|true $url URL地址 true 带域名获取 - * @return string - */ - public function url($url = null) - { - if (!is_null($url) && true !== $url) { - $this->url = $url; - return $this; - } elseif (!$this->url) { - if (IS_CLI) { - $this->url = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; - } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { - $this->url = $_SERVER['HTTP_X_REWRITE_URL']; - } elseif (isset($_SERVER['REQUEST_URI'])) { - $this->url = $_SERVER['REQUEST_URI']; - } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { - $this->url = $_SERVER['ORIG_PATH_INFO'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : ''); - } else { - $this->url = ''; - } - } - return true === $url ? $this->domain() . $this->url : $this->url; - } - - /** - * 设置或获取当前URL 不含QUERY_STRING - * @access public - * @param string $url URL地址 - * @return string - */ - public function baseUrl($url = null) - { - if (!is_null($url) && true !== $url) { - $this->baseUrl = $url; - return $this; - } elseif (!$this->baseUrl) { - $str = $this->url(); - $this->baseUrl = strpos($str, '?') ? strstr($str, '?', true) : $str; - } - return true === $url ? $this->domain() . $this->baseUrl : $this->baseUrl; - } - - /** - * 设置或获取当前执行的文件 SCRIPT_NAME - * @access public - * @param string $file 当前执行的文件 - * @return string - */ - public function baseFile($file = null) - { - if (!is_null($file) && true !== $file) { - $this->baseFile = $file; - return $this; - } elseif (!$this->baseFile) { - $url = ''; - if (!IS_CLI) { - $script_name = basename($_SERVER['SCRIPT_FILENAME']); - if (basename($_SERVER['SCRIPT_NAME']) === $script_name) { - $url = $_SERVER['SCRIPT_NAME']; - } elseif (basename($_SERVER['PHP_SELF']) === $script_name) { - $url = $_SERVER['PHP_SELF']; - } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $script_name) { - $url = $_SERVER['ORIG_SCRIPT_NAME']; - } elseif (($pos = strpos($_SERVER['PHP_SELF'], '/' . $script_name)) !== false) { - $url = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $script_name; - } elseif (isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT']) === 0) { - $url = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME'])); - } - } - $this->baseFile = $url; - } - return true === $file ? $this->domain() . $this->baseFile : $this->baseFile; - } - - /** - * 设置或获取URL访问根地址 - * @access public - * @param string $url URL地址 - * @return string - */ - public function root($url = null) - { - if (!is_null($url) && true !== $url) { - $this->root = $url; - return $this; - } elseif (!$this->root) { - $file = $this->baseFile(); - if ($file && 0 !== strpos($this->url(), $file)) { - $file = str_replace('\\', '/', dirname($file)); - } - $this->root = rtrim($file, '/'); - } - return true === $url ? $this->domain() . $this->root : $this->root; - } - - /** - * 获取当前请求URL的pathinfo信息(含URL后缀) - * @access public - * @return string - */ - public function pathinfo() - { - if (is_null($this->pathinfo)) { - if (isset($_GET[Config::get('var_pathinfo')])) { - // 判断URL里面是否有兼容模式参数 - $_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')]; - unset($_GET[Config::get('var_pathinfo')]); - } elseif (IS_CLI) { - // CLI模式下 index.php module/controller/action/params/... - $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; - } - - // 分析PATHINFO信息 - if (!isset($_SERVER['PATH_INFO'])) { - foreach (Config::get('pathinfo_fetch') as $type) { - if (!empty($_SERVER[$type])) { - $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ? - substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; - break; - } - } - } - $this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/'); - } - return $this->pathinfo; - } - - /** - * 获取当前请求URL的pathinfo信息(不含URL后缀) - * @access public - * @return string - */ - public function path() - { - if (is_null($this->path)) { - $suffix = Config::get('url_html_suffix'); - $pathinfo = $this->pathinfo(); - if (false === $suffix) { - // 禁止伪静态访问 - $this->path = $pathinfo; - } elseif ($suffix) { - // 去除正常的URL后缀 - $this->path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo); - } else { - // 允许任何后缀访问 - $this->path = preg_replace('/\.' . $this->ext() . '$/i', '', $pathinfo); - } - } - return $this->path; - } - - /** - * 当前URL的访问后缀 - * @access public - * @return string - */ - public function ext() - { - return pathinfo($this->pathinfo(), PATHINFO_EXTENSION); - } - - /** - * 获取当前请求的时间 - * @access public - * @param bool $float 是否使用浮点类型 - * @return integer|float - */ - public function time($float = false) - { - return $float ? $_SERVER['REQUEST_TIME_FLOAT'] : $_SERVER['REQUEST_TIME']; - } - - /** - * 当前请求的资源类型 - * @access public - * @return false|string - */ - public function type() - { - $accept = $this->server('HTTP_ACCEPT'); - if (empty($accept)) { - return false; - } - - foreach ($this->mimeType as $key => $val) { - $array = explode(',', $val); - foreach ($array as $k => $v) { - if (stristr($accept, $v)) { - return $key; - } - } - } - return false; - } - - /** - * 设置资源类型 - * @access public - * @param string|array $type 资源类型名 - * @param string $val 资源类型 - * @return void - */ - public function mimeType($type, $val = '') - { - if (is_array($type)) { - $this->mimeType = array_merge($this->mimeType, $type); - } else { - $this->mimeType[$type] = $val; - } - } - - /** - * 当前的请求类型 - * @access public - * @param bool $method true 获取原始请求类型 - * @return string - */ - public function method($method = false) - { - if (true === $method) { - // 获取原始请求类型 - return $this->server('REQUEST_METHOD') ?: 'GET'; - } elseif (!$this->method) { - if (isset($_POST[Config::get('var_method')])) { - $this->method = strtoupper($_POST[Config::get('var_method')]); - $this->{$this->method}($_POST); - } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { - $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); - } else { - $this->method = $this->server('REQUEST_METHOD') ?: 'GET'; - } - } - return $this->method; - } - - /** - * 是否为GET请求 - * @access public - * @return bool - */ - public function isGet() - { - return $this->method() == 'GET'; - } - - /** - * 是否为POST请求 - * @access public - * @return bool - */ - public function isPost() - { - return $this->method() == 'POST'; - } - - /** - * 是否为PUT请求 - * @access public - * @return bool - */ - public function isPut() - { - return $this->method() == 'PUT'; - } - - /** - * 是否为DELTE请求 - * @access public - * @return bool - */ - public function isDelete() - { - return $this->method() == 'DELETE'; - } - - /** - * 是否为HEAD请求 - * @access public - * @return bool - */ - public function isHead() - { - return $this->method() == 'HEAD'; - } - - /** - * 是否为PATCH请求 - * @access public - * @return bool - */ - public function isPatch() - { - return $this->method() == 'PATCH'; - } - - /** - * 是否为OPTIONS请求 - * @access public - * @return bool - */ - public function isOptions() - { - return $this->method() == 'OPTIONS'; - } - - /** - * 是否为cli - * @access public - * @return bool - */ - public function isCli() - { - return PHP_SAPI == 'cli'; - } - - /** - * 是否为cgi - * @access public - * @return bool - */ - public function isCgi() - { - return strpos(PHP_SAPI, 'cgi') === 0; - } - - /** - * 获取当前请求的参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function param($name = '', $default = null, $filter = '') - { - if (empty($this->mergeParam)) { - $method = $this->method(true); - // 自动获取请求变量 - switch ($method) { - case 'POST': - $vars = $this->post(false); - break; - case 'PUT': - case 'DELETE': - case 'PATCH': - $vars = $this->put(false); - break; - default: - $vars = []; - } - // 当前请求参数和URL地址中的参数合并 - $this->param = array_merge($this->param, $this->get(false), $vars, $this->route(false)); - $this->mergeParam = true; - } - if (true === $name) { - // 获取包含文件上传信息的数组 - $file = $this->file(); - $data = is_array($file) ? array_merge($this->param, $file) : $this->param; - return $this->input($data, '', $default, $filter); - } - return $this->input($this->param, $name, $default, $filter); - } - - /** - * 设置获取路由参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function route($name = '', $default = null, $filter = '') - { - if (is_array($name)) { - $this->param = []; - $this->mergeParam = false; - return $this->route = array_merge($this->route, $name); - } - return $this->input($this->route, $name, $default, $filter); - } - - /** - * 设置获取GET参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function get($name = '', $default = null, $filter = '') - { - if (empty($this->get)) { - $this->get = $_GET; - } - if (is_array($name)) { - $this->param = []; - $this->mergeParam = false; - return $this->get = array_merge($this->get, $name); - } - return $this->input($this->get, $name, $default, $filter); - } - - /** - * 设置获取POST参数 - * @access public - * @param string $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function post($name = '', $default = null, $filter = '') - { - if (empty($this->post)) { - $content = $this->input; - if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) { - $this->post = (array) json_decode($content, true); - } else { - $this->post = $_POST; - } - } - if (is_array($name)) { - $this->param = []; - $this->mergeParam = false; - return $this->post = array_merge($this->post, $name); - } - return $this->input($this->post, $name, $default, $filter); - } - - /** - * 设置获取PUT参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function put($name = '', $default = null, $filter = '') - { - if (is_null($this->put)) { - $content = $this->input; - if (false !== strpos($this->contentType(), 'application/json')) { - $this->put = (array) json_decode($content, true); - } else { - parse_str($content, $this->put); - } - } - if (is_array($name)) { - $this->param = []; - $this->mergeParam = false; - return $this->put = is_null($this->put) ? $name : array_merge($this->put, $name); - } - - return $this->input($this->put, $name, $default, $filter); - } - - /** - * 设置获取DELETE参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function delete($name = '', $default = null, $filter = '') - { - return $this->put($name, $default, $filter); - } - - /** - * 设置获取PATCH参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function patch($name = '', $default = null, $filter = '') - { - return $this->put($name, $default, $filter); - } - - /** - * 获取request变量 - * @param string $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function request($name = '', $default = null, $filter = '') - { - if (empty($this->request)) { - $this->request = $_REQUEST; - } - if (is_array($name)) { - $this->param = []; - $this->mergeParam = false; - return $this->request = array_merge($this->request, $name); - } - return $this->input($this->request, $name, $default, $filter); - } - - /** - * 获取session数据 - * @access public - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function session($name = '', $default = null, $filter = '') - { - if (empty($this->session)) { - $this->session = Session::get(); - } - if (is_array($name)) { - return $this->session = array_merge($this->session, $name); - } - return $this->input($this->session, $name, $default, $filter); - } - - /** - * 获取cookie参数 - * @access public - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function cookie($name = '', $default = null, $filter = '') - { - if (empty($this->cookie)) { - $this->cookie = Cookie::get(); - } - if (is_array($name)) { - return $this->cookie = array_merge($this->cookie, $name); - } elseif (!empty($name)) { - $data = Cookie::has($name) ? Cookie::get($name) : $default; - } else { - $data = $this->cookie; - } - - // 解析过滤器 - $filter = $this->getFilter($filter, $default); - - if (is_array($data)) { - array_walk_recursive($data, [$this, 'filterValue'], $filter); - reset($data); - } else { - $this->filterValue($data, $name, $filter); - } - return $data; - } - - /** - * 获取server参数 - * @access public - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function server($name = '', $default = null, $filter = '') - { - if (empty($this->server)) { - $this->server = $_SERVER; - } - if (is_array($name)) { - return $this->server = array_merge($this->server, $name); - } - return $this->input($this->server, false === $name ? false : strtoupper($name), $default, $filter); - } - - /** - * 获取上传的文件信息 - * @access public - * @param string|array $name 名称 - * @return null|array|\think\File - */ - public function file($name = '') - { - if (empty($this->file)) { - $this->file = isset($_FILES) ? $_FILES : []; - } - if (is_array($name)) { - return $this->file = array_merge($this->file, $name); - } - $files = $this->file; - if (!empty($files)) { - // 处理上传文件 - $array = []; - foreach ($files as $key => $file) { - if (is_array($file['name'])) { - $item = []; - $keys = array_keys($file); - $count = count($file['name']); - for ($i = 0; $i < $count; $i++) { - if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) { - continue; - } - $temp['key'] = $key; - foreach ($keys as $_key) { - $temp[$_key] = $file[$_key][$i]; - } - $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp); - } - $array[$key] = $item; - } else { - if ($file instanceof File) { - $array[$key] = $file; - } else { - if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) { - continue; - } - $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file); - } - } - } - if (strpos($name, '.')) { - list($name, $sub) = explode('.', $name); - } - if ('' === $name) { - // 获取全部文件 - return $array; - } elseif (isset($sub) && isset($array[$name][$sub])) { - return $array[$name][$sub]; - } elseif (isset($array[$name])) { - return $array[$name]; - } - } - return; - } - - /** - * 获取环境变量 - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function env($name = '', $default = null, $filter = '') - { - if (empty($this->env)) { - $this->env = $_ENV; - } - if (is_array($name)) { - return $this->env = array_merge($this->env, $name); - } - return $this->input($this->env, false === $name ? false : strtoupper($name), $default, $filter); - } - - /** - * 设置或者获取当前的Header - * @access public - * @param string|array $name header名称 - * @param string $default 默认值 - * @return string - */ - public function header($name = '', $default = null) - { - if (empty($this->header)) { - $header = []; - if (function_exists('apache_request_headers') && $result = apache_request_headers()) { - $header = $result; - } else { - $server = $this->server ?: $_SERVER; - foreach ($server as $key => $val) { - if (0 === strpos($key, 'HTTP_')) { - $key = str_replace('_', '-', strtolower(substr($key, 5))); - $header[$key] = $val; - } - } - if (isset($server['CONTENT_TYPE'])) { - $header['content-type'] = $server['CONTENT_TYPE']; - } - if (isset($server['CONTENT_LENGTH'])) { - $header['content-length'] = $server['CONTENT_LENGTH']; - } - } - $this->header = array_change_key_case($header); - } - if (is_array($name)) { - return $this->header = array_merge($this->header, $name); - } - if ('' === $name) { - return $this->header; - } - $name = str_replace('_', '-', strtolower($name)); - return isset($this->header[$name]) ? $this->header[$name] : $default; - } - - /** - * 获取变量 支持过滤和默认值 - * @param array $data 数据源 - * @param string|false $name 字段名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤函数 - * @return mixed - */ - public function input($data = [], $name = '', $default = null, $filter = '') - { - if (false === $name) { - // 获取原始数据 - return $data; - } - $name = (string) $name; - if ('' != $name) { - // 解析name - if (strpos($name, '/')) { - list($name, $type) = explode('/', $name); - } else { - $type = 's'; - } - // 按.拆分成多维数组进行判断 - foreach (explode('.', $name) as $val) { - if (isset($data[$val])) { - $data = $data[$val]; - } else { - // 无输入数据,返回默认值 - return $default; - } - } - if (is_object($data)) { - return $data; - } - } - - // 解析过滤器 - $filter = $this->getFilter($filter, $default); - - if (is_array($data)) { - array_walk_recursive($data, [$this, 'filterValue'], $filter); - reset($data); - } else { - $this->filterValue($data, $name, $filter); - } - - if (isset($type) && $data !== $default) { - // 强制类型转换 - $this->typeCast($data, $type); - } - return $data; - } - - /** - * 设置或获取当前的过滤规则 - * @param mixed $filter 过滤规则 - * @return mixed - */ - public function filter($filter = null) - { - if (is_null($filter)) { - return $this->filter; - } else { - $this->filter = $filter; - } - } - - protected function getFilter($filter, $default) - { - if (is_null($filter)) { - $filter = []; - } else { - $filter = $filter ?: $this->filter; - if (is_string($filter) && false === strpos($filter, '/')) { - $filter = explode(',', $filter); - } else { - $filter = (array) $filter; - } - } - - $filter[] = $default; - return $filter; - } - - /** - * 递归过滤给定的值 - * @param mixed $value 键值 - * @param mixed $key 键名 - * @param array $filters 过滤方法+默认值 - * @return mixed - */ - private function filterValue(&$value, $key, $filters) - { - $default = array_pop($filters); - foreach ($filters as $filter) { - if (is_callable($filter)) { - // 调用函数或者方法过滤 - $value = call_user_func($filter, $value); - } elseif (is_scalar($value)) { - if (false !== strpos($filter, '/')) { - // 正则过滤 - if (!preg_match($filter, $value)) { - // 匹配不成功返回默认值 - $value = $default; - break; - } - } elseif (!empty($filter)) { - // filter函数不存在时, 则使用filter_var进行过滤 - // filter为非整形值时, 调用filter_id取得过滤id - $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter)); - if (false === $value) { - $value = $default; - break; - } - } - } - } - return $this->filterExp($value); - } - - /** - * 过滤表单中的表达式 - * @param string $value - * @return void - */ - public function filterExp(&$value) - { - // 过滤查询特殊字符 - if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOT EXISTS|NOTEXISTS|EXISTS|NOT NULL|NOTNULL|NULL|BETWEEN TIME|NOT BETWEEN TIME|NOTBETWEEN TIME|NOTIN|NOT IN|IN)$/i', $value)) { - $value .= ' '; - } - // TODO 其他安全过滤 - } - - /** - * 强制类型转换 - * @param string $data - * @param string $type - * @return mixed - */ - private function typeCast(&$data, $type) - { - switch (strtolower($type)) { - // 数组 - case 'a': - $data = (array) $data; - break; - // 数字 - case 'd': - $data = (int) $data; - break; - // 浮点 - case 'f': - $data = (float) $data; - break; - // 布尔 - case 'b': - $data = (boolean) $data; - break; - // 字符串 - case 's': - default: - if (is_scalar($data)) { - $data = (string) $data; - } else { - throw new \InvalidArgumentException('variable type error:' . gettype($data)); - } - } - } - - /** - * 是否存在某个请求参数 - * @access public - * @param string $name 变量名 - * @param string $type 变量类型 - * @param bool $checkEmpty 是否检测空值 - * @return mixed - */ - public function has($name, $type = 'param', $checkEmpty = false) - { - if (empty($this->$type)) { - $param = $this->$type(); - } else { - $param = $this->$type; - } - // 按.拆分成多维数组进行判断 - foreach (explode('.', $name) as $val) { - if (isset($param[$val])) { - $param = $param[$val]; - } else { - return false; - } - } - return ($checkEmpty && '' === $param) ? false : true; - } - - /** - * 获取指定的参数 - * @access public - * @param string|array $name 变量名 - * @param string $type 变量类型 - * @return mixed - */ - public function only($name, $type = 'param') - { - $param = $this->$type(); - if (is_string($name)) { - $name = explode(',', $name); - } - $item = []; - foreach ($name as $key) { - if (isset($param[$key])) { - $item[$key] = $param[$key]; - } - } - return $item; - } - - /** - * 排除指定参数获取 - * @access public - * @param string|array $name 变量名 - * @param string $type 变量类型 - * @return mixed - */ - public function except($name, $type = 'param') - { - $param = $this->$type(); - if (is_string($name)) { - $name = explode(',', $name); - } - foreach ($name as $key) { - if (isset($param[$key])) { - unset($param[$key]); - } - } - return $param; - } - - /** - * 当前是否ssl - * @access public - * @return bool - */ - public function isSsl() - { - $server = array_merge($_SERVER, $this->server); - if (isset($server['HTTPS']) && ('1' == $server['HTTPS'] || 'on' == strtolower($server['HTTPS']))) { - return true; - } elseif (isset($server['REQUEST_SCHEME']) && 'https' == $server['REQUEST_SCHEME']) { - return true; - } elseif (isset($server['SERVER_PORT']) && ('443' == $server['SERVER_PORT'])) { - return true; - } elseif (isset($server['HTTP_X_FORWARDED_PROTO']) && 'https' == $server['HTTP_X_FORWARDED_PROTO']) { - return true; - } elseif (Config::get('https_agent_name') && isset($server[Config::get('https_agent_name')])) { - return true; - } - return false; - } - - /** - * 当前是否Ajax请求 - * @access public - * @param bool $ajax true 获取原始ajax请求 - * @return bool - */ - public function isAjax($ajax = false) - { - $value = $this->server('HTTP_X_REQUESTED_WITH', '', 'strtolower'); - $result = ('xmlhttprequest' == $value) ? true : false; - if (true === $ajax) { - return $result; - } else { - $result = $this->param(Config::get('var_ajax')) ? true : $result; - $this->mergeParam = false; - return $result; - } - } - - /** - * 当前是否Pjax请求 - * @access public - * @param bool $pjax true 获取原始pjax请求 - * @return bool - */ - public function isPjax($pjax = false) - { - $result = !is_null($this->server('HTTP_X_PJAX')) ? true : false; - if (true === $pjax) { - return $result; - } else { - $result = $this->param(Config::get('var_pjax')) ? true : $result; - $this->mergeParam = false; - return $result; - } - } - - /** - * 获取客户端IP地址 - * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 - * @param boolean $adv 是否进行高级模式获取(有可能被伪装) - * @return mixed - */ - public function ip($type = 0, $adv = true) - { - $type = $type ? 1 : 0; - static $ip = null; - if (null !== $ip) { - return $ip[$type]; - } - - $httpAgentIp = Config::get('http_agent_ip'); - - if ($httpAgentIp && isset($_SERVER[$httpAgentIp])) { - $ip = $_SERVER[$httpAgentIp]; - } elseif ($adv) { - if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); - $pos = array_search('unknown', $arr); - if (false !== $pos) { - unset($arr[$pos]); - } - $ip = trim(current($arr)); - } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { - $ip = $_SERVER['HTTP_CLIENT_IP']; - } elseif (isset($_SERVER['REMOTE_ADDR'])) { - $ip = $_SERVER['REMOTE_ADDR']; - } - } elseif (isset($_SERVER['REMOTE_ADDR'])) { - $ip = $_SERVER['REMOTE_ADDR']; - } - // IP地址合法验证 - $long = sprintf("%u", ip2long($ip)); - $ip = $long ? [$ip, $long] : ['0.0.0.0', 0]; - return $ip[$type]; - } - - /** - * 检测是否使用手机访问 - * @access public - * @return bool - */ - public function isMobile() - { - if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) { - return true; - } elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), "VND.WAP.WML")) { - return true; - } elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) { - return true; - } elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])) { - return true; - } else { - return false; - } - } - - /** - * 当前URL地址中的scheme参数 - * @access public - * @return string - */ - public function scheme() - { - return $this->isSsl() ? 'https' : 'http'; - } - - /** - * 当前请求URL地址中的query参数 - * @access public - * @return string - */ - public function query() - { - return $this->server('QUERY_STRING'); - } - - /** - * 当前请求的host - * @access public - * @param bool $strict true 仅仅获取HOST - * @return string - */ - public function host($strict = false) - { - if (isset($_SERVER['HTTP_X_REAL_HOST'])) { - $host = $_SERVER['HTTP_X_REAL_HOST']; - } else { - $host = $this->server('HTTP_HOST'); - } - - return true === $strict && strpos($host, ':') ? strstr($host, ':', true) : $host; - } - - /** - * 当前请求URL地址中的port参数 - * @access public - * @return integer - */ - public function port() - { - return $this->server('SERVER_PORT'); - } - - /** - * 当前请求 SERVER_PROTOCOL - * @access public - * @return integer - */ - public function protocol() - { - return $this->server('SERVER_PROTOCOL'); - } - - /** - * 当前请求 REMOTE_PORT - * @access public - * @return integer - */ - public function remotePort() - { - return $this->server('REMOTE_PORT'); - } - - /** - * 当前请求 HTTP_CONTENT_TYPE - * @access public - * @return string - */ - public function contentType() - { - $contentType = $this->server('CONTENT_TYPE'); - if ($contentType) { - if (strpos($contentType, ';')) { - list($type) = explode(';', $contentType); - } else { - $type = $contentType; - } - return trim($type); - } - return ''; - } - - /** - * 获取当前请求的路由信息 - * @access public - * @param array $route 路由名称 - * @return array - */ - public function routeInfo($route = []) - { - if (!empty($route)) { - $this->routeInfo = $route; - } else { - return $this->routeInfo; - } - } - - /** - * 设置或者获取当前请求的调度信息 - * @access public - * @param array $dispatch 调度信息 - * @return array - */ - public function dispatch($dispatch = null) - { - if (!is_null($dispatch)) { - $this->dispatch = $dispatch; - } - return $this->dispatch; - } - - /** - * 设置或者获取当前的模块名 - * @access public - * @param string $module 模块名 - * @return string|Request - */ - public function module($module = null) - { - if (!is_null($module)) { - $this->module = $module; - return $this; - } else { - return $this->module ?: ''; - } - } - - /** - * 设置或者获取当前的控制器名 - * @access public - * @param string $controller 控制器名 - * @return string|Request - */ - public function controller($controller = null) - { - if (!is_null($controller)) { - $this->controller = $controller; - return $this; - } else { - return $this->controller ?: ''; - } - } - - /** - * 设置或者获取当前的操作名 - * @access public - * @param string $action 操作名 - * @return string|Request - */ - public function action($action = null) - { - if (!is_null($action) && !is_bool($action)) { - $this->action = $action; - return $this; - } else { - $name = $this->action ?: ''; - return true === $action ? $name : strtolower($name); - } - } - - /** - * 设置或者获取当前的语言 - * @access public - * @param string $lang 语言名 - * @return string|Request - */ - public function langset($lang = null) - { - if (!is_null($lang)) { - $this->langset = $lang; - return $this; - } else { - return $this->langset ?: ''; - } - } - - /** - * 设置或者获取当前请求的content - * @access public - * @return string - */ - public function getContent() - { - if (is_null($this->content)) { - $this->content = $this->input; - } - return $this->content; - } - - /** - * 获取当前请求的php://input - * @access public - * @return string - */ - public function getInput() - { - return $this->input; - } - - /** - * 生成请求令牌 - * @access public - * @param string $name 令牌名称 - * @param mixed $type 令牌生成方法 - * @return string - */ - public function token($name = '__token__', $type = 'md5') - { - $type = is_callable($type) ? $type : 'md5'; - $token = call_user_func($type, $_SERVER['REQUEST_TIME_FLOAT']); - if ($this->isAjax()) { - header($name . ': ' . $token); - } - Session::set($name, $token); - return $token; - } - - /** - * 设置当前地址的请求缓存 - * @access public - * @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id - * @param mixed $expire 缓存有效期 - * @param array $except 缓存排除 - * @param string $tag 缓存标签 - * @return void - */ - public function cache($key, $expire = null, $except = [], $tag = null) - { - if (!is_array($except)) { - $tag = $except; - $except = []; - } - - if (false !== $key && $this->isGet() && !$this->isCheckCache) { - // 标记请求缓存检查 - $this->isCheckCache = true; - if (false === $expire) { - // 关闭当前缓存 - return; - } - if ($key instanceof \Closure) { - $key = call_user_func_array($key, [$this]); - } elseif (true === $key) { - foreach ($except as $rule) { - if (0 === stripos($this->url(), $rule)) { - return; - } - } - // 自动缓存功能 - $key = '__URL__'; - } elseif (strpos($key, '|')) { - list($key, $fun) = explode('|', $key); - } - // 特殊规则替换 - if (false !== strpos($key, '__')) { - $key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__', ''], [$this->module, $this->controller, $this->action, md5($this->url(true))], $key); - } - - if (false !== strpos($key, ':')) { - $param = $this->param(); - foreach ($param as $item => $val) { - if (is_string($val) && false !== strpos($key, ':' . $item)) { - $key = str_replace(':' . $item, $val, $key); - } - } - } elseif (strpos($key, ']')) { - if ('[' . $this->ext() . ']' == $key) { - // 缓存某个后缀的请求 - $key = md5($this->url()); - } else { - return; - } - } - if (isset($fun)) { - $key = $fun($key); - } - - if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) { - // 读取缓存 - $response = Response::create()->code(304); - throw new \think\exception\HttpResponseException($response); - } elseif (Cache::has($key)) { - list($content, $header) = Cache::get($key); - $response = Response::create($content)->header($header); - throw new \think\exception\HttpResponseException($response); - } else { - $this->cache = [$key, $expire, $tag]; - } - } - } - - /** - * 读取请求缓存设置 - * @access public - * @return array - */ - public function getCache() - { - return $this->cache; - } - - /** - * 设置当前请求绑定的对象实例 - * @access public - * @param string|array $name 绑定的对象标识 - * @param mixed $obj 绑定的对象实例 - * @return mixed - */ - public function bind($name, $obj = null) - { - if (is_array($name)) { - $this->bind = array_merge($this->bind, $name); - } else { - $this->bind[$name] = $obj; - } - } - - public function __set($name, $value) - { - $this->bind[$name] = $value; - } - - public function __get($name) - { - return isset($this->bind[$name]) ? $this->bind[$name] : null; - } - - public function __isset($name) - { - return isset($this->bind[$name]); - } - - /** - * 强制覆盖GET参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function forceGet($name = '', $default = null, $filter = '') - { - if (empty($this->get)) { - $this->get = $_GET; - } - if (is_array($name)) { - $this->param = []; - return $this->get = $name; - } - return $this->input($this->get, $name, $default, $filter); - } - - /** - * 强制覆盖POST参数 - * @access public - * @param string $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function forcePost($name = '', $default = null, $filter = '') - { - if (empty($this->post)) { - $content = $this->input; - if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) { - $this->post = (array) json_decode($content, true); - } else { - $this->post = $_POST; - } - } - if (is_array($name)) { - $this->param = []; - return $this->post = $name; - } - return $this->input($this->post, $name, $default, $filter); - } - - /** - * 强制覆盖PUT参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function forcePut($name = '', $default = null, $filter = '') - { - if (is_null($this->put)) { - $content = $this->input; - if (false !== strpos($this->contentType(), 'application/json')) { - $this->put = (array) json_decode($content, true); - } else { - parse_str($content, $this->put); - } - } - if (is_array($name)) { - $this->param = []; - return $this->put = $name; - } - - return $this->input($this->put, $name, $default, $filter); - } - - /** - * 强制覆盖DELETE参数 - * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 - * @return mixed - */ - public function forceDelete($name = '', $default = null, $filter = '') - { - return $this->forcePut($name, $default, $filter); - } -} diff --git a/thinkphp/library/think/Response.php b/thinkphp/library/think/Response.php deleted file mode 100755 index c5c1520..0000000 --- a/thinkphp/library/think/Response.php +++ /dev/null @@ -1,332 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\response\Json as JsonResponse; -use think\response\Jsonp as JsonpResponse; -use think\response\Redirect as RedirectResponse; -use think\response\View as ViewResponse; -use think\response\Xml as XmlResponse; - -class Response -{ - // 原始数据 - protected $data; - - // 当前的contentType - protected $contentType = 'text/html'; - - // 字符集 - protected $charset = 'utf-8'; - - //状态 - protected $code = 200; - - // 输出参数 - protected $options = []; - // header参数 - protected $header = []; - - protected $content = null; - - /** - * 构造函数 - * @access public - * @param mixed $data 输出数据 - * @param int $code - * @param array $header - * @param array $options 输出参数 - */ - public function __construct($data = '', $code = 200, array $header = [], $options = []) - { - $this->data($data); - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - $this->contentType($this->contentType, $this->charset); - $this->header = array_merge($this->header, $header); - $this->code = $code; - } - - /** - * 创建Response对象 - * @access public - * @param mixed $data 输出数据 - * @param string $type 输出类型 - * @param int $code - * @param array $header - * @param array $options 输出参数 - * @return Response|JsonResponse|ViewResponse|XmlResponse|RedirectResponse|JsonpResponse - */ - public static function create($data = '', $type = '', $code = 200, array $header = [], $options = []) - { - $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type)); - if (class_exists($class)) { - $response = new $class($data, $code, $header, $options); - } else { - $response = new static($data, $code, $header, $options); - } - - return $response; - } - - /** - * 发送数据到客户端 - * @access public - * @return mixed - * @throws \InvalidArgumentException - */ - public function send() - { - // 监听response_send - Hook::listen('response_send', $this); - - // 处理输出数据 - $data = $this->getContent(); - - // Trace调试注入 - if (Env::get('app_trace', Config::get('app_trace'))) { - Debug::inject($this, $data); - } - - if (200 == $this->code) { - $cache = Request::instance()->getCache(); - if ($cache) { - $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate'; - $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT'; - $this->header['Expires'] = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT'; - Cache::tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]); - } - } - - if (!headers_sent() && !empty($this->header)) { - // 发送状态码 - http_response_code($this->code); - // 发送头部信息 - foreach ($this->header as $name => $val) { - if (is_null($val)) { - header($name); - } else { - header($name . ':' . $val); - } - } - } - - echo $data; - - if (function_exists('fastcgi_finish_request')) { - // 提高页面响应 - fastcgi_finish_request(); - } - - // 监听response_end - Hook::listen('response_end', $this); - - // 清空当次请求有效的数据 - if (!($this instanceof RedirectResponse)) { - Session::flush(); - } - } - - /** - * 处理数据 - * @access protected - * @param mixed $data 要处理的数据 - * @return mixed - */ - protected function output($data) - { - return $data; - } - - /** - * 输出的参数 - * @access public - * @param mixed $options 输出参数 - * @return $this - */ - public function options($options = []) - { - $this->options = array_merge($this->options, $options); - return $this; - } - - /** - * 输出数据设置 - * @access public - * @param mixed $data 输出数据 - * @return $this - */ - public function data($data) - { - $this->data = $data; - return $this; - } - - /** - * 设置响应头 - * @access public - * @param string|array $name 参数名 - * @param string $value 参数值 - * @return $this - */ - public function header($name, $value = null) - { - if (is_array($name)) { - $this->header = array_merge($this->header, $name); - } else { - $this->header[$name] = $value; - } - return $this; - } - - /** - * 设置页面输出内容 - * @param $content - * @return $this - */ - public function content($content) - { - if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ - $content, - '__toString', - ]) - ) { - throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); - } - - $this->content = (string) $content; - - return $this; - } - - /** - * 发送HTTP状态 - * @param integer $code 状态码 - * @return $this - */ - public function code($code) - { - $this->code = $code; - return $this; - } - - /** - * LastModified - * @param string $time - * @return $this - */ - public function lastModified($time) - { - $this->header['Last-Modified'] = $time; - return $this; - } - - /** - * Expires - * @param string $time - * @return $this - */ - public function expires($time) - { - $this->header['Expires'] = $time; - return $this; - } - - /** - * ETag - * @param string $eTag - * @return $this - */ - public function eTag($eTag) - { - $this->header['ETag'] = $eTag; - return $this; - } - - /** - * 页面缓存控制 - * @param string $cache 状态码 - * @return $this - */ - public function cacheControl($cache) - { - $this->header['Cache-control'] = $cache; - return $this; - } - - /** - * 页面输出类型 - * @param string $contentType 输出类型 - * @param string $charset 输出编码 - * @return $this - */ - public function contentType($contentType, $charset = 'utf-8') - { - $this->header['Content-Type'] = $contentType . '; charset=' . $charset; - return $this; - } - - /** - * 获取头部信息 - * @param string $name 头部名称 - * @return mixed - */ - public function getHeader($name = '') - { - if (!empty($name)) { - return isset($this->header[$name]) ? $this->header[$name] : null; - } else { - return $this->header; - } - } - - /** - * 获取原始数据 - * @return mixed - */ - public function getData() - { - return $this->data; - } - - /** - * 获取输出数据 - * @return mixed - */ - public function getContent() - { - if (null == $this->content) { - $content = $this->output($this->data); - - if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ - $content, - '__toString', - ]) - ) { - throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); - } - - $this->content = (string) $content; - } - return $this->content; - } - - /** - * 获取状态码 - * @return integer - */ - public function getCode() - { - return $this->code; - } -} diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php deleted file mode 100755 index ab53aa2..0000000 --- a/thinkphp/library/think/Route.php +++ /dev/null @@ -1,1645 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\HttpException; - -class Route -{ - // 路由规则 - private static $rules = [ - 'get' => [], - 'post' => [], - 'put' => [], - 'delete' => [], - 'patch' => [], - 'head' => [], - 'options' => [], - '*' => [], - 'alias' => [], - 'domain' => [], - 'pattern' => [], - 'name' => [], - ]; - - // REST路由操作方法定义 - private static $rest = [ - 'index' => ['get', '', 'index'], - 'create' => ['get', '/create', 'create'], - 'edit' => ['get', '/:id/edit', 'edit'], - 'read' => ['get', '/:id', 'read'], - 'save' => ['post', '', 'save'], - 'update' => ['put', '/:id', 'update'], - 'delete' => ['delete', '/:id', 'delete'], - ]; - - // 不同请求类型的方法前缀 - private static $methodPrefix = [ - 'get' => 'get', - 'post' => 'post', - 'put' => 'put', - 'delete' => 'delete', - 'patch' => 'patch', - ]; - - // 子域名 - private static $subDomain = ''; - // 域名绑定 - private static $bind = []; - // 当前分组信息 - private static $group = []; - // 当前子域名绑定 - private static $domainBind; - private static $domainRule; - // 当前域名 - private static $domain; - // 当前路由执行过程中的参数 - private static $option = []; - - /** - * 注册变量规则 - * @access public - * @param string|array $name 变量名 - * @param string $rule 变量规则 - * @return void - */ - public static function pattern($name = null, $rule = '') - { - if (is_array($name)) { - self::$rules['pattern'] = array_merge(self::$rules['pattern'], $name); - } else { - self::$rules['pattern'][$name] = $rule; - } - } - - /** - * 注册子域名部署规则 - * @access public - * @param string|array $domain 子域名 - * @param mixed $rule 路由规则 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function domain($domain, $rule = '', $option = [], $pattern = []) - { - if (is_array($domain)) { - foreach ($domain as $key => $item) { - self::domain($key, $item, $option, $pattern); - } - } elseif ($rule instanceof \Closure) { - // 执行闭包 - self::setDomain($domain); - call_user_func_array($rule, []); - self::setDomain(null); - } elseif (is_array($rule)) { - self::setDomain($domain); - self::group('', function () use ($rule) { - // 动态注册域名的路由规则 - self::registerRules($rule); - }, $option, $pattern); - self::setDomain(null); - } else { - self::$rules['domain'][$domain]['[bind]'] = [$rule, $option, $pattern]; - } - } - - private static function setDomain($domain) - { - self::$domain = $domain; - } - - /** - * 设置路由绑定 - * @access public - * @param mixed $bind 绑定信息 - * @param string $type 绑定类型 默认为module 支持 namespace class controller - * @return mixed - */ - public static function bind($bind, $type = 'module') - { - self::$bind = ['type' => $type, $type => $bind]; - } - - /** - * 设置或者获取路由标识 - * @access public - * @param string|array $name 路由命名标识 数组表示批量设置 - * @param array $value 路由地址及变量信息 - * @return array - */ - public static function name($name = '', $value = null) - { - if (is_array($name)) { - return self::$rules['name'] = $name; - } elseif ('' === $name) { - return self::$rules['name']; - } elseif (!is_null($value)) { - self::$rules['name'][strtolower($name)][] = $value; - } else { - $name = strtolower($name); - return isset(self::$rules['name'][$name]) ? self::$rules['name'][$name] : null; - } - } - - /** - * 读取路由绑定 - * @access public - * @param string $type 绑定类型 - * @return mixed - */ - public static function getBind($type) - { - return isset(self::$bind[$type]) ? self::$bind[$type] : null; - } - - /** - * 导入配置文件的路由规则 - * @access public - * @param array $rule 路由规则 - * @param string $type 请求类型 - * @return void - */ - public static function import(array $rule, $type = '*') - { - // 检查域名部署 - if (isset($rule['__domain__'])) { - self::domain($rule['__domain__']); - unset($rule['__domain__']); - } - - // 检查变量规则 - if (isset($rule['__pattern__'])) { - self::pattern($rule['__pattern__']); - unset($rule['__pattern__']); - } - - // 检查路由别名 - if (isset($rule['__alias__'])) { - self::alias($rule['__alias__']); - unset($rule['__alias__']); - } - - // 检查资源路由 - if (isset($rule['__rest__'])) { - self::resource($rule['__rest__']); - unset($rule['__rest__']); - } - - self::registerRules($rule, strtolower($type)); - } - - // 批量注册路由 - protected static function registerRules($rules, $type = '*') - { - foreach ($rules as $key => $val) { - if (is_numeric($key)) { - $key = array_shift($val); - } - if (empty($val)) { - continue; - } - if (is_string($key) && 0 === strpos($key, '[')) { - $key = substr($key, 1, -1); - self::group($key, $val); - } elseif (is_array($val)) { - self::setRule($key, $val[0], $type, $val[1], isset($val[2]) ? $val[2] : []); - } else { - self::setRule($key, $val, $type); - } - } - } - - /** - * 注册路由规则 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param string $type 请求类型 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = []) - { - $group = self::getGroup('name'); - - if (!is_null($group)) { - // 路由分组 - $option = array_merge(self::getGroup('option'), $option); - $pattern = array_merge(self::getGroup('pattern'), $pattern); - } - - $type = strtolower($type); - - if (strpos($type, '|')) { - $option['method'] = $type; - $type = '*'; - } - if (is_array($rule) && empty($route)) { - foreach ($rule as $key => $val) { - if (is_numeric($key)) { - $key = array_shift($val); - } - if (is_array($val)) { - $route = $val[0]; - $option1 = array_merge($option, $val[1]); - $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []); - } else { - $option1 = null; - $pattern1 = null; - $route = $val; - } - self::setRule($key, $route, $type, !is_null($option1) ? $option1 : $option, !is_null($pattern1) ? $pattern1 : $pattern, $group); - } - } else { - self::setRule($rule, $route, $type, $option, $pattern, $group); - } - - } - - /** - * 设置路由规则 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param string $type 请求类型 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @param string $group 所属分组 - * @return void - */ - protected static function setRule($rule, $route, $type = '*', $option = [], $pattern = [], $group = '') - { - if (is_array($rule)) { - $name = $rule[0]; - $rule = $rule[1]; - } elseif (is_string($route)) { - $name = $route; - } - if (!isset($option['complete_match'])) { - if (Config::get('route_complete_match')) { - $option['complete_match'] = true; - } elseif ('$' == substr($rule, -1, 1)) { - // 是否完整匹配 - $option['complete_match'] = true; - } - } elseif (empty($option['complete_match']) && '$' == substr($rule, -1, 1)) { - // 是否完整匹配 - $option['complete_match'] = true; - } - - if ('$' == substr($rule, -1, 1)) { - $rule = substr($rule, 0, -1); - } - - if ('/' != $rule || $group) { - $rule = trim($rule, '/'); - } - $vars = self::parseVar($rule); - if (isset($name)) { - $key = $group ? $group . ($rule ? '/' . $rule : '') : $rule; - $suffix = isset($option['ext']) ? $option['ext'] : null; - self::name($name, [$key, $vars, self::$domain, $suffix]); - } - if (isset($option['modular'])) { - $route = $option['modular'] . '/' . $route; - } - if ($group) { - if ('*' != $type) { - $option['method'] = $type; - } - if (self::$domain) { - self::$rules['domain'][self::$domain]['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; - } else { - self::$rules['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; - } - } else { - if ('*' != $type && isset(self::$rules['*'][$rule])) { - unset(self::$rules['*'][$rule]); - } - if (self::$domain) { - self::$rules['domain'][self::$domain][$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; - } else { - self::$rules[$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; - } - if ('*' == $type) { - // 注册路由快捷方式 - foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) { - if (self::$domain && !isset(self::$rules['domain'][self::$domain][$method][$rule])) { - self::$rules['domain'][self::$domain][$method][$rule] = true; - } elseif (!self::$domain && !isset(self::$rules[$method][$rule])) { - self::$rules[$method][$rule] = true; - } - } - } - } - } - - /** - * 设置当前执行的参数信息 - * @access public - * @param array $options 参数信息 - * @return mixed - */ - protected static function setOption($options = []) - { - self::$option[] = $options; - } - - /** - * 获取当前执行的所有参数信息 - * @access public - * @return array - */ - public static function getOption() - { - return self::$option; - } - - /** - * 获取当前的分组信息 - * @access public - * @param string $type 分组信息名称 name option pattern - * @return mixed - */ - public static function getGroup($type) - { - if (isset(self::$group[$type])) { - return self::$group[$type]; - } else { - return 'name' == $type ? null : []; - } - } - - /** - * 设置当前的路由分组 - * @access public - * @param string $name 分组名称 - * @param array $option 分组路由参数 - * @param array $pattern 分组变量规则 - * @return void - */ - public static function setGroup($name, $option = [], $pattern = []) - { - self::$group['name'] = $name; - self::$group['option'] = $option ?: []; - self::$group['pattern'] = $pattern ?: []; - } - - /** - * 注册路由分组 - * @access public - * @param string|array $name 分组名称或者参数 - * @param array|\Closure $routes 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function group($name, $routes, $option = [], $pattern = []) - { - if (is_array($name)) { - $option = $name; - $name = isset($option['name']) ? $option['name'] : ''; - } - // 分组 - $currentGroup = self::getGroup('name'); - if ($currentGroup) { - $name = $currentGroup . ($name ? '/' . ltrim($name, '/') : ''); - } - if (!empty($name)) { - if ($routes instanceof \Closure) { - $currentOption = self::getGroup('option'); - $currentPattern = self::getGroup('pattern'); - self::setGroup($name, array_merge($currentOption, $option), array_merge($currentPattern, $pattern)); - call_user_func_array($routes, []); - self::setGroup($currentGroup, $currentOption, $currentPattern); - if ($currentGroup != $name) { - self::$rules['*'][$name]['route'] = ''; - self::$rules['*'][$name]['var'] = self::parseVar($name); - self::$rules['*'][$name]['option'] = $option; - self::$rules['*'][$name]['pattern'] = $pattern; - } - } else { - $item = []; - $completeMatch = Config::get('route_complete_match'); - foreach ($routes as $key => $val) { - if (is_numeric($key)) { - $key = array_shift($val); - } - if (is_array($val)) { - $route = $val[0]; - $option1 = array_merge($option, isset($val[1]) ? $val[1] : []); - $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []); - } else { - $route = $val; - } - - $options = isset($option1) ? $option1 : $option; - $patterns = isset($pattern1) ? $pattern1 : $pattern; - if ('$' == substr($key, -1, 1)) { - // 是否完整匹配 - $options['complete_match'] = true; - $key = substr($key, 0, -1); - } elseif ($completeMatch) { - $options['complete_match'] = true; - } - $key = trim($key, '/'); - $vars = self::parseVar($key); - $item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns]; - // 设置路由标识 - $suffix = isset($options['ext']) ? $options['ext'] : null; - self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain, $suffix]); - } - self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern]; - } - - foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) { - if (!isset(self::$rules[$method][$name])) { - self::$rules[$method][$name] = true; - } elseif (is_array(self::$rules[$method][$name])) { - self::$rules[$method][$name] = array_merge(self::$rules['*'][$name], self::$rules[$method][$name]); - } - } - - } elseif ($routes instanceof \Closure) { - // 闭包注册 - $currentOption = self::getGroup('option'); - $currentPattern = self::getGroup('pattern'); - self::setGroup('', array_merge($currentOption, $option), array_merge($currentPattern, $pattern)); - call_user_func_array($routes, []); - self::setGroup($currentGroup, $currentOption, $currentPattern); - } else { - // 批量注册路由 - self::rule($routes, '', '*', $option, $pattern); - } - } - - /** - * 注册路由 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function any($rule, $route = '', $option = [], $pattern = []) - { - self::rule($rule, $route, '*', $option, $pattern); - } - - /** - * 注册GET路由 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function get($rule, $route = '', $option = [], $pattern = []) - { - self::rule($rule, $route, 'GET', $option, $pattern); - } - - /** - * 注册POST路由 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function post($rule, $route = '', $option = [], $pattern = []) - { - self::rule($rule, $route, 'POST', $option, $pattern); - } - - /** - * 注册PUT路由 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function put($rule, $route = '', $option = [], $pattern = []) - { - self::rule($rule, $route, 'PUT', $option, $pattern); - } - - /** - * 注册DELETE路由 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function delete($rule, $route = '', $option = [], $pattern = []) - { - self::rule($rule, $route, 'DELETE', $option, $pattern); - } - - /** - * 注册PATCH路由 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function patch($rule, $route = '', $option = [], $pattern = []) - { - self::rule($rule, $route, 'PATCH', $option, $pattern); - } - - /** - * 注册资源路由 - * @access public - * @param string|array $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function resource($rule, $route = '', $option = [], $pattern = []) - { - if (is_array($rule)) { - foreach ($rule as $key => $val) { - if (is_array($val)) { - list($val, $option, $pattern) = array_pad($val, 3, []); - } - self::resource($key, $val, $option, $pattern); - } - } else { - if (strpos($rule, '.')) { - // 注册嵌套资源路由 - $array = explode('.', $rule); - $last = array_pop($array); - $item = []; - foreach ($array as $val) { - $item[] = $val . '/:' . (isset($option['var'][$val]) ? $option['var'][$val] : $val . '_id'); - } - $rule = implode('/', $item) . '/' . $last; - } - // 注册资源路由 - foreach (self::$rest as $key => $val) { - if ((isset($option['only']) && !in_array($key, $option['only'])) - || (isset($option['except']) && in_array($key, $option['except']))) { - continue; - } - if (isset($last) && strpos($val[1], ':id') && isset($option['var'][$last])) { - $val[1] = str_replace(':id', ':' . $option['var'][$last], $val[1]); - } elseif (strpos($val[1], ':id') && isset($option['var'][$rule])) { - $val[1] = str_replace(':id', ':' . $option['var'][$rule], $val[1]); - } - $item = ltrim($rule . $val[1], '/'); - $option['rest'] = $key; - self::rule($item . '$', $route . '/' . $val[2], $val[0], $option, $pattern); - } - } - } - - /** - * 注册控制器路由 操作方法对应不同的请求后缀 - * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public static function controller($rule, $route = '', $option = [], $pattern = []) - { - foreach (self::$methodPrefix as $type => $val) { - self::$type($rule . '/:action', $route . '/' . $val . ':action', $option, $pattern); - } - } - - /** - * 注册别名路由 - * @access public - * @param string|array $rule 路由别名 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @return void - */ - public static function alias($rule = null, $route = '', $option = []) - { - if (is_array($rule)) { - self::$rules['alias'] = array_merge(self::$rules['alias'], $rule); - } else { - self::$rules['alias'][$rule] = $option ? [$route, $option] : $route; - } - } - - /** - * 设置不同请求类型下面的方法前缀 - * @access public - * @param string $method 请求类型 - * @param string $prefix 类型前缀 - * @return void - */ - public static function setMethodPrefix($method, $prefix = '') - { - if (is_array($method)) { - self::$methodPrefix = array_merge(self::$methodPrefix, array_change_key_case($method)); - } else { - self::$methodPrefix[strtolower($method)] = $prefix; - } - } - - /** - * rest方法定义和修改 - * @access public - * @param string|array $name 方法名称 - * @param array|bool $resource 资源 - * @return void - */ - public static function rest($name, $resource = []) - { - if (is_array($name)) { - self::$rest = $resource ? $name : array_merge(self::$rest, $name); - } else { - self::$rest[$name] = $resource; - } - } - - /** - * 注册未匹配路由规则后的处理 - * @access public - * @param string $route 路由地址 - * @param string $method 请求类型 - * @param array $option 路由参数 - * @return void - */ - public static function miss($route, $method = '*', $option = []) - { - self::rule('__miss__', $route, $method, $option, []); - } - - /** - * 注册一个自动解析的URL路由 - * @access public - * @param string $route 路由地址 - * @return void - */ - public static function auto($route) - { - self::rule('__auto__', $route, '*', [], []); - } - - /** - * 获取或者批量设置路由定义 - * @access public - * @param mixed $rules 请求类型或者路由定义数组 - * @return array - */ - public static function rules($rules = '') - { - if (is_array($rules)) { - self::$rules = $rules; - } elseif ($rules) { - return true === $rules ? self::$rules : self::$rules[strtolower($rules)]; - } else { - $rules = self::$rules; - unset($rules['pattern'], $rules['alias'], $rules['domain'], $rules['name']); - return $rules; - } - } - - /** - * 检测子域名部署 - * @access public - * @param Request $request Request请求对象 - * @param array $currentRules 当前路由规则 - * @param string $method 请求类型 - * @return void - */ - public static function checkDomain($request, &$currentRules, $method = 'get') - { - // 域名规则 - $rules = self::$rules['domain']; - // 开启子域名部署 支持二级和三级域名 - if (!empty($rules)) { - $host = $request->host(true); - if (isset($rules[$host])) { - // 完整域名或者IP配置 - $item = $rules[$host]; - } else { - $rootDomain = Config::get('url_domain_root'); - if ($rootDomain) { - // 配置域名根 例如 thinkphp.cn 163.com.cn 如果是国家级域名 com.cn net.cn 之类的域名需要配置 - $domain = explode('.', rtrim(stristr($host, $rootDomain, true), '.')); - } else { - $domain = explode('.', $host, -2); - } - // 子域名配置 - if (!empty($domain)) { - // 当前子域名 - $subDomain = implode('.', $domain); - self::$subDomain = $subDomain; - $domain2 = array_pop($domain); - if ($domain) { - // 存在三级域名 - $domain3 = array_pop($domain); - } - if ($subDomain && isset($rules[$subDomain])) { - // 子域名配置 - $item = $rules[$subDomain]; - } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { - // 泛三级域名 - $item = $rules['*.' . $domain2]; - $panDomain = $domain3; - } elseif (isset($rules['*']) && !empty($domain2)) { - // 泛二级域名 - if ('www' != $domain2) { - $item = $rules['*']; - $panDomain = $domain2; - } - } - } - } - if (!empty($item)) { - if (isset($panDomain)) { - // 保存当前泛域名 - $request->route(['__domain__' => $panDomain]); - } - if (isset($item['[bind]'])) { - // 解析子域名部署规则 - list($rule, $option, $pattern) = $item['[bind]']; - if (!empty($option['https']) && !$request->isSsl()) { - // https检测 - throw new HttpException(404, 'must use https request:' . $host); - } - - if (strpos($rule, '?')) { - // 传入其它参数 - $array = parse_url($rule); - $result = $array['path']; - parse_str($array['query'], $params); - if (isset($panDomain)) { - $pos = array_search('*', $params); - if (false !== $pos) { - // 泛域名作为参数 - $params[$pos] = $panDomain; - } - } - $_GET = array_merge($_GET, $params); - } else { - $result = $rule; - } - - if (0 === strpos($result, '\\')) { - // 绑定到命名空间 例如 \app\index\behavior - self::$bind = ['type' => 'namespace', 'namespace' => $result]; - } elseif (0 === strpos($result, '@')) { - // 绑定到类 例如 @app\index\controller\User - self::$bind = ['type' => 'class', 'class' => substr($result, 1)]; - } else { - // 绑定到模块/控制器 例如 index/user - self::$bind = ['type' => 'module', 'module' => $result]; - } - self::$domainBind = true; - } else { - self::$domainRule = $item; - $currentRules = isset($item[$method]) ? $item[$method] : $item['*']; - } - } - } - } - - /** - * 检测URL路由 - * @access public - * @param Request $request Request请求对象 - * @param string $url URL地址 - * @param string $depr URL分隔符 - * @param bool $checkDomain 是否检测域名规则 - * @return false|array - */ - public static function check($request, $url, $depr = '/', $checkDomain = false) - { - //检查解析缓存 - if (!App::$debug && Config::get('route_check_cache')) { - $key = self::getCheckCacheKey($request); - if (Cache::has($key)) { - list($rule, $route, $pathinfo, $option, $matches) = Cache::get($key); - return self::parseRule($rule, $route, $pathinfo, $option, $matches, true); - } - } - - // 分隔符替换 确保路由定义使用统一的分隔符 - $url = str_replace($depr, '|', $url); - - if (isset(self::$rules['alias'][$url]) || isset(self::$rules['alias'][strstr($url, '|', true)])) { - // 检测路由别名 - $result = self::checkRouteAlias($request, $url, $depr); - if (false !== $result) { - return $result; - } - } - $method = strtolower($request->method()); - // 获取当前请求类型的路由规则 - $rules = isset(self::$rules[$method]) ? self::$rules[$method] : []; - // 检测域名部署 - if ($checkDomain) { - self::checkDomain($request, $rules, $method); - } - // 检测URL绑定 - $return = self::checkUrlBind($url, $rules, $depr); - if (false !== $return) { - return $return; - } - if ('|' != $url) { - $url = rtrim($url, '|'); - } - $item = str_replace('|', '/', $url); - if (isset($rules[$item])) { - // 静态路由规则检测 - $rule = $rules[$item]; - if (true === $rule) { - $rule = self::getRouteExpress($item); - } - if (!empty($rule['route']) && self::checkOption($rule['option'], $request)) { - self::setOption($rule['option']); - return self::parseRule($item, $rule['route'], $url, $rule['option']); - } - } - - // 路由规则检测 - if (!empty($rules)) { - return self::checkRoute($request, $rules, $url, $depr); - } - return false; - } - - private static function getRouteExpress($key) - { - return self::$domainRule ? self::$domainRule['*'][$key] : self::$rules['*'][$key]; - } - - /** - * 检测路由规则 - * @access private - * @param Request $request - * @param array $rules 路由规则 - * @param string $url URL地址 - * @param string $depr URL分割符 - * @param string $group 路由分组名 - * @param array $options 路由参数(分组) - * @return mixed - */ - private static function checkRoute($request, $rules, $url, $depr = '/', $group = '', $options = []) - { - foreach ($rules as $key => $item) { - if (true === $item) { - $item = self::getRouteExpress($key); - } - if (!isset($item['rule'])) { - continue; - } - $rule = $item['rule']; - $route = $item['route']; - $vars = $item['var']; - $option = $item['option']; - $pattern = $item['pattern']; - - // 检查参数有效性 - if (!self::checkOption($option, $request)) { - continue; - } - - if (isset($option['ext'])) { - // 路由ext参数 优先于系统配置的URL伪静态后缀参数 - $url = preg_replace('/\.' . $request->ext() . '$/i', '', $url); - } - - if (is_array($rule)) { - // 分组路由 - $pos = strpos(str_replace('<', ':', $key), ':'); - if (false !== $pos) { - $str = substr($key, 0, $pos); - } else { - $str = $key; - } - if (is_string($str) && $str && 0 !== stripos(str_replace('|', '/', $url), $str)) { - continue; - } - self::setOption($option); - $result = self::checkRoute($request, $rule, $url, $depr, $key, $option); - if (false !== $result) { - return $result; - } - } elseif ($route) { - if ('__miss__' == $rule || '__auto__' == $rule) { - // 指定特殊路由 - $var = trim($rule, '__'); - ${$var} = $item; - continue; - } - if ($group) { - $rule = $group . ($rule ? '/' . ltrim($rule, '/') : ''); - } - - self::setOption($option); - if (isset($options['bind_model']) && isset($option['bind_model'])) { - $option['bind_model'] = array_merge($options['bind_model'], $option['bind_model']); - } - $result = self::checkRule($rule, $route, $url, $pattern, $option, $depr); - if (false !== $result) { - return $result; - } - } - } - if (isset($auto)) { - // 自动解析URL地址 - return self::parseUrl($auto['route'] . '/' . $url, $depr); - } elseif (isset($miss)) { - // 未匹配所有路由的路由规则处理 - return self::parseRule('', $miss['route'], $url, $miss['option']); - } - return false; - } - - /** - * 检测路由别名 - * @access private - * @param Request $request - * @param string $url URL地址 - * @param string $depr URL分隔符 - * @return mixed - */ - private static function checkRouteAlias($request, $url, $depr) - { - $array = explode('|', $url); - $alias = array_shift($array); - $item = self::$rules['alias'][$alias]; - - if (is_array($item)) { - list($rule, $option) = $item; - $action = $array[0]; - if (isset($option['allow']) && !in_array($action, explode(',', $option['allow']))) { - // 允许操作 - return false; - } elseif (isset($option['except']) && in_array($action, explode(',', $option['except']))) { - // 排除操作 - return false; - } - if (isset($option['method'][$action])) { - $option['method'] = $option['method'][$action]; - } - } else { - $rule = $item; - } - $bind = implode('|', $array); - // 参数有效性检查 - if (isset($option) && !self::checkOption($option, $request)) { - // 路由不匹配 - return false; - } elseif (0 === strpos($rule, '\\')) { - // 路由到类 - return self::bindToClass($bind, substr($rule, 1), $depr); - } elseif (0 === strpos($rule, '@')) { - // 路由到控制器类 - return self::bindToController($bind, substr($rule, 1), $depr); - } else { - // 路由到模块/控制器 - return self::bindToModule($bind, $rule, $depr); - } - } - - /** - * 检测URL绑定 - * @access private - * @param string $url URL地址 - * @param array $rules 路由规则 - * @param string $depr URL分隔符 - * @return mixed - */ - private static function checkUrlBind(&$url, &$rules, $depr = '/') - { - if (!empty(self::$bind)) { - $type = self::$bind['type']; - $bind = self::$bind[$type]; - // 记录绑定信息 - App::$debug && Log::record('[ BIND ] ' . var_export($bind, true), 'info'); - // 如果有URL绑定 则进行绑定检测 - switch ($type) { - case 'class': - // 绑定到类 - return self::bindToClass($url, $bind, $depr); - case 'controller': - // 绑定到控制器类 - return self::bindToController($url, $bind, $depr); - case 'namespace': - // 绑定到命名空间 - return self::bindToNamespace($url, $bind, $depr); - } - } - return false; - } - - /** - * 绑定到类 - * @access public - * @param string $url URL地址 - * @param string $class 类名(带命名空间) - * @param string $depr URL分隔符 - * @return array - */ - public static function bindToClass($url, $class, $depr = '/') - { - $url = str_replace($depr, '|', $url); - $array = explode('|', $url, 2); - $action = !empty($array[0]) ? $array[0] : Config::get('default_action'); - if (!empty($array[1])) { - self::parseUrlParams($array[1]); - } - return ['type' => 'method', 'method' => [$class, $action], 'var' => []]; - } - - /** - * 绑定到命名空间 - * @access public - * @param string $url URL地址 - * @param string $namespace 命名空间 - * @param string $depr URL分隔符 - * @return array - */ - public static function bindToNamespace($url, $namespace, $depr = '/') - { - $url = str_replace($depr, '|', $url); - $array = explode('|', $url, 3); - $class = !empty($array[0]) ? $array[0] : Config::get('default_controller'); - $method = !empty($array[1]) ? $array[1] : Config::get('default_action'); - if (!empty($array[2])) { - self::parseUrlParams($array[2]); - } - return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method], 'var' => []]; - } - - /** - * 绑定到控制器类 - * @access public - * @param string $url URL地址 - * @param string $controller 控制器名 (支持带模块名 index/user ) - * @param string $depr URL分隔符 - * @return array - */ - public static function bindToController($url, $controller, $depr = '/') - { - $url = str_replace($depr, '|', $url); - $array = explode('|', $url, 2); - $action = !empty($array[0]) ? $array[0] : Config::get('default_action'); - if (!empty($array[1])) { - self::parseUrlParams($array[1]); - } - return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'var' => []]; - } - - /** - * 绑定到模块/控制器 - * @access public - * @param string $url URL地址 - * @param string $controller 控制器类名(带命名空间) - * @param string $depr URL分隔符 - * @return array - */ - public static function bindToModule($url, $controller, $depr = '/') - { - $url = str_replace($depr, '|', $url); - $array = explode('|', $url, 2); - $action = !empty($array[0]) ? $array[0] : Config::get('default_action'); - if (!empty($array[1])) { - self::parseUrlParams($array[1]); - } - return ['type' => 'module', 'module' => $controller . '/' . $action]; - } - - /** - * 路由参数有效性检查 - * @access private - * @param array $option 路由参数 - * @param Request $request Request对象 - * @return bool - */ - private static function checkOption($option, $request) - { - if ((isset($option['method']) && is_string($option['method']) && false === stripos($option['method'], $request->method())) - || (isset($option['ajax']) && $option['ajax'] && !$request->isAjax()) // Ajax检测 - || (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测 - || (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测 - || (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测 - || (isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', '|' . $request->ext() . '|')) // 伪静态后缀检测 - || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', '|' . $request->ext() . '|')) - || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测 - || (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测 - || (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测 - || (!empty($option['before_behavior']) && false === Hook::exec($option['before_behavior'])) // 行为检测 - || (!empty($option['callback']) && is_callable($option['callback']) && false === call_user_func($option['callback'])) // 自定义检测 - ) { - return false; - } - return true; - } - - /** - * 检测路由规则 - * @access private - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param string $url URL地址 - * @param array $pattern 变量规则 - * @param array $option 路由参数 - * @param string $depr URL分隔符(全局) - * @return array|false - */ - private static function checkRule($rule, $route, $url, $pattern, $option, $depr) - { - // 检查完整规则定义 - if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) { - return false; - } - // 检查路由的参数分隔符 - if (isset($option['param_depr'])) { - $url = str_replace(['|', $option['param_depr']], [$depr, '|'], $url); - } - - $len1 = substr_count($url, '|'); - $len2 = substr_count($rule, '/'); - // 多余参数是否合并 - $merge = !empty($option['merge_extra_vars']); - if ($merge && $len1 > $len2) { - $url = str_replace('|', $depr, $url); - $url = implode('|', explode($depr, $url, $len2 + 1)); - } - - if ($len1 >= $len2 || strpos($rule, '[')) { - if (!empty($option['complete_match'])) { - // 完整匹配 - if (!$merge && $len1 != $len2 && (false === strpos($rule, '[') || $len1 > $len2 || $len1 < $len2 - substr_count($rule, '['))) { - return false; - } - } - $pattern = array_merge(self::$rules['pattern'], $pattern); - if (false !== $match = self::match($url, $rule, $pattern)) { - // 匹配到路由规则 - return self::parseRule($rule, $route, $url, $option, $match); - } - } - return false; - } - - /** - * 解析模块的URL地址 [模块/控制器/操作?]参数1=值1&参数2=值2... - * @access public - * @param string $url URL地址 - * @param string $depr URL分隔符 - * @param bool $autoSearch 是否自动深度搜索控制器 - * @return array - */ - public static function parseUrl($url, $depr = '/', $autoSearch = false) - { - - if (isset(self::$bind['module'])) { - $bind = str_replace('/', $depr, self::$bind['module']); - // 如果有模块/控制器绑定 - $url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr); - } - $url = str_replace($depr, '|', $url); - list($path, $var) = self::parseUrlPath($url); - $route = [null, null, null]; - if (isset($path)) { - // 解析模块 - $module = Config::get('app_multi_module') ? array_shift($path) : null; - if ($autoSearch) { - // 自动搜索控制器 - $dir = APP_PATH . ($module ? $module . DS : '') . Config::get('url_controller_layer'); - $suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : ''; - $item = []; - $find = false; - foreach ($path as $val) { - $item[] = $val; - $file = $dir . DS . str_replace('.', DS, $val) . $suffix . EXT; - $file = pathinfo($file, PATHINFO_DIRNAME) . DS . Loader::parseName(pathinfo($file, PATHINFO_FILENAME), 1) . EXT; - if (is_file($file)) { - $find = true; - break; - } else { - $dir .= DS . Loader::parseName($val); - } - } - if ($find) { - $controller = implode('.', $item); - $path = array_slice($path, count($item)); - } else { - $controller = array_shift($path); - } - } else { - // 解析控制器 - $controller = !empty($path) ? array_shift($path) : null; - } - // 解析操作 - $action = !empty($path) ? array_shift($path) : null; - // 解析额外参数 - self::parseUrlParams(empty($path) ? '' : implode('|', $path)); - // 封装路由 - $route = [$module, $controller, $action]; - // 检查地址是否被定义过路由 - $name = strtolower($module . '/' . Loader::parseName($controller, 1) . '/' . $action); - $name2 = ''; - if (empty($module) || isset($bind) && $module == $bind) { - $name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action); - } - - if (isset(self::$rules['name'][$name]) || isset(self::$rules['name'][$name2])) { - throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url)); - } - } - return ['type' => 'module', 'module' => $route]; - } - - /** - * 解析URL的pathinfo参数和变量 - * @access private - * @param string $url URL地址 - * @return array - */ - private static function parseUrlPath($url) - { - // 分隔符替换 确保路由定义使用统一的分隔符 - $url = str_replace('|', '/', $url); - $url = trim($url, '/'); - $var = []; - if (false !== strpos($url, '?')) { - // [模块/控制器/操作?]参数1=值1&参数2=值2... - $info = parse_url($url); - $path = explode('/', $info['path']); - parse_str($info['query'], $var); - } elseif (strpos($url, '/')) { - // [模块/控制器/操作] - $path = explode('/', $url); - } else { - $path = [$url]; - } - return [$path, $var]; - } - - /** - * 检测URL和规则路由是否匹配 - * @access private - * @param string $url URL地址 - * @param string $rule 路由规则 - * @param array $pattern 变量规则 - * @return array|false - */ - private static function match($url, $rule, $pattern) - { - $m2 = explode('/', $rule); - $m1 = explode('|', $url); - - $var = []; - foreach ($m2 as $key => $val) { - // val中定义了多个变量 - if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) { - $value = []; - $replace = []; - foreach ($matches[1] as $name) { - if (strpos($name, '?')) { - $name = substr($name, 0, -1); - $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . ')?'; - } else { - $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . ')'; - } - $value[] = $name; - } - $val = str_replace($matches[0], $replace, $val); - if (preg_match('/^' . $val . '$/', isset($m1[$key]) ? $m1[$key] : '', $match)) { - array_shift($match); - foreach ($value as $k => $name) { - if (isset($match[$k])) { - $var[$name] = $match[$k]; - } - } - continue; - } else { - return false; - } - } - - if (0 === strpos($val, '[:')) { - // 可选参数 - $val = substr($val, 1, -1); - $optional = true; - } else { - $optional = false; - } - if (0 === strpos($val, ':')) { - // URL变量 - $name = substr($val, 1); - if (!$optional && !isset($m1[$key])) { - return false; - } - if (isset($m1[$key]) && isset($pattern[$name])) { - // 检查变量规则 - if ($pattern[$name] instanceof \Closure) { - $result = call_user_func_array($pattern[$name], [$m1[$key]]); - if (false === $result) { - return false; - } - } elseif (!preg_match(0 === strpos($pattern[$name], '/') ? $pattern[$name] : '/^' . $pattern[$name] . '$/', $m1[$key])) { - return false; - } - } - $var[$name] = isset($m1[$key]) ? $m1[$key] : ''; - } elseif (!isset($m1[$key]) || 0 !== strcasecmp($val, $m1[$key])) { - return false; - } - } - // 成功匹配后返回URL中的动态变量数组 - return $var; - } - - /** - * 解析规则路由 - * @access private - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param string $pathinfo URL地址 - * @param array $option 路由参数 - * @param array $matches 匹配的变量 - * @param bool $fromCache 通过缓存解析 - * @return array - */ - private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = [], $fromCache = false) - { - $request = Request::instance(); - - //保存解析缓存 - if (Config::get('route_check_cache') && !$fromCache) { - try { - $key = self::getCheckCacheKey($request); - Cache::tag('route_check')->set($key, [$rule, $route, $pathinfo, $option, $matches]); - } catch (\Exception $e) { - - } - } - - // 解析路由规则 - if ($rule) { - $rule = explode('/', $rule); - // 获取URL地址中的参数 - $paths = explode('|', $pathinfo); - foreach ($rule as $item) { - $fun = ''; - if (0 === strpos($item, '[:')) { - $item = substr($item, 1, -1); - } - if (0 === strpos($item, ':')) { - $var = substr($item, 1); - $matches[$var] = array_shift($paths); - } else { - // 过滤URL中的静态变量 - array_shift($paths); - } - } - } else { - $paths = explode('|', $pathinfo); - } - - // 获取路由地址规则 - if (is_string($route) && isset($option['prefix'])) { - // 路由地址前缀 - $route = $option['prefix'] . $route; - } - // 替换路由地址中的变量 - if (is_string($route) && !empty($matches)) { - foreach ($matches as $key => $val) { - if (false !== strpos($route, ':' . $key)) { - $route = str_replace(':' . $key, $val, $route); - } - } - } - - // 绑定模型数据 - if (isset($option['bind_model'])) { - $bind = []; - foreach ($option['bind_model'] as $key => $val) { - if ($val instanceof \Closure) { - $result = call_user_func_array($val, [$matches]); - } else { - if (is_array($val)) { - $fields = explode('&', $val[1]); - $model = $val[0]; - $exception = isset($val[2]) ? $val[2] : true; - } else { - $fields = ['id']; - $model = $val; - $exception = true; - } - $where = []; - $match = true; - foreach ($fields as $field) { - if (!isset($matches[$field])) { - $match = false; - break; - } else { - $where[$field] = $matches[$field]; - } - } - if ($match) { - $query = strpos($model, '\\') ? $model::where($where) : Loader::model($model)->where($where); - $result = $query->failException($exception)->find(); - } - } - if (!empty($result)) { - $bind[$key] = $result; - } - } - $request->bind($bind); - } - - if (!empty($option['response'])) { - Hook::add('response_send', $option['response']); - } - - // 解析额外参数 - self::parseUrlParams(empty($paths) ? '' : implode('|', $paths), $matches); - // 记录匹配的路由信息 - $request->routeInfo(['rule' => $rule, 'route' => $route, 'option' => $option, 'var' => $matches]); - - // 检测路由after行为 - if (!empty($option['after_behavior'])) { - if ($option['after_behavior'] instanceof \Closure) { - $result = call_user_func_array($option['after_behavior'], []); - } else { - foreach ((array) $option['after_behavior'] as $behavior) { - $result = Hook::exec($behavior, ''); - if (!is_null($result)) { - break; - } - } - } - // 路由规则重定向 - if ($result instanceof Response) { - return ['type' => 'response', 'response' => $result]; - } elseif (is_array($result)) { - return $result; - } - } - - if ($route instanceof \Closure) { - // 执行闭包 - $result = ['type' => 'function', 'function' => $route]; - } elseif (0 === strpos($route, '/') || strpos($route, '://')) { - // 路由到重定向地址 - $result = ['type' => 'redirect', 'url' => $route, 'status' => isset($option['status']) ? $option['status'] : 301]; - } elseif (false !== strpos($route, '\\')) { - // 路由到方法 - list($path, $var) = self::parseUrlPath($route); - $route = str_replace('/', '@', implode('/', $path)); - $method = strpos($route, '@') ? explode('@', $route) : $route; - $result = ['type' => 'method', 'method' => $method, 'var' => $var]; - } elseif (0 === strpos($route, '@')) { - // 路由到控制器 - $route = substr($route, 1); - list($route, $var) = self::parseUrlPath($route); - $result = ['type' => 'controller', 'controller' => implode('/', $route), 'var' => $var]; - $request->action(array_pop($route)); - $request->controller($route ? array_pop($route) : Config::get('default_controller')); - $request->module($route ? array_pop($route) : Config::get('default_module')); - App::$modulePath = APP_PATH . (Config::get('app_multi_module') ? $request->module() . DS : ''); - } else { - // 路由到模块/控制器/操作 - $result = self::parseModule($route, isset($option['convert']) ? $option['convert'] : false); - } - // 开启请求缓存 - if ($request->isGet() && isset($option['cache'])) { - $cache = $option['cache']; - if (is_array($cache)) { - list($key, $expire, $tag) = array_pad($cache, 3, null); - } else { - $key = str_replace('|', '/', $pathinfo); - $expire = $cache; - $tag = null; - } - $request->cache($key, $expire, $tag); - } - return $result; - } - - /** - * 解析URL地址为 模块/控制器/操作 - * @access private - * @param string $url URL地址 - * @param bool $convert 是否自动转换URL地址 - * @return array - */ - private static function parseModule($url, $convert = false) - { - list($path, $var) = self::parseUrlPath($url); - $action = array_pop($path); - $controller = !empty($path) ? array_pop($path) : null; - $module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null; - $method = Request::instance()->method(); - if (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) { - // 操作方法前缀支持 - $action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action; - } - // 设置当前请求的路由变量 - Request::instance()->route($var); - // 路由到模块/控制器/操作 - return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => $convert]; - } - - /** - * 解析URL地址中的参数Request对象 - * @access private - * @param string $url 路由规则 - * @param array $var 变量 - * @return void - */ - private static function parseUrlParams($url, &$var = []) - { - if ($url) { - if (Config::get('url_param_type')) { - $var += explode('|', $url); - } else { - preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) { - $var[$match[1]] = strip_tags($match[2]); - }, $url); - } - } - // 设置当前请求的参数 - Request::instance()->route($var); - } - - // 分析路由规则中的变量 - private static function parseVar($rule) - { - // 提取路由规则中的变量 - $var = []; - foreach (explode('/', $rule) as $val) { - $optional = false; - if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) { - foreach ($matches[1] as $name) { - if (strpos($name, '?')) { - $name = substr($name, 0, -1); - $optional = true; - } else { - $optional = false; - } - $var[$name] = $optional ? 2 : 1; - } - } - - if (0 === strpos($val, '[:')) { - // 可选参数 - $optional = true; - $val = substr($val, 1, -1); - } - if (0 === strpos($val, ':')) { - // URL变量 - $name = substr($val, 1); - $var[$name] = $optional ? 2 : 1; - } - } - return $var; - } - - /** - * 获取路由解析缓存的key - * @param Request $request - * @return string - */ - private static function getCheckCacheKey(Request $request) - { - static $key; - - if (empty($key)) { - if ($callback = Config::get('route_check_cache_key')) { - $key = call_user_func($callback, $request); - } else { - $key = "{$request->host(true)}|{$request->method()}|{$request->path()}"; - } - } - - return $key; - } -} diff --git a/thinkphp/library/think/Session.php b/thinkphp/library/think/Session.php deleted file mode 100755 index 61150bc..0000000 --- a/thinkphp/library/think/Session.php +++ /dev/null @@ -1,366 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\ClassNotFoundException; - -class Session -{ - protected static $prefix = ''; - protected static $init = null; - - /** - * 设置或者获取session作用域(前缀) - * @param string $prefix - * @return string|void - */ - public static function prefix($prefix = '') - { - empty(self::$init) && self::boot(); - if (empty($prefix) && null !== $prefix) { - return self::$prefix; - } else { - self::$prefix = $prefix; - } - } - - /** - * session初始化 - * @param array $config - * @return void - * @throws \think\Exception - */ - public static function init(array $config = []) - { - if (empty($config)) { - $config = Config::get('session'); - } - // 记录初始化信息 - App::$debug && Log::record('[ SESSION ] INIT ' . var_export($config, true), 'info'); - $isDoStart = false; - if (isset($config['use_trans_sid'])) { - ini_set('session.use_trans_sid', $config['use_trans_sid'] ? 1 : 0); - } - - // 启动session - if (!empty($config['auto_start']) && PHP_SESSION_ACTIVE != session_status()) { - ini_set('session.auto_start', 0); - $isDoStart = true; - } - - if (isset($config['prefix']) && ('' === self::$prefix || null === self::$prefix)) { - self::$prefix = $config['prefix']; - } - if (isset($config['var_session_id']) && isset($_REQUEST[$config['var_session_id']])) { - session_id($_REQUEST[$config['var_session_id']]); - } elseif (isset($config['id']) && !empty($config['id'])) { - session_id($config['id']); - } - if (isset($config['name'])) { - session_name($config['name']); - } - if (isset($config['path'])) { - session_save_path($config['path']); - } - if (isset($config['domain'])) { - ini_set('session.cookie_domain', $config['domain']); - } - if (isset($config['expire'])) { - ini_set('session.gc_maxlifetime', $config['expire']); - ini_set('session.cookie_lifetime', $config['expire']); - } - if (isset($config['secure'])) { - ini_set('session.cookie_secure', $config['secure']); - } - if (isset($config['httponly'])) { - ini_set('session.cookie_httponly', $config['httponly']); - } - if (isset($config['use_cookies'])) { - ini_set('session.use_cookies', $config['use_cookies'] ? 1 : 0); - } - if (isset($config['cache_limiter'])) { - session_cache_limiter($config['cache_limiter']); - } - if (isset($config['cache_expire'])) { - session_cache_expire($config['cache_expire']); - } - if (!empty($config['type'])) { - // 读取session驱动 - $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\session\\driver\\' . ucwords($config['type']); - - // 检查驱动类 - if (!class_exists($class) || !session_set_save_handler(new $class($config))) { - throw new ClassNotFoundException('error session handler:' . $class, $class); - } - } - if ($isDoStart) { - session_start(); - self::$init = true; - } else { - self::$init = false; - } - } - - /** - * session自动启动或者初始化 - * @return void - */ - public static function boot() - { - if (is_null(self::$init)) { - self::init(); - } elseif (false === self::$init) { - if (PHP_SESSION_ACTIVE != session_status()) { - session_start(); - } - self::$init = true; - } - } - - /** - * session设置 - * @param string $name session名称 - * @param mixed $value session值 - * @param string|null $prefix 作用域(前缀) - * @return void - */ - public static function set($name, $value = '', $prefix = null) - { - empty(self::$init) && self::boot(); - - $prefix = !is_null($prefix) ? $prefix : self::$prefix; - if (strpos($name, '.')) { - // 二维数组赋值 - list($name1, $name2) = explode('.', $name); - if ($prefix) { - $_SESSION[$prefix][$name1][$name2] = $value; - } else { - $_SESSION[$name1][$name2] = $value; - } - } elseif ($prefix) { - $_SESSION[$prefix][$name] = $value; - } else { - $_SESSION[$name] = $value; - } - } - - /** - * session获取 - * @param string $name session名称 - * @param string|null $prefix 作用域(前缀) - * @return mixed - */ - public static function get($name = '', $prefix = null) - { - empty(self::$init) && self::boot(); - $prefix = !is_null($prefix) ? $prefix : self::$prefix; - if ('' == $name) { - // 获取全部的session - $value = $prefix ? (!empty($_SESSION[$prefix]) ? $_SESSION[$prefix] : []) : $_SESSION; - } elseif ($prefix) { - // 获取session - if (strpos($name, '.')) { - list($name1, $name2) = explode('.', $name); - $value = isset($_SESSION[$prefix][$name1][$name2]) ? $_SESSION[$prefix][$name1][$name2] : null; - } else { - $value = isset($_SESSION[$prefix][$name]) ? $_SESSION[$prefix][$name] : null; - } - } else { - if (strpos($name, '.')) { - list($name1, $name2) = explode('.', $name); - $value = isset($_SESSION[$name1][$name2]) ? $_SESSION[$name1][$name2] : null; - } else { - $value = isset($_SESSION[$name]) ? $_SESSION[$name] : null; - } - } - return $value; - } - - /** - * session获取并删除 - * @param string $name session名称 - * @param string|null $prefix 作用域(前缀) - * @return mixed - */ - public static function pull($name, $prefix = null) - { - $result = self::get($name, $prefix); - if ($result) { - self::delete($name, $prefix); - return $result; - } else { - return; - } - } - - /** - * session设置 下一次请求有效 - * @param string $name session名称 - * @param mixed $value session值 - * @param string|null $prefix 作用域(前缀) - * @return void - */ - public static function flash($name, $value) - { - self::set($name, $value); - if (!self::has('__flash__.__time__')) { - self::set('__flash__.__time__', $_SERVER['REQUEST_TIME_FLOAT']); - } - self::push('__flash__', $name); - } - - /** - * 清空当前请求的session数据 - * @return void - */ - public static function flush() - { - if (self::$init) { - $item = self::get('__flash__'); - - if (!empty($item)) { - $time = $item['__time__']; - if ($_SERVER['REQUEST_TIME_FLOAT'] > $time) { - unset($item['__time__']); - self::delete($item); - self::set('__flash__', []); - } - } - } - } - - /** - * 删除session数据 - * @param string|array $name session名称 - * @param string|null $prefix 作用域(前缀) - * @return void - */ - public static function delete($name, $prefix = null) - { - empty(self::$init) && self::boot(); - $prefix = !is_null($prefix) ? $prefix : self::$prefix; - if (is_array($name)) { - foreach ($name as $key) { - self::delete($key, $prefix); - } - } elseif (strpos($name, '.')) { - list($name1, $name2) = explode('.', $name); - if ($prefix) { - unset($_SESSION[$prefix][$name1][$name2]); - } else { - unset($_SESSION[$name1][$name2]); - } - } else { - if ($prefix) { - unset($_SESSION[$prefix][$name]); - } else { - unset($_SESSION[$name]); - } - } - } - - /** - * 清空session数据 - * @param string|null $prefix 作用域(前缀) - * @return void - */ - public static function clear($prefix = null) - { - empty(self::$init) && self::boot(); - $prefix = !is_null($prefix) ? $prefix : self::$prefix; - if ($prefix) { - unset($_SESSION[$prefix]); - } else { - $_SESSION = []; - } - } - - /** - * 判断session数据 - * @param string $name session名称 - * @param string|null $prefix - * @return bool - */ - public static function has($name, $prefix = null) - { - empty(self::$init) && self::boot(); - $prefix = !is_null($prefix) ? $prefix : self::$prefix; - if (strpos($name, '.')) { - // 支持数组 - list($name1, $name2) = explode('.', $name); - return $prefix ? isset($_SESSION[$prefix][$name1][$name2]) : isset($_SESSION[$name1][$name2]); - } else { - return $prefix ? isset($_SESSION[$prefix][$name]) : isset($_SESSION[$name]); - } - } - - /** - * 添加数据到一个session数组 - * @param string $key - * @param mixed $value - * @return void - */ - public static function push($key, $value) - { - $array = self::get($key); - if (is_null($array)) { - $array = []; - } - $array[] = $value; - self::set($key, $array); - } - - /** - * 启动session - * @return void - */ - public static function start() - { - session_start(); - self::$init = true; - } - - /** - * 销毁session - * @return void - */ - public static function destroy() - { - if (!empty($_SESSION)) { - $_SESSION = []; - } - session_unset(); - session_destroy(); - self::$init = null; - } - - /** - * 重新生成session_id - * @param bool $delete 是否删除关联会话文件 - * @return void - */ - public static function regenerate($delete = false) - { - session_regenerate_id($delete); - } - - /** - * 暂停session - * @return void - */ - public static function pause() - { - // 暂停session - session_write_close(); - self::$init = false; - } -} diff --git a/thinkphp/library/think/Template.php b/thinkphp/library/think/Template.php deleted file mode 100755 index 9ba0ff3..0000000 --- a/thinkphp/library/think/Template.php +++ /dev/null @@ -1,1139 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\TemplateNotFoundException; -use think\template\TagLib; - -/** - * ThinkPHP分离出来的模板引擎 - * 支持XML标签和普通标签的模板解析 - * 编译型模板引擎 支持动态缓存 - */ -class Template -{ - // 模板变量 - protected $data = []; - // 引擎配置 - protected $config = [ - 'view_path' => '', // 模板路径 - 'view_base' => '', - 'view_suffix' => 'html', // 默认模板文件后缀 - 'view_depr' => DS, - 'cache_suffix' => 'php', // 默认模板缓存后缀 - 'tpl_deny_func_list' => 'echo,exit', // 模板引擎禁用函数 - 'tpl_deny_php' => false, // 默认模板引擎是否禁用PHP原生代码 - 'tpl_begin' => '{', // 模板引擎普通标签开始标记 - 'tpl_end' => '}', // 模板引擎普通标签结束标记 - 'strip_space' => false, // 是否去除模板文件里面的html空格与换行 - 'tpl_cache' => true, // 是否开启模板编译缓存,设为false则每次都会重新编译 - 'compile_type' => 'file', // 模板编译类型 - 'cache_prefix' => '', // 模板缓存前缀标识,可以动态改变 - 'cache_time' => 0, // 模板缓存有效期 0 为永久,(以数字为值,单位:秒) - 'layout_on' => false, // 布局模板开关 - 'layout_name' => 'layout', // 布局模板入口文件 - 'layout_item' => '{__CONTENT__}', // 布局模板的内容替换标识 - 'taglib_begin' => '{', // 标签库标签开始标记 - 'taglib_end' => '}', // 标签库标签结束标记 - 'taglib_load' => true, // 是否使用内置标签库之外的其它标签库,默认自动检测 - 'taglib_build_in' => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序 - 'taglib_pre_load' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 - 'display_cache' => false, // 模板渲染缓存 - 'cache_id' => '', // 模板缓存ID - 'tpl_replace_string' => [], - 'tpl_var_identify' => 'array', // .语法变量识别,array|object|'', 为空时自动识别 - ]; - - private $literal = []; - private $includeFile = []; // 记录所有模板包含的文件路径及更新时间 - protected $storage; - - /** - * 构造函数 - * @access public - * @param array $config - */ - public function __construct(array $config = []) - { - $this->config['cache_path'] = TEMP_PATH; - $this->config = array_merge($this->config, $config); - - $this->config['taglib_begin_origin'] = $this->config['taglib_begin']; - $this->config['taglib_end_origin'] = $this->config['taglib_end']; - - $this->config['taglib_begin'] = preg_quote($this->config['taglib_begin'], '/'); - $this->config['taglib_end'] = preg_quote($this->config['taglib_end'], '/'); - $this->config['tpl_begin'] = preg_quote($this->config['tpl_begin'], '/'); - $this->config['tpl_end'] = preg_quote($this->config['tpl_end'], '/'); - - // 初始化模板编译存储器 - $type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File'; - $class = false !== strpos($type, '\\') ? $type : '\\think\\template\\driver\\' . ucwords($type); - $this->storage = new $class(); - } - - /** - * 模板变量赋值 - * @access public - * @param mixed $name - * @param mixed $value - * @return void - */ - public function assign($name, $value = '') - { - if (is_array($name)) { - $this->data = array_merge($this->data, $name); - } else { - $this->data[$name] = $value; - } - } - - /** - * 模板引擎参数赋值 - * @access public - * @param mixed $name - * @param mixed $value - */ - public function __set($name, $value) - { - $this->config[$name] = $value; - } - - /** - * 模板引擎配置项 - * @access public - * @param array|string $config - * @return string|void|array - */ - public function config($config) - { - if (is_array($config)) { - $this->config = array_merge($this->config, $config); - } elseif (isset($this->config[$config])) { - return $this->config[$config]; - } else { - return; - } - } - - /** - * 模板变量获取 - * @access public - * @param string $name 变量名 - * @return mixed - */ - public function get($name = '') - { - if ('' == $name) { - return $this->data; - } else { - $data = $this->data; - foreach (explode('.', $name) as $key => $val) { - if (isset($data[$val])) { - $data = $data[$val]; - } else { - $data = null; - break; - } - } - return $data; - } - } - - /** - * 渲染模板文件 - * @access public - * @param string $template 模板文件 - * @param array $vars 模板变量 - * @param array $config 模板参数 - * @return void - */ - public function fetch($template, $vars = [], $config = []) - { - if ($vars) { - $this->data = $vars; - } - if ($config) { - $this->config($config); - } - if (!empty($this->config['cache_id']) && $this->config['display_cache']) { - // 读取渲染缓存 - $cacheContent = Cache::get($this->config['cache_id']); - if (false !== $cacheContent) { - echo $cacheContent; - return; - } - } - $template = $this->parseTemplateFile($template); - if ($template) { - $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($this->config['layout_name'] . $template) . '.' . ltrim($this->config['cache_suffix'], '.'); - if (!$this->checkCache($cacheFile)) { - // 缓存无效 重新模板编译 - $content = file_get_contents($template); - $this->compiler($content, $cacheFile); - } - // 页面缓存 - ob_start(); - ob_implicit_flush(0); - // 读取编译存储 - $this->storage->read($cacheFile, $this->data); - // 获取并清空缓存 - $content = ob_get_clean(); - if (!empty($this->config['cache_id']) && $this->config['display_cache']) { - // 缓存页面输出 - Cache::set($this->config['cache_id'], $content, $this->config['cache_time']); - } - echo $content; - } - } - - /** - * 渲染模板内容 - * @access public - * @param string $content 模板内容 - * @param array $vars 模板变量 - * @param array $config 模板参数 - * @return void - */ - public function display($content, $vars = [], $config = []) - { - if ($vars) { - $this->data = $vars; - } - if ($config) { - $this->config($config); - } - $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($content) . '.' . ltrim($this->config['cache_suffix'], '.'); - if (!$this->checkCache($cacheFile)) { - // 缓存无效 模板编译 - $this->compiler($content, $cacheFile); - } - // 读取编译存储 - $this->storage->read($cacheFile, $this->data); - } - - /** - * 设置布局 - * @access public - * @param mixed $name 布局模板名称 false 则关闭布局 - * @param string $replace 布局模板内容替换标识 - * @return Template - */ - public function layout($name, $replace = '') - { - if (false === $name) { - // 关闭布局 - $this->config['layout_on'] = false; - } else { - // 开启布局 - $this->config['layout_on'] = true; - // 名称必须为字符串 - if (is_string($name)) { - $this->config['layout_name'] = $name; - } - if (!empty($replace)) { - $this->config['layout_item'] = $replace; - } - } - return $this; - } - - /** - * 检查编译缓存是否有效 - * 如果无效则需要重新编译 - * @access private - * @param string $cacheFile 缓存文件名 - * @return boolean - */ - private function checkCache($cacheFile) - { - // 未开启缓存功能 - if (!$this->config['tpl_cache']) { - return false; - } - // 缓存文件不存在 - if (!is_file($cacheFile)) { - return false; - } - // 读取缓存文件失败 - if (!$handle = @fopen($cacheFile, "r")) { - return false; - } - // 读取第一行 - preg_match('/\/\*(.+?)\*\//', fgets($handle), $matches); - if (!isset($matches[1])) { - return false; - } - $includeFile = unserialize($matches[1]); - if (!is_array($includeFile)) { - return false; - } - // 检查模板文件是否有更新 - foreach ($includeFile as $path => $time) { - if (is_file($path) && filemtime($path) > $time) { - // 模板文件如果有更新则缓存需要更新 - return false; - } - } - // 检查编译存储是否有效 - return $this->storage->check($cacheFile, $this->config['cache_time']); - } - - /** - * 检查编译缓存是否存在 - * @access public - * @param string $cacheId 缓存的id - * @return boolean - */ - public function isCache($cacheId) - { - if ($cacheId && $this->config['display_cache']) { - // 缓存页面输出 - return Cache::has($cacheId); - } - return false; - } - - /** - * 编译模板文件内容 - * @access private - * @param string $content 模板内容 - * @param string $cacheFile 缓存文件名 - * @return void - */ - private function compiler(&$content, $cacheFile) - { - // 判断是否启用布局 - if ($this->config['layout_on']) { - if (false !== strpos($content, '{__NOLAYOUT__}')) { - // 可以单独定义不使用布局 - $content = str_replace('{__NOLAYOUT__}', '', $content); - } else { - // 读取布局模板 - $layoutFile = $this->parseTemplateFile($this->config['layout_name']); - if ($layoutFile) { - // 替换布局的主体内容 - $content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile)); - } - } - } else { - $content = str_replace('{__NOLAYOUT__}', '', $content); - } - - // 模板解析 - $this->parse($content); - if ($this->config['strip_space']) { - /* 去除html空格与换行 */ - $find = ['~>\s+<~', '~>(\s+\n|\r)~']; - $replace = ['><', '>']; - $content = preg_replace($find, $replace, $content); - } - // 优化生成的php代码 - $content = preg_replace('/\?>\s*<\?php\s(?!echo\b)/s', '', $content); - // 模板过滤输出 - $replace = $this->config['tpl_replace_string']; - $content = str_replace(array_keys($replace), array_values($replace), $content); - // 添加安全代码及模板引用记录 - $content = 'includeFile) . '*/ ?>' . "\n" . $content; - // 编译存储 - $this->storage->write($cacheFile, $content); - $this->includeFile = []; - return; - } - - /** - * 模板解析入口 - * 支持普通标签和TagLib解析 支持自定义标签库 - * @access public - * @param string $content 要解析的模板内容 - * @return void - */ - public function parse(&$content) - { - // 内容为空不解析 - if (empty($content)) { - return; - } - // 替换literal标签内容 - $this->parseLiteral($content); - // 解析继承 - $this->parseExtend($content); - // 解析布局 - $this->parseLayout($content); - // 检查include语法 - $this->parseInclude($content); - // 替换包含文件中literal标签内容 - $this->parseLiteral($content); - // 检查PHP语法 - $this->parsePhp($content); - - // 获取需要引入的标签库列表 - // 标签库只需要定义一次,允许引入多个一次 - // 一般放在文件的最前面 - // 格式: - // 当TAGLIB_LOAD配置为true时才会进行检测 - if ($this->config['taglib_load']) { - $tagLibs = $this->getIncludeTagLib($content); - if (!empty($tagLibs)) { - // 对导入的TagLib进行解析 - foreach ($tagLibs as $tagLibName) { - $this->parseTagLib($tagLibName, $content); - } - } - } - // 预先加载的标签库 无需在每个模板中使用taglib标签加载 但必须使用标签库XML前缀 - if ($this->config['taglib_pre_load']) { - $tagLibs = explode(',', $this->config['taglib_pre_load']); - foreach ($tagLibs as $tag) { - $this->parseTagLib($tag, $content); - } - } - // 内置标签库 无需使用taglib标签导入就可以使用 并且不需使用标签库XML前缀 - $tagLibs = explode(',', $this->config['taglib_build_in']); - foreach ($tagLibs as $tag) { - $this->parseTagLib($tag, $content, true); - } - // 解析普通模板标签 {$tagName} - $this->parseTag($content); - - // 还原被替换的Literal标签 - $this->parseLiteral($content, true); - return; - } - - /** - * 检查PHP语法 - * @access private - * @param string $content 要解析的模板内容 - * @return void - * @throws \think\Exception - */ - private function parsePhp(&$content) - { - // 短标签的情况要将' . "\n", $content); - // PHP语法检查 - if ($this->config['tpl_deny_php'] && false !== strpos($content, 'getRegex('layout'), $content, $matches)) { - // 替换Layout标签 - $content = str_replace($matches[0], '', $content); - // 解析Layout标签 - $array = $this->parseAttr($matches[0]); - if (!$this->config['layout_on'] || $this->config['layout_name'] != $array['name']) { - // 读取布局模板 - $layoutFile = $this->parseTemplateFile($array['name']); - if ($layoutFile) { - $replace = isset($array['replace']) ? $array['replace'] : $this->config['layout_item']; - // 替换布局的主体内容 - $content = str_replace($replace, $content, file_get_contents($layoutFile)); - } - } - } else { - $content = str_replace('{__NOLAYOUT__}', '', $content); - } - return; - } - - /** - * 解析模板中的include标签 - * @access private - * @param string $content 要解析的模板内容 - * @return void - */ - private function parseInclude(&$content) - { - $regex = $this->getRegex('include'); - $func = function ($template) use (&$func, &$regex, &$content) { - if (preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) { - foreach ($matches as $match) { - $array = $this->parseAttr($match[0]); - $file = $array['file']; - unset($array['file']); - // 分析模板文件名并读取内容 - $parseStr = $this->parseTemplateName($file); - foreach ($array as $k => $v) { - // 以$开头字符串转换成模板变量 - if (0 === strpos($v, '$')) { - $v = $this->get(substr($v, 1)); - } - $parseStr = str_replace('[' . $k . ']', $v, $parseStr); - } - $content = str_replace($match[0], $parseStr, $content); - // 再次对包含文件进行模板分析 - $func($parseStr); - } - unset($matches); - } - }; - // 替换模板中的include标签 - $func($content); - return; - } - - /** - * 解析模板中的extend标签 - * @access private - * @param string $content 要解析的模板内容 - * @return void - */ - private function parseExtend(&$content) - { - $regex = $this->getRegex('extend'); - $array = $blocks = $baseBlocks = []; - $extend = ''; - $func = function ($template) use (&$func, &$regex, &$array, &$extend, &$blocks, &$baseBlocks) { - if (preg_match($regex, $template, $matches)) { - if (!isset($array[$matches['name']])) { - $array[$matches['name']] = 1; - // 读取继承模板 - $extend = $this->parseTemplateName($matches['name']); - // 递归检查继承 - $func($extend); - // 取得block标签内容 - $blocks = array_merge($blocks, $this->parseBlock($template)); - return; - } - } else { - // 取得顶层模板block标签内容 - $baseBlocks = $this->parseBlock($template, true); - if (empty($extend)) { - // 无extend标签但有block标签的情况 - $extend = $template; - } - } - }; - - $func($content); - if (!empty($extend)) { - if ($baseBlocks) { - $children = []; - foreach ($baseBlocks as $name => $val) { - $replace = $val['content']; - if (!empty($children[$name])) { - // 如果包含有子block标签 - foreach ($children[$name] as $key) { - $replace = str_replace($baseBlocks[$key]['begin'] . $baseBlocks[$key]['content'] . $baseBlocks[$key]['end'], $blocks[$key]['content'], $replace); - } - } - if (isset($blocks[$name])) { - // 带有{__block__}表示与所继承模板的相应标签合并,而不是覆盖 - $replace = str_replace(['{__BLOCK__}', '{__block__}'], $replace, $blocks[$name]['content']); - if (!empty($val['parent'])) { - // 如果不是最顶层的block标签 - $parent = $val['parent']; - if (isset($blocks[$parent])) { - $blocks[$parent]['content'] = str_replace($blocks[$name]['begin'] . $blocks[$name]['content'] . $blocks[$name]['end'], $replace, $blocks[$parent]['content']); - } - $blocks[$name]['content'] = $replace; - $children[$parent][] = $name; - continue; - } - } elseif (!empty($val['parent'])) { - // 如果子标签没有被继承则用原值 - $children[$val['parent']][] = $name; - $blocks[$name] = $val; - } - if (!$val['parent']) { - // 替换模板中的顶级block标签 - $extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend); - } - } - } - $content = $extend; - unset($blocks, $baseBlocks); - } - return; - } - - /** - * 替换页面中的literal标签 - * @access private - * @param string $content 模板内容 - * @param boolean $restore 是否为还原 - * @return void - */ - private function parseLiteral(&$content, $restore = false) - { - $regex = $this->getRegex($restore ? 'restoreliteral' : 'literal'); - if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { - if (!$restore) { - $count = count($this->literal); - // 替换literal标签 - foreach ($matches as $match) { - $this->literal[] = substr($match[0], strlen($match[1]), -strlen($match[2])); - $content = str_replace($match[0], "", $content); - $count++; - } - } else { - // 还原literal标签 - foreach ($matches as $match) { - $content = str_replace($match[0], $this->literal[$match[1]], $content); - } - // 清空literal记录 - $this->literal = []; - } - unset($matches); - } - return; - } - - /** - * 获取模板中的block标签 - * @access private - * @param string $content 模板内容 - * @param boolean $sort 是否排序 - * @return array - */ - private function parseBlock(&$content, $sort = false) - { - $regex = $this->getRegex('block'); - $result = []; - if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { - $right = $keys = []; - foreach ($matches as $match) { - if (empty($match['name'][0])) { - if (count($right) > 0) { - $tag = array_pop($right); - $start = $tag['offset'] + strlen($tag['tag']); - $length = $match[0][1] - $start; - $result[$tag['name']] = [ - 'begin' => $tag['tag'], - 'content' => substr($content, $start, $length), - 'end' => $match[0][0], - 'parent' => count($right) ? end($right)['name'] : '', - ]; - $keys[$tag['name']] = $match[0][1]; - } - } else { - // 标签头压入栈 - $right[] = [ - 'name' => $match[2][0], - 'offset' => $match[0][1], - 'tag' => $match[0][0], - ]; - } - } - unset($right, $matches); - if ($sort) { - // 按block标签结束符在模板中的位置排序 - array_multisort($keys, $result); - } - } - return $result; - } - - /** - * 搜索模板页面中包含的TagLib库 - * 并返回列表 - * @access private - * @param string $content 模板内容 - * @return array|null - */ - private function getIncludeTagLib(&$content) - { - // 搜索是否有TagLib标签 - if (preg_match($this->getRegex('taglib'), $content, $matches)) { - // 替换TagLib标签 - $content = str_replace($matches[0], '', $content); - return explode(',', $matches['name']); - } - return; - } - - /** - * TagLib库解析 - * @access public - * @param string $tagLib 要解析的标签库 - * @param string $content 要解析的模板内容 - * @param boolean $hide 是否隐藏标签库前缀 - * @return void - */ - public function parseTagLib($tagLib, &$content, $hide = false) - { - if (false !== strpos($tagLib, '\\')) { - // 支持指定标签库的命名空间 - $className = $tagLib; - $tagLib = substr($tagLib, strrpos($tagLib, '\\') + 1); - } else { - $className = '\\think\\template\\taglib\\' . ucwords($tagLib); - } - /** @var Taglib $tLib */ - $tLib = new $className($this); - $tLib->parseTag($content, $hide ? '' : $tagLib); - return; - } - - /** - * 分析标签属性 - * @access public - * @param string $str 属性字符串 - * @param string $name 不为空时返回指定的属性名 - * @return array - */ - public function parseAttr($str, $name = null) - { - $regex = '/\s+(?>(?P[\w-]+)\s*)=(?>\s*)([\"\'])(?P(?:(?!\\2).)*)\\2/is'; - $array = []; - if (preg_match_all($regex, $str, $matches, PREG_SET_ORDER)) { - foreach ($matches as $match) { - $array[$match['name']] = $match['value']; - } - unset($matches); - } - if (!empty($name) && isset($array[$name])) { - return $array[$name]; - } else { - return $array; - } - } - - /** - * 模板标签解析 - * 格式: {TagName:args [|content] } - * @access private - * @param string $content 要解析的模板内容 - * @return void - */ - private function parseTag(&$content) - { - $regex = $this->getRegex('tag'); - if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { - foreach ($matches as $match) { - $str = stripslashes($match[1]); - $flag = substr($str, 0, 1); - switch ($flag) { - case '$': - // 解析模板变量 格式 {$varName} - // 是否带有?号 - if (false !== $pos = strpos($str, '?')) { - $array = preg_split('/([!=]={1,2}|(?<]={0,1})/', substr($str, 0, $pos), 2, PREG_SPLIT_DELIM_CAPTURE); - $name = $array[0]; - $this->parseVar($name); - $this->parseVarFunction($name); - - $str = trim(substr($str, $pos + 1)); - $this->parseVar($str); - $first = substr($str, 0, 1); - if (strpos($name, ')')) { - // $name为对象或是自动识别,或者含有函数 - if (isset($array[1])) { - $this->parseVar($array[2]); - $name .= $array[1] . $array[2]; - } - switch ($first) { - case '?': - $str = ''; - break; - case '=': - $str = ''; - break; - default: - $str = ''; - } - } else { - if (isset($array[1])) { - $this->parseVar($array[2]); - $express = $name . $array[1] . $array[2]; - } else { - $express = false; - } - // $name为数组 - switch ($first) { - case '?': - // {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx - $str = ''; - break; - case '=': - // {$varname?='xxx'} $varname为真时才输出xxx - $str = ''; - break; - case ':': - // {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx - $str = ''; - break; - default: - $str = ''; - } - } - } else { - $this->parseVar($str); - $this->parseVarFunction($str); - $str = ''; - } - break; - case ':': - // 输出某个函数的结果 - $str = substr($str, 1); - $this->parseVar($str); - $str = ''; - break; - case '~': - // 执行某个函数 - $str = substr($str, 1); - $this->parseVar($str); - $str = ''; - break; - case '-': - case '+': - // 输出计算 - $this->parseVar($str); - $str = ''; - break; - case '/': - // 注释标签 - $flag2 = substr($str, 1, 1); - if ('/' == $flag2 || ('*' == $flag2 && substr(rtrim($str), -2) == '*/')) { - $str = ''; - } - break; - default: - // 未识别的标签直接返回 - $str = $this->config['tpl_begin'] . $str . $this->config['tpl_end']; - break; - } - $content = str_replace($match[0], $str, $content); - } - unset($matches); - } - return; - } - - /** - * 模板变量解析,支持使用函数 - * 格式: {$varname|function1|function2=arg1,arg2} - * @access public - * @param string $varStr 变量数据 - * @return void - */ - public function parseVar(&$varStr) - { - $varStr = trim($varStr); - if (preg_match_all('/\$[a-zA-Z_](?>\w*)(?:[:\.][0-9a-zA-Z_](?>\w*))+/', $varStr, $matches, PREG_OFFSET_CAPTURE)) { - static $_varParseList = []; - while ($matches[0]) { - $match = array_pop($matches[0]); - //如果已经解析过该变量字串,则直接返回变量值 - if (isset($_varParseList[$match[0]])) { - $parseStr = $_varParseList[$match[0]]; - } else { - if (strpos($match[0], '.')) { - $vars = explode('.', $match[0]); - $first = array_shift($vars); - if ('$Think' == $first) { - // 所有以Think.打头的以特殊变量对待 无需模板赋值就可以输出 - $parseStr = $this->parseThinkVar($vars); - } elseif ('$Request' == $first) { - // 获取Request请求对象参数 - $method = array_shift($vars); - if (!empty($vars)) { - $params = implode('.', $vars); - if ('true' != $params) { - $params = '\'' . $params . '\''; - } - } else { - $params = ''; - } - $parseStr = '\think\Request::instance()->' . $method . '(' . $params . ')'; - } else { - switch ($this->config['tpl_var_identify']) { - case 'array': // 识别为数组 - $parseStr = $first . '[\'' . implode('\'][\'', $vars) . '\']'; - break; - case 'obj': // 识别为对象 - $parseStr = $first . '->' . implode('->', $vars); - break; - default: // 自动判断数组或对象 - $parseStr = '(is_array(' . $first . ')?' . $first . '[\'' . implode('\'][\'', $vars) . '\']:' . $first . '->' . implode('->', $vars) . ')'; - } - } - } else { - $parseStr = str_replace(':', '->', $match[0]); - } - $_varParseList[$match[0]] = $parseStr; - } - $varStr = substr_replace($varStr, $parseStr, $match[1], strlen($match[0])); - } - unset($matches); - } - return; - } - - /** - * 对模板中使用了函数的变量进行解析 - * 格式 {$varname|function1|function2=arg1,arg2} - * @access public - * @param string $varStr 变量字符串 - * @return void - */ - public function parseVarFunction(&$varStr) - { - if (false == strpos($varStr, '|')) { - return; - } - static $_varFunctionList = []; - $_key = md5($varStr); - //如果已经解析过该变量字串,则直接返回变量值 - if (isset($_varFunctionList[$_key])) { - $varStr = $_varFunctionList[$_key]; - } else { - $varArray = explode('|', $varStr); - // 取得变量名称 - $name = array_shift($varArray); - // 对变量使用函数 - $length = count($varArray); - // 取得模板禁止使用函数列表 - $template_deny_funs = explode(',', $this->config['tpl_deny_func_list']); - for ($i = 0; $i < $length; $i++) { - $args = explode('=', $varArray[$i], 2); - // 模板函数过滤 - $fun = trim($args[0]); - switch ($fun) { - case 'default': // 特殊模板函数 - if (false === strpos($name, '(')) { - $name = '(isset(' . $name . ') && (' . $name . ' !== \'\')?' . $name . ':' . $args[1] . ')'; - } else { - $name = '(' . $name . ' ?: ' . $args[1] . ')'; - } - break; - default: // 通用模板函数 - if (!in_array($fun, $template_deny_funs)) { - if (isset($args[1])) { - if (strstr($args[1], '###')) { - $args[1] = str_replace('###', $name, $args[1]); - $name = "$fun($args[1])"; - } else { - $name = "$fun($name,$args[1])"; - } - } else { - if (!empty($args[0])) { - $name = "$fun($name)"; - } - } - } - } - } - $_varFunctionList[$_key] = $name; - $varStr = $name; - } - return; - } - - /** - * 特殊模板变量解析 - * 格式 以 $Think. 打头的变量属于特殊模板变量 - * @access public - * @param array $vars 变量数组 - * @return string - */ - public function parseThinkVar($vars) - { - $type = strtoupper(trim(array_shift($vars))); - $param = implode('.', $vars); - if ($vars) { - switch ($type) { - case 'SERVER': - $parseStr = '\\think\\Request::instance()->server(\'' . $param . '\')'; - break; - case 'GET': - $parseStr = '\\think\\Request::instance()->get(\'' . $param . '\')'; - break; - case 'POST': - $parseStr = '\\think\\Request::instance()->post(\'' . $param . '\')'; - break; - case 'COOKIE': - $parseStr = '\\think\\Cookie::get(\'' . $param . '\')'; - break; - case 'SESSION': - $parseStr = '\\think\\Session::get(\'' . $param . '\')'; - break; - case 'ENV': - $parseStr = '\\think\\Request::instance()->env(\'' . $param . '\')'; - break; - case 'REQUEST': - $parseStr = '\\think\\Request::instance()->request(\'' . $param . '\')'; - break; - case 'CONST': - $parseStr = strtoupper($param); - break; - case 'LANG': - $parseStr = '\\think\\Lang::get(\'' . $param . '\')'; - break; - case 'CONFIG': - $parseStr = '\\think\\Config::get(\'' . $param . '\')'; - break; - default: - $parseStr = '\'\''; - break; - } - } else { - switch ($type) { - case 'NOW': - $parseStr = "date('Y-m-d g:i a',time())"; - break; - case 'VERSION': - $parseStr = 'THINK_VERSION'; - break; - case 'LDELIM': - $parseStr = '\'' . ltrim($this->config['tpl_begin'], '\\') . '\''; - break; - case 'RDELIM': - $parseStr = '\'' . ltrim($this->config['tpl_end'], '\\') . '\''; - break; - default: - if (defined($type)) { - $parseStr = $type; - } else { - $parseStr = ''; - } - } - } - return $parseStr; - } - - /** - * 分析加载的模板文件并读取内容 支持多个模板文件读取 - * @access private - * @param string $templateName 模板文件名 - * @return string - */ - private function parseTemplateName($templateName) - { - $array = explode(',', $templateName); - $parseStr = ''; - foreach ($array as $templateName) { - if (empty($templateName)) { - continue; - } - if (0 === strpos($templateName, '$')) { - //支持加载变量文件名 - $templateName = $this->get(substr($templateName, 1)); - } - $template = $this->parseTemplateFile($templateName); - if ($template) { - // 获取模板文件内容 - $parseStr .= file_get_contents($template); - } - } - return $parseStr; - } - - /** - * 解析模板文件名 - * @access private - * @param string $template 文件名 - * @return string|false - */ - private function parseTemplateFile($template) - { - if ('' == pathinfo($template, PATHINFO_EXTENSION)) { - if (strpos($template, '@')) { - list($module, $template) = explode('@', $template); - } - if (0 !== strpos($template, '/')) { - $template = str_replace(['/', ':'], $this->config['view_depr'], $template); - } else { - $template = str_replace(['/', ':'], $this->config['view_depr'], substr($template, 1)); - } - if ($this->config['view_base']) { - $module = isset($module) ? $module : Request::instance()->module(); - $path = $this->config['view_base'] . ($module ? $module . DS : ''); - } else { - $path = isset($module) ? APP_PATH . $module . DS . basename($this->config['view_path']) . DS : $this->config['view_path']; - } - $template = realpath($path . $template . '.' . ltrim($this->config['view_suffix'], '.')); - } - - if (is_file($template)) { - // 记录模板文件的更新时间 - $this->includeFile[$template] = filemtime($template); - return $template; - } else { - throw new TemplateNotFoundException('template not exists:' . $template, $template); - } - } - - /** - * 按标签生成正则 - * @access private - * @param string $tagName 标签名 - * @return string - */ - private function getRegex($tagName) - { - $regex = ''; - if ('tag' == $tagName) { - $begin = $this->config['tpl_begin']; - $end = $this->config['tpl_end']; - if (strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1) { - $regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>[^' . $end . ']*))' . $end; - } else { - $regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end; - } - } else { - $begin = $this->config['taglib_begin']; - $end = $this->config['taglib_end']; - $single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false; - switch ($tagName) { - case 'block': - if ($single) { - $regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?P[\$\w\-\/\.]+)\\1(?>[^' . $end . ']*)|\/' . $tagName . ')' . $end; - } else { - $regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?P[\$\w\-\/\.]+)\\1(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end; - } - break; - case 'literal': - if ($single) { - $regex = '(' . $begin . $tagName . '\b(?>[^' . $end . ']*)' . $end . ')'; - $regex .= '(?:(?>[^' . $begin . ']*)(?>(?!' . $begin . '(?>' . $tagName . '\b[^' . $end . ']*|\/' . $tagName . ')' . $end . ')' . $begin . '[^' . $begin . ']*)*)'; - $regex .= '(' . $begin . '\/' . $tagName . $end . ')'; - } else { - $regex = '(' . $begin . $tagName . '\b(?>(?:(?!' . $end . ').)*)' . $end . ')'; - $regex .= '(?:(?>(?:(?!' . $begin . ').)*)(?>(?!' . $begin . '(?>' . $tagName . '\b(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end . ')' . $begin . '(?>(?:(?!' . $begin . ').)*))*)'; - $regex .= '(' . $begin . '\/' . $tagName . $end . ')'; - } - break; - case 'restoreliteral': - $regex = ''; - break; - case 'include': - $name = 'file'; - case 'taglib': - case 'layout': - case 'extend': - if (empty($name)) { - $name = 'name'; - } - if ($single) { - $regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?P[\$\w\-\/\.\:@,\\\\]+)\\1(?>[^' . $end . ']*)' . $end; - } else { - $regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?P[\$\w\-\/\.\:@,\\\\]+)\\1(?>(?:(?!' . $end . ').)*)' . $end; - } - break; - } - } - return '/' . $regex . '/is'; - } -} diff --git a/thinkphp/library/think/Url.php b/thinkphp/library/think/Url.php deleted file mode 100755 index 53a545f..0000000 --- a/thinkphp/library/think/Url.php +++ /dev/null @@ -1,333 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class Url -{ - // 生成URL地址的root - protected static $root; - protected static $bindCheck; - - /** - * URL生成 支持路由反射 - * @param string $url 路由地址 - * @param string|array $vars 参数(支持数组和字符串)a=val&b=val2... ['a'=>'val1', 'b'=>'val2'] - * @param string|bool $suffix 伪静态后缀,默认为true表示获取配置值 - * @param boolean|string $domain 是否显示域名 或者直接传入域名 - * @return string - */ - public static function build($url = '', $vars = '', $suffix = true, $domain = false) - { - if (false === $domain && Route::rules('domain')) { - $domain = true; - } - // 解析URL - if (0 === strpos($url, '[') && $pos = strpos($url, ']')) { - // [name] 表示使用路由命名标识生成URL - $name = substr($url, 1, $pos - 1); - $url = 'name' . substr($url, $pos + 1); - } - if (false === strpos($url, '://') && 0 !== strpos($url, '/')) { - $info = parse_url($url); - $url = !empty($info['path']) ? $info['path'] : ''; - if (isset($info['fragment'])) { - // 解析锚点 - $anchor = $info['fragment']; - if (false !== strpos($anchor, '?')) { - // 解析参数 - list($anchor, $info['query']) = explode('?', $anchor, 2); - } - if (false !== strpos($anchor, '@')) { - // 解析域名 - list($anchor, $domain) = explode('@', $anchor, 2); - } - } elseif (strpos($url, '@') && false === strpos($url, '\\')) { - // 解析域名 - list($url, $domain) = explode('@', $url, 2); - } - } - - // 解析参数 - if (is_string($vars)) { - // aaa=1&bbb=2 转换成数组 - parse_str($vars, $vars); - } - - if ($url) { - $rule = Route::name(isset($name) ? $name : $url . (isset($info['query']) ? '?' . $info['query'] : '')); - if (is_null($rule) && isset($info['query'])) { - $rule = Route::name($url); - // 解析地址里面参数 合并到vars - parse_str($info['query'], $params); - $vars = array_merge($params, $vars); - unset($info['query']); - } - } - if (!empty($rule) && $match = self::getRuleUrl($rule, $vars)) { - // 匹配路由命名标识 - $url = $match[0]; - // 替换可选分隔符 - $url = preg_replace(['/(\W)\?$/', '/(\W)\?/'], ['', '\1'], $url); - if (!empty($match[1])) { - $domain = $match[1]; - } - if (!is_null($match[2])) { - $suffix = $match[2]; - } - } elseif (!empty($rule) && isset($name)) { - throw new \InvalidArgumentException('route name not exists:' . $name); - } else { - // 检查别名路由 - $alias = Route::rules('alias'); - $matchAlias = false; - if ($alias) { - // 别名路由解析 - foreach ($alias as $key => $val) { - if (is_array($val)) { - $val = $val[0]; - } - if (0 === strpos($url, $val)) { - $url = $key . substr($url, strlen($val)); - $matchAlias = true; - break; - } - } - } - if (!$matchAlias) { - // 路由标识不存在 直接解析 - $url = self::parseUrl($url, $domain); - } - if (isset($info['query'])) { - // 解析地址里面参数 合并到vars - parse_str($info['query'], $params); - $vars = array_merge($params, $vars); - } - } - - // 检测URL绑定 - if (!self::$bindCheck) { - $type = Route::getBind('type'); - if ($type) { - $bind = Route::getBind($type); - if ($bind && 0 === strpos($url, $bind)) { - $url = substr($url, strlen($bind) + 1); - } - } - } - // 还原URL分隔符 - $depr = Config::get('pathinfo_depr'); - $url = str_replace('/', $depr, $url); - - // URL后缀 - $suffix = in_array($url, ['/', '']) ? '' : self::parseSuffix($suffix); - // 锚点 - $anchor = !empty($anchor) ? '#' . $anchor : ''; - // 参数组装 - if (!empty($vars)) { - // 添加参数 - if (Config::get('url_common_param')) { - $vars = http_build_query($vars); - $url .= $suffix . '?' . $vars . $anchor; - } else { - $paramType = Config::get('url_param_type'); - foreach ($vars as $var => $val) { - if ('' !== trim($val)) { - if ($paramType) { - $url .= $depr . urlencode($val); - } else { - $url .= $depr . $var . $depr . urlencode($val); - } - } - } - $url .= $suffix . $anchor; - } - } else { - $url .= $suffix . $anchor; - } - // 检测域名 - $domain = self::parseDomain($url, $domain); - // URL组装 - $url = $domain . rtrim(self::$root ?: Request::instance()->root(), '/') . '/' . ltrim($url, '/'); - - self::$bindCheck = false; - return $url; - } - - // 直接解析URL地址 - protected static function parseUrl($url, &$domain) - { - $request = Request::instance(); - if (0 === strpos($url, '/')) { - // 直接作为路由地址解析 - $url = substr($url, 1); - } elseif (false !== strpos($url, '\\')) { - // 解析到类 - $url = ltrim(str_replace('\\', '/', $url), '/'); - } elseif (0 === strpos($url, '@')) { - // 解析到控制器 - $url = substr($url, 1); - } else { - // 解析到 模块/控制器/操作 - $module = $request->module(); - $domains = Route::rules('domain'); - if (true === $domain && 2 == substr_count($url, '/')) { - $current = $request->host(); - $match = []; - $pos = []; - foreach ($domains as $key => $item) { - if (isset($item['[bind]']) && 0 === strpos($url, $item['[bind]'][0])) { - $pos[$key] = strlen($item['[bind]'][0]) + 1; - $match[] = $key; - $module = ''; - } - } - if ($match) { - $domain = current($match); - foreach ($match as $item) { - if (0 === strpos($current, $item)) { - $domain = $item; - } - } - self::$bindCheck = true; - $url = substr($url, $pos[$domain]); - } - } elseif ($domain) { - if (isset($domains[$domain]['[bind]'][0])) { - $bindModule = $domains[$domain]['[bind]'][0]; - if ($bindModule && !in_array($bindModule[0], ['\\', '@'])) { - $module = ''; - } - } - } - $module = $module ? $module . '/' : ''; - - $controller = $request->controller(); - if ('' == $url) { - // 空字符串输出当前的 模块/控制器/操作 - $action = $request->action(); - } else { - $path = explode('/', $url); - $action = array_pop($path); - $controller = empty($path) ? $controller : array_pop($path); - $module = empty($path) ? $module : array_pop($path) . '/'; - } - if (Config::get('url_convert')) { - $action = strtolower($action); - $controller = Loader::parseName($controller); - } - $url = $module . $controller . '/' . $action; - } - return $url; - } - - // 检测域名 - protected static function parseDomain(&$url, $domain) - { - if (!$domain) { - return ''; - } - $request = Request::instance(); - $rootDomain = Config::get('url_domain_root'); - if (true === $domain) { - // 自动判断域名 - $domain = Config::get('app_host') ?: $request->host(); - - $domains = Route::rules('domain'); - if ($domains) { - $route_domain = array_keys($domains); - foreach ($route_domain as $domain_prefix) { - if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) { - foreach ($domains as $key => $rule) { - $rule = is_array($rule) ? $rule[0] : $rule; - if (is_string($rule) && false === strpos($key, '*') && 0 === strpos($url, $rule)) { - $url = ltrim($url, $rule); - $domain = $key; - // 生成对应子域名 - if (!empty($rootDomain)) { - $domain .= $rootDomain; - } - break; - } elseif (false !== strpos($key, '*')) { - if (!empty($rootDomain)) { - $domain .= $rootDomain; - } - break; - } - } - } - } - } - - } else { - if (empty($rootDomain)) { - $host = Config::get('app_host') ?: $request->host(); - $rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host; - } - if (substr_count($domain, '.') < 2 && !strpos($domain, $rootDomain)) { - $domain .= '.' . $rootDomain; - } - } - if (false !== strpos($domain, '://')) { - $scheme = ''; - } else { - $scheme = $request->isSsl() || Config::get('is_https') ? 'https://' : 'http://'; - } - return $scheme . $domain; - } - - // 解析URL后缀 - protected static function parseSuffix($suffix) - { - if ($suffix) { - $suffix = true === $suffix ? Config::get('url_html_suffix') : $suffix; - if ($pos = strpos($suffix, '|')) { - $suffix = substr($suffix, 0, $pos); - } - } - return (empty($suffix) || 0 === strpos($suffix, '.')) ? $suffix : '.' . $suffix; - } - - // 匹配路由地址 - public static function getRuleUrl($rule, &$vars = []) - { - foreach ($rule as $item) { - list($url, $pattern, $domain, $suffix) = $item; - if (empty($pattern)) { - return [rtrim($url, '$'), $domain, $suffix]; - } - $type = Config::get('url_common_param'); - foreach ($pattern as $key => $val) { - if (isset($vars[$key])) { - $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $type ? $vars[$key] : urlencode($vars[$key]), $url); - unset($vars[$key]); - $result = [$url, $domain, $suffix]; - } elseif (2 == $val) { - $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); - $result = [$url, $domain, $suffix]; - } else { - break; - } - } - if (isset($result)) { - return $result; - } - } - return false; - } - - // 指定当前生成URL地址的root - public static function root($root) - { - self::$root = $root; - Request::instance()->root($root); - } -} diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php deleted file mode 100755 index df6c6e7..0000000 --- a/thinkphp/library/think/Validate.php +++ /dev/null @@ -1,1367 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -use think\exception\ClassNotFoundException; - -class Validate -{ - // 实例 - protected static $instance; - - // 自定义的验证类型 - protected static $type = []; - - // 验证类型别名 - protected $alias = [ - '>' => 'gt', '>=' => 'egt', '<' => 'lt', '<=' => 'elt', '=' => 'eq', 'same' => 'eq', - ]; - - // 当前验证的规则 - protected $rule = []; - - // 验证提示信息 - protected $message = []; - // 验证字段描述 - protected $field = []; - - // 验证规则默认提示信息 - protected static $typeMsg = [ - 'require' => ':attribute require', - 'number' => ':attribute must be numeric', - 'integer' => ':attribute must be integer', - 'float' => ':attribute must be float', - 'boolean' => ':attribute must be bool', - 'email' => ':attribute not a valid email address', - 'array' => ':attribute must be a array', - 'accepted' => ':attribute must be yes,on or 1', - 'date' => ':attribute not a valid datetime', - 'file' => ':attribute not a valid file', - 'image' => ':attribute not a valid image', - 'alpha' => ':attribute must be alpha', - 'alphaNum' => ':attribute must be alpha-numeric', - 'alphaDash' => ':attribute must be alpha-numeric, dash, underscore', - 'activeUrl' => ':attribute not a valid domain or ip', - 'chs' => ':attribute must be chinese', - 'chsAlpha' => ':attribute must be chinese or alpha', - 'chsAlphaNum' => ':attribute must be chinese,alpha-numeric', - 'chsDash' => ':attribute must be chinese,alpha-numeric,underscore, dash', - 'url' => ':attribute not a valid url', - 'ip' => ':attribute not a valid ip', - 'dateFormat' => ':attribute must be dateFormat of :rule', - 'in' => ':attribute must be in :rule', - 'notIn' => ':attribute be notin :rule', - 'between' => ':attribute must between :1 - :2', - 'notBetween' => ':attribute not between :1 - :2', - 'length' => 'size of :attribute must be :rule', - 'max' => 'max size of :attribute must be :rule', - 'min' => 'min size of :attribute must be :rule', - 'after' => ':attribute cannot be less than :rule', - 'before' => ':attribute cannot exceed :rule', - 'afterWith' => ':attribute cannot be less than :rule', - 'beforeWith' => ':attribute cannot exceed :rule', - 'expire' => ':attribute not within :rule', - 'allowIp' => 'access IP is not allowed', - 'denyIp' => 'access IP denied', - 'confirm' => ':attribute out of accord with :2', - 'different' => ':attribute cannot be same with :2', - 'egt' => ':attribute must greater than or equal :rule', - 'gt' => ':attribute must greater than :rule', - 'elt' => ':attribute must less than or equal :rule', - 'lt' => ':attribute must less than :rule', - 'eq' => ':attribute must equal :rule', - 'unique' => ':attribute has exists', - 'regex' => ':attribute not conform to the rules', - 'method' => 'invalid Request method', - 'token' => 'invalid token', - 'fileSize' => 'filesize not match', - 'fileExt' => 'extensions to upload is not allowed', - 'fileMime' => 'mimetype to upload is not allowed', - ]; - - // 当前验证场景 - protected $currentScene = null; - - // 正则表达式 regex = ['zip'=>'\d{6}',...] - protected $regex = []; - - // 验证场景 scene = ['edit'=>'name1,name2,...'] - protected $scene = []; - - // 验证失败错误信息 - protected $error = []; - - // 批量验证 - protected $batch = false; - - /** - * 构造函数 - * @access public - * @param array $rules 验证规则 - * @param array $message 验证提示信息 - * @param array $field 验证字段描述信息 - */ - public function __construct(array $rules = [], $message = [], $field = []) - { - $this->rule = array_merge($this->rule, $rules); - $this->message = array_merge($this->message, $message); - $this->field = array_merge($this->field, $field); - } - - /** - * 实例化验证 - * @access public - * @param array $rules 验证规则 - * @param array $message 验证提示信息 - * @param array $field 验证字段描述信息 - * @return Validate - */ - public static function make($rules = [], $message = [], $field = []) - { - if (is_null(self::$instance)) { - self::$instance = new self($rules, $message, $field); - } - return self::$instance; - } - - /** - * 添加字段验证规则 - * @access protected - * @param string|array $name 字段名称或者规则数组 - * @param mixed $rule 验证规则 - * @return Validate - */ - public function rule($name, $rule = '') - { - if (is_array($name)) { - $this->rule = array_merge($this->rule, $name); - } else { - $this->rule[$name] = $rule; - } - return $this; - } - - /** - * 注册验证(类型)规则 - * @access public - * @param string $type 验证规则类型 - * @param mixed $callback callback方法(或闭包) - * @return void - */ - public static function extend($type, $callback = null) - { - if (is_array($type)) { - self::$type = array_merge(self::$type, $type); - } else { - self::$type[$type] = $callback; - } - } - - /** - * 设置验证规则的默认提示信息 - * @access protected - * @param string|array $type 验证规则类型名称或者数组 - * @param string $msg 验证提示信息 - * @return void - */ - public static function setTypeMsg($type, $msg = null) - { - if (is_array($type)) { - self::$typeMsg = array_merge(self::$typeMsg, $type); - } else { - self::$typeMsg[$type] = $msg; - } - } - - /** - * 设置提示信息 - * @access public - * @param string|array $name 字段名称 - * @param string $message 提示信息 - * @return Validate - */ - public function message($name, $message = '') - { - if (is_array($name)) { - $this->message = array_merge($this->message, $name); - } else { - $this->message[$name] = $message; - } - return $this; - } - - /** - * 设置验证场景 - * @access public - * @param string|array $name 场景名或者场景设置数组 - * @param mixed $fields 要验证的字段 - * @return Validate - */ - public function scene($name, $fields = null) - { - if (is_array($name)) { - $this->scene = array_merge($this->scene, $name); - }if (is_null($fields)) { - // 设置当前场景 - $this->currentScene = $name; - } else { - // 设置验证场景 - $this->scene[$name] = $fields; - } - return $this; - } - - /** - * 判断是否存在某个验证场景 - * @access public - * @param string $name 场景名 - * @return bool - */ - public function hasScene($name) - { - return isset($this->scene[$name]); - } - - /** - * 设置批量验证 - * @access public - * @param bool $batch 是否批量验证 - * @return Validate - */ - public function batch($batch = true) - { - $this->batch = $batch; - return $this; - } - - /** - * 数据自动验证 - * @access public - * @param array $data 数据 - * @param mixed $rules 验证规则 - * @param string $scene 验证场景 - * @return bool - */ - public function check($data, $rules = [], $scene = '') - { - $this->error = []; - - if (empty($rules)) { - // 读取验证规则 - $rules = $this->rule; - } - - // 分析验证规则 - $scene = $this->getScene($scene); - if (is_array($scene)) { - // 处理场景验证字段 - $change = []; - $array = []; - foreach ($scene as $k => $val) { - if (is_numeric($k)) { - $array[] = $val; - } else { - $array[] = $k; - $change[$k] = $val; - } - } - } - - foreach ($rules as $key => $item) { - // field => rule1|rule2... field=>['rule1','rule2',...] - if (is_numeric($key)) { - // [field,rule1|rule2,msg1|msg2] - $key = $item[0]; - $rule = $item[1]; - if (isset($item[2])) { - $msg = is_string($item[2]) ? explode('|', $item[2]) : $item[2]; - } else { - $msg = []; - } - } else { - $rule = $item; - $msg = []; - } - if (strpos($key, '|')) { - // 字段|描述 用于指定属性名称 - list($key, $title) = explode('|', $key); - } else { - $title = isset($this->field[$key]) ? $this->field[$key] : $key; - } - - // 场景检测 - if (!empty($scene)) { - if ($scene instanceof \Closure && !call_user_func_array($scene, [$key, $data])) { - continue; - } elseif (is_array($scene)) { - if (!in_array($key, $array)) { - continue; - } elseif (isset($change[$key])) { - // 重载某个验证规则 - $rule = $change[$key]; - } - } - } - - // 获取数据 支持二维数组 - $value = $this->getDataValue($data, $key); - - // 字段验证 - if ($rule instanceof \Closure) { - // 匿名函数验证 支持传入当前字段和所有字段两个数据 - $result = call_user_func_array($rule, [$value, $data]); - } else { - $result = $this->checkItem($key, $value, $rule, $data, $title, $msg); - } - - if (true !== $result) { - // 没有返回true 则表示验证失败 - if (!empty($this->batch)) { - // 批量验证 - if (is_array($result)) { - $this->error = array_merge($this->error, $result); - } else { - $this->error[$key] = $result; - } - } else { - $this->error = $result; - return false; - } - } - } - return !empty($this->error) ? false : true; - } - - /** - * 根据验证规则验证数据 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rules 验证规则 - * @return bool - */ - protected function checkRule($value, $rules) - { - if ($rules instanceof \Closure) { - return call_user_func_array($rules, [$value]); - } elseif (is_string($rules)) { - $rules = explode('|', $rules); - } - - foreach ($rules as $key => $rule) { - if ($rule instanceof \Closure) { - $result = call_user_func_array($rule, [$value]); - } else { - // 判断验证类型 - list($type, $rule) = $this->getValidateType($key, $rule); - - $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type]; - - $result = call_user_func_array($callback, [$value, $rule]); - } - - if (true !== $result) { - return $result; - } - } - - return true; - } - - /** - * 验证单个字段规则 - * @access protected - * @param string $field 字段名 - * @param mixed $value 字段值 - * @param mixed $rules 验证规则 - * @param array $data 数据 - * @param string $title 字段描述 - * @param array $msg 提示信息 - * @return mixed - */ - protected function checkItem($field, $value, $rules, $data, $title = '', $msg = []) - { - // 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...] - if (is_string($rules)) { - $rules = explode('|', $rules); - } - $i = 0; - foreach ($rules as $key => $rule) { - if ($rule instanceof \Closure) { - $result = call_user_func_array($rule, [$value, $data]); - $info = is_numeric($key) ? '' : $key; - } else { - // 判断验证类型 - list($type, $rule, $info) = $this->getValidateType($key, $rule); - - // 如果不是require 有数据才会行验证 - if (0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) { - // 验证类型 - $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type]; - // 验证数据 - $result = call_user_func_array($callback, [$value, $rule, $data, $field, $title]); - } else { - $result = true; - } - } - - if (false === $result) { - // 验证失败 返回错误信息 - if (isset($msg[$i])) { - $message = $msg[$i]; - if (is_string($message) && strpos($message, '{%') === 0) { - $message = Lang::get(substr($message, 2, -1)); - } - } else { - $message = $this->getRuleMsg($field, $title, $info, $rule); - } - return $message; - } elseif (true !== $result) { - // 返回自定义错误信息 - if (is_string($result) && false !== strpos($result, ':')) { - $result = str_replace([':attribute', ':rule'], [$title, (string) $rule], $result); - } - return $result; - } - $i++; - } - return $result; - } - - /** - * 获取当前验证类型及规则 - * @access public - * @param mixed $key - * @param mixed $rule - * @return array - */ - protected function getValidateType($key, $rule) - { - // 判断验证类型 - if (!is_numeric($key)) { - return [$key, $rule, $key]; - } - - if (strpos($rule, ':')) { - list($type, $rule) = explode(':', $rule, 2); - if (isset($this->alias[$type])) { - // 判断别名 - $type = $this->alias[$type]; - } - $info = $type; - } elseif (method_exists($this, $rule)) { - $type = $rule; - $info = $rule; - $rule = ''; - } else { - $type = 'is'; - $info = $rule; - } - - return [$type, $rule, $info]; - } - - /** - * 验证是否和某个字段的值一致 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @param string $field 字段名 - * @return bool - */ - protected function confirm($value, $rule, $data, $field = '') - { - if ('' == $rule) { - if (strpos($field, '_confirm')) { - $rule = strstr($field, '_confirm', true); - } else { - $rule = $field . '_confirm'; - } - } - return $this->getDataValue($data, $rule) === $value; - } - - /** - * 验证是否和某个字段的值是否不同 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function different($value, $rule, $data) - { - return $this->getDataValue($data, $rule) != $value; - } - - /** - * 验证是否大于等于某个值 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function egt($value, $rule, $data) - { - $val = $this->getDataValue($data, $rule); - return !is_null($val) && $value >= $val; - } - - /** - * 验证是否大于某个值 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function gt($value, $rule, $data) - { - $val = $this->getDataValue($data, $rule); - return !is_null($val) && $value > $val; - } - - /** - * 验证是否小于等于某个值 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function elt($value, $rule, $data) - { - $val = $this->getDataValue($data, $rule); - return !is_null($val) && $value <= $val; - } - - /** - * 验证是否小于某个值 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function lt($value, $rule, $data) - { - $val = $this->getDataValue($data, $rule); - return !is_null($val) && $value < $val; - } - - /** - * 验证是否等于某个值 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function eq($value, $rule) - { - return $value == $rule; - } - - /** - * 验证字段值是否为有效格式 - * @access protected - * @param mixed $value 字段值 - * @param string $rule 验证规则 - * @param array $data 验证数据 - * @return bool - */ - protected function is($value, $rule, $data = []) - { - switch ($rule) { - case 'require': - // 必须 - $result = !empty($value) || '0' == $value; - break; - case 'accepted': - // 接受 - $result = in_array($value, ['1', 'on', 'yes']); - break; - case 'date': - // 是否是一个有效日期 - $result = false !== strtotime($value); - break; - case 'alpha': - // 只允许字母 - $result = $this->regex($value, '/^[A-Za-z]+$/'); - break; - case 'alphaNum': - // 只允许字母和数字 - $result = $this->regex($value, '/^[A-Za-z0-9]+$/'); - break; - case 'alphaDash': - // 只允许字母、数字和下划线 破折号 - $result = $this->regex($value, '/^[A-Za-z0-9\-\_]+$/'); - break; - case 'chs': - // 只允许汉字 - $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}]+$/u'); - break; - case 'chsAlpha': - // 只允许汉字、字母 - $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u'); - break; - case 'chsAlphaNum': - // 只允许汉字、字母和数字 - $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]+$/u'); - break; - case 'chsDash': - // 只允许汉字、字母、数字和下划线_及破折号- - $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u'); - break; - case 'activeUrl': - // 是否为有效的网址 - $result = checkdnsrr($value); - break; - case 'ip': - // 是否为IP地址 - $result = $this->filter($value, [FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6]); - break; - case 'url': - // 是否为一个URL地址 - $result = $this->filter($value, FILTER_VALIDATE_URL); - break; - case 'float': - // 是否为float - $result = $this->filter($value, FILTER_VALIDATE_FLOAT); - break; - case 'number': - $result = is_numeric($value); - break; - case 'integer': - // 是否为整型 - $result = $this->filter($value, FILTER_VALIDATE_INT); - break; - case 'email': - // 是否为邮箱地址 - $result = $this->filter($value, FILTER_VALIDATE_EMAIL); - break; - case 'boolean': - // 是否为布尔值 - $result = in_array($value, [true, false, 0, 1, '0', '1'], true); - break; - case 'array': - // 是否为数组 - $result = is_array($value); - break; - case 'file': - $result = $value instanceof File; - break; - case 'image': - $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]); - break; - case 'token': - $result = $this->token($value, '__token__', $data); - break; - default: - if (isset(self::$type[$rule])) { - // 注册的验证规则 - $result = call_user_func_array(self::$type[$rule], [$value]); - } else { - // 正则验证 - $result = $this->regex($value, $rule); - } - } - return $result; - } - - // 判断图像类型 - protected function getImageType($image) - { - if (function_exists('exif_imagetype')) { - return exif_imagetype($image); - } else { - try { - $info = getimagesize($image); - return $info ? $info[2] : false; - } catch (\Exception $e) { - return false; - } - } - } - - /** - * 验证是否为合格的域名或者IP 支持A,MX,NS,SOA,PTR,CNAME,AAAA,A6, SRV,NAPTR,TXT 或者 ANY类型 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function activeUrl($value, $rule) - { - if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) { - $rule = 'MX'; - } - return checkdnsrr($value, $rule); - } - - /** - * 验证是否有效IP - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 ipv4 ipv6 - * @return bool - */ - protected function ip($value, $rule) - { - if (!in_array($rule, ['ipv4', 'ipv6'])) { - $rule = 'ipv4'; - } - return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]); - } - - /** - * 验证上传文件后缀 - * @access protected - * @param mixed $file 上传文件 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function fileExt($file, $rule) - { - if (is_array($file)) { - foreach ($file as $item) { - if (!($item instanceof File) || !$item->checkExt($rule)) { - return false; - } - } - return true; - } elseif ($file instanceof File) { - return $file->checkExt($rule); - } else { - return false; - } - } - - /** - * 验证上传文件类型 - * @access protected - * @param mixed $file 上传文件 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function fileMime($file, $rule) - { - if (is_array($file)) { - foreach ($file as $item) { - if (!($item instanceof File) || !$item->checkMime($rule)) { - return false; - } - } - return true; - } elseif ($file instanceof File) { - return $file->checkMime($rule); - } else { - return false; - } - } - - /** - * 验证上传文件大小 - * @access protected - * @param mixed $file 上传文件 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function fileSize($file, $rule) - { - if (is_array($file)) { - foreach ($file as $item) { - if (!($item instanceof File) || !$item->checkSize($rule)) { - return false; - } - } - return true; - } elseif ($file instanceof File) { - return $file->checkSize($rule); - } else { - return false; - } - } - - /** - * 验证图片的宽高及类型 - * @access protected - * @param mixed $file 上传文件 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function image($file, $rule) - { - if (!($file instanceof File)) { - return false; - } - if ($rule) { - $rule = explode(',', $rule); - list($width, $height, $type) = getimagesize($file->getRealPath()); - if (isset($rule[2])) { - $imageType = strtolower($rule[2]); - if ('jpeg' == $imageType) { - $imageType = 'jpg'; - } - if (image_type_to_extension($type, false) != $imageType) { - return false; - } - } - - list($w, $h) = $rule; - return $w == $width && $h == $height; - } else { - return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]); - } - } - - /** - * 验证请求类型 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function method($value, $rule) - { - $method = Request::instance()->method(); - return strtoupper($rule) == $method; - } - - /** - * 验证时间和日期是否符合指定格式 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function dateFormat($value, $rule) - { - $info = date_parse_from_format($rule, $value); - return 0 == $info['warning_count'] && 0 == $info['error_count']; - } - - /** - * 验证是否唯一 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 格式:数据表,字段名,排除ID,主键名 - * @param array $data 数据 - * @param string $field 验证字段名 - * @return bool - */ - protected function unique($value, $rule, $data, $field) - { - if (is_string($rule)) { - $rule = explode(',', $rule); - } - if (false !== strpos($rule[0], '\\')) { - // 指定模型类 - $db = new $rule[0]; - } else { - try { - $db = Loader::model($rule[0]); - } catch (ClassNotFoundException $e) { - $db = Db::name($rule[0]); - } - } - $key = isset($rule[1]) ? $rule[1] : $field; - - if (strpos($key, '^')) { - // 支持多个字段验证 - $fields = explode('^', $key); - foreach ($fields as $key) { - $map[$key] = $data[$key]; - } - } elseif (strpos($key, '=')) { - parse_str($key, $map); - } else { - $map[$key] = $data[$field]; - } - - $pk = isset($rule[3]) ? $rule[3] : $db->getPk(); - if (is_string($pk)) { - if (isset($rule[2])) { - $map[$pk] = ['neq', $rule[2]]; - } elseif (isset($data[$pk])) { - $map[$pk] = ['neq', $data[$pk]]; - } - } - if ($db->where($map)->field($pk)->find()) { - return false; - } - return true; - } - - /** - * 使用行为类验证 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return mixed - */ - protected function behavior($value, $rule, $data) - { - return Hook::exec($rule, '', $data); - } - - /** - * 使用filter_var方式验证 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function filter($value, $rule) - { - if (is_string($rule) && strpos($rule, ',')) { - list($rule, $param) = explode(',', $rule); - } elseif (is_array($rule)) { - $param = isset($rule[1]) ? $rule[1] : null; - $rule = $rule[0]; - } else { - $param = null; - } - return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param); - } - - /** - * 验证某个字段等于某个值的时候必须 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function requireIf($value, $rule, $data) - { - list($field, $val) = explode(',', $rule); - if ($this->getDataValue($data, $field) == $val) { - return !empty($value) || '0' == $value; - } else { - return true; - } - } - - /** - * 通过回调方法验证某个字段是否必须 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function requireCallback($value, $rule, $data) - { - $result = call_user_func_array($rule, [$value, $data]); - if ($result) { - return !empty($value) || '0' == $value; - } else { - return true; - } - } - - /** - * 验证某个字段有值的情况下必须 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function requireWith($value, $rule, $data) - { - $val = $this->getDataValue($data, $rule); - if (!empty($val)) { - return !empty($value) || '0' == $value; - } else { - return true; - } - } - - /** - * 验证是否在范围内 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function in($value, $rule) - { - return in_array($value, is_array($rule) ? $rule : explode(',', $rule)); - } - - /** - * 验证是否不在某个范围 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function notIn($value, $rule) - { - return !in_array($value, is_array($rule) ? $rule : explode(',', $rule)); - } - - /** - * between验证数据 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function between($value, $rule) - { - if (is_string($rule)) { - $rule = explode(',', $rule); - } - list($min, $max) = $rule; - return $value >= $min && $value <= $max; - } - - /** - * 使用notbetween验证数据 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function notBetween($value, $rule) - { - if (is_string($rule)) { - $rule = explode(',', $rule); - } - list($min, $max) = $rule; - return $value < $min || $value > $max; - } - - /** - * 验证数据长度 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function length($value, $rule) - { - if (is_array($value)) { - $length = count($value); - } elseif ($value instanceof File) { - $length = $value->getSize(); - } else { - $length = mb_strlen((string) $value); - } - - if (strpos($rule, ',')) { - // 长度区间 - list($min, $max) = explode(',', $rule); - return $length >= $min && $length <= $max; - } else { - // 指定长度 - return $length == $rule; - } - } - - /** - * 验证数据最大长度 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function max($value, $rule) - { - if (is_array($value)) { - $length = count($value); - } elseif ($value instanceof File) { - $length = $value->getSize(); - } else { - $length = mb_strlen((string) $value); - } - return $length <= $rule; - } - - /** - * 验证数据最小长度 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function min($value, $rule) - { - if (is_array($value)) { - $length = count($value); - } elseif ($value instanceof File) { - $length = $value->getSize(); - } else { - $length = mb_strlen((string) $value); - } - return $length >= $rule; - } - - /** - * 验证日期 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function after($value, $rule, $data) - { - return strtotime($value) >= strtotime($rule); - } - - /** - * 验证日期 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function before($value, $rule, $data) - { - return strtotime($value) <= strtotime($rule); - } - - /** - * 验证日期字段 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function afterWith($value, $rule, $data) - { - $rule = $this->getDataValue($data, $rule); - return !is_null($rule) && strtotime($value) >= strtotime($rule); - } - - /** - * 验证日期字段 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function beforeWith($value, $rule, $data) - { - $rule = $this->getDataValue($data, $rule); - return !is_null($rule) && strtotime($value) <= strtotime($rule); - } - - /** - * 验证有效期 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @return bool - */ - protected function expire($value, $rule) - { - if (is_string($rule)) { - $rule = explode(',', $rule); - } - list($start, $end) = $rule; - if (!is_numeric($start)) { - $start = strtotime($start); - } - - if (!is_numeric($end)) { - $end = strtotime($end); - } - return $_SERVER['REQUEST_TIME'] >= $start && $_SERVER['REQUEST_TIME'] <= $end; - } - - /** - * 验证IP许可 - * @access protected - * @param string $value 字段值 - * @param mixed $rule 验证规则 - * @return mixed - */ - protected function allowIp($value, $rule) - { - return in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule)); - } - - /** - * 验证IP禁用 - * @access protected - * @param string $value 字段值 - * @param mixed $rule 验证规则 - * @return mixed - */ - protected function denyIp($value, $rule) - { - return !in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule)); - } - - /** - * 使用正则验证数据 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 正则规则或者预定义正则名 - * @return mixed - */ - protected function regex($value, $rule) - { - if (isset($this->regex[$rule])) { - $rule = $this->regex[$rule]; - } - if (0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) { - // 不是正则表达式则两端补上/ - $rule = '/^' . $rule . '$/'; - } - return is_scalar($value) && 1 === preg_match($rule, (string) $value); - } - - /** - * 验证表单令牌 - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function token($value, $rule, $data) - { - $rule = !empty($rule) ? $rule : '__token__'; - if (!isset($data[$rule]) || !Session::has($rule)) { - // 令牌数据无效 - return false; - } - - // 令牌验证 - if (isset($data[$rule]) && Session::get($rule) === $data[$rule]) { - // 防止重复提交 - Session::delete($rule); // 验证完成销毁session - return true; - } - // 开启TOKEN重置 - Session::delete($rule); - return false; - } - - // 获取错误信息 - public function getError() - { - return $this->error; - } - - /** - * 获取数据值 - * @access protected - * @param array $data 数据 - * @param string $key 数据标识 支持二维 - * @return mixed - */ - protected function getDataValue($data, $key) - { - if (is_numeric($key)) { - $value = $key; - } elseif (strpos($key, '.')) { - // 支持二维数组验证 - list($name1, $name2) = explode('.', $key); - $value = isset($data[$name1][$name2]) ? $data[$name1][$name2] : null; - } else { - $value = isset($data[$key]) ? $data[$key] : null; - } - return $value; - } - - /** - * 获取验证规则的错误提示信息 - * @access protected - * @param string $attribute 字段英文名 - * @param string $title 字段描述名 - * @param string $type 验证规则名称 - * @param mixed $rule 验证规则数据 - * @return string - */ - protected function getRuleMsg($attribute, $title, $type, $rule) - { - if (isset($this->message[$attribute . '.' . $type])) { - $msg = $this->message[$attribute . '.' . $type]; - } elseif (isset($this->message[$attribute][$type])) { - $msg = $this->message[$attribute][$type]; - } elseif (isset($this->message[$attribute])) { - $msg = $this->message[$attribute]; - } elseif (isset(self::$typeMsg[$type])) { - $msg = self::$typeMsg[$type]; - } elseif (0 === strpos($type, 'require')) { - $msg = self::$typeMsg['require']; - } else { - $msg = $title . Lang::get('not conform to the rules'); - } - - if (is_string($msg) && 0 === strpos($msg, '{%')) { - $msg = Lang::get(substr($msg, 2, -1)); - } elseif (Lang::has($msg)) { - $msg = Lang::get($msg); - } - - if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) { - // 变量替换 - if (is_string($rule) && strpos($rule, ',')) { - $array = array_pad(explode(',', $rule), 3, ''); - } else { - $array = array_pad([], 3, ''); - } - $msg = str_replace( - [':attribute', ':rule', ':1', ':2', ':3'], - [$title, (string) $rule, $array[0], $array[1], $array[2]], - $msg); - } - return $msg; - } - - /** - * 获取数据验证的场景 - * @access protected - * @param string $scene 验证场景 - * @return array - */ - protected function getScene($scene = '') - { - if (empty($scene)) { - // 读取指定场景 - $scene = $this->currentScene; - } - - if (!empty($scene) && isset($this->scene[$scene])) { - // 如果设置了验证适用场景 - $scene = $this->scene[$scene]; - if (is_string($scene)) { - $scene = explode(',', $scene); - } - } else { - $scene = []; - } - return $scene; - } - - public static function __callStatic($method, $params) - { - $class = self::make(); - if (method_exists($class, $method)) { - return call_user_func_array([$class, $method], $params); - } else { - throw new \BadMethodCallException('method not exists:' . __CLASS__ . '->' . $method); - } - } -} diff --git a/thinkphp/library/think/View.php b/thinkphp/library/think/View.php deleted file mode 100755 index ca2dadb..0000000 --- a/thinkphp/library/think/View.php +++ /dev/null @@ -1,239 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -class View -{ - // 视图实例 - protected static $instance; - // 模板引擎实例 - public $engine; - // 模板变量 - protected $data = []; - // 用于静态赋值的模板变量 - protected static $var = []; - // 视图输出替换 - protected $replace = []; - - /** - * 构造函数 - * @access public - * @param array $engine 模板引擎参数 - * @param array $replace 字符串替换参数 - */ - public function __construct($engine = [], $replace = []) - { - // 初始化模板引擎 - $this->engine($engine); - // 基础替换字符串 - $request = Request::instance(); - $base = $request->root(); - $root = strpos($base, '.') ? ltrim(dirname($base), DS) : $base; - if ('' != $root) { - $root = '/' . ltrim($root, '/'); - } - $baseReplace = [ - '__ROOT__' => $root, - '__URL__' => $base . '/' . $request->module() . '/' . Loader::parseName($request->controller()), - '__STATIC__' => $root . '/static', - '__CSS__' => $root . '/static/css', - '__JS__' => $root . '/static/js', - ]; - $this->replace = array_merge($baseReplace, (array) $replace); - } - - /** - * 初始化视图 - * @access public - * @param array $engine 模板引擎参数 - * @param array $replace 字符串替换参数 - * @return object - */ - public static function instance($engine = [], $replace = []) - { - if (is_null(self::$instance)) { - self::$instance = new self($engine, $replace); - } - return self::$instance; - } - - /** - * 模板变量静态赋值 - * @access public - * @param mixed $name 变量名 - * @param mixed $value 变量值 - * @return void - */ - public static function share($name, $value = '') - { - if (is_array($name)) { - self::$var = array_merge(self::$var, $name); - } else { - self::$var[$name] = $value; - } - } - - /** - * 模板变量赋值 - * @access public - * @param mixed $name 变量名 - * @param mixed $value 变量值 - * @return $this - */ - public function assign($name, $value = '') - { - if (is_array($name)) { - $this->data = array_merge($this->data, $name); - } else { - $this->data[$name] = $value; - } - return $this; - } - - /** - * 设置当前模板解析的引擎 - * @access public - * @param array|string $options 引擎参数 - * @return $this - */ - public function engine($options = []) - { - if (is_string($options)) { - $type = $options; - $options = []; - } else { - $type = !empty($options['type']) ? $options['type'] : 'Think'; - } - - $class = false !== strpos($type, '\\') ? $type : '\\think\\view\\driver\\' . ucfirst($type); - if (isset($options['type'])) { - unset($options['type']); - } - $this->engine = new $class($options); - return $this; - } - - /** - * 配置模板引擎 - * @access private - * @param string|array $name 参数名 - * @param mixed $value 参数值 - * @return $this - */ - public function config($name, $value = null) - { - $this->engine->config($name, $value); - return $this; - } - - /** - * 解析和获取模板内容 用于输出 - * @param string $template 模板文件名或者内容 - * @param array $vars 模板输出变量 - * @param array $replace 替换内容 - * @param array $config 模板参数 - * @param bool $renderContent 是否渲染内容 - * @return string - * @throws Exception - */ - public function fetch($template = '', $vars = [], $replace = [], $config = [], $renderContent = false) - { - // 模板变量 - $vars = array_merge(self::$var, $this->data, $vars); - - // 页面缓存 - ob_start(); - ob_implicit_flush(0); - - // 渲染输出 - try { - $method = $renderContent ? 'display' : 'fetch'; - // 允许用户自定义模板的字符串替换 - $replace = array_merge($this->replace, $replace, (array) $this->engine->config('tpl_replace_string')); - $this->engine->config('tpl_replace_string', $replace); - $this->engine->$method($template, $vars, $config); - } catch (\Exception $e) { - ob_end_clean(); - throw $e; - } - - // 获取并清空缓存 - $content = ob_get_clean(); - // 内容过滤标签 - Hook::listen('view_filter', $content); - return $content; - } - - /** - * 视图内容替换 - * @access public - * @param string|array $content 被替换内容(支持批量替换) - * @param string $replace 替换内容 - * @return $this - */ - public function replace($content, $replace = '') - { - if (is_array($content)) { - $this->replace = array_merge($this->replace, $content); - } else { - $this->replace[$content] = $replace; - } - return $this; - } - - /** - * 渲染内容输出 - * @access public - * @param string $content 内容 - * @param array $vars 模板输出变量 - * @param array $replace 替换内容 - * @param array $config 模板参数 - * @return mixed - */ - public function display($content, $vars = [], $replace = [], $config = []) - { - return $this->fetch($content, $vars, $replace, $config, true); - } - - /** - * 模板变量赋值 - * @access public - * @param string $name 变量名 - * @param mixed $value 变量值 - */ - public function __set($name, $value) - { - $this->data[$name] = $value; - } - - /** - * 取得模板显示变量的值 - * @access protected - * @param string $name 模板变量 - * @return mixed - */ - public function __get($name) - { - return $this->data[$name]; - } - - /** - * 检测模板变量是否设置 - * @access public - * @param string $name 模板变量名 - * @return bool - */ - public function __isset($name) - { - return isset($this->data[$name]); - } -} diff --git a/thinkphp/library/think/cache/Driver.php b/thinkphp/library/think/cache/Driver.php deleted file mode 100755 index 07805e4..0000000 --- a/thinkphp/library/think/cache/Driver.php +++ /dev/null @@ -1,231 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache; - -/** - * 缓存基础类 - */ -abstract class Driver -{ - protected $handler = null; - protected $options = []; - protected $tag; - - /** - * 判断缓存是否存在 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - abstract public function has($name); - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - abstract public function get($name, $default = false); - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param int $expire 有效时间 0为永久 - * @return boolean - */ - abstract public function set($name, $value, $expire = null); - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - abstract public function inc($name, $step = 1); - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - abstract public function dec($name, $step = 1); - - /** - * 删除缓存 - * @access public - * @param string $name 缓存变量名 - * @return boolean - */ - abstract public function rm($name); - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return boolean - */ - abstract public function clear($tag = null); - - /** - * 获取实际的缓存标识 - * @access public - * @param string $name 缓存名 - * @return string - */ - protected function getCacheKey($name) - { - return $this->options['prefix'] . $name; - } - - /** - * 读取缓存并删除 - * @access public - * @param string $name 缓存变量名 - * @return mixed - */ - public function pull($name) - { - $result = $this->get($name, false); - if ($result) { - $this->rm($name); - return $result; - } else { - return; - } - } - - /** - * 如果不存在则写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param int $expire 有效时间 0为永久 - * @return mixed - */ - public function remember($name, $value, $expire = null) - { - if (!$this->has($name)) { - $time = time(); - while ($time + 5 > time() && $this->has($name . '_lock')) { - // 存在锁定则等待 - usleep(200000); - } - - try { - // 锁定 - $this->set($name . '_lock', true); - if ($value instanceof \Closure) { - $value = call_user_func($value); - } - $this->set($name, $value, $expire); - // 解锁 - $this->rm($name . '_lock'); - } catch (\Exception $e) { - // 解锁 - $this->rm($name . '_lock'); - throw $e; - } catch (\throwable $e) { - $this->rm($name . '_lock'); - throw $e; - } - } else { - $value = $this->get($name); - } - return $value; - } - - /** - * 缓存标签 - * @access public - * @param string $name 标签名 - * @param string|array $keys 缓存标识 - * @param bool $overlay 是否覆盖 - * @return $this - */ - public function tag($name, $keys = null, $overlay = false) - { - if (is_null($name)) { - - } elseif (is_null($keys)) { - $this->tag = $name; - } else { - $key = 'tag_' . md5($name); - if (is_string($keys)) { - $keys = explode(',', $keys); - } - $keys = array_map([$this, 'getCacheKey'], $keys); - if ($overlay) { - $value = $keys; - } else { - $value = array_unique(array_merge($this->getTagItem($name), $keys)); - } - $this->set($key, implode(',', $value), 0); - } - return $this; - } - - /** - * 更新标签 - * @access public - * @param string $name 缓存标识 - * @return void - */ - protected function setTagItem($name) - { - if ($this->tag) { - $key = 'tag_' . md5($this->tag); - $this->tag = null; - if ($this->has($key)) { - $value = explode(',', $this->get($key)); - $value[] = $name; - $value = implode(',', array_unique($value)); - } else { - $value = $name; - } - $this->set($key, $value, 0); - } - } - - /** - * 获取标签包含的缓存标识 - * @access public - * @param string $tag 缓存标签 - * @return array - */ - protected function getTagItem($tag) - { - $key = 'tag_' . md5($tag); - $value = $this->get($key); - if ($value) { - return array_filter(explode(',', $value)); - } else { - return []; - } - } - - /** - * 返回句柄对象,可执行其它高级方法 - * - * @access public - * @return object - */ - public function handler() - { - return $this->handler; - } -} diff --git a/thinkphp/library/think/cache/driver/File.php b/thinkphp/library/think/cache/driver/File.php deleted file mode 100755 index fee6489..0000000 --- a/thinkphp/library/think/cache/driver/File.php +++ /dev/null @@ -1,268 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -/** - * 文件类型缓存类 - * @author liu21st - */ -class File extends Driver -{ - protected $options = [ - 'expire' => 0, - 'cache_subdir' => true, - 'prefix' => '', - 'path' => CACHE_PATH, - 'data_compress' => false, - ]; - - protected $expire; - - /** - * 构造函数 - * @param array $options - */ - public function __construct($options = []) - { - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - if (substr($this->options['path'], -1) != DS) { - $this->options['path'] .= DS; - } - $this->init(); - } - - /** - * 初始化检查 - * @access private - * @return boolean - */ - private function init() - { - // 创建项目缓存目录 - if (!is_dir($this->options['path'])) { - if (mkdir($this->options['path'], 0755, true)) { - return true; - } - } - return false; - } - - /** - * 取得变量的存储文件名 - * @access protected - * @param string $name 缓存变量名 - * @param bool $auto 是否自动创建目录 - * @return string - */ - protected function getCacheKey($name, $auto = false) - { - $name = md5($name); - if ($this->options['cache_subdir']) { - // 使用子目录 - $name = substr($name, 0, 2) . DS . substr($name, 2); - } - if ($this->options['prefix']) { - $name = $this->options['prefix'] . DS . $name; - } - $filename = $this->options['path'] . $name . '.php'; - $dir = dirname($filename); - - if ($auto && !is_dir($dir)) { - mkdir($dir, 0755, true); - } - return $filename; - } - - /** - * 判断缓存是否存在 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public function has($name) - { - return $this->get($name) ? true : false; - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $filename = $this->getCacheKey($name); - if (!is_file($filename)) { - return $default; - } - $content = file_get_contents($filename); - $this->expire = null; - if (false !== $content) { - $expire = (int) substr($content, 8, 12); - if (0 != $expire && time() > filemtime($filename) + $expire) { - return $default; - } - $this->expire = $expire; - $content = substr($content, 32); - if ($this->options['data_compress'] && function_exists('gzcompress')) { - //启用数据压缩 - $content = gzuncompress($content); - } - $content = unserialize($content); - return $content; - } else { - return $default; - } - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return boolean - */ - public function set($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp() - time(); - } - $filename = $this->getCacheKey($name, true); - if ($this->tag && !is_file($filename)) { - $first = true; - } - $data = serialize($value); - if ($this->options['data_compress'] && function_exists('gzcompress')) { - //数据压缩 - $data = gzcompress($data, 3); - } - $data = "\n" . $data; - $result = file_put_contents($filename, $data); - if ($result) { - isset($first) && $this->setTagItem($filename); - clearstatcache(); - return true; - } else { - return false; - } - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - if ($this->has($name)) { - $value = $this->get($name) + $step; - $expire = $this->expire; - } else { - $value = $step; - $expire = 0; - } - - return $this->set($name, $value, $expire) ? $value : false; - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - if ($this->has($name)) { - $value = $this->get($name) - $step; - $expire = $this->expire; - } else { - $value = -$step; - $expire = 0; - } - - return $this->set($name, $value, $expire) ? $value : false; - } - - /** - * 删除缓存 - * @access public - * @param string $name 缓存变量名 - * @return boolean - */ - public function rm($name) - { - $filename = $this->getCacheKey($name); - try { - return $this->unlink($filename); - } catch (\Exception $e) { - } - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return boolean - */ - public function clear($tag = null) - { - if ($tag) { - // 指定标签清除 - $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - $this->unlink($key); - } - $this->rm('tag_' . md5($tag)); - return true; - } - $files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*'); - foreach ($files as $path) { - if (is_dir($path)) { - $matches = glob($path . '/*.php'); - if (is_array($matches)) { - array_map('unlink', $matches); - } - rmdir($path); - } else { - unlink($path); - } - } - return true; - } - - /** - * 判断文件是否存在后,删除 - * @param $path - * @return bool - * @author byron sampson - * @return boolean - */ - private function unlink($path) - { - return is_file($path) && unlink($path); - } - -} diff --git a/thinkphp/library/think/cache/driver/Lite.php b/thinkphp/library/think/cache/driver/Lite.php deleted file mode 100755 index 8cbf08f..0000000 --- a/thinkphp/library/think/cache/driver/Lite.php +++ /dev/null @@ -1,187 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -/** - * 文件类型缓存类 - * @author liu21st - */ -class Lite extends Driver -{ - protected $options = [ - 'prefix' => '', - 'path' => '', - 'expire' => 0, // 等于 10*365*24*3600(10年) - ]; - - /** - * 构造函数 - * @access public - * - * @param array $options - */ - public function __construct($options = []) - { - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - if (substr($this->options['path'], -1) != DS) { - $this->options['path'] .= DS; - } - - } - - /** - * 取得变量的存储文件名 - * @access protected - * @param string $name 缓存变量名 - * @return string - */ - protected function getCacheKey($name) - { - return $this->options['path'] . $this->options['prefix'] . md5($name) . '.php'; - } - - /** - * 判断缓存是否存在 - * @access public - * @param string $name 缓存变量名 - * @return mixed - */ - public function has($name) - { - return $this->get($name) ? true : false; - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $filename = $this->getCacheKey($name); - if (is_file($filename)) { - // 判断是否过期 - $mtime = filemtime($filename); - if ($mtime < time()) { - // 清除已经过期的文件 - unlink($filename); - return $default; - } - return include $filename; - } else { - return $default; - } - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return bool - */ - public function set($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp(); - } else { - $expire = 0 === $expire ? 10 * 365 * 24 * 3600 : $expire; - $expire = time() + $expire; - } - $filename = $this->getCacheKey($name); - if ($this->tag && !is_file($filename)) { - $first = true; - } - $ret = file_put_contents($filename, ("setTagItem($filename); - touch($filename, $expire); - } - return $ret; - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - if ($this->has($name)) { - $value = $this->get($name) + $step; - } else { - $value = $step; - } - return $this->set($name, $value, 0) ? $value : false; - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - if ($this->has($name)) { - $value = $this->get($name) - $step; - } else { - $value = -$step; - } - return $this->set($name, $value, 0) ? $value : false; - } - - /** - * 删除缓存 - * @access public - * @param string $name 缓存变量名 - * @return boolean - */ - public function rm($name) - { - return unlink($this->getCacheKey($name)); - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return bool - */ - public function clear($tag = null) - { - if ($tag) { - // 指定标签清除 - $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - unlink($key); - } - $this->rm('tag_' . md5($tag)); - return true; - } - array_map("unlink", glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*.php')); - } -} diff --git a/thinkphp/library/think/cache/driver/Memcache.php b/thinkphp/library/think/cache/driver/Memcache.php deleted file mode 100755 index 58703ea..0000000 --- a/thinkphp/library/think/cache/driver/Memcache.php +++ /dev/null @@ -1,177 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -class Memcache extends Driver -{ - protected $options = [ - 'host' => '127.0.0.1', - 'port' => 11211, - 'expire' => 0, - 'timeout' => 0, // 超时时间(单位:毫秒) - 'persistent' => true, - 'prefix' => '', - ]; - - /** - * 构造函数 - * @param array $options 缓存参数 - * @access public - * @throws \BadFunctionCallException - */ - public function __construct($options = []) - { - if (!extension_loaded('memcache')) { - throw new \BadFunctionCallException('not support: memcache'); - } - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - $this->handler = new \Memcache; - // 支持集群 - $hosts = explode(',', $this->options['host']); - $ports = explode(',', $this->options['port']); - if (empty($ports[0])) { - $ports[0] = 11211; - } - // 建立连接 - foreach ((array) $hosts as $i => $host) { - $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; - $this->options['timeout'] > 0 ? - $this->handler->addServer($host, $port, $this->options['persistent'], 1, $this->options['timeout']) : - $this->handler->addServer($host, $port, $this->options['persistent'], 1); - } - } - - /** - * 判断缓存 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public function has($name) - { - $key = $this->getCacheKey($name); - return false !== $this->handler->get($key); - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $result = $this->handler->get($this->getCacheKey($name)); - return false !== $result ? $result : $default; - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return bool - */ - public function set($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp() - time(); - } - if ($this->tag && !$this->has($name)) { - $first = true; - } - $key = $this->getCacheKey($name); - if ($this->handler->set($key, $value, 0, $expire)) { - isset($first) && $this->setTagItem($key); - return true; - } - return false; - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - $key = $this->getCacheKey($name); - if ($this->handler->get($key)) { - return $this->handler->increment($key, $step); - } - return $this->handler->set($key, $step); - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - $key = $this->getCacheKey($name); - $value = $this->handler->get($key) - $step; - $res = $this->handler->set($key, $value); - if (!$res) { - return false; - } else { - return $value; - } - } - - /** - * 删除缓存 - * @param string $name 缓存变量名 - * @param bool|false $ttl - * @return bool - */ - public function rm($name, $ttl = false) - { - $key = $this->getCacheKey($name); - return false === $ttl ? - $this->handler->delete($key) : - $this->handler->delete($key, $ttl); - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return bool - */ - public function clear($tag = null) - { - if ($tag) { - // 指定标签清除 - $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - $this->handler->delete($key); - } - $this->rm('tag_' . md5($tag)); - return true; - } - return $this->handler->flush(); - } -} diff --git a/thinkphp/library/think/cache/driver/Memcached.php b/thinkphp/library/think/cache/driver/Memcached.php deleted file mode 100755 index 5aab5a3..0000000 --- a/thinkphp/library/think/cache/driver/Memcached.php +++ /dev/null @@ -1,187 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -class Memcached extends Driver -{ - protected $options = [ - 'host' => '127.0.0.1', - 'port' => 11211, - 'expire' => 0, - 'timeout' => 0, // 超时时间(单位:毫秒) - 'prefix' => '', - 'username' => '', //账号 - 'password' => '', //密码 - 'option' => [], - ]; - - /** - * 构造函数 - * @param array $options 缓存参数 - * @access public - */ - public function __construct($options = []) - { - if (!extension_loaded('memcached')) { - throw new \BadFunctionCallException('not support: memcached'); - } - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - $this->handler = new \Memcached; - if (!empty($this->options['option'])) { - $this->handler->setOptions($this->options['option']); - } - // 设置连接超时时间(单位:毫秒) - if ($this->options['timeout'] > 0) { - $this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->options['timeout']); - } - // 支持集群 - $hosts = explode(',', $this->options['host']); - $ports = explode(',', $this->options['port']); - if (empty($ports[0])) { - $ports[0] = 11211; - } - // 建立连接 - $servers = []; - foreach ((array) $hosts as $i => $host) { - $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1]; - } - $this->handler->addServers($servers); - if ('' != $this->options['username']) { - $this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); - $this->handler->setSaslAuthData($this->options['username'], $this->options['password']); - } - } - - /** - * 判断缓存 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public function has($name) - { - $key = $this->getCacheKey($name); - return $this->handler->get($key) ? true : false; - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $result = $this->handler->get($this->getCacheKey($name)); - return false !== $result ? $result : $default; - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return bool - */ - public function set($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp() - time(); - } - if ($this->tag && !$this->has($name)) { - $first = true; - } - $key = $this->getCacheKey($name); - $expire = 0 == $expire ? 0 : $_SERVER['REQUEST_TIME'] + $expire; - if ($this->handler->set($key, $value, $expire)) { - isset($first) && $this->setTagItem($key); - return true; - } - return false; - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - $key = $this->getCacheKey($name); - if ($this->handler->get($key)) { - return $this->handler->increment($key, $step); - } - return $this->handler->set($key, $step); - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - $key = $this->getCacheKey($name); - $value = $this->handler->get($key) - $step; - $res = $this->handler->set($key, $value); - if (!$res) { - return false; - } else { - return $value; - } - } - - /** - * 删除缓存 - * @param string $name 缓存变量名 - * @param bool|false $ttl - * @return bool - */ - public function rm($name, $ttl = false) - { - $key = $this->getCacheKey($name); - return false === $ttl ? - $this->handler->delete($key) : - $this->handler->delete($key, $ttl); - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return bool - */ - public function clear($tag = null) - { - if ($tag) { - // 指定标签清除 - $keys = $this->getTagItem($tag); - $this->handler->deleteMulti($keys); - $this->rm('tag_' . md5($tag)); - return true; - } - return $this->handler->flush(); - } -} diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php deleted file mode 100755 index 027b3ea..0000000 --- a/thinkphp/library/think/cache/driver/Redis.php +++ /dev/null @@ -1,188 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -/** - * Redis缓存驱动,适合单机部署、有前端代理实现高可用的场景,性能最好 - * 有需要在业务层实现读写分离、或者使用RedisCluster的需求,请使用Redisd驱动 - * - * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis - * @author 尘缘 <130775@qq.com> - */ -class Redis extends Driver -{ - protected $options = [ - 'host' => '127.0.0.1', - 'port' => 6379, - 'password' => '', - 'select' => 0, - 'timeout' => 0, - 'expire' => 0, - 'persistent' => false, - 'prefix' => '', - ]; - - /** - * 构造函数 - * @param array $options 缓存参数 - * @access public - */ - public function __construct($options = []) - { - if (!extension_loaded('redis')) { - throw new \BadFunctionCallException('not support: redis'); - } - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - $this->handler = new \Redis; - if ($this->options['persistent']) { - $this->handler->pconnect($this->options['host'], $this->options['port'], $this->options['timeout'], 'persistent_id_' . $this->options['select']); - } else { - $this->handler->connect($this->options['host'], $this->options['port'], $this->options['timeout']); - } - - if ('' != $this->options['password']) { - $this->handler->auth($this->options['password']); - } - - if (0 != $this->options['select']) { - $this->handler->select($this->options['select']); - } - } - - /** - * 判断缓存 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public function has($name) - { - return $this->handler->exists($this->getCacheKey($name)); - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $value = $this->handler->get($this->getCacheKey($name)); - if (is_null($value) || false === $value) { - return $default; - } - - try { - $result = 0 === strpos($value, 'think_serialize:') ? unserialize(substr($value, 16)) : $value; - } catch (\Exception $e) { - $result = $default; - } - - return $result; - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return boolean - */ - public function set($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp() - time(); - } - if ($this->tag && !$this->has($name)) { - $first = true; - } - $key = $this->getCacheKey($name); - $value = is_scalar($value) ? $value : 'think_serialize:' . serialize($value); - if ($expire) { - $result = $this->handler->setex($key, $expire, $value); - } else { - $result = $this->handler->set($key, $value); - } - isset($first) && $this->setTagItem($key); - return $result; - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - $key = $this->getCacheKey($name); - - return $this->handler->incrby($key, $step); - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - $key = $this->getCacheKey($name); - - return $this->handler->decrby($key, $step); - } - - /** - * 删除缓存 - * @access public - * @param string $name 缓存变量名 - * @return boolean - */ - public function rm($name) - { - return $this->handler->delete($this->getCacheKey($name)); - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return boolean - */ - public function clear($tag = null) - { - if ($tag) { - // 指定标签清除 - $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - $this->handler->delete($key); - } - $this->rm('tag_' . md5($tag)); - return true; - } - return $this->handler->flushDB(); - } - -} diff --git a/thinkphp/library/think/cache/driver/Sqlite.php b/thinkphp/library/think/cache/driver/Sqlite.php deleted file mode 100755 index dc2ee05..0000000 --- a/thinkphp/library/think/cache/driver/Sqlite.php +++ /dev/null @@ -1,199 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -/** - * Sqlite缓存驱动 - * @author liu21st - */ -class Sqlite extends Driver -{ - protected $options = [ - 'db' => ':memory:', - 'table' => 'sharedmemory', - 'prefix' => '', - 'expire' => 0, - 'persistent' => false, - ]; - - /** - * 构造函数 - * @param array $options 缓存参数 - * @throws \BadFunctionCallException - * @access public - */ - public function __construct($options = []) - { - if (!extension_loaded('sqlite')) { - throw new \BadFunctionCallException('not support: sqlite'); - } - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - $func = $this->options['persistent'] ? 'sqlite_popen' : 'sqlite_open'; - $this->handler = $func($this->options['db']); - } - - /** - * 获取实际的缓存标识 - * @access public - * @param string $name 缓存名 - * @return string - */ - protected function getCacheKey($name) - { - return $this->options['prefix'] . sqlite_escape_string($name); - } - - /** - * 判断缓存 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public function has($name) - { - $name = $this->getCacheKey($name); - $sql = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\' AND (expire=0 OR expire >' . $_SERVER['REQUEST_TIME'] . ') LIMIT 1'; - $result = sqlite_query($this->handler, $sql); - return sqlite_num_rows($result); - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $name = $this->getCacheKey($name); - $sql = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\' AND (expire=0 OR expire >' . $_SERVER['REQUEST_TIME'] . ') LIMIT 1'; - $result = sqlite_query($this->handler, $sql); - if (sqlite_num_rows($result)) { - $content = sqlite_fetch_single($result); - if (function_exists('gzcompress')) { - //启用数据压缩 - $content = gzuncompress($content); - } - return unserialize($content); - } - return $default; - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return boolean - */ - public function set($name, $value, $expire = null) - { - $name = $this->getCacheKey($name); - $value = sqlite_escape_string(serialize($value)); - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp(); - } else { - $expire = (0 == $expire) ? 0 : (time() + $expire); //缓存有效期为0表示永久缓存 - } - if (function_exists('gzcompress')) { - //数据压缩 - $value = gzcompress($value, 3); - } - if ($this->tag) { - $tag = $this->tag; - $this->tag = null; - } else { - $tag = ''; - } - $sql = 'REPLACE INTO ' . $this->options['table'] . ' (var, value, expire, tag) VALUES (\'' . $name . '\', \'' . $value . '\', \'' . $expire . '\', \'' . $tag . '\')'; - if (sqlite_query($this->handler, $sql)) { - return true; - } - return false; - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - if ($this->has($name)) { - $value = $this->get($name) + $step; - } else { - $value = $step; - } - return $this->set($name, $value, 0) ? $value : false; - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - if ($this->has($name)) { - $value = $this->get($name) - $step; - } else { - $value = -$step; - } - return $this->set($name, $value, 0) ? $value : false; - } - - /** - * 删除缓存 - * @access public - * @param string $name 缓存变量名 - * @return boolean - */ - public function rm($name) - { - $name = $this->getCacheKey($name); - $sql = 'DELETE FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\''; - sqlite_query($this->handler, $sql); - return true; - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return boolean - */ - public function clear($tag = null) - { - if ($tag) { - $name = sqlite_escape_string($tag); - $sql = 'DELETE FROM ' . $this->options['table'] . ' WHERE tag=\'' . $name . '\''; - sqlite_query($this->handler, $sql); - return true; - } - $sql = 'DELETE FROM ' . $this->options['table']; - sqlite_query($this->handler, $sql); - return true; - } -} diff --git a/thinkphp/library/think/cache/driver/Wincache.php b/thinkphp/library/think/cache/driver/Wincache.php deleted file mode 100755 index 03f8d35..0000000 --- a/thinkphp/library/think/cache/driver/Wincache.php +++ /dev/null @@ -1,152 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -/** - * Wincache缓存驱动 - * @author liu21st - */ -class Wincache extends Driver -{ - protected $options = [ - 'prefix' => '', - 'expire' => 0, - ]; - - /** - * 构造函数 - * @param array $options 缓存参数 - * @throws \BadFunctionCallException - * @access public - */ - public function __construct($options = []) - { - if (!function_exists('wincache_ucache_info')) { - throw new \BadFunctionCallException('not support: WinCache'); - } - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - } - - /** - * 判断缓存 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public function has($name) - { - $key = $this->getCacheKey($name); - return wincache_ucache_exists($key); - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $key = $this->getCacheKey($name); - return wincache_ucache_exists($key) ? wincache_ucache_get($key) : $default; - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return boolean - */ - public function set($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp() - time(); - } - $key = $this->getCacheKey($name); - if ($this->tag && !$this->has($name)) { - $first = true; - } - if (wincache_ucache_set($key, $value, $expire)) { - isset($first) && $this->setTagItem($key); - return true; - } - return false; - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - $key = $this->getCacheKey($name); - return wincache_ucache_inc($key, $step); - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - $key = $this->getCacheKey($name); - return wincache_ucache_dec($key, $step); - } - - /** - * 删除缓存 - * @access public - * @param string $name 缓存变量名 - * @return boolean - */ - public function rm($name) - { - return wincache_ucache_delete($this->getCacheKey($name)); - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return boolean - */ - public function clear($tag = null) - { - if ($tag) { - $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - wincache_ucache_delete($key); - } - $this->rm('tag_' . md5($tag)); - return true; - } else { - return wincache_ucache_clear(); - } - } - -} diff --git a/thinkphp/library/think/cache/driver/Xcache.php b/thinkphp/library/think/cache/driver/Xcache.php deleted file mode 100755 index 4d94c03..0000000 --- a/thinkphp/library/think/cache/driver/Xcache.php +++ /dev/null @@ -1,155 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\cache\driver; - -use think\cache\Driver; - -/** - * Xcache缓存驱动 - * @author liu21st - */ -class Xcache extends Driver -{ - protected $options = [ - 'prefix' => '', - 'expire' => 0, - ]; - - /** - * 构造函数 - * @param array $options 缓存参数 - * @access public - * @throws \BadFunctionCallException - */ - public function __construct($options = []) - { - if (!function_exists('xcache_info')) { - throw new \BadFunctionCallException('not support: Xcache'); - } - if (!empty($options)) { - $this->options = array_merge($this->options, $options); - } - } - - /** - * 判断缓存 - * @access public - * @param string $name 缓存变量名 - * @return bool - */ - public function has($name) - { - $key = $this->getCacheKey($name); - return xcache_isset($key); - } - - /** - * 读取缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $default 默认值 - * @return mixed - */ - public function get($name, $default = false) - { - $key = $this->getCacheKey($name); - return xcache_isset($key) ? xcache_get($key) : $default; - } - - /** - * 写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer|\DateTime $expire 有效时间(秒) - * @return boolean - */ - public function set($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - if ($expire instanceof \DateTime) { - $expire = $expire->getTimestamp() - time(); - } - if ($this->tag && !$this->has($name)) { - $first = true; - } - $key = $this->getCacheKey($name); - if (xcache_set($key, $value, $expire)) { - isset($first) && $this->setTagItem($key); - return true; - } - return false; - } - - /** - * 自增缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function inc($name, $step = 1) - { - $key = $this->getCacheKey($name); - return xcache_inc($key, $step); - } - - /** - * 自减缓存(针对数值缓存) - * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 - * @return false|int - */ - public function dec($name, $step = 1) - { - $key = $this->getCacheKey($name); - return xcache_dec($key, $step); - } - - /** - * 删除缓存 - * @access public - * @param string $name 缓存变量名 - * @return boolean - */ - public function rm($name) - { - return xcache_unset($this->getCacheKey($name)); - } - - /** - * 清除缓存 - * @access public - * @param string $tag 标签名 - * @return boolean - */ - public function clear($tag = null) - { - if ($tag) { - // 指定标签清除 - $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - xcache_unset($key); - } - $this->rm('tag_' . md5($tag)); - return true; - } - if (function_exists('xcache_unset_by_prefix')) { - return xcache_unset_by_prefix($this->options['prefix']); - } else { - return false; - } - } -} diff --git a/thinkphp/library/think/config/driver/Ini.php b/thinkphp/library/think/config/driver/Ini.php deleted file mode 100755 index bcd12b6..0000000 --- a/thinkphp/library/think/config/driver/Ini.php +++ /dev/null @@ -1,24 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\config\driver; - -class Ini -{ - public function parse($config) - { - if (is_file($config)) { - return parse_ini_file($config, true); - } else { - return parse_ini_string($config, true); - } - } -} diff --git a/thinkphp/library/think/config/driver/Json.php b/thinkphp/library/think/config/driver/Json.php deleted file mode 100755 index 479dcc8..0000000 --- a/thinkphp/library/think/config/driver/Json.php +++ /dev/null @@ -1,24 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\config\driver; - -class Json -{ - public function parse($config) - { - if (is_file($config)) { - $config = file_get_contents($config); - } - $result = json_decode($config, true); - return $result; - } -} diff --git a/thinkphp/library/think/config/driver/Xml.php b/thinkphp/library/think/config/driver/Xml.php deleted file mode 100755 index 1158519..0000000 --- a/thinkphp/library/think/config/driver/Xml.php +++ /dev/null @@ -1,31 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\config\driver; - -class Xml -{ - public function parse($config) - { - if (is_file($config)) { - $content = simplexml_load_file($config); - } else { - $content = simplexml_load_string($config); - } - $result = (array) $content; - foreach ($result as $key => $val) { - if (is_object($val)) { - $result[$key] = (array) $val; - } - } - return $result; - } -} diff --git a/thinkphp/library/think/console/Command.php b/thinkphp/library/think/console/Command.php deleted file mode 100755 index d0caad2..0000000 --- a/thinkphp/library/think/console/Command.php +++ /dev/null @@ -1,470 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console; - -use think\Console; -use think\console\input\Argument; -use think\console\input\Definition; -use think\console\input\Option; - -class Command -{ - - /** @var Console */ - private $console; - private $name; - private $aliases = []; - private $definition; - private $help; - private $description; - private $ignoreValidationErrors = false; - private $consoleDefinitionMerged = false; - private $consoleDefinitionMergedWithArgs = false; - private $code; - private $synopsis = []; - private $usages = []; - - /** @var Input */ - protected $input; - - /** @var Output */ - protected $output; - - /** - * 构造方法 - * @param string|null $name 命令名称,如果没有设置则比如在 configure() 里设置 - * @throws \LogicException - * @api - */ - public function __construct($name = null) - { - $this->definition = new Definition(); - - if (null !== $name) { - $this->setName($name); - } - - $this->configure(); - - if (!$this->name) { - throw new \LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this))); - } - } - - /** - * 忽略验证错误 - */ - public function ignoreValidationErrors() - { - $this->ignoreValidationErrors = true; - } - - /** - * 设置控制台 - * @param Console $console - */ - public function setConsole(Console $console = null) - { - $this->console = $console; - } - - /** - * 获取控制台 - * @return Console - * @api - */ - public function getConsole() - { - return $this->console; - } - - /** - * 是否有效 - * @return bool - */ - public function isEnabled() - { - return true; - } - - /** - * 配置指令 - */ - protected function configure() - { - } - - /** - * 执行指令 - * @param Input $input - * @param Output $output - * @return null|int - * @throws \LogicException - * @see setCode() - */ - protected function execute(Input $input, Output $output) - { - throw new \LogicException('You must override the execute() method in the concrete command class.'); - } - - /** - * 用户验证 - * @param Input $input - * @param Output $output - */ - protected function interact(Input $input, Output $output) - { - } - - /** - * 初始化 - * @param Input $input An InputInterface instance - * @param Output $output An OutputInterface instance - */ - protected function initialize(Input $input, Output $output) - { - } - - /** - * 执行 - * @param Input $input - * @param Output $output - * @return int - * @throws \Exception - * @see setCode() - * @see execute() - */ - public function run(Input $input, Output $output) - { - $this->input = $input; - $this->output = $output; - - $this->getSynopsis(true); - $this->getSynopsis(false); - - $this->mergeConsoleDefinition(); - - try { - $input->bind($this->definition); - } catch (\Exception $e) { - if (!$this->ignoreValidationErrors) { - throw $e; - } - } - - $this->initialize($input, $output); - - if ($input->isInteractive()) { - $this->interact($input, $output); - } - - $input->validate(); - - if ($this->code) { - $statusCode = call_user_func($this->code, $input, $output); - } else { - $statusCode = $this->execute($input, $output); - } - - return is_numeric($statusCode) ? (int) $statusCode : 0; - } - - /** - * 设置执行代码 - * @param callable $code callable(InputInterface $input, OutputInterface $output) - * @return Command - * @throws \InvalidArgumentException - * @see execute() - */ - public function setCode(callable $code) - { - if (!is_callable($code)) { - throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.'); - } - - if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) { - $r = new \ReflectionFunction($code); - if (null === $r->getClosureThis()) { - $code = \Closure::bind($code, $this); - } - } - - $this->code = $code; - - return $this; - } - - /** - * 合并参数定义 - * @param bool $mergeArgs - */ - public function mergeConsoleDefinition($mergeArgs = true) - { - if (null === $this->console - || (true === $this->consoleDefinitionMerged - && ($this->consoleDefinitionMergedWithArgs || !$mergeArgs)) - ) { - return; - } - - if ($mergeArgs) { - $currentArguments = $this->definition->getArguments(); - $this->definition->setArguments($this->console->getDefinition()->getArguments()); - $this->definition->addArguments($currentArguments); - } - - $this->definition->addOptions($this->console->getDefinition()->getOptions()); - - $this->consoleDefinitionMerged = true; - if ($mergeArgs) { - $this->consoleDefinitionMergedWithArgs = true; - } - } - - /** - * 设置参数定义 - * @param array|Definition $definition - * @return Command - * @api - */ - public function setDefinition($definition) - { - if ($definition instanceof Definition) { - $this->definition = $definition; - } else { - $this->definition->setDefinition($definition); - } - - $this->consoleDefinitionMerged = false; - - return $this; - } - - /** - * 获取参数定义 - * @return Definition - * @api - */ - public function getDefinition() - { - return $this->definition; - } - - /** - * 获取当前指令的参数定义 - * @return Definition - */ - public function getNativeDefinition() - { - return $this->getDefinition(); - } - - /** - * 添加参数 - * @param string $name 名称 - * @param int $mode 类型 - * @param string $description 描述 - * @param mixed $default 默认值 - * @return Command - */ - public function addArgument($name, $mode = null, $description = '', $default = null) - { - $this->definition->addArgument(new Argument($name, $mode, $description, $default)); - - return $this; - } - - /** - * 添加选项 - * @param string $name 选项名称 - * @param string $shortcut 别名 - * @param int $mode 类型 - * @param string $description 描述 - * @param mixed $default 默认值 - * @return Command - */ - public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null) - { - $this->definition->addOption(new Option($name, $shortcut, $mode, $description, $default)); - - return $this; - } - - /** - * 设置指令名称 - * @param string $name - * @return Command - * @throws \InvalidArgumentException - */ - public function setName($name) - { - $this->validateName($name); - - $this->name = $name; - - return $this; - } - - /** - * 获取指令名称 - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * 设置描述 - * @param string $description - * @return Command - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * 获取描述 - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * 设置帮助信息 - * @param string $help - * @return Command - */ - public function setHelp($help) - { - $this->help = $help; - - return $this; - } - - /** - * 获取帮助信息 - * @return string - */ - public function getHelp() - { - return $this->help; - } - - /** - * 描述信息 - * @return string - */ - public function getProcessedHelp() - { - $name = $this->name; - - $placeholders = [ - '%command.name%', - '%command.full_name%', - ]; - $replacements = [ - $name, - $_SERVER['PHP_SELF'] . ' ' . $name, - ]; - - return str_replace($placeholders, $replacements, $this->getHelp()); - } - - /** - * 设置别名 - * @param string[] $aliases - * @return Command - * @throws \InvalidArgumentException - */ - public function setAliases($aliases) - { - if (!is_array($aliases) && !$aliases instanceof \Traversable) { - throw new \InvalidArgumentException('$aliases must be an array or an instance of \Traversable'); - } - - foreach ($aliases as $alias) { - $this->validateName($alias); - } - - $this->aliases = $aliases; - - return $this; - } - - /** - * 获取别名 - * @return array - */ - public function getAliases() - { - return $this->aliases; - } - - /** - * 获取简介 - * @param bool $short 是否简单的 - * @return string - */ - public function getSynopsis($short = false) - { - $key = $short ? 'short' : 'long'; - - if (!isset($this->synopsis[$key])) { - $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short))); - } - - return $this->synopsis[$key]; - } - - /** - * 添加用法介绍 - * @param string $usage - * @return $this - */ - public function addUsage($usage) - { - if (0 !== strpos($usage, $this->name)) { - $usage = sprintf('%s %s', $this->name, $usage); - } - - $this->usages[] = $usage; - - return $this; - } - - /** - * 获取用法介绍 - * @return array - */ - public function getUsages() - { - return $this->usages; - } - - /** - * 验证指令名称 - * @param string $name - * @throws \InvalidArgumentException - */ - private function validateName($name) - { - if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) { - throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); - } - } -} diff --git a/thinkphp/library/think/console/Input.php b/thinkphp/library/think/console/Input.php deleted file mode 100755 index 2482dfd..0000000 --- a/thinkphp/library/think/console/Input.php +++ /dev/null @@ -1,464 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console; - -use think\console\input\Argument; -use think\console\input\Definition; -use think\console\input\Option; - -class Input -{ - - /** - * @var Definition - */ - protected $definition; - - /** - * @var Option[] - */ - protected $options = []; - - /** - * @var Argument[] - */ - protected $arguments = []; - - protected $interactive = true; - - private $tokens; - private $parsed; - - public function __construct($argv = null) - { - if (null === $argv) { - $argv = $_SERVER['argv']; - // 去除命令名 - array_shift($argv); - } - - $this->tokens = $argv; - - $this->definition = new Definition(); - } - - protected function setTokens(array $tokens) - { - $this->tokens = $tokens; - } - - /** - * 绑定实例 - * @param Definition $definition A InputDefinition instance - */ - public function bind(Definition $definition) - { - $this->arguments = []; - $this->options = []; - $this->definition = $definition; - - $this->parse(); - } - - /** - * 解析参数 - */ - protected function parse() - { - $parseOptions = true; - $this->parsed = $this->tokens; - while (null !== $token = array_shift($this->parsed)) { - if ($parseOptions && '' == $token) { - $this->parseArgument($token); - } elseif ($parseOptions && '--' == $token) { - $parseOptions = false; - } elseif ($parseOptions && 0 === strpos($token, '--')) { - $this->parseLongOption($token); - } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { - $this->parseShortOption($token); - } else { - $this->parseArgument($token); - } - } - } - - /** - * 解析短选项 - * @param string $token 当前的指令. - */ - private function parseShortOption($token) - { - $name = substr($token, 1); - - if (strlen($name) > 1) { - if ($this->definition->hasShortcut($name[0]) - && $this->definition->getOptionForShortcut($name[0])->acceptValue() - ) { - $this->addShortOption($name[0], substr($name, 1)); - } else { - $this->parseShortOptionSet($name); - } - } else { - $this->addShortOption($name, null); - } - } - - /** - * 解析短选项 - * @param string $name 当前指令 - * @throws \RuntimeException - */ - private function parseShortOptionSet($name) - { - $len = strlen($name); - for ($i = 0; $i < $len; ++$i) { - if (!$this->definition->hasShortcut($name[$i])) { - throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i])); - } - - $option = $this->definition->getOptionForShortcut($name[$i]); - if ($option->acceptValue()) { - $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1)); - - break; - } else { - $this->addLongOption($option->getName(), null); - } - } - } - - /** - * 解析完整选项 - * @param string $token 当前指令 - */ - private function parseLongOption($token) - { - $name = substr($token, 2); - - if (false !== $pos = strpos($name, '=')) { - $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1)); - } else { - $this->addLongOption($name, null); - } - } - - /** - * 解析参数 - * @param string $token 当前指令 - * @throws \RuntimeException - */ - private function parseArgument($token) - { - $c = count($this->arguments); - - if ($this->definition->hasArgument($c)) { - $arg = $this->definition->getArgument($c); - - $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token; - - } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { - $arg = $this->definition->getArgument($c - 1); - - $this->arguments[$arg->getName()][] = $token; - } else { - throw new \RuntimeException('Too many arguments.'); - } - } - - /** - * 添加一个短选项的值 - * @param string $shortcut 短名称 - * @param mixed $value 值 - * @throws \RuntimeException - */ - private function addShortOption($shortcut, $value) - { - if (!$this->definition->hasShortcut($shortcut)) { - throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); - } - - /** - * 添加一个完整选项的值 - * @param string $name 选项名 - * @param mixed $value 值 - * @throws \RuntimeException - */ - private function addLongOption($name, $value) - { - if (!$this->definition->hasOption($name)) { - throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name)); - } - - $option = $this->definition->getOption($name); - - if (false === $value) { - $value = null; - } - - if (null !== $value && !$option->acceptValue()) { - throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name, $value)); - } - - if (null === $value && $option->acceptValue() && count($this->parsed)) { - $next = array_shift($this->parsed); - if (isset($next[0]) && '-' !== $next[0]) { - $value = $next; - } elseif (empty($next)) { - $value = ''; - } else { - array_unshift($this->parsed, $next); - } - } - - if (null === $value) { - if ($option->isValueRequired()) { - throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name)); - } - - if (!$option->isArray()) { - $value = $option->isValueOptional() ? $option->getDefault() : true; - } - } - - if ($option->isArray()) { - $this->options[$name][] = $value; - } else { - $this->options[$name] = $value; - } - } - - /** - * 获取第一个参数 - * @return string|null - */ - public function getFirstArgument() - { - foreach ($this->tokens as $token) { - if ($token && '-' === $token[0]) { - continue; - } - - return $token; - } - return; - } - - /** - * 检查原始参数是否包含某个值 - * @param string|array $values 需要检查的值 - * @return bool - */ - public function hasParameterOption($values) - { - $values = (array) $values; - - foreach ($this->tokens as $token) { - foreach ($values as $value) { - if ($token === $value || 0 === strpos($token, $value . '=')) { - return true; - } - } - } - - return false; - } - - /** - * 获取原始选项的值 - * @param string|array $values 需要检查的值 - * @param mixed $default 默认值 - * @return mixed The option value - */ - public function getParameterOption($values, $default = false) - { - $values = (array) $values; - $tokens = $this->tokens; - - while (0 < count($tokens)) { - $token = array_shift($tokens); - - foreach ($values as $value) { - if ($token === $value || 0 === strpos($token, $value . '=')) { - if (false !== $pos = strpos($token, '=')) { - return substr($token, $pos + 1); - } - - return array_shift($tokens); - } - } - } - - return $default; - } - - /** - * 验证输入 - * @throws \RuntimeException - */ - public function validate() - { - if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) { - throw new \RuntimeException('Not enough arguments.'); - } - } - - /** - * 检查输入是否是交互的 - * @return bool - */ - public function isInteractive() - { - return $this->interactive; - } - - /** - * 设置输入的交互 - * @param bool - */ - public function setInteractive($interactive) - { - $this->interactive = (bool) $interactive; - } - - /** - * 获取所有的参数 - * @return Argument[] - */ - public function getArguments() - { - return array_merge($this->definition->getArgumentDefaults(), $this->arguments); - } - - /** - * 根据名称获取参数 - * @param string $name 参数名 - * @return mixed - * @throws \InvalidArgumentException - */ - public function getArgument($name) - { - if (!$this->definition->hasArgument($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name) - ->getDefault(); - } - - /** - * 设置参数的值 - * @param string $name 参数名 - * @param string $value 值 - * @throws \InvalidArgumentException - */ - public function setArgument($name, $value) - { - if (!$this->definition->hasArgument($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $this->arguments[$name] = $value; - } - - /** - * 检查是否存在某个参数 - * @param string|int $name 参数名或位置 - * @return bool - */ - public function hasArgument($name) - { - return $this->definition->hasArgument($name); - } - - /** - * 获取所有的选项 - * @return Option[] - */ - public function getOptions() - { - return array_merge($this->definition->getOptionDefaults(), $this->options); - } - - /** - * 获取选项值 - * @param string $name 选项名称 - * @return mixed - * @throws \InvalidArgumentException - */ - public function getOption($name) - { - if (!$this->definition->hasOption($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); - } - - return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault(); - } - - /** - * 设置选项值 - * @param string $name 选项名 - * @param string|bool $value 值 - * @throws \InvalidArgumentException - */ - public function setOption($name, $value) - { - if (!$this->definition->hasOption($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); - } - - $this->options[$name] = $value; - } - - /** - * 是否有某个选项 - * @param string $name 选项名 - * @return bool - */ - public function hasOption($name) - { - return $this->definition->hasOption($name) && isset($this->options[$name]); - } - - /** - * 转义指令 - * @param string $token - * @return string - */ - public function escapeToken($token) - { - return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token); - } - - /** - * 返回传递给命令的参数的字符串 - * @return string - */ - public function __toString() - { - $tokens = array_map(function ($token) { - if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) { - return $match[1] . $this->escapeToken($match[2]); - } - - if ($token && '-' !== $token[0]) { - return $this->escapeToken($token); - } - - return $token; - }, $this->tokens); - - return implode(' ', $tokens); - } -} diff --git a/thinkphp/library/think/console/LICENSE b/thinkphp/library/think/console/LICENSE deleted file mode 100755 index 0abe056..0000000 --- a/thinkphp/library/think/console/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2004-2016 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/thinkphp/library/think/console/Output.php b/thinkphp/library/think/console/Output.php deleted file mode 100755 index 65dc9fb..0000000 --- a/thinkphp/library/think/console/Output.php +++ /dev/null @@ -1,222 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console; - -use Exception; -use think\console\output\Ask; -use think\console\output\Descriptor; -use think\console\output\driver\Buffer; -use think\console\output\driver\Console; -use think\console\output\driver\Nothing; -use think\console\output\Question; -use think\console\output\question\Choice; -use think\console\output\question\Confirmation; - -/** - * Class Output - * @package think\console - * - * @see \think\console\output\driver\Console::setDecorated - * @method void setDecorated($decorated) - * - * @see \think\console\output\driver\Buffer::fetch - * @method string fetch() - * - * @method void info($message) - * @method void error($message) - * @method void comment($message) - * @method void warning($message) - * @method void highlight($message) - * @method void question($message) - */ -class Output -{ - const VERBOSITY_QUIET = 0; - const VERBOSITY_NORMAL = 1; - const VERBOSITY_VERBOSE = 2; - const VERBOSITY_VERY_VERBOSE = 3; - const VERBOSITY_DEBUG = 4; - - const OUTPUT_NORMAL = 0; - const OUTPUT_RAW = 1; - const OUTPUT_PLAIN = 2; - - private $verbosity = self::VERBOSITY_NORMAL; - - /** @var Buffer|Console|Nothing */ - private $handle = null; - - protected $styles = [ - 'info', - 'error', - 'comment', - 'question', - 'highlight', - 'warning' - ]; - - public function __construct($driver = 'console') - { - $class = '\\think\\console\\output\\driver\\' . ucwords($driver); - - $this->handle = new $class($this); - } - - public function ask(Input $input, $question, $default = null, $validator = null) - { - $question = new Question($question, $default); - $question->setValidator($validator); - - return $this->askQuestion($input, $question); - } - - public function askHidden(Input $input, $question, $validator = null) - { - $question = new Question($question); - - $question->setHidden(true); - $question->setValidator($validator); - - return $this->askQuestion($input, $question); - } - - public function confirm(Input $input, $question, $default = true) - { - return $this->askQuestion($input, new Confirmation($question, $default)); - } - - /** - * {@inheritdoc} - */ - public function choice(Input $input, $question, array $choices, $default = null) - { - if (null !== $default) { - $values = array_flip($choices); - $default = $values[$default]; - } - - return $this->askQuestion($input, new Choice($question, $choices, $default)); - } - - protected function askQuestion(Input $input, Question $question) - { - $ask = new Ask($input, $this, $question); - $answer = $ask->run(); - - if ($input->isInteractive()) { - $this->newLine(); - } - - return $answer; - } - - protected function block($style, $message) - { - $this->writeln("<{$style}>{$message}"); - } - - /** - * 输出空行 - * @param int $count - */ - public function newLine($count = 1) - { - $this->write(str_repeat(PHP_EOL, $count)); - } - - /** - * 输出信息并换行 - * @param string $messages - * @param int $type - */ - public function writeln($messages, $type = self::OUTPUT_NORMAL) - { - $this->write($messages, true, $type); - } - - /** - * 输出信息 - * @param string $messages - * @param bool $newline - * @param int $type - */ - public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) - { - $this->handle->write($messages, $newline, $type); - } - - public function renderException(\Exception $e) - { - $this->handle->renderException($e); - } - - /** - * {@inheritdoc} - */ - public function setVerbosity($level) - { - $this->verbosity = (int) $level; - } - - /** - * {@inheritdoc} - */ - public function getVerbosity() - { - return $this->verbosity; - } - - public function isQuiet() - { - return self::VERBOSITY_QUIET === $this->verbosity; - } - - public function isVerbose() - { - return self::VERBOSITY_VERBOSE <= $this->verbosity; - } - - public function isVeryVerbose() - { - return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; - } - - public function isDebug() - { - return self::VERBOSITY_DEBUG <= $this->verbosity; - } - - public function describe($object, array $options = []) - { - $descriptor = new Descriptor(); - $options = array_merge([ - 'raw_text' => false, - ], $options); - - $descriptor->describe($this, $object, $options); - } - - public function __call($method, $args) - { - if (in_array($method, $this->styles)) { - array_unshift($args, $method); - return call_user_func_array([$this, 'block'], $args); - } - - if ($this->handle && method_exists($this->handle, $method)) { - return call_user_func_array([$this->handle, $method], $args); - } else { - throw new Exception('method not exists:' . __CLASS__ . '->' . $method); - } - } - -} diff --git a/thinkphp/library/think/console/bin/README.md b/thinkphp/library/think/console/bin/README.md deleted file mode 100755 index 9acc52f..0000000 --- a/thinkphp/library/think/console/bin/README.md +++ /dev/null @@ -1 +0,0 @@ -console 工具使用 hiddeninput.exe 在 windows 上隐藏密码输入,该二进制文件由第三方提供,相关源码和其他细节可以在 [Hidden Input](https://github.com/Seldaek/hidden-input) 找到。 diff --git a/thinkphp/library/think/console/bin/hiddeninput.exe b/thinkphp/library/think/console/bin/hiddeninput.exe deleted file mode 100755 index c8cf65e8d819e6e525121cf6b21f1c2429746038..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9216 zcmeHNe{@sVeZR8hV88~S)=Hp|Mpn({rC^@)BwNOI{ERJXCYlx+k1K6PLHo z_e!z_fhOzeA3JTX&-Z@s{rFOgjEwBlqjr!)9f zjyHz`A+ni`!0Taby{Uj5Y>jQq(k5A+X})PLWAi|{IZbtc8n^^trM{GI=P_15U6d?l zJJ3PW8XjfHpR}6`k{&5@JcEeH_SqQoQbU62o2YS30W)p_t&Fjy*RXQCZt$gCf|ao| zx&3R}m6|-Lfi@pua=$26n(UlnWo$>K67*|+#(qL_An=?l0M02AhOSJDv3;~?1ORfw z76EdK#MpSHqACHLcnJLIYlCSiX4eS@Pr8rN)Xwz0dk7O*y^0_C(Yks2Kvg! z-d-fJ)F9@k?>)m(XqDKIe2OKfhCQde9fpO0ko24yn*4xzX7q+ze`Z*=aJgwV?D?73 zaJ8UkSk|NN>@-|mB*f`EIK7$ElgAB<7p&p`^Vuq$58#;?B^*Bz7&d$B#+AYUC z(^m|`7{lqx&b^5$;i`j|S!+u|lcaQplp_&Nb)!>r>vGh3wb!tW zLq6%bkSt8jO|(vWH>LiPV(Xkp%BiGhl1q!PXXNKVKE!>Y5cHc2%cJOJA{-&ZsSn`T z#8~TA#(HWH4m>uCd+kCMTFgMI*s*n3!iCOwEI`{vGcVhzDu!Lw%-Ea^JATtrF`q3`+#KvvYJ0vM~A}D#LOD zlw`4ncB0U*Jji=--Wz#>I&5?hy;MgYW2u91d8ob=7MWfY`u;7Xe-J{Qsb0=0p|SM2 zG|=~mERIj4?gi)Ew|{LIN#oAsh20k_khIYjJBBN6rrIJ=eQO=nE;rTnPSiaQS$1$# z+|JRh0!IbQIa*f1(TZ}QM;|WO0+jTy(e)ggN4>zqp2E>C>hGPLHjHBh--2%@{EZNE zbUk{<3MABX&20QwK{MxK8`1Vk>^%dO5i@VTfu>NG3$K4NC=hSPsj9UYy`rNO}sBnB9QdKdIk7G+2_amnWstdTYVg z7HgLJGC~XLZG`63GwH8PdO_+G(k6~?J8Wj5mQos#21kC4W#2)guQXI)!z^{@F)U)5 z*re+r(2dib3D4P~%Z6TL=$PIkpmm<_#isu%t=%DcIwNkJhMeJ|bpahHO%8h|y~Ccf zUg#xVk+dyu>Q1O7JZ~8KS>tqi0qK**X*y6yHM71`bT=kFZ=@E%oe2!Km1^2sa>v+onZ%x_>aOJF+N0{i~z|<(IzgT*{0PpQq}E zQpU35@bm;qI?t_znGI&5&4sZV>+%m}w$(4hSDvLk)l<{5XyMlnCl7C%AjM3XnWvVz z{NoFsX)JB)SoqABZxUa*Yq+^^(cbq4mL%^lO12c${z{pf+)|kTTI~nQywyYF6}6|8 zlsN9&{-vwTrTyu<5^90_AsIU-ID#ZG@6d%poU44<**%xVe?`uxf}_Mr$SLHLS|K_N zQnw>(Lr2U=%$-<2D~RSzbG)2W2u^KMDnFFE?GmmbQ)V)fty957F`4OvQ_25E68ITr z5?`suu`|v?r!y=gFOGj$%9IJ zuTP=&2GcnoZZ0qSe6YL-*-lg>Q#>?Ew`a=GDc4vI#<1sNdKn?n7iSj0Orl$-#FMFi zykr>X-Xvi>sVr;92+8*H!r|3L$#o~hXa0z>AmF=z z?|@FF;*S|S0yqsw0j>Z(3mX-HD!|{N-vYc9paC8Ld=|6?00!6(_%lERupO`&um*4k z0b~W>e*uhTe4;V;mq>(ox$9FB`wLt!*DKj~!aOh|fL&#Pg*b??tm%5~_6M#02wqeC zS~wO>TWGnSp^r<0&8f2V6W->w=C+p~daC5e5wNQM*(* z66^}b0(!q3)zq$mu&VnbR#nr3;h5DS*o7{y66=!#;Dy4$pd1ZH<6WEOi0oJ8SxRL* z*v-9@Z^2w%^S(w5dO{_9Duby%2RT~;ppxaE$l()x6&}>7Wcg=u_&>f`Vs8OJGTy{X z2HpG=ThJz<{%|4Qq-~ad0qcrc87n88DHpM(nypwXIkZn<{zIT$ul&BQ?{ApCAZtyr zs2YpNt@x(G*faTU*HCKnAk(G=Tl~>r1QK8LY~J8mFFGoN5iIkYSwlm4Lsj#g4dsE5 zU-4;*Kdh-zv!rT4N$O}Q&n)?v0-9Y)lRFz58^P-KtKonzrfQ1p@0V_10^0||cGRn9 zRG<-#_TEV2nn4{BOh{YVBR4e!V!D?0K%BAlQN!D%M#k1bHypiIHT)5tlj>p0Pp_;+ z!cqC-JIs@JRhB+#teGs$Cib_=(yjRo4OJg^YPg%58aJVsC(LQ?W6%pn!-#aMZwoPcopo^Rn6BE z3=c5&W5~pP(C(-2r;PnH-S0{F`runM0ERCf3rESX$+S(MKOXmKJL9zXF}9-lf^xUs z+bb)+P%L&gV@<4q{6w^xEJ>Y>TQFUeoz0o-yq)jUqww=?wjUO8Y{a5G;DJ0Jr!LL+ zWhgsLuzi&eDrGDn$2DJwpFfH-?SGWbr>qRb?v{P`_%)So)CQgzO^HQ%;y#tJ=knH4 z95jX;^bF#BiuTH^%-j}{9VrZD=R%Q%wselH^p>5 z7d>gWB-st&3Fj%Mt*|tR5iK3J=`xhs&G)I7E>`FO@o7L z@S$B!pYMuzz5DN@X!O4DPm5n@raPJn-Q#o*m*e^5lk$g?0esg%$;>g5QW-|;c=H2GM}bo2tW^D924wmOkrUbWxcQ# z#v6bP%Tdfe~jtCRzAL;-OahZ=#yvUixu2-9fD2j$*|YY`F?0wF-{a# ztr<&kZjZ+81}6ZESqtgW)8kP#s@VLTSUR{}6?U^R*x7RE3Rl&n=VnFFqg9Uqz1n@N9N|=9<4} zuJfy^+}|D9X&vm3MAdqmu0&UMd^=K>b1hLAm_E!$rZC2b;;T~Dl zI`Eo_yRY76uM})|6wk9->of(=9&4jLv5#p@OzS~Yl>@pG)^>6`R+KtL{<4ly4o9WiM!%p_pfROU354)e8PIeE z1_s?#;OX6waNvvb&UQRN(WLbR+}&b#jo&WY-LlwCX}Q*$jGuKYuOGoIoyR(>e}}ix z+t}Q^cEcC8Y{@h}>HmJ^gD!l@gzwHmiBKl26x_lZVZG2UY!`w;RJd122;US&geQdW z3Qq}R!gIo5;ka;0I4c-Jq5X6A6?VzK&c4y!ZXdAUYu{r}*!SBXw?Aor+J4-A(*COb zb^CwV-?3k`zi-cX*c`VzL`RLI(b4MgIrGN z%ojf`E*6)Gg1A9!7q^N##2zsss^V9~-Qt7d!{UDNZ^XY9pA^3@9ui*?e=7c5d`nD; z?}~R(p>y1Kw!>|X4ycYEAkcZa*n-R%y! zqi)Up756UpqwfE7=hfigw$k~G@25gaxF9UGTkV>C(7x1Rbx4jb#|}rxq0vQ!n-c#f J0sQ~1{4brj`U(I5 diff --git a/thinkphp/library/think/console/command/Build.php b/thinkphp/library/think/console/command/Build.php deleted file mode 100755 index 39806c3..0000000 --- a/thinkphp/library/think/console/command/Build.php +++ /dev/null @@ -1,56 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\command; - -use think\console\Command; -use think\console\Input; -use think\console\input\Option; -use think\console\Output; - -class Build extends Command -{ - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this->setName('build') - ->setDefinition([ - new Option('config', null, Option::VALUE_OPTIONAL, "build.php path"), - new Option('module', null, Option::VALUE_OPTIONAL, "module name"), - ]) - ->setDescription('Build Application Dirs'); - } - - protected function execute(Input $input, Output $output) - { - if ($input->hasOption('module')) { - \think\Build::module($input->getOption('module')); - $output->writeln("Successed"); - return; - } - - if ($input->hasOption('config')) { - $build = include $input->getOption('config'); - } else { - $build = include APP_PATH . 'build.php'; - } - if (empty($build)) { - $output->writeln("Build Config Is Empty"); - return; - } - \think\Build::run($build); - $output->writeln("Successed"); - - } -} diff --git a/thinkphp/library/think/console/command/Clear.php b/thinkphp/library/think/console/command/Clear.php deleted file mode 100755 index 1b5102e..0000000 --- a/thinkphp/library/think/console/command/Clear.php +++ /dev/null @@ -1,63 +0,0 @@ - -// +---------------------------------------------------------------------- -namespace think\console\command; - -use think\Cache; -use think\console\Command; -use think\console\Input; -use think\console\input\Argument; -use think\console\input\Option; -use think\console\Output; - -class Clear extends Command -{ - protected function configure() - { - // 指令配置 - $this - ->setName('clear') - ->addArgument('type', Argument::OPTIONAL, 'type to clear', null) - ->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null) - ->setDescription('Clear runtime file'); - } - - protected function execute(Input $input, Output $output) - { - $path = $input->getOption('path') ?: RUNTIME_PATH; - - $type = $input->getArgument('type'); - - if ($type == 'route') { - Cache::clear('route_check'); - } else { - if (is_dir($path)) { - $this->clearPath($path); - } - } - - $output->writeln("Clear Successed"); - } - - protected function clearPath($path) - { - $path = realpath($path) . DS; - $files = scandir($path); - if ($files) { - foreach ($files as $file) { - if ('.' != $file && '..' != $file && is_dir($path . $file)) { - $this->clearPath($path . $file); - } elseif ('.gitignore' != $file && is_file($path . $file)) { - unlink($path . $file); - } - } - } - } -} diff --git a/thinkphp/library/think/console/command/Help.php b/thinkphp/library/think/console/command/Help.php deleted file mode 100755 index bae2c65..0000000 --- a/thinkphp/library/think/console/command/Help.php +++ /dev/null @@ -1,69 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\command; - -use think\console\Command; -use think\console\Input; -use think\console\input\Argument as InputArgument; -use think\console\input\Option as InputOption; -use think\console\Output; - -class Help extends Command -{ - - private $command; - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this->ignoreValidationErrors(); - - $this->setName('help')->setDefinition([ - new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), - new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), - ])->setDescription('Displays help for a command')->setHelp(<<%command.name% command displays help for a given command: - - php %command.full_name% list - -To display the list of available commands, please use the list command. -EOF - ); - } - - /** - * Sets the command. - * @param Command $command The command to set - */ - public function setCommand(Command $command) - { - $this->command = $command; - } - - /** - * {@inheritdoc} - */ - protected function execute(Input $input, Output $output) - { - if (null === $this->command) { - $this->command = $this->getConsole()->find($input->getArgument('command_name')); - } - - $output->describe($this->command, [ - 'raw_text' => $input->getOption('raw'), - ]); - - $this->command = null; - } -} diff --git a/thinkphp/library/think/console/command/Lists.php b/thinkphp/library/think/console/command/Lists.php deleted file mode 100755 index 084ddaa..0000000 --- a/thinkphp/library/think/console/command/Lists.php +++ /dev/null @@ -1,74 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\command; - -use think\console\Command; -use think\console\Input; -use think\console\Output; -use think\console\input\Argument as InputArgument; -use think\console\input\Option as InputOption; -use think\console\input\Definition as InputDefinition; - -class Lists extends Command -{ - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this->setName('list')->setDefinition($this->createDefinition())->setDescription('Lists commands')->setHelp(<<%command.name% command lists all commands: - - php %command.full_name% - -You can also display the commands for a specific namespace: - - php %command.full_name% test - -It's also possible to get raw list of commands (useful for embedding command runner): - - php %command.full_name% --raw -EOF - ); - } - - /** - * {@inheritdoc} - */ - public function getNativeDefinition() - { - return $this->createDefinition(); - } - - /** - * {@inheritdoc} - */ - protected function execute(Input $input, Output $output) - { - $output->describe($this->getConsole(), [ - 'raw_text' => $input->getOption('raw'), - 'namespace' => $input->getArgument('namespace'), - ]); - } - - /** - * {@inheritdoc} - */ - private function createDefinition() - { - return new InputDefinition([ - new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), - new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list') - ]); - } -} diff --git a/thinkphp/library/think/console/command/Make.php b/thinkphp/library/think/console/command/Make.php deleted file mode 100755 index d1daf34..0000000 --- a/thinkphp/library/think/console/command/Make.php +++ /dev/null @@ -1,110 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\command; - -use think\App; -use think\Config; -use think\console\Command; -use think\console\Input; -use think\console\input\Argument; -use think\console\Output; - -abstract class Make extends Command -{ - - protected $type; - - abstract protected function getStub(); - - protected function configure() - { - $this->addArgument('name', Argument::REQUIRED, "The name of the class"); - } - - protected function execute(Input $input, Output $output) - { - - $name = trim($input->getArgument('name')); - - $classname = $this->getClassName($name); - - $pathname = $this->getPathName($classname); - - if (is_file($pathname)) { - $output->writeln('' . $this->type . ' already exists!'); - return false; - } - - if (!is_dir(dirname($pathname))) { - mkdir(strtolower(dirname($pathname)), 0755, true); - } - - file_put_contents($pathname, $this->buildClass($classname)); - - $output->writeln('' . $this->type . ' created successfully.'); - - } - - protected function buildClass($name) - { - $stub = file_get_contents($this->getStub()); - - $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\'); - - $class = str_replace($namespace . '\\', '', $name); - - return str_replace(['{%className%}', '{%namespace%}', '{%app_namespace%}'], [ - $class, - $namespace, - App::$namespace, - ], $stub); - - } - - protected function getPathName($name) - { - $name = str_replace(App::$namespace . '\\', '', $name); - - return APP_PATH . str_replace('\\', '/', $name) . '.php'; - } - - protected function getClassName($name) - { - $appNamespace = App::$namespace; - - if (strpos($name, $appNamespace . '\\') === 0) { - return $name; - } - - if (Config::get('app_multi_module')) { - if (strpos($name, '/')) { - list($module, $name) = explode('/', $name, 2); - } else { - $module = 'common'; - } - } else { - $module = null; - } - - if (strpos($name, '/') !== false) { - $name = str_replace('/', '\\', $name); - } - - return $this->getNamespace($appNamespace, $module) . '\\' . $name; - } - - protected function getNamespace($appNamespace, $module) - { - return $module ? ($appNamespace . '\\' . $module) : $appNamespace; - } - -} diff --git a/thinkphp/library/think/console/command/make/Controller.php b/thinkphp/library/think/console/command/make/Controller.php deleted file mode 100755 index afa7be9..0000000 --- a/thinkphp/library/think/console/command/make/Controller.php +++ /dev/null @@ -1,50 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\command\make; - -use think\Config; -use think\console\command\Make; -use think\console\input\Option; - -class Controller extends Make -{ - - protected $type = "Controller"; - - protected function configure() - { - parent::configure(); - $this->setName('make:controller') - ->addOption('plain', null, Option::VALUE_NONE, 'Generate an empty controller class.') - ->setDescription('Create a new resource controller class'); - } - - protected function getStub() - { - if ($this->input->getOption('plain')) { - return __DIR__ . '/stubs/controller.plain.stub'; - } - - return __DIR__ . '/stubs/controller.stub'; - } - - protected function getClassName($name) - { - return parent::getClassName($name) . (Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : ''); - } - - protected function getNamespace($appNamespace, $module) - { - return parent::getNamespace($appNamespace, $module) . '\controller'; - } - -} diff --git a/thinkphp/library/think/console/command/make/Model.php b/thinkphp/library/think/console/command/make/Model.php deleted file mode 100755 index d4e9b5d..0000000 --- a/thinkphp/library/think/console/command/make/Model.php +++ /dev/null @@ -1,36 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\command\make; - -use think\console\command\Make; - -class Model extends Make -{ - protected $type = "Model"; - - protected function configure() - { - parent::configure(); - $this->setName('make:model') - ->setDescription('Create a new model class'); - } - - protected function getStub() - { - return __DIR__ . '/stubs/model.stub'; - } - - protected function getNamespace($appNamespace, $module) - { - return parent::getNamespace($appNamespace, $module) . '\model'; - } -} diff --git a/thinkphp/library/think/console/command/make/stubs/controller.plain.stub b/thinkphp/library/think/console/command/make/stubs/controller.plain.stub deleted file mode 100755 index b7539dc..0000000 --- a/thinkphp/library/think/console/command/make/stubs/controller.plain.stub +++ /dev/null @@ -1,10 +0,0 @@ - -// +---------------------------------------------------------------------- -namespace think\console\command\optimize; - -use think\App; -use think\Config; -use think\console\Command; -use think\console\Input; -use think\console\Output; - -class Autoload extends Command -{ - - protected function configure() - { - $this->setName('optimize:autoload') - ->setDescription('Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'); - } - - protected function execute(Input $input, Output $output) - { - - $classmapFile = << realpath(rtrim(APP_PATH)), - 'think\\' => LIB_PATH . 'think', - 'behavior\\' => LIB_PATH . 'behavior', - 'traits\\' => LIB_PATH . 'traits', - '' => realpath(rtrim(EXTEND_PATH)), - ]; - - $root_namespace = Config::get('root_namespace'); - foreach ($root_namespace as $namespace => $dir) { - $namespacesToScan[$namespace . '\\'] = realpath($dir); - } - - krsort($namespacesToScan); - $classMap = []; - foreach ($namespacesToScan as $namespace => $dir) { - - if (!is_dir($dir)) { - continue; - } - - $namespaceFilter = $namespace === '' ? null : $namespace; - $classMap = $this->addClassMapCode($dir, $namespaceFilter, $classMap); - } - - ksort($classMap); - foreach ($classMap as $class => $code) { - $classmapFile .= ' ' . var_export($class, true) . ' => ' . $code; - } - $classmapFile .= "];\n"; - - if (!is_dir(RUNTIME_PATH)) { - @mkdir(RUNTIME_PATH, 0755, true); - } - - file_put_contents(RUNTIME_PATH . 'classmap' . EXT, $classmapFile); - - $output->writeln('Succeed!'); - } - - protected function addClassMapCode($dir, $namespace, $classMap) - { - foreach ($this->createMap($dir, $namespace) as $class => $path) { - - $pathCode = $this->getPathCode($path) . ",\n"; - - if (!isset($classMap[$class])) { - $classMap[$class] = $pathCode; - } elseif ($classMap[$class] !== $pathCode && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($classMap[$class] . ' ' . $path, '\\', '/'))) { - $this->output->writeln( - 'Warning: Ambiguous class resolution, "' . $class . '"' . - ' was found in both "' . str_replace(["',\n"], [ - '', - ], $classMap[$class]) . '" and "' . $path . '", the first will be used.' - ); - } - } - return $classMap; - } - - protected function getPathCode($path) - { - - $baseDir = ''; - $libPath = $this->normalizePath(realpath(LIB_PATH)); - $appPath = $this->normalizePath(realpath(APP_PATH)); - $extendPath = $this->normalizePath(realpath(EXTEND_PATH)); - $rootPath = $this->normalizePath(realpath(ROOT_PATH)); - $path = $this->normalizePath($path); - - if ($libPath !== null && strpos($path, $libPath . '/') === 0) { - $path = substr($path, strlen(LIB_PATH)); - $baseDir = 'LIB_PATH'; - } elseif ($appPath !== null && strpos($path, $appPath . '/') === 0) { - $path = substr($path, strlen($appPath) + 1); - $baseDir = 'APP_PATH'; - } elseif ($extendPath !== null && strpos($path, $extendPath . '/') === 0) { - $path = substr($path, strlen($extendPath) + 1); - $baseDir = 'EXTEND_PATH'; - } elseif ($rootPath !== null && strpos($path, $rootPath . '/') === 0) { - $path = substr($path, strlen($rootPath) + 1); - $baseDir = 'ROOT_PATH'; - } - - if ($path !== false) { - $baseDir .= " . "; - } - - return $baseDir . (($path !== false) ? var_export($path, true) : ""); - } - - protected function normalizePath($path) - { - if ($path === false) { - return; - } - $parts = []; - $path = strtr($path, '\\', '/'); - $prefix = ''; - $absolute = false; - - if (preg_match('{^([0-9a-z]+:(?://(?:[a-z]:)?)?)}i', $path, $match)) { - $prefix = $match[1]; - $path = substr($path, strlen($prefix)); - } - - if (substr($path, 0, 1) === '/') { - $absolute = true; - $path = substr($path, 1); - } - - $up = false; - foreach (explode('/', $path) as $chunk) { - if ('..' === $chunk && ($absolute || $up)) { - array_pop($parts); - $up = !(empty($parts) || '..' === end($parts)); - } elseif ('.' !== $chunk && '' !== $chunk) { - $parts[] = $chunk; - $up = '..' !== $chunk; - } - } - - return $prefix . ($absolute ? '/' : '') . implode('/', $parts); - } - - protected function createMap($path, $namespace = null) - { - if (is_string($path)) { - if (is_file($path)) { - $path = [new \SplFileInfo($path)]; - } elseif (is_dir($path)) { - - $objects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST); - - $path = []; - - /** @var \SplFileInfo $object */ - foreach ($objects as $object) { - if ($object->isFile() && $object->getExtension() == 'php') { - $path[] = $object; - } - } - } else { - throw new \RuntimeException( - 'Could not scan for classes inside "' . $path . - '" which does not appear to be a file nor a folder' - ); - } - } - - $map = []; - - /** @var \SplFileInfo $file */ - foreach ($path as $file) { - $filePath = $file->getRealPath(); - - if (pathinfo($filePath, PATHINFO_EXTENSION) != 'php') { - continue; - } - - $classes = $this->findClasses($filePath); - - foreach ($classes as $class) { - if (null !== $namespace && 0 !== strpos($class, $namespace)) { - continue; - } - - if (!isset($map[$class])) { - $map[$class] = $filePath; - } elseif ($map[$class] !== $filePath && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($map[$class] . ' ' . $filePath, '\\', '/'))) { - $this->output->writeln( - 'Warning: Ambiguous class resolution, "' . $class . '"' . - ' was found in both "' . $map[$class] . '" and "' . $filePath . '", the first will be used.' - ); - } - } - } - - return $map; - } - - protected function findClasses($path) - { - $extraTypes = '|trait'; - - $contents = @php_strip_whitespace($path); - if (!$contents) { - if (!file_exists($path)) { - $message = 'File at "%s" does not exist, check your classmap definitions'; - } elseif (!is_readable($path)) { - $message = 'File at "%s" is not readable, check its permissions'; - } elseif ('' === trim(file_get_contents($path))) { - return []; - } else { - $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted'; - } - $error = error_get_last(); - if (isset($error['message'])) { - $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message']; - } - throw new \RuntimeException(sprintf($message, $path)); - } - - if (!preg_match('{\b(?:class|interface' . $extraTypes . ')\s}i', $contents)) { - return []; - } - - // strip heredocs/nowdocs - $contents = preg_replace('{<<<\s*(\'?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)\\2(?=\r\n|\n|\r|;)}s', 'null', $contents); - // strip strings - $contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents); - // strip leading non-php code if needed - if (substr($contents, 0, 2) !== '.+<\?}s', '?>'); - if (false !== $pos && false === strpos(substr($contents, $pos), '])(?Pclass|interface' . $extraTypes . ') \s++ (?P[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+) - | \b(?])(?Pnamespace) (?P\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;] - ) - }ix', $contents, $matches); - - $classes = []; - $namespace = ''; - - for ($i = 0, $len = count($matches['type']); $i < $len; $i++) { - if (!empty($matches['ns'][$i])) { - $namespace = str_replace([' ', "\t", "\r", "\n"], '', $matches['nsname'][$i]) . '\\'; - } else { - $name = $matches['name'][$i]; - if ($name[0] === ':') { - $name = 'xhp' . substr(str_replace(['-', ':'], ['_', '__'], $name), 1); - } elseif ($matches['type'][$i] === 'enum') { - $name = rtrim($name, ':'); - } - $classes[] = ltrim($namespace . $name, '\\'); - } - } - - return $classes; - } - -} diff --git a/thinkphp/library/think/console/command/optimize/Config.php b/thinkphp/library/think/console/command/optimize/Config.php deleted file mode 100755 index 59c69a8..0000000 --- a/thinkphp/library/think/console/command/optimize/Config.php +++ /dev/null @@ -1,93 +0,0 @@ - -// +---------------------------------------------------------------------- -namespace think\console\command\optimize; - -use think\Config as ThinkConfig; -use think\console\Command; -use think\console\Input; -use think\console\input\Argument; -use think\console\Output; - -class Config extends Command -{ - /** @var Output */ - protected $output; - - protected function configure() - { - $this->setName('optimize:config') - ->addArgument('module', Argument::OPTIONAL, 'Build module config cache .') - ->setDescription('Build config and common file cache.'); - } - - protected function execute(Input $input, Output $output) - { - if ($input->getArgument('module')) { - $module = $input->getArgument('module') . DS; - } else { - $module = ''; - } - - $content = 'buildCacheContent($module); - - if (!is_dir(RUNTIME_PATH . $module)) { - @mkdir(RUNTIME_PATH . $module, 0755, true); - } - - file_put_contents(RUNTIME_PATH . $module . 'init' . EXT, $content); - - $output->writeln('Succeed!'); - } - - protected function buildCacheContent($module) - { - $content = ''; - $path = realpath(APP_PATH . $module) . DS; - - if ($module) { - // 加载模块配置 - $config = ThinkConfig::load(CONF_PATH . $module . 'config' . CONF_EXT); - - // 读取数据库配置文件 - $filename = CONF_PATH . $module . 'database' . CONF_EXT; - ThinkConfig::load($filename, 'database'); - - // 加载应用状态配置 - if ($config['app_status']) { - $config = ThinkConfig::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); - } - // 读取扩展配置文件 - if (is_dir(CONF_PATH . $module . 'extra')) { - $dir = CONF_PATH . $module . 'extra'; - $files = scandir($dir); - foreach ($files as $file) { - if (strpos($file, CONF_EXT)) { - $filename = $dir . DS . $file; - ThinkConfig::load($filename, pathinfo($file, PATHINFO_FILENAME)); - } - } - } - } - - // 加载行为扩展文件 - if (is_file(CONF_PATH . $module . 'tags' . EXT)) { - $content .= '\think\Hook::import(' . (var_export(include CONF_PATH . $module . 'tags' . EXT, true)) . ');' . PHP_EOL; - } - - // 加载公共文件 - if (is_file($path . 'common' . EXT)) { - $content .= substr(php_strip_whitespace($path . 'common' . EXT), 5) . PHP_EOL; - } - - $content .= '\think\Config::set(' . var_export(ThinkConfig::get(), true) . ');'; - return $content; - } -} diff --git a/thinkphp/library/think/console/command/optimize/Route.php b/thinkphp/library/think/console/command/optimize/Route.php deleted file mode 100755 index 6da1d9a..0000000 --- a/thinkphp/library/think/console/command/optimize/Route.php +++ /dev/null @@ -1,75 +0,0 @@ - -// +---------------------------------------------------------------------- -namespace think\console\command\optimize; - -use think\console\Command; -use think\console\Input; -use think\console\Output; - -class Route extends Command -{ - /** @var Output */ - protected $output; - - protected function configure() - { - $this->setName('optimize:route') - ->setDescription('Build route cache.'); - } - - protected function execute(Input $input, Output $output) - { - - if (!is_dir(RUNTIME_PATH)) { - @mkdir(RUNTIME_PATH, 0755, true); - } - - file_put_contents(RUNTIME_PATH . 'route.php', $this->buildRouteCache()); - $output->writeln('Succeed!'); - } - - protected function buildRouteCache() - { - $files = \think\Config::get('route_config_file'); - foreach ($files as $file) { - if (is_file(CONF_PATH . $file . CONF_EXT)) { - $config = include CONF_PATH . $file . CONF_EXT; - if (is_array($config)) { - \think\Route::import($config); - } - } - } - $rules = \think\Route::rules(true); - array_walk_recursive($rules, [$this, 'buildClosure']); - $content = 'getStartLine(); - $endLine = $reflection->getEndLine(); - $file = $reflection->getFileName(); - $item = file($file); - $content = ''; - for ($i = $startLine - 1; $i <= $endLine - 1; $i++) { - $content .= $item[$i]; - } - $start = strpos($content, 'function'); - $end = strrpos($content, '}'); - $value = '[__start__' . substr($content, $start, $end - $start + 1) . '__end__]'; - } - } -} diff --git a/thinkphp/library/think/console/command/optimize/Schema.php b/thinkphp/library/think/console/command/optimize/Schema.php deleted file mode 100755 index 3353424..0000000 --- a/thinkphp/library/think/console/command/optimize/Schema.php +++ /dev/null @@ -1,118 +0,0 @@ - -// +---------------------------------------------------------------------- -namespace think\console\command\optimize; - -use think\App; -use think\console\Command; -use think\console\Input; -use think\console\input\Option; -use think\console\Output; -use think\Db; - -class Schema extends Command -{ - /** @var Output */ - protected $output; - - protected function configure() - { - $this->setName('optimize:schema') - ->addOption('config', null, Option::VALUE_REQUIRED, 'db config .') - ->addOption('db', null, Option::VALUE_REQUIRED, 'db name .') - ->addOption('table', null, Option::VALUE_REQUIRED, 'table name .') - ->addOption('module', null, Option::VALUE_REQUIRED, 'module name .') - ->setDescription('Build database schema cache.'); - } - - protected function execute(Input $input, Output $output) - { - if (!is_dir(RUNTIME_PATH . 'schema')) { - @mkdir(RUNTIME_PATH . 'schema', 0755, true); - } - $config = []; - if ($input->hasOption('config')) { - $config = $input->getOption('config'); - } - if ($input->hasOption('module')) { - $module = $input->getOption('module'); - // 读取模型 - $path = APP_PATH . $module . DS . 'model'; - $list = is_dir($path) ? scandir($path) : []; - $app = App::$namespace; - foreach ($list as $file) { - if (0 === strpos($file, '.')) { - continue; - } - $class = '\\' . $app . '\\' . $module . '\\model\\' . pathinfo($file, PATHINFO_FILENAME); - $this->buildModelSchema($class); - } - $output->writeln('Succeed!'); - return; - } elseif ($input->hasOption('table')) { - $table = $input->getOption('table'); - if (!strpos($table, '.')) { - $dbName = Db::connect($config)->getConfig('database'); - } - $tables[] = $table; - } elseif ($input->hasOption('db')) { - $dbName = $input->getOption('db'); - $tables = Db::connect($config)->getTables($dbName); - } elseif (!\think\Config::get('app_multi_module')) { - $app = App::$namespace; - $path = APP_PATH . 'model'; - $list = is_dir($path) ? scandir($path) : []; - foreach ($list as $file) { - if (0 === strpos($file, '.')) { - continue; - } - $class = '\\' . $app . '\\model\\' . pathinfo($file, PATHINFO_FILENAME); - $this->buildModelSchema($class); - } - $output->writeln('Succeed!'); - return; - } else { - $tables = Db::connect($config)->getTables(); - } - - $db = isset($dbName) ? $dbName . '.' : ''; - $this->buildDataBaseSchema($tables, $db, $config); - - $output->writeln('Succeed!'); - } - - protected function buildModelSchema($class) - { - $reflect = new \ReflectionClass($class); - if (!$reflect->isAbstract() && $reflect->isSubclassOf('\think\Model')) { - $table = $class::getTable(); - $dbName = $class::getConfig('database'); - $content = 'getFields($table); - $content .= var_export($info, true) . ';'; - file_put_contents(RUNTIME_PATH . 'schema' . DS . $dbName . '.' . $table . EXT, $content); - } - } - - protected function buildDataBaseSchema($tables, $db, $config) - { - if ('' == $db) { - $dbName = Db::connect($config)->getConfig('database') . '.'; - } else { - $dbName = $db; - } - foreach ($tables as $table) { - $content = 'getFields($db . $table); - $content .= var_export($info, true) . ';'; - file_put_contents(RUNTIME_PATH . 'schema' . DS . $dbName . $table . EXT, $content); - } - } -} diff --git a/thinkphp/library/think/console/input/Argument.php b/thinkphp/library/think/console/input/Argument.php deleted file mode 100755 index 16223bb..0000000 --- a/thinkphp/library/think/console/input/Argument.php +++ /dev/null @@ -1,115 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\input; - -class Argument -{ - - const REQUIRED = 1; - const OPTIONAL = 2; - const IS_ARRAY = 4; - - private $name; - private $mode; - private $default; - private $description; - - /** - * 构造方法 - * @param string $name 参数名 - * @param int $mode 参数类型: self::REQUIRED 或者 self::OPTIONAL - * @param string $description 描述 - * @param mixed $default 默认值 (仅 self::OPTIONAL 类型有效) - * @throws \InvalidArgumentException - */ - public function __construct($name, $mode = null, $description = '', $default = null) - { - if (null === $mode) { - $mode = self::OPTIONAL; - } elseif (!is_int($mode) || $mode > 7 || $mode < 1) { - throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode)); - } - - $this->name = $name; - $this->mode = $mode; - $this->description = $description; - - $this->setDefault($default); - } - - /** - * 获取参数名 - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * 是否必须 - * @return bool - */ - public function isRequired() - { - return self::REQUIRED === (self::REQUIRED & $this->mode); - } - - /** - * 该参数是否接受数组 - * @return bool - */ - public function isArray() - { - return self::IS_ARRAY === (self::IS_ARRAY & $this->mode); - } - - /** - * 设置默认值 - * @param mixed $default 默认值 - * @throws \LogicException - */ - public function setDefault($default = null) - { - if (self::REQUIRED === $this->mode && null !== $default) { - throw new \LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); - } - - if ($this->isArray()) { - if (null === $default) { - $default = []; - } elseif (!is_array($default)) { - throw new \LogicException('A default value for an array argument must be an array.'); - } - } - - $this->default = $default; - } - - /** - * 获取默认值 - * @return mixed - */ - public function getDefault() - { - return $this->default; - } - - /** - * 获取描述 - * @return string - */ - public function getDescription() - { - return $this->description; - } -} diff --git a/thinkphp/library/think/console/input/Definition.php b/thinkphp/library/think/console/input/Definition.php deleted file mode 100755 index c71977e..0000000 --- a/thinkphp/library/think/console/input/Definition.php +++ /dev/null @@ -1,375 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\input; - -class Definition -{ - - /** - * @var Argument[] - */ - private $arguments; - - private $requiredCount; - private $hasAnArrayArgument = false; - private $hasOptional; - - /** - * @var Option[] - */ - private $options; - private $shortcuts; - - /** - * 构造方法 - * @param array $definition - * @api - */ - public function __construct(array $definition = []) - { - $this->setDefinition($definition); - } - - /** - * 设置指令的定义 - * @param array $definition 定义的数组 - */ - public function setDefinition(array $definition) - { - $arguments = []; - $options = []; - foreach ($definition as $item) { - if ($item instanceof Option) { - $options[] = $item; - } else { - $arguments[] = $item; - } - } - - $this->setArguments($arguments); - $this->setOptions($options); - } - - /** - * 设置参数 - * @param Argument[] $arguments 参数数组 - */ - public function setArguments($arguments = []) - { - $this->arguments = []; - $this->requiredCount = 0; - $this->hasOptional = false; - $this->hasAnArrayArgument = false; - $this->addArguments($arguments); - } - - /** - * 添加参数 - * @param Argument[] $arguments 参数数组 - * @api - */ - public function addArguments($arguments = []) - { - if (null !== $arguments) { - foreach ($arguments as $argument) { - $this->addArgument($argument); - } - } - } - - /** - * 添加一个参数 - * @param Argument $argument 参数 - * @throws \LogicException - */ - public function addArgument(Argument $argument) - { - if (isset($this->arguments[$argument->getName()])) { - throw new \LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName())); - } - - if ($this->hasAnArrayArgument) { - throw new \LogicException('Cannot add an argument after an array argument.'); - } - - if ($argument->isRequired() && $this->hasOptional) { - throw new \LogicException('Cannot add a required argument after an optional one.'); - } - - if ($argument->isArray()) { - $this->hasAnArrayArgument = true; - } - - if ($argument->isRequired()) { - ++$this->requiredCount; - } else { - $this->hasOptional = true; - } - - $this->arguments[$argument->getName()] = $argument; - } - - /** - * 根据名称或者位置获取参数 - * @param string|int $name 参数名或者位置 - * @return Argument 参数 - * @throws \InvalidArgumentException - */ - public function getArgument($name) - { - if (!$this->hasArgument($name)) { - throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments; - - return $arguments[$name]; - } - - /** - * 根据名称或位置检查是否具有某个参数 - * @param string|int $name 参数名或者位置 - * @return bool - * @api - */ - public function hasArgument($name) - { - $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments; - - return isset($arguments[$name]); - } - - /** - * 获取所有的参数 - * @return Argument[] 参数数组 - */ - public function getArguments() - { - return $this->arguments; - } - - /** - * 获取参数数量 - * @return int - */ - public function getArgumentCount() - { - return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments); - } - - /** - * 获取必填的参数的数量 - * @return int - */ - public function getArgumentRequiredCount() - { - return $this->requiredCount; - } - - /** - * 获取参数默认值 - * @return array - */ - public function getArgumentDefaults() - { - $values = []; - foreach ($this->arguments as $argument) { - $values[$argument->getName()] = $argument->getDefault(); - } - - return $values; - } - - /** - * 设置选项 - * @param Option[] $options 选项数组 - */ - public function setOptions($options = []) - { - $this->options = []; - $this->shortcuts = []; - $this->addOptions($options); - } - - /** - * 添加选项 - * @param Option[] $options 选项数组 - * @api - */ - public function addOptions($options = []) - { - foreach ($options as $option) { - $this->addOption($option); - } - } - - /** - * 添加一个选项 - * @param Option $option 选项 - * @throws \LogicException - * @api - */ - public function addOption(Option $option) - { - if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { - throw new \LogicException(sprintf('An option named "%s" already exists.', $option->getName())); - } - - if ($option->getShortcut()) { - foreach (explode('|', $option->getShortcut()) as $shortcut) { - if (isset($this->shortcuts[$shortcut]) - && !$option->equals($this->options[$this->shortcuts[$shortcut]]) - ) { - throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut)); - } - } - } - - $this->options[$option->getName()] = $option; - if ($option->getShortcut()) { - foreach (explode('|', $option->getShortcut()) as $shortcut) { - $this->shortcuts[$shortcut] = $option->getName(); - } - } - } - - /** - * 根据名称获取选项 - * @param string $name 选项名 - * @return Option - * @throws \InvalidArgumentException - * @api - */ - public function getOption($name) - { - if (!$this->hasOption($name)) { - throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name)); - } - - return $this->options[$name]; - } - - /** - * 根据名称检查是否有这个选项 - * @param string $name 选项名 - * @return bool - * @api - */ - public function hasOption($name) - { - return isset($this->options[$name]); - } - - /** - * 获取所有选项 - * @return Option[] - * @api - */ - public function getOptions() - { - return $this->options; - } - - /** - * 根据名称检查某个选项是否有短名称 - * @param string $name 短名称 - * @return bool - */ - public function hasShortcut($name) - { - return isset($this->shortcuts[$name]); - } - - /** - * 根据短名称获取选项 - * @param string $shortcut 短名称 - * @return Option - */ - public function getOptionForShortcut($shortcut) - { - return $this->getOption($this->shortcutToName($shortcut)); - } - - /** - * 获取所有选项的默认值 - * @return array - */ - public function getOptionDefaults() - { - $values = []; - foreach ($this->options as $option) { - $values[$option->getName()] = $option->getDefault(); - } - - return $values; - } - - /** - * 根据短名称获取选项名 - * @param string $shortcut 短名称 - * @return string - * @throws \InvalidArgumentException - */ - private function shortcutToName($shortcut) - { - if (!isset($this->shortcuts[$shortcut])) { - throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - return $this->shortcuts[$shortcut]; - } - - /** - * 获取该指令的介绍 - * @param bool $short 是否简洁介绍 - * @return string - */ - public function getSynopsis($short = false) - { - $elements = []; - - if ($short && $this->getOptions()) { - $elements[] = '[options]'; - } elseif (!$short) { - foreach ($this->getOptions() as $option) { - $value = ''; - if ($option->acceptValue()) { - $value = sprintf(' %s%s%s', $option->isValueOptional() ? '[' : '', strtoupper($option->getName()), $option->isValueOptional() ? ']' : ''); - } - - $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : ''; - $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value); - } - } - - if (count($elements) && $this->getArguments()) { - $elements[] = '[--]'; - } - - foreach ($this->getArguments() as $argument) { - $element = '<' . $argument->getName() . '>'; - if (!$argument->isRequired()) { - $element = '[' . $element . ']'; - } elseif ($argument->isArray()) { - $element .= ' (' . $element . ')'; - } - - if ($argument->isArray()) { - $element .= '...'; - } - - $elements[] = $element; - } - - return implode(' ', $elements); - } -} diff --git a/thinkphp/library/think/console/input/Option.php b/thinkphp/library/think/console/input/Option.php deleted file mode 100755 index e5707c9..0000000 --- a/thinkphp/library/think/console/input/Option.php +++ /dev/null @@ -1,190 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\input; - -class Option -{ - - const VALUE_NONE = 1; - const VALUE_REQUIRED = 2; - const VALUE_OPTIONAL = 4; - const VALUE_IS_ARRAY = 8; - - private $name; - private $shortcut; - private $mode; - private $default; - private $description; - - /** - * 构造方法 - * @param string $name 选项名 - * @param string|array $shortcut 短名称,多个用|隔开或者使用数组 - * @param int $mode 选项类型(可选类型为 self::VALUE_*) - * @param string $description 描述 - * @param mixed $default 默认值 (类型为 self::VALUE_REQUIRED 或者 self::VALUE_NONE 的时候必须为null) - * @throws \InvalidArgumentException - */ - public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null) - { - if (0 === strpos($name, '--')) { - $name = substr($name, 2); - } - - if (empty($name)) { - throw new \InvalidArgumentException('An option name cannot be empty.'); - } - - if (empty($shortcut)) { - $shortcut = null; - } - - if (null !== $shortcut) { - if (is_array($shortcut)) { - $shortcut = implode('|', $shortcut); - } - $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-')); - $shortcuts = array_filter($shortcuts); - $shortcut = implode('|', $shortcuts); - - if (empty($shortcut)) { - throw new \InvalidArgumentException('An option shortcut cannot be empty.'); - } - } - - if (null === $mode) { - $mode = self::VALUE_NONE; - } elseif (!is_int($mode) || $mode > 15 || $mode < 1) { - throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode)); - } - - $this->name = $name; - $this->shortcut = $shortcut; - $this->mode = $mode; - $this->description = $description; - - if ($this->isArray() && !$this->acceptValue()) { - throw new \InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.'); - } - - $this->setDefault($default); - } - - /** - * 获取短名称 - * @return string - */ - public function getShortcut() - { - return $this->shortcut; - } - - /** - * 获取选项名 - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * 是否可以设置值 - * @return bool 类型不是 self::VALUE_NONE 的时候返回true,其他均返回false - */ - public function acceptValue() - { - return $this->isValueRequired() || $this->isValueOptional(); - } - - /** - * 是否必须 - * @return bool 类型是 self::VALUE_REQUIRED 的时候返回true,其他均返回false - */ - public function isValueRequired() - { - return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode); - } - - /** - * 是否可选 - * @return bool 类型是 self::VALUE_OPTIONAL 的时候返回true,其他均返回false - */ - public function isValueOptional() - { - return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode); - } - - /** - * 选项值是否接受数组 - * @return bool 类型是 self::VALUE_IS_ARRAY 的时候返回true,其他均返回false - */ - public function isArray() - { - return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); - } - - /** - * 设置默认值 - * @param mixed $default 默认值 - * @throws \LogicException - */ - public function setDefault($default = null) - { - if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { - throw new \LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); - } - - if ($this->isArray()) { - if (null === $default) { - $default = []; - } elseif (!is_array($default)) { - throw new \LogicException('A default value for an array option must be an array.'); - } - } - - $this->default = $this->acceptValue() ? $default : false; - } - - /** - * 获取默认值 - * @return mixed - */ - public function getDefault() - { - return $this->default; - } - - /** - * 获取描述文字 - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * 检查所给选项是否是当前这个 - * @param Option $option - * @return bool - */ - public function equals(Option $option) - { - return $option->getName() === $this->getName() - && $option->getShortcut() === $this->getShortcut() - && $option->getDefault() === $this->getDefault() - && $option->isArray() === $this->isArray() - && $option->isValueRequired() === $this->isValueRequired() - && $option->isValueOptional() === $this->isValueOptional(); - } -} diff --git a/thinkphp/library/think/console/output/Ask.php b/thinkphp/library/think/console/output/Ask.php deleted file mode 100755 index 3933eb2..0000000 --- a/thinkphp/library/think/console/output/Ask.php +++ /dev/null @@ -1,340 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output; - -use think\console\Input; -use think\console\Output; -use think\console\output\question\Choice; -use think\console\output\question\Confirmation; - -class Ask -{ - private static $stty; - - private static $shell; - - /** @var Input */ - protected $input; - - /** @var Output */ - protected $output; - - /** @var Question */ - protected $question; - - public function __construct(Input $input, Output $output, Question $question) - { - $this->input = $input; - $this->output = $output; - $this->question = $question; - } - - public function run() - { - if (!$this->input->isInteractive()) { - return $this->question->getDefault(); - } - - if (!$this->question->getValidator()) { - return $this->doAsk(); - } - - $that = $this; - - $interviewer = function () use ($that) { - return $that->doAsk(); - }; - - return $this->validateAttempts($interviewer); - } - - protected function doAsk() - { - $this->writePrompt(); - - $inputStream = STDIN; - $autocomplete = $this->question->getAutocompleterValues(); - - if (null === $autocomplete || !$this->hasSttyAvailable()) { - $ret = false; - if ($this->question->isHidden()) { - try { - $ret = trim($this->getHiddenResponse($inputStream)); - } catch (\RuntimeException $e) { - if (!$this->question->isHiddenFallback()) { - throw $e; - } - } - } - - if (false === $ret) { - $ret = fgets($inputStream, 4096); - if (false === $ret) { - throw new \RuntimeException('Aborted'); - } - $ret = trim($ret); - } - } else { - $ret = trim($this->autocomplete($inputStream)); - } - - $ret = strlen($ret) > 0 ? $ret : $this->question->getDefault(); - - if ($normalizer = $this->question->getNormalizer()) { - return $normalizer($ret); - } - - return $ret; - } - - private function autocomplete($inputStream) - { - $autocomplete = $this->question->getAutocompleterValues(); - $ret = ''; - - $i = 0; - $ofs = -1; - $matches = $autocomplete; - $numMatches = count($matches); - - $sttyMode = shell_exec('stty -g'); - - shell_exec('stty -icanon -echo'); - - while (!feof($inputStream)) { - $c = fread($inputStream, 1); - - if ("\177" === $c) { - if (0 === $numMatches && 0 !== $i) { - --$i; - $this->output->write("\033[1D"); - } - - if ($i === 0) { - $ofs = -1; - $matches = $autocomplete; - $numMatches = count($matches); - } else { - $numMatches = 0; - } - - $ret = substr($ret, 0, $i); - } elseif ("\033" === $c) { - $c .= fread($inputStream, 2); - - if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { - if ('A' === $c[2] && -1 === $ofs) { - $ofs = 0; - } - - if (0 === $numMatches) { - continue; - } - - $ofs += ('A' === $c[2]) ? -1 : 1; - $ofs = ($numMatches + $ofs) % $numMatches; - } - } elseif (ord($c) < 32) { - if ("\t" === $c || "\n" === $c) { - if ($numMatches > 0 && -1 !== $ofs) { - $ret = $matches[$ofs]; - $this->output->write(substr($ret, $i)); - $i = strlen($ret); - } - - if ("\n" === $c) { - $this->output->write($c); - break; - } - - $numMatches = 0; - } - - continue; - } else { - $this->output->write($c); - $ret .= $c; - ++$i; - - $numMatches = 0; - $ofs = 0; - - foreach ($autocomplete as $value) { - if (0 === strpos($value, $ret) && $i !== strlen($value)) { - $matches[$numMatches++] = $value; - } - } - } - - $this->output->write("\033[K"); - - if ($numMatches > 0 && -1 !== $ofs) { - $this->output->write("\0337"); - $this->output->highlight(substr($matches[$ofs], $i)); - $this->output->write("\0338"); - } - } - - shell_exec(sprintf('stty %s', $sttyMode)); - - return $ret; - } - - protected function getHiddenResponse($inputStream) - { - if ('\\' === DIRECTORY_SEPARATOR) { - $exe = __DIR__ . '/../bin/hiddeninput.exe'; - - $value = rtrim(shell_exec($exe)); - $this->output->writeln(''); - - if (isset($tmpExe)) { - unlink($tmpExe); - } - - return $value; - } - - if ($this->hasSttyAvailable()) { - $sttyMode = shell_exec('stty -g'); - - shell_exec('stty -echo'); - $value = fgets($inputStream, 4096); - shell_exec(sprintf('stty %s', $sttyMode)); - - if (false === $value) { - throw new \RuntimeException('Aborted'); - } - - $value = trim($value); - $this->output->writeln(''); - - return $value; - } - - if (false !== $shell = $this->getShell()) { - $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword'; - $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); - $value = rtrim(shell_exec($command)); - $this->output->writeln(''); - - return $value; - } - - throw new \RuntimeException('Unable to hide the response.'); - } - - protected function validateAttempts($interviewer) - { - /** @var \Exception $error */ - $error = null; - $attempts = $this->question->getMaxAttempts(); - while (null === $attempts || $attempts--) { - if (null !== $error) { - $this->output->error($error->getMessage()); - } - - try { - return call_user_func($this->question->getValidator(), $interviewer()); - } catch (\Exception $error) { - } - } - - throw $error; - } - - /** - * 显示问题的提示信息 - */ - protected function writePrompt() - { - $text = $this->question->getQuestion(); - $default = $this->question->getDefault(); - - switch (true) { - case null === $default: - $text = sprintf(' %s:', $text); - - break; - - case $this->question instanceof Confirmation: - $text = sprintf(' %s (yes/no) [%s]:', $text, $default ? 'yes' : 'no'); - - break; - - case $this->question instanceof Choice && $this->question->isMultiselect(): - $choices = $this->question->getChoices(); - $default = explode(',', $default); - - foreach ($default as $key => $value) { - $default[$key] = $choices[trim($value)]; - } - - $text = sprintf(' %s [%s]:', $text, implode(', ', $default)); - - break; - - case $this->question instanceof Choice: - $choices = $this->question->getChoices(); - $text = sprintf(' %s [%s]:', $text, $choices[$default]); - - break; - - default: - $text = sprintf(' %s [%s]:', $text, $default); - } - - $this->output->writeln($text); - - if ($this->question instanceof Choice) { - $width = max(array_map('strlen', array_keys($this->question->getChoices()))); - - foreach ($this->question->getChoices() as $key => $value) { - $this->output->writeln(sprintf(" [%-${width}s] %s", $key, $value)); - } - } - - $this->output->write(' > '); - } - - private function getShell() - { - if (null !== self::$shell) { - return self::$shell; - } - - self::$shell = false; - - if (file_exists('/usr/bin/env')) { - $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; - foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) { - if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { - self::$shell = $sh; - break; - } - } - } - - return self::$shell; - } - - private function hasSttyAvailable() - { - if (null !== self::$stty) { - return self::$stty; - } - - exec('stty 2>&1', $output, $exitcode); - - return self::$stty = $exitcode === 0; - } -} diff --git a/thinkphp/library/think/console/output/Descriptor.php b/thinkphp/library/think/console/output/Descriptor.php deleted file mode 100755 index 23dc648..0000000 --- a/thinkphp/library/think/console/output/Descriptor.php +++ /dev/null @@ -1,319 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output; - -use think\Console; -use think\console\Command; -use think\console\input\Argument as InputArgument; -use think\console\input\Definition as InputDefinition; -use think\console\input\Option as InputOption; -use think\console\Output; -use think\console\output\descriptor\Console as ConsoleDescription; - -class Descriptor -{ - - /** - * @var Output - */ - protected $output; - - /** - * {@inheritdoc} - */ - public function describe(Output $output, $object, array $options = []) - { - $this->output = $output; - - switch (true) { - case $object instanceof InputArgument: - $this->describeInputArgument($object, $options); - break; - case $object instanceof InputOption: - $this->describeInputOption($object, $options); - break; - case $object instanceof InputDefinition: - $this->describeInputDefinition($object, $options); - break; - case $object instanceof Command: - $this->describeCommand($object, $options); - break; - case $object instanceof Console: - $this->describeConsole($object, $options); - break; - default: - throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object))); - } - } - - /** - * 输出内容 - * @param string $content - * @param bool $decorated - */ - protected function write($content, $decorated = false) - { - $this->output->write($content, false, $decorated ? Output::OUTPUT_NORMAL : Output::OUTPUT_RAW); - } - - /** - * 描述参数 - * @param InputArgument $argument - * @param array $options - * @return void - */ - protected function describeInputArgument(InputArgument $argument, array $options = []) - { - if (null !== $argument->getDefault() - && (!is_array($argument->getDefault()) - || count($argument->getDefault())) - ) { - $default = sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault())); - } else { - $default = ''; - } - - $totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName()); - $spacingWidth = $totalWidth - strlen($argument->getName()) + 2; - - $this->writeText(sprintf(" %s%s%s%s", $argument->getName(), str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + + + 2 spaces - preg_replace('/\s*\R\s*/', PHP_EOL . str_repeat(' ', $totalWidth + 17), $argument->getDescription()), $default), $options); - } - - /** - * 描述选项 - * @param InputOption $option - * @param array $options - * @return void - */ - protected function describeInputOption(InputOption $option, array $options = []) - { - if ($option->acceptValue() && null !== $option->getDefault() - && (!is_array($option->getDefault()) - || count($option->getDefault())) - ) { - $default = sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault())); - } else { - $default = ''; - } - - $value = ''; - if ($option->acceptValue()) { - $value = '=' . strtoupper($option->getName()); - - if ($option->isValueOptional()) { - $value = '[' . $value . ']'; - } - } - - $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions([$option]); - $synopsis = sprintf('%s%s', $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : ' ', sprintf('--%s%s', $option->getName(), $value)); - - $spacingWidth = $totalWidth - strlen($synopsis) + 2; - - $this->writeText(sprintf(" %s%s%s%s%s", $synopsis, str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + + + 2 spaces - preg_replace('/\s*\R\s*/', "\n" . str_repeat(' ', $totalWidth + 17), $option->getDescription()), $default, $option->isArray() ? ' (multiple values allowed)' : ''), $options); - } - - /** - * 描述输入 - * @param InputDefinition $definition - * @param array $options - * @return void - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = []) - { - $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions()); - foreach ($definition->getArguments() as $argument) { - $totalWidth = max($totalWidth, strlen($argument->getName())); - } - - if ($definition->getArguments()) { - $this->writeText('Arguments:', $options); - $this->writeText("\n"); - foreach ($definition->getArguments() as $argument) { - $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth])); - $this->writeText("\n"); - } - } - - if ($definition->getArguments() && $definition->getOptions()) { - $this->writeText("\n"); - } - - if ($definition->getOptions()) { - $laterOptions = []; - - $this->writeText('Options:', $options); - foreach ($definition->getOptions() as $option) { - if (strlen($option->getShortcut()) > 1) { - $laterOptions[] = $option; - continue; - } - $this->writeText("\n"); - $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); - } - foreach ($laterOptions as $option) { - $this->writeText("\n"); - $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); - } - } - } - - /** - * 描述指令 - * @param Command $command - * @param array $options - * @return void - */ - protected function describeCommand(Command $command, array $options = []) - { - $command->getSynopsis(true); - $command->getSynopsis(false); - $command->mergeConsoleDefinition(false); - - $this->writeText('Usage:', $options); - foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) { - $this->writeText("\n"); - $this->writeText(' ' . $usage, $options); - } - $this->writeText("\n"); - - $definition = $command->getNativeDefinition(); - if ($definition->getOptions() || $definition->getArguments()) { - $this->writeText("\n"); - $this->describeInputDefinition($definition, $options); - $this->writeText("\n"); - } - - if ($help = $command->getProcessedHelp()) { - $this->writeText("\n"); - $this->writeText('Help:', $options); - $this->writeText("\n"); - $this->writeText(' ' . str_replace("\n", "\n ", $help), $options); - $this->writeText("\n"); - } - } - - /** - * 描述控制台 - * @param Console $console - * @param array $options - * @return void - */ - protected function describeConsole(Console $console, array $options = []) - { - $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; - $description = new ConsoleDescription($console, $describedNamespace); - - if (isset($options['raw_text']) && $options['raw_text']) { - $width = $this->getColumnWidth($description->getCommands()); - - foreach ($description->getCommands() as $command) { - $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options); - $this->writeText("\n"); - } - } else { - if ('' != $help = $console->getHelp()) { - $this->writeText("$help\n\n", $options); - } - - $this->writeText("Usage:\n", $options); - $this->writeText(" command [options] [arguments]\n\n", $options); - - $this->describeInputDefinition(new InputDefinition($console->getDefinition()->getOptions()), $options); - - $this->writeText("\n"); - $this->writeText("\n"); - - $width = $this->getColumnWidth($description->getCommands()); - - if ($describedNamespace) { - $this->writeText(sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options); - } else { - $this->writeText('Available commands:', $options); - } - - // add commands by namespace - foreach ($description->getNamespaces() as $namespace) { - if (!$describedNamespace && ConsoleDescription::GLOBAL_NAMESPACE !== $namespace['id']) { - $this->writeText("\n"); - $this->writeText(' ' . $namespace['id'] . '', $options); - } - - foreach ($namespace['commands'] as $name) { - $this->writeText("\n"); - $spacingWidth = $width - strlen($name); - $this->writeText(sprintf(" %s%s%s", $name, str_repeat(' ', $spacingWidth), $description->getCommand($name) - ->getDescription()), $options); - } - } - - $this->writeText("\n"); - } - } - - /** - * {@inheritdoc} - */ - private function writeText($content, array $options = []) - { - $this->write(isset($options['raw_text']) - && $options['raw_text'] ? strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : true); - } - - /** - * 格式化 - * @param mixed $default - * @return string - */ - private function formatDefaultValue($default) - { - return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } - - /** - * @param Command[] $commands - * @return int - */ - private function getColumnWidth(array $commands) - { - $width = 0; - foreach ($commands as $command) { - $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width; - } - - return $width + 2; - } - - /** - * @param InputOption[] $options - * @return int - */ - private function calculateTotalWidthForOptions($options) - { - $totalWidth = 0; - foreach ($options as $option) { - $nameLength = 4 + strlen($option->getName()) + 2; // - + shortcut + , + whitespace + name + -- - - if ($option->acceptValue()) { - $valueLength = 1 + strlen($option->getName()); // = + value - $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ] - - $nameLength += $valueLength; - } - $totalWidth = max($totalWidth, $nameLength); - } - - return $totalWidth; - } -} diff --git a/thinkphp/library/think/console/output/Formatter.php b/thinkphp/library/think/console/output/Formatter.php deleted file mode 100755 index f8bee55..0000000 --- a/thinkphp/library/think/console/output/Formatter.php +++ /dev/null @@ -1,198 +0,0 @@ - -// +---------------------------------------------------------------------- -namespace think\console\output; - -use think\console\output\formatter\Stack as StyleStack; -use think\console\output\formatter\Style; - -class Formatter -{ - - private $decorated = false; - private $styles = []; - private $styleStack; - - /** - * 转义 - * @param string $text - * @return string - */ - public static function escape($text) - { - return preg_replace('/([^\\\\]?)setStyle('error', new Style('white', 'red')); - $this->setStyle('info', new Style('green')); - $this->setStyle('comment', new Style('yellow')); - $this->setStyle('question', new Style('black', 'cyan')); - $this->setStyle('highlight', new Style('red')); - $this->setStyle('warning', new Style('black', 'yellow')); - - $this->styleStack = new StyleStack(); - } - - /** - * 设置外观标识 - * @param bool $decorated 是否美化文字 - */ - public function setDecorated($decorated) - { - $this->decorated = (bool) $decorated; - } - - /** - * 获取外观标识 - * @return bool - */ - public function isDecorated() - { - return $this->decorated; - } - - /** - * 添加一个新样式 - * @param string $name 样式名 - * @param Style $style 样式实例 - */ - public function setStyle($name, Style $style) - { - $this->styles[strtolower($name)] = $style; - } - - /** - * 是否有这个样式 - * @param string $name - * @return bool - */ - public function hasStyle($name) - { - return isset($this->styles[strtolower($name)]); - } - - /** - * 获取样式 - * @param string $name - * @return Style - * @throws \InvalidArgumentException - */ - public function getStyle($name) - { - if (!$this->hasStyle($name)) { - throw new \InvalidArgumentException(sprintf('Undefined style: %s', $name)); - } - - return $this->styles[strtolower($name)]; - } - - /** - * 使用所给的样式格式化文字 - * @param string $message 文字 - * @return string - */ - public function format($message) - { - $offset = 0; - $output = ''; - $tagRegex = '[a-z][a-z0-9_=;-]*'; - preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#isx", $message, $matches, PREG_OFFSET_CAPTURE); - foreach ($matches[0] as $i => $match) { - $pos = $match[1]; - $text = $match[0]; - - if (0 != $pos && '\\' == $message[$pos - 1]) { - continue; - } - - $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset)); - $offset = $pos + strlen($text); - - if ($open = '/' != $text[1]) { - $tag = $matches[1][$i][0]; - } else { - $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : ''; - } - - if (!$open && !$tag) { - // - $this->styleStack->pop(); - } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) { - $output .= $this->applyCurrentStyle($text); - } elseif ($open) { - $this->styleStack->push($style); - } else { - $this->styleStack->pop($style); - } - } - - $output .= $this->applyCurrentStyle(substr($message, $offset)); - - return str_replace('\\<', '<', $output); - } - - /** - * @return StyleStack - */ - public function getStyleStack() - { - return $this->styleStack; - } - - /** - * 根据字符串创建新的样式实例 - * @param string $string - * @return Style|bool - */ - private function createStyleFromString($string) - { - if (isset($this->styles[$string])) { - return $this->styles[$string]; - } - - if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) { - return false; - } - - $style = new Style(); - foreach ($matches as $match) { - array_shift($match); - - if ('fg' == $match[0]) { - $style->setForeground($match[1]); - } elseif ('bg' == $match[0]) { - $style->setBackground($match[1]); - } else { - try { - $style->setOption($match[1]); - } catch (\InvalidArgumentException $e) { - return false; - } - } - } - - return $style; - } - - /** - * 从堆栈应用样式到文字 - * @param string $text 文字 - * @return string - */ - private function applyCurrentStyle($text) - { - return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text; - } -} diff --git a/thinkphp/library/think/console/output/Question.php b/thinkphp/library/think/console/output/Question.php deleted file mode 100755 index 03975f2..0000000 --- a/thinkphp/library/think/console/output/Question.php +++ /dev/null @@ -1,211 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output; - -class Question -{ - - private $question; - private $attempts; - private $hidden = false; - private $hiddenFallback = true; - private $autocompleterValues; - private $validator; - private $default; - private $normalizer; - - /** - * 构造方法 - * @param string $question 问题 - * @param mixed $default 默认答案 - */ - public function __construct($question, $default = null) - { - $this->question = $question; - $this->default = $default; - } - - /** - * 获取问题 - * @return string - */ - public function getQuestion() - { - return $this->question; - } - - /** - * 获取默认答案 - * @return mixed - */ - public function getDefault() - { - return $this->default; - } - - /** - * 是否隐藏答案 - * @return bool - */ - public function isHidden() - { - return $this->hidden; - } - - /** - * 隐藏答案 - * @param bool $hidden - * @return Question - */ - public function setHidden($hidden) - { - if ($this->autocompleterValues) { - throw new \LogicException('A hidden question cannot use the autocompleter.'); - } - - $this->hidden = (bool) $hidden; - - return $this; - } - - /** - * 不能被隐藏是否撤销 - * @return bool - */ - public function isHiddenFallback() - { - return $this->hiddenFallback; - } - - /** - * 设置不能被隐藏的时候的操作 - * @param bool $fallback - * @return Question - */ - public function setHiddenFallback($fallback) - { - $this->hiddenFallback = (bool) $fallback; - - return $this; - } - - /** - * 获取自动完成 - * @return null|array|\Traversable - */ - public function getAutocompleterValues() - { - return $this->autocompleterValues; - } - - /** - * 设置自动完成的值 - * @param null|array|\Traversable $values - * @return Question - * @throws \InvalidArgumentException - * @throws \LogicException - */ - public function setAutocompleterValues($values) - { - if (is_array($values) && $this->isAssoc($values)) { - $values = array_merge(array_keys($values), array_values($values)); - } - - if (null !== $values && !is_array($values)) { - if (!$values instanceof \Traversable || $values instanceof \Countable) { - throw new \InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.'); - } - } - - if ($this->hidden) { - throw new \LogicException('A hidden question cannot use the autocompleter.'); - } - - $this->autocompleterValues = $values; - - return $this; - } - - /** - * 设置答案的验证器 - * @param null|callable $validator - * @return Question The current instance - */ - public function setValidator($validator) - { - $this->validator = $validator; - - return $this; - } - - /** - * 获取验证器 - * @return null|callable - */ - public function getValidator() - { - return $this->validator; - } - - /** - * 设置最大重试次数 - * @param null|int $attempts - * @return Question - * @throws \InvalidArgumentException - */ - public function setMaxAttempts($attempts) - { - if (null !== $attempts && $attempts < 1) { - throw new \InvalidArgumentException('Maximum number of attempts must be a positive value.'); - } - - $this->attempts = $attempts; - - return $this; - } - - /** - * 获取最大重试次数 - * @return null|int - */ - public function getMaxAttempts() - { - return $this->attempts; - } - - /** - * 设置响应的回调 - * @param string|\Closure $normalizer - * @return Question - */ - public function setNormalizer($normalizer) - { - $this->normalizer = $normalizer; - - return $this; - } - - /** - * 获取响应回调 - * The normalizer can ba a callable (a string), a closure or a class implementing __invoke. - * @return string|\Closure - */ - public function getNormalizer() - { - return $this->normalizer; - } - - protected function isAssoc($array) - { - return (bool) count(array_filter(array_keys($array), 'is_string')); - } -} diff --git a/thinkphp/library/think/console/output/descriptor/Console.php b/thinkphp/library/think/console/output/descriptor/Console.php deleted file mode 100755 index 4648b68..0000000 --- a/thinkphp/library/think/console/output/descriptor/Console.php +++ /dev/null @@ -1,149 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\descriptor; - -use think\Console as ThinkConsole; -use think\console\Command; - -class Console -{ - - const GLOBAL_NAMESPACE = '_global'; - - /** - * @var ThinkConsole - */ - private $console; - - /** - * @var null|string - */ - private $namespace; - - /** - * @var array - */ - private $namespaces; - - /** - * @var Command[] - */ - private $commands; - - /** - * @var Command[] - */ - private $aliases; - - /** - * 构造方法 - * @param ThinkConsole $console - * @param string|null $namespace - */ - public function __construct(ThinkConsole $console, $namespace = null) - { - $this->console = $console; - $this->namespace = $namespace; - } - - /** - * @return array - */ - public function getNamespaces() - { - if (null === $this->namespaces) { - $this->inspectConsole(); - } - - return $this->namespaces; - } - - /** - * @return Command[] - */ - public function getCommands() - { - if (null === $this->commands) { - $this->inspectConsole(); - } - - return $this->commands; - } - - /** - * @param string $name - * @return Command - * @throws \InvalidArgumentException - */ - public function getCommand($name) - { - if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) { - throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name)); - } - - return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name]; - } - - private function inspectConsole() - { - $this->commands = []; - $this->namespaces = []; - - $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null); - foreach ($this->sortCommands($all) as $namespace => $commands) { - $names = []; - - /** @var Command $command */ - foreach ($commands as $name => $command) { - if (!$command->getName()) { - continue; - } - - if ($command->getName() === $name) { - $this->commands[$name] = $command; - } else { - $this->aliases[$name] = $command; - } - - $names[] = $name; - } - - $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names]; - } - } - - /** - * @param array $commands - * @return array - */ - private function sortCommands(array $commands) - { - $namespacedCommands = []; - foreach ($commands as $name => $command) { - $key = $this->console->extractNamespace($name, 1); - if (!$key) { - $key = self::GLOBAL_NAMESPACE; - } - - $namespacedCommands[$key][$name] = $command; - } - ksort($namespacedCommands); - - foreach ($namespacedCommands as &$commandsSet) { - ksort($commandsSet); - } - // unset reference to keep scope clear - unset($commandsSet); - - return $namespacedCommands; - } -} diff --git a/thinkphp/library/think/console/output/driver/Buffer.php b/thinkphp/library/think/console/output/driver/Buffer.php deleted file mode 100755 index c77a2ec..0000000 --- a/thinkphp/library/think/console/output/driver/Buffer.php +++ /dev/null @@ -1,52 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\driver; - -use think\console\Output; - -class Buffer -{ - /** - * @var string - */ - private $buffer = ''; - - public function __construct(Output $output) - { - // do nothing - } - - public function fetch() - { - $content = $this->buffer; - $this->buffer = ''; - return $content; - } - - public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL) - { - $messages = (array) $messages; - - foreach ($messages as $message) { - $this->buffer .= $message; - } - if ($newline) { - $this->buffer .= "\n"; - } - } - - public function renderException(\Exception $e) - { - // do nothing - } - -} diff --git a/thinkphp/library/think/console/output/driver/Console.php b/thinkphp/library/think/console/output/driver/Console.php deleted file mode 100755 index 8f29fd0..0000000 --- a/thinkphp/library/think/console/output/driver/Console.php +++ /dev/null @@ -1,373 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\driver; - -use think\console\Output; -use think\console\output\Formatter; - -class Console -{ - - /** @var Resource */ - private $stdout; - - /** @var Formatter */ - private $formatter; - - private $terminalDimensions; - - /** @var Output */ - private $output; - - public function __construct(Output $output) - { - $this->output = $output; - $this->formatter = new Formatter(); - $this->stdout = $this->openOutputStream(); - $decorated = $this->hasColorSupport($this->stdout); - $this->formatter->setDecorated($decorated); - } - - public function getFormatter() - { - return $this->formatter; - } - - public function setDecorated($decorated) - { - $this->formatter->setDecorated($decorated); - } - - public function write($messages, $newline = false, $type = Output::OUTPUT_NORMAL, $stream = null) - { - if (Output::VERBOSITY_QUIET === $this->output->getVerbosity()) { - return; - } - - $messages = (array) $messages; - - foreach ($messages as $message) { - switch ($type) { - case Output::OUTPUT_NORMAL: - $message = $this->formatter->format($message); - break; - case Output::OUTPUT_RAW: - break; - case Output::OUTPUT_PLAIN: - $message = strip_tags($this->formatter->format($message)); - break; - default: - throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type)); - } - - $this->doWrite($message, $newline, $stream); - } - } - - public function renderException(\Exception $e) - { - $stderr = $this->openErrorStream(); - $decorated = $this->hasColorSupport($stderr); - $this->formatter->setDecorated($decorated); - - do { - $title = sprintf(' [%s] ', get_class($e)); - - $len = $this->stringWidth($title); - - $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX; - - if (defined('HHVM_VERSION') && $width > 1 << 31) { - $width = 1 << 31; - } - $lines = []; - foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) { - foreach ($this->splitStringByWidth($line, $width - 4) as $line) { - - $lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $line)) + 4; - $lines[] = [$line, $lineLength]; - - $len = max($lineLength, $len); - } - } - - $messages = ['', '']; - $messages[] = $emptyLine = sprintf('%s', str_repeat(' ', $len)); - $messages[] = sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))); - foreach ($lines as $line) { - $messages[] = sprintf(' %s %s', $line[0], str_repeat(' ', $len - $line[1])); - } - $messages[] = $emptyLine; - $messages[] = ''; - $messages[] = ''; - - $this->write($messages, true, Output::OUTPUT_NORMAL, $stderr); - - if (Output::VERBOSITY_VERBOSE <= $this->output->getVerbosity()) { - $this->write('Exception trace:', true, Output::OUTPUT_NORMAL, $stderr); - - // exception related properties - $trace = $e->getTrace(); - array_unshift($trace, [ - 'function' => '', - 'file' => $e->getFile() !== null ? $e->getFile() : 'n/a', - 'line' => $e->getLine() !== null ? $e->getLine() : 'n/a', - 'args' => [], - ]); - - for ($i = 0, $count = count($trace); $i < $count; ++$i) { - $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : ''; - $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : ''; - $function = $trace[$i]['function']; - $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a'; - $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; - - $this->write(sprintf(' %s%s%s() at %s:%s', $class, $type, $function, $file, $line), true, Output::OUTPUT_NORMAL, $stderr); - } - - $this->write('', true, Output::OUTPUT_NORMAL, $stderr); - $this->write('', true, Output::OUTPUT_NORMAL, $stderr); - } - } while ($e = $e->getPrevious()); - - } - - /** - * 获取终端宽度 - * @return int|null - */ - protected function getTerminalWidth() - { - $dimensions = $this->getTerminalDimensions(); - - return $dimensions[0]; - } - - /** - * 获取终端高度 - * @return int|null - */ - protected function getTerminalHeight() - { - $dimensions = $this->getTerminalDimensions(); - - return $dimensions[1]; - } - - /** - * 获取当前终端的尺寸 - * @return array - */ - public function getTerminalDimensions() - { - if ($this->terminalDimensions) { - return $this->terminalDimensions; - } - - if ('\\' === DS) { - if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) { - return [(int) $matches[1], (int) $matches[2]]; - } - if (preg_match('/^(\d+)x(\d+)$/', $this->getMode(), $matches)) { - return [(int) $matches[1], (int) $matches[2]]; - } - } - - if ($sttyString = $this->getSttyColumns()) { - if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { - return [(int) $matches[2], (int) $matches[1]]; - } - if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) { - return [(int) $matches[2], (int) $matches[1]]; - } - } - - return [null, null]; - } - - /** - * 获取stty列数 - * @return string - */ - private function getSttyColumns() - { - if (!function_exists('proc_open')) { - return; - } - - $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; - $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); - if (is_resource($process)) { - $info = stream_get_contents($pipes[1]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - - return $info; - } - return; - } - - /** - * 获取终端模式 - * @return string x 或 null - */ - private function getMode() - { - if (!function_exists('proc_open')) { - return; - } - - $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; - $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); - if (is_resource($process)) { - $info = stream_get_contents($pipes[1]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - - if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { - return $matches[2] . 'x' . $matches[1]; - } - } - return; - } - - private function stringWidth($string) - { - if (!function_exists('mb_strwidth')) { - return strlen($string); - } - - if (false === $encoding = mb_detect_encoding($string)) { - return strlen($string); - } - - return mb_strwidth($string, $encoding); - } - - private function splitStringByWidth($string, $width) - { - if (!function_exists('mb_strwidth')) { - return str_split($string, $width); - } - - if (false === $encoding = mb_detect_encoding($string)) { - return str_split($string, $width); - } - - $utf8String = mb_convert_encoding($string, 'utf8', $encoding); - $lines = []; - $line = ''; - foreach (preg_split('//u', $utf8String) as $char) { - if (mb_strwidth($line . $char, 'utf8') <= $width) { - $line .= $char; - continue; - } - $lines[] = str_pad($line, $width); - $line = $char; - } - if (strlen($line)) { - $lines[] = count($lines) ? str_pad($line, $width) : $line; - } - - mb_convert_variables($encoding, 'utf8', $lines); - - return $lines; - } - - private function isRunningOS400() - { - $checks = [ - function_exists('php_uname') ? php_uname('s') : '', - getenv('OSTYPE'), - PHP_OS, - ]; - return false !== stripos(implode(';', $checks), 'OS400'); - } - - /** - * 当前环境是否支持写入控制台输出到stdout. - * - * @return bool - */ - protected function hasStdoutSupport() - { - return false === $this->isRunningOS400(); - } - - /** - * 当前环境是否支持写入控制台输出到stderr. - * - * @return bool - */ - protected function hasStderrSupport() - { - return false === $this->isRunningOS400(); - } - - /** - * @return resource - */ - private function openOutputStream() - { - if (!$this->hasStdoutSupport()) { - return fopen('php://output', 'w'); - } - return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w'); - } - - /** - * @return resource - */ - private function openErrorStream() - { - return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w'); - } - - /** - * 将消息写入到输出。 - * @param string $message 消息 - * @param bool $newline 是否另起一行 - * @param null $stream - */ - protected function doWrite($message, $newline, $stream = null) - { - if (null === $stream) { - $stream = $this->stdout; - } - if (false === @fwrite($stream, $message . ($newline ? PHP_EOL : ''))) { - throw new \RuntimeException('Unable to write output.'); - } - - fflush($stream); - } - - /** - * 是否支持着色 - * @param $stream - * @return bool - */ - protected function hasColorSupport($stream) - { - if (DIRECTORY_SEPARATOR === '\\') { - return - '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR . '.' . PHP_WINDOWS_VERSION_MINOR . '.' . PHP_WINDOWS_VERSION_BUILD - || false !== getenv('ANSICON') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM'); - } - - return function_exists('posix_isatty') && @posix_isatty($stream); - } - -} diff --git a/thinkphp/library/think/console/output/driver/Nothing.php b/thinkphp/library/think/console/output/driver/Nothing.php deleted file mode 100755 index 9a55f77..0000000 --- a/thinkphp/library/think/console/output/driver/Nothing.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\driver; - -use think\console\Output; - -class Nothing -{ - - public function __construct(Output $output) - { - // do nothing - } - - public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL) - { - // do nothing - } - - public function renderException(\Exception $e) - { - // do nothing - } -} diff --git a/thinkphp/library/think/console/output/formatter/Stack.php b/thinkphp/library/think/console/output/formatter/Stack.php deleted file mode 100755 index 4864a3f..0000000 --- a/thinkphp/library/think/console/output/formatter/Stack.php +++ /dev/null @@ -1,116 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\formatter; - -class Stack -{ - - /** - * @var Style[] - */ - private $styles; - - /** - * @var Style - */ - private $emptyStyle; - - /** - * 构造方法 - * @param Style|null $emptyStyle - */ - public function __construct(Style $emptyStyle = null) - { - $this->emptyStyle = $emptyStyle ?: new Style(); - $this->reset(); - } - - /** - * 重置堆栈 - */ - public function reset() - { - $this->styles = []; - } - - /** - * 推一个样式进入堆栈 - * @param Style $style - */ - public function push(Style $style) - { - $this->styles[] = $style; - } - - /** - * 从堆栈中弹出一个样式 - * @param Style|null $style - * @return Style - * @throws \InvalidArgumentException - */ - public function pop(Style $style = null) - { - if (empty($this->styles)) { - return $this->emptyStyle; - } - - if (null === $style) { - return array_pop($this->styles); - } - - /** - * @var int $index - * @var Style $stackedStyle - */ - foreach (array_reverse($this->styles, true) as $index => $stackedStyle) { - if ($style->apply('') === $stackedStyle->apply('')) { - $this->styles = array_slice($this->styles, 0, $index); - - return $stackedStyle; - } - } - - throw new \InvalidArgumentException('Incorrectly nested style tag found.'); - } - - /** - * 计算堆栈的当前样式。 - * @return Style - */ - public function getCurrent() - { - if (empty($this->styles)) { - return $this->emptyStyle; - } - - return $this->styles[count($this->styles) - 1]; - } - - /** - * @param Style $emptyStyle - * @return Stack - */ - public function setEmptyStyle(Style $emptyStyle) - { - $this->emptyStyle = $emptyStyle; - - return $this; - } - - /** - * @return Style - */ - public function getEmptyStyle() - { - return $this->emptyStyle; - } -} diff --git a/thinkphp/library/think/console/output/formatter/Style.php b/thinkphp/library/think/console/output/formatter/Style.php deleted file mode 100755 index d9b0999..0000000 --- a/thinkphp/library/think/console/output/formatter/Style.php +++ /dev/null @@ -1,189 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\formatter; - -class Style -{ - - private static $availableForegroundColors = [ - 'black' => ['set' => 30, 'unset' => 39], - 'red' => ['set' => 31, 'unset' => 39], - 'green' => ['set' => 32, 'unset' => 39], - 'yellow' => ['set' => 33, 'unset' => 39], - 'blue' => ['set' => 34, 'unset' => 39], - 'magenta' => ['set' => 35, 'unset' => 39], - 'cyan' => ['set' => 36, 'unset' => 39], - 'white' => ['set' => 37, 'unset' => 39], - ]; - private static $availableBackgroundColors = [ - 'black' => ['set' => 40, 'unset' => 49], - 'red' => ['set' => 41, 'unset' => 49], - 'green' => ['set' => 42, 'unset' => 49], - 'yellow' => ['set' => 43, 'unset' => 49], - 'blue' => ['set' => 44, 'unset' => 49], - 'magenta' => ['set' => 45, 'unset' => 49], - 'cyan' => ['set' => 46, 'unset' => 49], - 'white' => ['set' => 47, 'unset' => 49], - ]; - private static $availableOptions = [ - 'bold' => ['set' => 1, 'unset' => 22], - 'underscore' => ['set' => 4, 'unset' => 24], - 'blink' => ['set' => 5, 'unset' => 25], - 'reverse' => ['set' => 7, 'unset' => 27], - 'conceal' => ['set' => 8, 'unset' => 28], - ]; - - private $foreground; - private $background; - private $options = []; - - /** - * 初始化输出的样式 - * @param string|null $foreground 字体颜色 - * @param string|null $background 背景色 - * @param array $options 格式 - * @api - */ - public function __construct($foreground = null, $background = null, array $options = []) - { - if (null !== $foreground) { - $this->setForeground($foreground); - } - if (null !== $background) { - $this->setBackground($background); - } - if (count($options)) { - $this->setOptions($options); - } - } - - /** - * 设置字体颜色 - * @param string|null $color 颜色名 - * @throws \InvalidArgumentException - * @api - */ - public function setForeground($color = null) - { - if (null === $color) { - $this->foreground = null; - - return; - } - - if (!isset(static::$availableForegroundColors[$color])) { - throw new \InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors)))); - } - - $this->foreground = static::$availableForegroundColors[$color]; - } - - /** - * 设置背景色 - * @param string|null $color 颜色名 - * @throws \InvalidArgumentException - * @api - */ - public function setBackground($color = null) - { - if (null === $color) { - $this->background = null; - - return; - } - - if (!isset(static::$availableBackgroundColors[$color])) { - throw new \InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors)))); - } - - $this->background = static::$availableBackgroundColors[$color]; - } - - /** - * 设置字体格式 - * @param string $option 格式名 - * @throws \InvalidArgumentException When the option name isn't defined - * @api - */ - public function setOption($option) - { - if (!isset(static::$availableOptions[$option])) { - throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); - } - - if (!in_array(static::$availableOptions[$option], $this->options)) { - $this->options[] = static::$availableOptions[$option]; - } - } - - /** - * 重置字体格式 - * @param string $option 格式名 - * @throws \InvalidArgumentException - */ - public function unsetOption($option) - { - if (!isset(static::$availableOptions[$option])) { - throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); - } - - $pos = array_search(static::$availableOptions[$option], $this->options); - if (false !== $pos) { - unset($this->options[$pos]); - } - } - - /** - * 批量设置字体格式 - * @param array $options - */ - public function setOptions(array $options) - { - $this->options = []; - - foreach ($options as $option) { - $this->setOption($option); - } - } - - /** - * 应用样式到文字 - * @param string $text 文字 - * @return string - */ - public function apply($text) - { - $setCodes = []; - $unsetCodes = []; - - if (null !== $this->foreground) { - $setCodes[] = $this->foreground['set']; - $unsetCodes[] = $this->foreground['unset']; - } - if (null !== $this->background) { - $setCodes[] = $this->background['set']; - $unsetCodes[] = $this->background['unset']; - } - if (count($this->options)) { - foreach ($this->options as $option) { - $setCodes[] = $option['set']; - $unsetCodes[] = $option['unset']; - } - } - - if (0 === count($setCodes)) { - return $text; - } - - return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes)); - } -} diff --git a/thinkphp/library/think/console/output/question/Choice.php b/thinkphp/library/think/console/output/question/Choice.php deleted file mode 100755 index f6760e5..0000000 --- a/thinkphp/library/think/console/output/question/Choice.php +++ /dev/null @@ -1,163 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\question; - -use think\console\output\Question; - -class Choice extends Question -{ - - private $choices; - private $multiselect = false; - private $prompt = ' > '; - private $errorMessage = 'Value "%s" is invalid'; - - /** - * 构造方法 - * @param string $question 问题 - * @param array $choices 选项 - * @param mixed $default 默认答案 - */ - public function __construct($question, array $choices, $default = null) - { - parent::__construct($question, $default); - - $this->choices = $choices; - $this->setValidator($this->getDefaultValidator()); - $this->setAutocompleterValues($choices); - } - - /** - * 可选项 - * @return array - */ - public function getChoices() - { - return $this->choices; - } - - /** - * 设置可否多选 - * @param bool $multiselect - * @return self - */ - public function setMultiselect($multiselect) - { - $this->multiselect = $multiselect; - $this->setValidator($this->getDefaultValidator()); - - return $this; - } - - public function isMultiselect() - { - return $this->multiselect; - } - - /** - * 获取提示 - * @return string - */ - public function getPrompt() - { - return $this->prompt; - } - - /** - * 设置提示 - * @param string $prompt - * @return self - */ - public function setPrompt($prompt) - { - $this->prompt = $prompt; - - return $this; - } - - /** - * 设置错误提示信息 - * @param string $errorMessage - * @return self - */ - public function setErrorMessage($errorMessage) - { - $this->errorMessage = $errorMessage; - $this->setValidator($this->getDefaultValidator()); - - return $this; - } - - /** - * 获取默认的验证方法 - * @return callable - */ - private function getDefaultValidator() - { - $choices = $this->choices; - $errorMessage = $this->errorMessage; - $multiselect = $this->multiselect; - $isAssoc = $this->isAssoc($choices); - - return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) { - // Collapse all spaces. - $selectedChoices = str_replace(' ', '', $selected); - - if ($multiselect) { - // Check for a separated comma values - if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) { - throw new \InvalidArgumentException(sprintf($errorMessage, $selected)); - } - $selectedChoices = explode(',', $selectedChoices); - } else { - $selectedChoices = [$selected]; - } - - $multiselectChoices = []; - foreach ($selectedChoices as $value) { - $results = []; - foreach ($choices as $key => $choice) { - if ($choice === $value) { - $results[] = $key; - } - } - - if (count($results) > 1) { - throw new \InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results))); - } - - $result = array_search($value, $choices); - - if (!$isAssoc) { - if (!empty($result)) { - $result = $choices[$result]; - } elseif (isset($choices[$value])) { - $result = $choices[$value]; - } - } elseif (empty($result) && array_key_exists($value, $choices)) { - $result = $value; - } - - if (empty($result)) { - throw new \InvalidArgumentException(sprintf($errorMessage, $value)); - } - array_push($multiselectChoices, $result); - } - - if ($multiselect) { - return $multiselectChoices; - } - - return current($multiselectChoices); - }; - } -} diff --git a/thinkphp/library/think/console/output/question/Confirmation.php b/thinkphp/library/think/console/output/question/Confirmation.php deleted file mode 100755 index 6598f9b..0000000 --- a/thinkphp/library/think/console/output/question/Confirmation.php +++ /dev/null @@ -1,57 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\output\question; - -use think\console\output\Question; - -class Confirmation extends Question -{ - - private $trueAnswerRegex; - - /** - * 构造方法 - * @param string $question 问题 - * @param bool $default 默认答案 - * @param string $trueAnswerRegex 验证正则 - */ - public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i') - { - parent::__construct($question, (bool) $default); - - $this->trueAnswerRegex = $trueAnswerRegex; - $this->setNormalizer($this->getDefaultNormalizer()); - } - - /** - * 获取默认的答案回调 - * @return callable - */ - private function getDefaultNormalizer() - { - $default = $this->getDefault(); - $regex = $this->trueAnswerRegex; - - return function ($answer) use ($default, $regex) { - if (is_bool($answer)) { - return $answer; - } - - $answerIsTrue = (bool) preg_match($regex, $answer); - if (false === $default) { - return $answer && $answerIsTrue; - } - - return !$answer || $answerIsTrue; - }; - } -} diff --git a/thinkphp/library/think/controller/Rest.php b/thinkphp/library/think/controller/Rest.php deleted file mode 100755 index 43ab2f6..0000000 --- a/thinkphp/library/think/controller/Rest.php +++ /dev/null @@ -1,99 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\controller; - -use think\App; -use think\Request; -use think\Response; - -abstract class Rest -{ - - protected $method; // 当前请求类型 - protected $type; // 当前资源类型 - // 输出类型 - protected $restMethodList = 'get|post|put|delete'; - protected $restDefaultMethod = 'get'; - protected $restTypeList = 'html|xml|json|rss'; - protected $restDefaultType = 'html'; - protected $restOutputType = [ // REST允许输出的资源类型列表 - 'xml' => 'application/xml', - 'json' => 'application/json', - 'html' => 'text/html', - ]; - - /** - * 构造函数 取得模板对象实例 - * @access public - */ - public function __construct() - { - // 资源类型检测 - $request = Request::instance(); - $ext = $request->ext(); - if ('' == $ext) { - // 自动检测资源类型 - $this->type = $request->type(); - } elseif (!preg_match('/(' . $this->restTypeList . ')$/i', $ext)) { - // 资源类型非法 则用默认资源类型访问 - $this->type = $this->restDefaultType; - } else { - $this->type = $ext; - } - // 请求方式检测 - $method = strtolower($request->method()); - if (!preg_match('/(' . $this->restMethodList . ')$/i', $method)) { - // 请求方式非法 则用默认请求方法 - $method = $this->restDefaultMethod; - } - $this->method = $method; - } - - /** - * REST 调用 - * @access public - * @param string $method 方法名 - * @return mixed - * @throws \Exception - */ - public function _empty($method) - { - if (method_exists($this, $method . '_' . $this->method . '_' . $this->type)) { - // RESTFul方法支持 - $fun = $method . '_' . $this->method . '_' . $this->type; - } elseif ($this->method == $this->restDefaultMethod && method_exists($this, $method . '_' . $this->type)) { - $fun = $method . '_' . $this->type; - } elseif ($this->type == $this->restDefaultType && method_exists($this, $method . '_' . $this->method)) { - $fun = $method . '_' . $this->method; - } - if (isset($fun)) { - return App::invokeMethod([$this, $fun]); - } else { - // 抛出异常 - throw new \Exception('error action :' . $method); - } - } - - /** - * 输出返回数据 - * @access protected - * @param mixed $data 要返回的数据 - * @param String $type 返回类型 JSON XML - * @param integer $code HTTP状态码 - * @return Response - */ - protected function response($data, $type = 'json', $code = 200) - { - return Response::create($data, $type)->code($code); - } - -} diff --git a/thinkphp/library/think/controller/Yar.php b/thinkphp/library/think/controller/Yar.php deleted file mode 100755 index af4e9a1..0000000 --- a/thinkphp/library/think/controller/Yar.php +++ /dev/null @@ -1,51 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\controller; - -/** - * ThinkPHP Yar控制器类 - */ -abstract class Yar -{ - - /** - * 构造函数 - * @access public - */ - public function __construct() - { - //控制器初始化 - if (method_exists($this, '_initialize')) { - $this->_initialize(); - } - - //判断扩展是否存在 - if (!extension_loaded('yar')) { - throw new \Exception('not support yar'); - } - - //实例化Yar_Server - $server = new \Yar_Server($this); - // 启动server - $server->handle(); - } - - /** - * 魔术方法 有不存在的操作的时候执行 - * @access public - * @param string $method 方法名 - * @param array $args 参数 - * @return mixed - */ - public function __call($method, $args) - {} -} diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php deleted file mode 100755 index 58b45aa..0000000 --- a/thinkphp/library/think/db/Builder.php +++ /dev/null @@ -1,899 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db; - -use PDO; -use think\Exception; - -abstract class Builder -{ - // connection对象实例 - protected $connection; - // 查询对象实例 - protected $query; - - // 数据库表达式 - protected $exp = ['eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'not like' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'exp' => 'EXP', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN', 'exists' => 'EXISTS', 'notexists' => 'NOT EXISTS', 'not exists' => 'NOT EXISTS', 'null' => 'NULL', 'notnull' => 'NOT NULL', 'not null' => 'NOT NULL', '> time' => '> TIME', '< time' => '< TIME', '>= time' => '>= TIME', '<= time' => '<= TIME', 'between time' => 'BETWEEN TIME', 'not between time' => 'NOT BETWEEN TIME', 'notbetween time' => 'NOT BETWEEN TIME']; - - // SQL表达式 - protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%UNION%%ORDER%%LIMIT%%LOCK%%COMMENT%'; - protected $insertSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; - protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; - protected $updateSql = 'UPDATE %TABLE% SET %SET% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; - protected $deleteSql = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; - - /** - * 构造函数 - * @access public - * @param Connection $connection 数据库连接对象实例 - * @param Query $query 数据库查询对象实例 - */ - public function __construct(Connection $connection, Query $query) - { - $this->connection = $connection; - $this->query = $query; - } - - /** - * 获取当前的连接对象实例 - * @access public - * @return Connection - */ - public function getConnection() - { - return $this->connection; - } - - /** - * 获取当前的Query对象实例 - * @access public - * @return Query - */ - public function getQuery() - { - return $this->query; - } - - /** - * 将SQL语句中的__TABLE_NAME__字符串替换成带前缀的表名(小写) - * @access protected - * @param string $sql sql语句 - * @return string - */ - protected function parseSqlTable($sql) - { - return $this->query->parseSqlTable($sql); - } - - /** - * 数据分析 - * @access protected - * @param array $data 数据 - * @param array $options 查询参数 - * @return array - * @throws Exception - */ - protected function parseData($data, $options) - { - if (empty($data)) { - return []; - } - - // 获取绑定信息 - $bind = $this->query->getFieldsBind($options['table']); - if ('*' == $options['field']) { - $fields = array_keys($bind); - } else { - $fields = $options['field']; - } - - $result = []; - foreach ($data as $key => $val) { - if ('*' != $options['field'] && !in_array($key, $fields, true)) { - continue; - } - - $item = $this->parseKey($key, $options, true); - if ($val instanceof Expression) { - $result[$item] = $val->getValue(); - continue; - } elseif (is_object($val) && method_exists($val, '__toString')) { - // 对象数据写入 - $val = $val->__toString(); - } - if (false === strpos($key, '.') && !in_array($key, $fields, true)) { - if ($options['strict']) { - throw new Exception('fields not exists:[' . $key . ']'); - } - } elseif (is_null($val)) { - $result[$item] = 'NULL'; - } elseif (is_array($val) && !empty($val)) { - switch (strtolower($val[0])) { - case 'inc': - $result[$item] = $item . '+' . floatval($val[1]); - break; - case 'dec': - $result[$item] = $item . '-' . floatval($val[1]); - break; - case 'exp': - throw new Exception('not support data:[' . $val[0] . ']'); - } - } elseif (is_scalar($val)) { - // 过滤非标量数据 - if (0 === strpos($val, ':') && $this->query->isBind(substr($val, 1))) { - $result[$item] = $val; - } else { - $key = str_replace('.', '_', $key); - $this->query->bind('data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); - $result[$item] = ':data__' . $key; - } - } - } - return $result; - } - - /** - * 字段名分析 - * @access protected - * @param string $key - * @param array $options - * @return string - */ - protected function parseKey($key, $options = [], $strict = false) - { - return $key; - } - - /** - * value分析 - * @access protected - * @param mixed $value - * @param string $field - * @return string|array - */ - protected function parseValue($value, $field = '') - { - if (is_string($value)) { - $value = strpos($value, ':') === 0 && $this->query->isBind(substr($value, 1)) ? $value : $this->connection->quote($value); - } elseif (is_array($value)) { - $value = array_map([$this, 'parseValue'], $value); - } elseif (is_bool($value)) { - $value = $value ? '1' : '0'; - } elseif (is_null($value)) { - $value = 'null'; - } - return $value; - } - - /** - * field分析 - * @access protected - * @param mixed $fields - * @param array $options - * @return string - */ - protected function parseField($fields, $options = []) - { - if ('*' == $fields || empty($fields)) { - $fieldsStr = '*'; - } elseif (is_array($fields)) { - // 支持 'field1'=>'field2' 这样的字段别名定义 - $array = []; - foreach ($fields as $key => $field) { - if ($field instanceof Expression) { - $array[] = $field->getValue(); - } elseif (!is_numeric($key)) { - $array[] = $this->parseKey($key, $options) . ' AS ' . $this->parseKey($field, $options, true); - } else { - $array[] = $this->parseKey($field, $options); - } - } - $fieldsStr = implode(',', $array); - } - return $fieldsStr; - } - - /** - * table分析 - * @access protected - * @param mixed $tables - * @param array $options - * @return string - */ - protected function parseTable($tables, $options = []) - { - $item = []; - foreach ((array) $tables as $key => $table) { - if (!is_numeric($key)) { - $key = $this->parseSqlTable($key); - $item[] = $this->parseKey($key) . ' ' . (isset($options['alias'][$table]) ? $this->parseKey($options['alias'][$table]) : $this->parseKey($table)); - } else { - $table = $this->parseSqlTable($table); - if (isset($options['alias'][$table])) { - $item[] = $this->parseKey($table) . ' ' . $this->parseKey($options['alias'][$table]); - } else { - $item[] = $this->parseKey($table); - } - } - } - return implode(',', $item); - } - - /** - * where分析 - * @access protected - * @param mixed $where 查询条件 - * @param array $options 查询参数 - * @return string - */ - protected function parseWhere($where, $options) - { - $whereStr = $this->buildWhere($where, $options); - if (!empty($options['soft_delete'])) { - // 附加软删除条件 - list($field, $condition) = $options['soft_delete']; - - $binds = $this->query->getFieldsBind($options['table']); - $whereStr = $whereStr ? '( ' . $whereStr . ' ) AND ' : ''; - $whereStr = $whereStr . $this->parseWhereItem($field, $condition, '', $options, $binds); - } - return empty($whereStr) ? '' : ' WHERE ' . $whereStr; - } - - /** - * 生成查询条件SQL - * @access public - * @param mixed $where - * @param array $options - * @return string - */ - public function buildWhere($where, $options) - { - if (empty($where)) { - $where = []; - } - - if ($where instanceof Query) { - return $this->buildWhere($where->getOptions('where'), $options); - } - - $whereStr = ''; - $binds = $this->query->getFieldsBind($options['table']); - foreach ($where as $key => $val) { - $str = []; - foreach ($val as $field => $value) { - if ($value instanceof Expression) { - $str[] = ' ' . $key . ' ( ' . $value->getValue() . ' )'; - } elseif ($value instanceof \Closure) { - // 使用闭包查询 - $query = new Query($this->connection); - call_user_func_array($value, [ & $query]); - $whereClause = $this->buildWhere($query->getOptions('where'), $options); - if (!empty($whereClause)) { - $str[] = ' ' . $key . ' ( ' . $whereClause . ' )'; - } - } elseif (strpos($field, '|')) { - // 不同字段使用相同查询条件(OR) - $array = explode('|', $field); - $item = []; - foreach ($array as $k) { - $item[] = $this->parseWhereItem($k, $value, '', $options, $binds); - } - $str[] = ' ' . $key . ' ( ' . implode(' OR ', $item) . ' )'; - } elseif (strpos($field, '&')) { - // 不同字段使用相同查询条件(AND) - $array = explode('&', $field); - $item = []; - foreach ($array as $k) { - $item[] = $this->parseWhereItem($k, $value, '', $options, $binds); - } - $str[] = ' ' . $key . ' ( ' . implode(' AND ', $item) . ' )'; - } else { - // 对字段使用表达式查询 - $field = is_string($field) ? $field : ''; - $str[] = ' ' . $key . ' ' . $this->parseWhereItem($field, $value, $key, $options, $binds); - } - } - - $whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($key) + 1) : implode(' ', $str); - } - - return $whereStr; - } - - // where子单元分析 - protected function parseWhereItem($field, $val, $rule = '', $options = [], $binds = [], $bindName = null) - { - // 字段分析 - $key = $field ? $this->parseKey($field, $options, true) : ''; - - // 查询规则和条件 - if (!is_array($val)) { - $val = is_null($val) ? ['null', ''] : ['=', $val]; - } - list($exp, $value) = $val; - - // 对一个字段使用多个查询条件 - if (is_array($exp)) { - $item = array_pop($val); - // 传入 or 或者 and - if (is_string($item) && in_array($item, ['AND', 'and', 'OR', 'or'])) { - $rule = $item; - } else { - array_push($val, $item); - } - foreach ($val as $k => $item) { - $bindName = 'where_' . str_replace('.', '_', $field) . '_' . $k; - $str[] = $this->parseWhereItem($field, $item, $rule, $options, $binds, $bindName); - } - return '( ' . implode(' ' . $rule . ' ', $str) . ' )'; - } - - // 检测操作符 - if (!in_array($exp, $this->exp)) { - $exp = strtolower($exp); - if (isset($this->exp[$exp])) { - $exp = $this->exp[$exp]; - } else { - throw new Exception('where express error:' . $exp); - } - } - $bindName = $bindName ?: 'where_' . $rule . '_' . str_replace(['.', '-'], '_', $field); - if (preg_match('/\W/', $bindName)) { - // 处理带非单词字符的字段名 - $bindName = md5($bindName); - } - - if ($value instanceof Expression) { - - } elseif (is_object($value) && method_exists($value, '__toString')) { - // 对象数据写入 - $value = $value->__toString(); - } - - $bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR; - if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) { - if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) { - if ($this->query->isBind($bindName)) { - $bindName .= '_' . str_replace('.', '_', uniqid('', true)); - } - $this->query->bind($bindName, $value, $bindType); - $value = ':' . $bindName; - } - } - - $whereStr = ''; - if (in_array($exp, ['=', '<>', '>', '>=', '<', '<='])) { - // 比较运算 - if ($value instanceof \Closure) { - $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value); - } else { - $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field); - } - } elseif ('LIKE' == $exp || 'NOT LIKE' == $exp) { - // 模糊匹配 - if (is_array($value)) { - foreach ($value as $item) { - $array[] = $key . ' ' . $exp . ' ' . $this->parseValue($item, $field); - } - $logic = isset($val[2]) ? $val[2] : 'AND'; - $whereStr .= '(' . implode($array, ' ' . strtoupper($logic) . ' ') . ')'; - } else { - $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field); - } - } elseif ('EXP' == $exp) { - // 表达式查询 - if ($value instanceof Expression) { - $whereStr .= '( ' . $key . ' ' . $value->getValue() . ' )'; - } else { - throw new Exception('where express error:' . $exp); - } - } elseif (in_array($exp, ['NOT NULL', 'NULL'])) { - // NULL 查询 - $whereStr .= $key . ' IS ' . $exp; - } elseif (in_array($exp, ['NOT IN', 'IN'])) { - // IN 查询 - if ($value instanceof \Closure) { - $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value); - } else { - $value = array_unique(is_array($value) ? $value : explode(',', $value)); - if (array_key_exists($field, $binds)) { - $bind = []; - $array = []; - $i = 0; - foreach ($value as $v) { - $i++; - if ($this->query->isBind($bindName . '_in_' . $i)) { - $bindKey = $bindName . '_in_' . uniqid() . '_' . $i; - } else { - $bindKey = $bindName . '_in_' . $i; - } - $bind[$bindKey] = [$v, $bindType]; - $array[] = ':' . $bindKey; - } - $this->query->bind($bind); - $zone = implode(',', $array); - } else { - $zone = implode(',', $this->parseValue($value, $field)); - } - $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')'; - } - } elseif (in_array($exp, ['NOT BETWEEN', 'BETWEEN'])) { - // BETWEEN 查询 - $data = is_array($value) ? $value : explode(',', $value); - if (array_key_exists($field, $binds)) { - if ($this->query->isBind($bindName . '_between_1')) { - $bindKey1 = $bindName . '_between_1' . uniqid(); - $bindKey2 = $bindName . '_between_2' . uniqid(); - } else { - $bindKey1 = $bindName . '_between_1'; - $bindKey2 = $bindName . '_between_2'; - } - $bind = [ - $bindKey1 => [$data[0], $bindType], - $bindKey2 => [$data[1], $bindType], - ]; - $this->query->bind($bind); - $between = ':' . $bindKey1 . ' AND :' . $bindKey2; - } else { - $between = $this->parseValue($data[0], $field) . ' AND ' . $this->parseValue($data[1], $field); - } - $whereStr .= $key . ' ' . $exp . ' ' . $between; - } elseif (in_array($exp, ['NOT EXISTS', 'EXISTS'])) { - // EXISTS 查询 - if ($value instanceof \Closure) { - $whereStr .= $exp . ' ' . $this->parseClosure($value); - } else { - $whereStr .= $exp . ' (' . $value . ')'; - } - } elseif (in_array($exp, ['< TIME', '> TIME', '<= TIME', '>= TIME'])) { - $whereStr .= $key . ' ' . substr($exp, 0, 2) . ' ' . $this->parseDateTime($value, $field, $options, $bindName, $bindType); - } elseif (in_array($exp, ['BETWEEN TIME', 'NOT BETWEEN TIME'])) { - if (is_string($value)) { - $value = explode(',', $value); - } - - $whereStr .= $key . ' ' . substr($exp, 0, -4) . $this->parseDateTime($value[0], $field, $options, $bindName . '_between_1', $bindType) . ' AND ' . $this->parseDateTime($value[1], $field, $options, $bindName . '_between_2', $bindType); - } - return $whereStr; - } - - // 执行闭包子查询 - protected function parseClosure($call, $show = true) - { - $query = new Query($this->connection); - call_user_func_array($call, [ & $query]); - return $query->buildSql($show); - } - - /** - * 日期时间条件解析 - * @access protected - * @param string $value - * @param string $key - * @param array $options - * @param string $bindName - * @param integer $bindType - * @return string - */ - protected function parseDateTime($value, $key, $options = [], $bindName = null, $bindType = null) - { - // 获取时间字段类型 - if (strpos($key, '.')) { - list($table, $key) = explode('.', $key); - if (isset($options['alias']) && $pos = array_search($table, $options['alias'])) { - $table = $pos; - } - } else { - $table = $options['table']; - } - $type = $this->query->getTableInfo($table, 'type'); - if (isset($type[$key])) { - $info = $type[$key]; - } - if (isset($info)) { - if (is_string($value)) { - $value = strtotime($value) ?: $value; - } - - if (preg_match('/(datetime|timestamp)/is', $info)) { - // 日期及时间戳类型 - $value = date('Y-m-d H:i:s', $value); - } elseif (preg_match('/(date)/is', $info)) { - // 日期及时间戳类型 - $value = date('Y-m-d', $value); - } - } - $bindName = $bindName ?: $key; - - if ($this->query->isBind($bindName)) { - $bindName .= '_' . str_replace('.', '_', uniqid('', true)); - } - - $this->query->bind($bindName, $value, $bindType); - return ':' . $bindName; - } - - /** - * limit分析 - * @access protected - * @param mixed $limit - * @return string - */ - protected function parseLimit($limit) - { - return (!empty($limit) && false === strpos($limit, '(')) ? ' LIMIT ' . $limit . ' ' : ''; - } - - /** - * join分析 - * @access protected - * @param array $join - * @param array $options 查询条件 - * @return string - */ - protected function parseJoin($join, $options = []) - { - $joinStr = ''; - if (!empty($join)) { - foreach ($join as $item) { - list($table, $type, $on) = $item; - $condition = []; - foreach ((array) $on as $val) { - if ($val instanceof Expression) { - $condition[] = $val->getValue(); - } elseif (strpos($val, '=')) { - list($val1, $val2) = explode('=', $val, 2); - $condition[] = $this->parseKey($val1, $options) . '=' . $this->parseKey($val2, $options); - } else { - $condition[] = $val; - } - } - - $table = $this->parseTable($table, $options); - $joinStr .= ' ' . $type . ' JOIN ' . $table . ' ON ' . implode(' AND ', $condition); - } - } - return $joinStr; - } - - /** - * order分析 - * @access protected - * @param mixed $order - * @param array $options 查询条件 - * @return string - */ - protected function parseOrder($order, $options = []) - { - if (empty($order)) { - return ''; - } - - $array = []; - foreach ($order as $key => $val) { - if ($val instanceof Expression) { - $array[] = $val->getValue(); - } elseif ('[rand]' == $val) { - $array[] = $this->parseRand(); - } else { - if (is_numeric($key)) { - list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' '); - } else { - $sort = $val; - } - $sort = strtoupper($sort); - $sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : ''; - $array[] = $this->parseKey($key, $options, true) . $sort; - } - } - $order = implode(',', $array); - - return !empty($order) ? ' ORDER BY ' . $order : ''; - } - - /** - * group分析 - * @access protected - * @param mixed $group - * @return string - */ - protected function parseGroup($group) - { - return !empty($group) ? ' GROUP BY ' . $this->parseKey($group) : ''; - } - - /** - * having分析 - * @access protected - * @param string $having - * @return string - */ - protected function parseHaving($having) - { - return !empty($having) ? ' HAVING ' . $having : ''; - } - - /** - * comment分析 - * @access protected - * @param string $comment - * @return string - */ - protected function parseComment($comment) - { - if (false !== strpos($comment, '*/')) { - $comment = strstr($comment, '*/', true); - } - return !empty($comment) ? ' /* ' . $comment . ' */' : ''; - } - - /** - * distinct分析 - * @access protected - * @param mixed $distinct - * @return string - */ - protected function parseDistinct($distinct) - { - return !empty($distinct) ? ' DISTINCT ' : ''; - } - - /** - * union分析 - * @access protected - * @param mixed $union - * @return string - */ - protected function parseUnion($union) - { - if (empty($union)) { - return ''; - } - $type = $union['type']; - unset($union['type']); - foreach ($union as $u) { - if ($u instanceof \Closure) { - $sql[] = $type . ' ' . $this->parseClosure($u); - } elseif (is_string($u)) { - $sql[] = $type . ' ( ' . $this->parseSqlTable($u) . ' )'; - } - } - return ' ' . implode(' ', $sql); - } - - /** - * index分析,可在操作链中指定需要强制使用的索引 - * @access protected - * @param mixed $index - * @return string - */ - protected function parseForce($index) - { - if (empty($index)) { - return ''; - } - - return sprintf(" FORCE INDEX ( %s ) ", is_array($index) ? implode(',', $index) : $index); - } - - /** - * 设置锁机制 - * @access protected - * @param bool|string $lock - * @return string - */ - protected function parseLock($lock = false) - { - if (is_bool($lock)) { - return $lock ? ' FOR UPDATE ' : ''; - } elseif (is_string($lock)) { - return ' ' . trim($lock) . ' '; - } - } - - /** - * 生成查询SQL - * @access public - * @param array $options 表达式 - * @return string - */ - public function select($options = []) - { - $sql = str_replace( - ['%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '%COMMENT%', '%FORCE%'], - [ - $this->parseTable($options['table'], $options), - $this->parseDistinct($options['distinct']), - $this->parseField($options['field'], $options), - $this->parseJoin($options['join'], $options), - $this->parseWhere($options['where'], $options), - $this->parseGroup($options['group']), - $this->parseHaving($options['having']), - $this->parseOrder($options['order'], $options), - $this->parseLimit($options['limit']), - $this->parseUnion($options['union']), - $this->parseLock($options['lock']), - $this->parseComment($options['comment']), - $this->parseForce($options['force']), - ], $this->selectSql); - return $sql; - } - - /** - * 生成insert SQL - * @access public - * @param array $data 数据 - * @param array $options 表达式 - * @param bool $replace 是否replace - * @return string - */ - public function insert(array $data, $options = [], $replace = false) - { - // 分析并处理数据 - $data = $this->parseData($data, $options); - if (empty($data)) { - return 0; - } - $fields = array_keys($data); - $values = array_values($data); - - $sql = str_replace( - ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'], - [ - $replace ? 'REPLACE' : 'INSERT', - $this->parseTable($options['table'], $options), - implode(' , ', $fields), - implode(' , ', $values), - $this->parseComment($options['comment']), - ], $this->insertSql); - - return $sql; - } - - /** - * 生成insertall SQL - * @access public - * @param array $dataSet 数据集 - * @param array $options 表达式 - * @param bool $replace 是否replace - * @return string - * @throws Exception - */ - public function insertAll($dataSet, $options = [], $replace = false) - { - // 获取合法的字段 - if ('*' == $options['field']) { - $fields = array_keys($this->query->getFieldsType($options['table'])); - } else { - $fields = $options['field']; - } - - foreach ($dataSet as $data) { - foreach ($data as $key => $val) { - if (!in_array($key, $fields, true)) { - if ($options['strict']) { - throw new Exception('fields not exists:[' . $key . ']'); - } - unset($data[$key]); - } elseif (is_null($val)) { - $data[$key] = 'NULL'; - } elseif (is_scalar($val)) { - $data[$key] = $this->parseValue($val, $key); - } elseif (is_object($val) && method_exists($val, '__toString')) { - // 对象数据写入 - $data[$key] = $val->__toString(); - } else { - // 过滤掉非标量数据 - unset($data[$key]); - } - } - $value = array_values($data); - $values[] = 'SELECT ' . implode(',', $value); - - if (!isset($insertFields)) { - $insertFields = array_keys($data); - } - } - - foreach ($insertFields as $field) { - $fields[] = $this->parseKey($field, $options, true); - } - - return str_replace( - ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'], - [ - $replace ? 'REPLACE' : 'INSERT', - $this->parseTable($options['table'], $options), - implode(' , ', $insertFields), - implode(' UNION ALL ', $values), - $this->parseComment($options['comment']), - ], $this->insertAllSql); - } - - /** - * 生成select insert SQL - * @access public - * @param array $fields 数据 - * @param string $table 数据表 - * @param array $options 表达式 - * @return string - */ - public function selectInsert($fields, $table, $options) - { - if (is_string($fields)) { - $fields = explode(',', $fields); - } - - $fields = array_map([$this, 'parseKey'], $fields); - $sql = 'INSERT INTO ' . $this->parseTable($table, $options) . ' (' . implode(',', $fields) . ') ' . $this->select($options); - return $sql; - } - - /** - * 生成update SQL - * @access public - * @param array $data 数据 - * @param array $options 表达式 - * @return string - */ - public function update($data, $options) - { - $table = $this->parseTable($options['table'], $options); - $data = $this->parseData($data, $options); - if (empty($data)) { - return ''; - } - foreach ($data as $key => $val) { - $set[] = $key . '=' . $val; - } - - $sql = str_replace( - ['%TABLE%', '%SET%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'], - [ - $this->parseTable($options['table'], $options), - implode(',', $set), - $this->parseJoin($options['join'], $options), - $this->parseWhere($options['where'], $options), - $this->parseOrder($options['order'], $options), - $this->parseLimit($options['limit']), - $this->parseLock($options['lock']), - $this->parseComment($options['comment']), - ], $this->updateSql); - - return $sql; - } - - /** - * 生成delete SQL - * @access public - * @param array $options 表达式 - * @return string - */ - public function delete($options) - { - $sql = str_replace( - ['%TABLE%', '%USING%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'], - [ - $this->parseTable($options['table'], $options), - !empty($options['using']) ? ' USING ' . $this->parseTable($options['using'], $options) . ' ' : '', - $this->parseJoin($options['join'], $options), - $this->parseWhere($options['where'], $options), - $this->parseOrder($options['order'], $options), - $this->parseLimit($options['limit']), - $this->parseLock($options['lock']), - $this->parseComment($options['comment']), - ], $this->deleteSql); - - return $sql; - } -} diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php deleted file mode 100755 index 578cc8f..0000000 --- a/thinkphp/library/think/db/Connection.php +++ /dev/null @@ -1,1059 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db; - -use PDO; -use PDOStatement; -use think\Db; -use think\db\exception\BindParamException; -use think\Debug; -use think\Exception; -use think\exception\PDOException; -use think\Log; - -/** - * Class Connection - * @package think - * @method Query table(string $table) 指定数据表(含前缀) - * @method Query name(string $name) 指定数据表(不含前缀) - * - */ -abstract class Connection -{ - - /** @var PDOStatement PDO操作实例 */ - protected $PDOStatement; - - /** @var string 当前SQL指令 */ - protected $queryStr = ''; - // 返回或者影响记录数 - protected $numRows = 0; - // 事务指令数 - protected $transTimes = 0; - // 错误信息 - protected $error = ''; - - /** @var PDO[] 数据库连接ID 支持多个连接 */ - protected $links = []; - - /** @var PDO 当前连接ID */ - protected $linkID; - protected $linkRead; - protected $linkWrite; - - // 查询结果类型 - protected $fetchType = PDO::FETCH_ASSOC; - // 字段属性大小写 - protected $attrCase = PDO::CASE_LOWER; - // 监听回调 - protected static $event = []; - // 使用Builder类 - protected $builder; - // 数据库连接参数配置 - protected $config = [ - // 数据库类型 - 'type' => '', - // 服务器地址 - 'hostname' => '', - // 数据库名 - 'database' => '', - // 用户名 - 'username' => '', - // 密码 - 'password' => '', - // 端口 - 'hostport' => '', - // 连接dsn - 'dsn' => '', - // 数据库连接参数 - 'params' => [], - // 数据库编码默认采用utf8 - 'charset' => 'utf8', - // 数据库表前缀 - 'prefix' => '', - // 数据库调试模式 - 'debug' => false, - // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'deploy' => 0, - // 数据库读写是否分离 主从式有效 - 'rw_separate' => false, - // 读写分离后 主服务器数量 - 'master_num' => 1, - // 指定从服务器序号 - 'slave_no' => '', - // 模型写入后自动读取主服务器 - 'read_master' => false, - // 是否严格检查字段是否存在 - 'fields_strict' => true, - // 数据返回类型 - 'result_type' => PDO::FETCH_ASSOC, - // 数据集返回类型 - 'resultset_type' => 'array', - // 自动写入时间戳字段 - 'auto_timestamp' => false, - // 时间字段取出后的默认时间格式 - 'datetime_format' => 'Y-m-d H:i:s', - // 是否需要进行SQL性能分析 - 'sql_explain' => false, - // Builder类 - 'builder' => '', - // Query类 - 'query' => '\\think\\db\\Query', - // 是否需要断线重连 - 'break_reconnect' => false, - ]; - - // PDO连接参数 - protected $params = [ - PDO::ATTR_CASE => PDO::CASE_NATURAL, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, - PDO::ATTR_STRINGIFY_FETCHES => false, - PDO::ATTR_EMULATE_PREPARES => false, - ]; - - // 绑定参数 - protected $bind = []; - - /** - * 构造函数 读取数据库配置信息 - * @access public - * @param array $config 数据库配置数组 - */ - public function __construct(array $config = []) - { - if (!empty($config)) { - $this->config = array_merge($this->config, $config); - } - } - - /** - * 获取新的查询对象 - * @access protected - * @return Query - */ - protected function getQuery() - { - $class = $this->config['query']; - return new $class($this); - } - - /** - * 获取当前连接器类对应的Builder类 - * @access public - * @return string - */ - public function getBuilder() - { - if (!empty($this->builder)) { - return $this->builder; - } else { - return $this->getConfig('builder') ?: '\\think\\db\\builder\\' . ucfirst($this->getConfig('type')); - } - } - - /** - * 调用Query类的查询方法 - * @access public - * @param string $method 方法名称 - * @param array $args 调用参数 - * @return mixed - */ - public function __call($method, $args) - { - return call_user_func_array([$this->getQuery(), $method], $args); - } - - /** - * 解析pdo连接的dsn信息 - * @access protected - * @param array $config 连接信息 - * @return string - */ - abstract protected function parseDsn($config); - - /** - * 取得数据表的字段信息 - * @access public - * @param string $tableName - * @return array - */ - abstract public function getFields($tableName); - - /** - * 取得数据库的表信息 - * @access public - * @param string $dbName - * @return array - */ - abstract public function getTables($dbName); - - /** - * SQL性能分析 - * @access protected - * @param string $sql - * @return array - */ - abstract protected function getExplain($sql); - - /** - * 对返数据表字段信息进行大小写转换出来 - * @access public - * @param array $info 字段信息 - * @return array - */ - public function fieldCase($info) - { - // 字段大小写转换 - switch ($this->attrCase) { - case PDO::CASE_LOWER: - $info = array_change_key_case($info); - break; - case PDO::CASE_UPPER: - $info = array_change_key_case($info, CASE_UPPER); - break; - case PDO::CASE_NATURAL: - default: - // 不做转换 - } - return $info; - } - - /** - * 获取数据库的配置参数 - * @access public - * @param string $config 配置名称 - * @return mixed - */ - public function getConfig($config = '') - { - return $config ? $this->config[$config] : $this->config; - } - - /** - * 设置数据库的配置参数 - * @access public - * @param string|array $config 配置名称 - * @param mixed $value 配置值 - * @return void - */ - public function setConfig($config, $value = '') - { - if (is_array($config)) { - $this->config = array_merge($this->config, $config); - } else { - $this->config[$config] = $value; - } - } - - /** - * 连接数据库方法 - * @access public - * @param array $config 连接参数 - * @param integer $linkNum 连接序号 - * @param array|bool $autoConnection 是否自动连接主数据库(用于分布式) - * @return PDO - * @throws Exception - */ - public function connect(array $config = [], $linkNum = 0, $autoConnection = false) - { - if (!isset($this->links[$linkNum])) { - if (!$config) { - $config = $this->config; - } else { - $config = array_merge($this->config, $config); - } - // 连接参数 - if (isset($config['params']) && is_array($config['params'])) { - $params = $config['params'] + $this->params; - } else { - $params = $this->params; - } - // 记录当前字段属性大小写设置 - $this->attrCase = $params[PDO::ATTR_CASE]; - - // 数据返回类型 - if (isset($config['result_type'])) { - $this->fetchType = $config['result_type']; - } - try { - if (empty($config['dsn'])) { - $config['dsn'] = $this->parseDsn($config); - } - if ($config['debug']) { - $startTime = microtime(true); - } - $this->links[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $params); - if ($config['debug']) { - // 记录数据库连接信息 - Log::record('[ DB ] CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn'], 'sql'); - } - } catch (\PDOException $e) { - if ($autoConnection) { - Log::record($e->getMessage(), 'error'); - return $this->connect($autoConnection, $linkNum); - } else { - throw $e; - } - } - } - return $this->links[$linkNum]; - } - - /** - * 释放查询结果 - * @access public - */ - public function free() - { - $this->PDOStatement = null; - } - - /** - * 获取PDO对象 - * @access public - * @return \PDO|false - */ - public function getPdo() - { - if (!$this->linkID) { - return false; - } else { - return $this->linkID; - } - } - - /** - * 执行查询 返回数据集 - * @access public - * @param string $sql sql指令 - * @param array $bind 参数绑定 - * @param bool $master 是否在主服务器读操作 - * @param bool $pdo 是否返回PDO对象 - * @return mixed - * @throws PDOException - * @throws \Exception - */ - public function query($sql, $bind = [], $master = false, $pdo = false) - { - $this->initConnect($master); - if (!$this->linkID) { - return false; - } - - // 记录SQL语句 - $this->queryStr = $sql; - if ($bind) { - $this->bind = $bind; - } - - Db::$queryTimes++; - try { - // 调试开始 - $this->debug(true); - - // 预处理 - $this->PDOStatement = $this->linkID->prepare($sql); - - // 是否为存储过程调用 - $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']); - // 参数绑定 - if ($procedure) { - $this->bindParam($bind); - } else { - $this->bindValue($bind); - } - // 执行查询 - $this->PDOStatement->execute(); - // 调试结束 - $this->debug(false, '', $master); - // 返回结果集 - return $this->getResult($pdo, $procedure); - } catch (\PDOException $e) { - if ($this->isBreak($e)) { - return $this->close()->query($sql, $bind, $master, $pdo); - } - throw new PDOException($e, $this->config, $this->getLastsql()); - } catch (\Throwable $e) { - if ($this->isBreak($e)) { - return $this->close()->query($sql, $bind, $master, $pdo); - } - throw $e; - } catch (\Exception $e) { - if ($this->isBreak($e)) { - return $this->close()->query($sql, $bind, $master, $pdo); - } - throw $e; - } - } - - /** - * 执行语句 - * @access public - * @param string $sql sql指令 - * @param array $bind 参数绑定 - * @param Query $query 查询对象 - * @return int - * @throws PDOException - * @throws \Exception - */ - public function execute($sql, $bind = [], Query $query = null) - { - $this->initConnect(true); - if (!$this->linkID) { - return false; - } - - // 记录SQL语句 - $this->queryStr = $sql; - if ($bind) { - $this->bind = $bind; - } - - Db::$executeTimes++; - try { - // 调试开始 - $this->debug(true); - - // 预处理 - $this->PDOStatement = $this->linkID->prepare($sql); - - // 是否为存储过程调用 - $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']); - // 参数绑定 - if ($procedure) { - $this->bindParam($bind); - } else { - $this->bindValue($bind); - } - // 执行语句 - $this->PDOStatement->execute(); - // 调试结束 - $this->debug(false, '', true); - - if ($query && !empty($this->config['deploy']) && !empty($this->config['read_master'])) { - $query->readMaster(); - } - - $this->numRows = $this->PDOStatement->rowCount(); - return $this->numRows; - } catch (\PDOException $e) { - if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind, $query); - } - throw new PDOException($e, $this->config, $this->getLastsql()); - } catch (\Throwable $e) { - if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind, $query); - } - throw $e; - } catch (\Exception $e) { - if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind, $query); - } - throw $e; - } - } - - /** - * 根据参数绑定组装最终的SQL语句 便于调试 - * @access public - * @param string $sql 带参数绑定的sql语句 - * @param array $bind 参数绑定列表 - * @return string - */ - public function getRealSql($sql, array $bind = []) - { - if (is_array($sql)) { - $sql = implode(';', $sql); - } - - foreach ($bind as $key => $val) { - $value = is_array($val) ? $val[0] : $val; - $type = is_array($val) ? $val[1] : PDO::PARAM_STR; - if (PDO::PARAM_STR == $type) { - $value = $this->quote($value); - } elseif (PDO::PARAM_INT == $type) { - $value = (float) $value; - } - // 判断占位符 - $sql = is_numeric($key) ? - substr_replace($sql, $value, strpos($sql, '?'), 1) : - str_replace( - [':' . $key . ')', ':' . $key . ',', ':' . $key . ' ', ':' . $key . PHP_EOL], - [$value . ')', $value . ',', $value . ' ', $value . PHP_EOL], - $sql . ' '); - } - return rtrim($sql); - } - - /** - * 参数绑定 - * 支持 ['name'=>'value','id'=>123] 对应命名占位符 - * 或者 ['value',123] 对应问号占位符 - * @access public - * @param array $bind 要绑定的参数列表 - * @return void - * @throws BindParamException - */ - protected function bindValue(array $bind = []) - { - foreach ($bind as $key => $val) { - // 占位符 - $param = is_numeric($key) ? $key + 1 : ':' . $key; - if (is_array($val)) { - if (PDO::PARAM_INT == $val[1] && '' === $val[0]) { - $val[0] = 0; - } - $result = $this->PDOStatement->bindValue($param, $val[0], $val[1]); - } else { - $result = $this->PDOStatement->bindValue($param, $val); - } - if (!$result) { - throw new BindParamException( - "Error occurred when binding parameters '{$param}'", - $this->config, - $this->getLastsql(), - $bind - ); - } - } - } - - /** - * 存储过程的输入输出参数绑定 - * @access public - * @param array $bind 要绑定的参数列表 - * @return void - * @throws BindParamException - */ - protected function bindParam($bind) - { - foreach ($bind as $key => $val) { - $param = is_numeric($key) ? $key + 1 : ':' . $key; - if (is_array($val)) { - array_unshift($val, $param); - $result = call_user_func_array([$this->PDOStatement, 'bindParam'], $val); - } else { - $result = $this->PDOStatement->bindValue($param, $val); - } - if (!$result) { - $param = array_shift($val); - throw new BindParamException( - "Error occurred when binding parameters '{$param}'", - $this->config, - $this->getLastsql(), - $bind - ); - } - } - } - - /** - * 获得数据集数组 - * @access protected - * @param bool $pdo 是否返回PDOStatement - * @param bool $procedure 是否存储过程 - * @return PDOStatement|array - */ - protected function getResult($pdo = false, $procedure = false) - { - if ($pdo) { - // 返回PDOStatement对象处理 - return $this->PDOStatement; - } - if ($procedure) { - // 存储过程返回结果 - return $this->procedure(); - } - $result = $this->PDOStatement->fetchAll($this->fetchType); - $this->numRows = count($result); - return $result; - } - - /** - * 获得存储过程数据集 - * @access protected - * @return array - */ - protected function procedure() - { - $item = []; - do { - $result = $this->getResult(); - if ($result) { - $item[] = $result; - } - } while ($this->PDOStatement->nextRowset()); - $this->numRows = count($item); - return $item; - } - - /** - * 执行数据库事务 - * @access public - * @param callable $callback 数据操作方法回调 - * @return mixed - * @throws PDOException - * @throws \Exception - * @throws \Throwable - */ - public function transaction($callback) - { - $this->startTrans(); - try { - $result = null; - if (is_callable($callback)) { - $result = call_user_func_array($callback, [$this]); - } - $this->commit(); - return $result; - } catch (\Exception $e) { - $this->rollback(); - throw $e; - } catch (\Throwable $e) { - $this->rollback(); - throw $e; - } - } - - /** - * 启动事务 - * @access public - * @return bool|mixed - * @throws \Exception - */ - public function startTrans() - { - $this->initConnect(true); - if (!$this->linkID) { - return false; - } - - ++$this->transTimes; - try { - if (1 == $this->transTimes) { - $this->linkID->beginTransaction(); - } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { - $this->linkID->exec( - $this->parseSavepoint('trans' . $this->transTimes) - ); - } - - } catch (\Exception $e) { - if ($this->isBreak($e)) { - --$this->transTimes; - return $this->close()->startTrans(); - } - throw $e; - } catch (\Error $e) { - if ($this->isBreak($e)) { - --$this->transTimes; - return $this->close()->startTrans(); - } - throw $e; - } - } - - /** - * 用于非自动提交状态下面的查询提交 - * @access public - * @return void - * @throws PDOException - */ - public function commit() - { - $this->initConnect(true); - - if (1 == $this->transTimes) { - $this->linkID->commit(); - } - - --$this->transTimes; - } - - /** - * 事务回滚 - * @access public - * @return void - * @throws PDOException - */ - public function rollback() - { - $this->initConnect(true); - - if (1 == $this->transTimes) { - $this->linkID->rollBack(); - } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { - $this->linkID->exec( - $this->parseSavepointRollBack('trans' . $this->transTimes) - ); - } - - $this->transTimes = max(0, $this->transTimes - 1); - } - - /** - * 是否支持事务嵌套 - * @return bool - */ - protected function supportSavepoint() - { - return false; - } - - /** - * 生成定义保存点的SQL - * @param $name - * @return string - */ - protected function parseSavepoint($name) - { - return 'SAVEPOINT ' . $name; - } - - /** - * 生成回滚到保存点的SQL - * @param $name - * @return string - */ - protected function parseSavepointRollBack($name) - { - return 'ROLLBACK TO SAVEPOINT ' . $name; - } - - /** - * 批处理执行SQL语句 - * 批处理的指令都认为是execute操作 - * @access public - * @param array $sqlArray SQL批处理指令 - * @return boolean - */ - public function batchQuery($sqlArray = [], $bind = [], Query $query = null) - { - if (!is_array($sqlArray)) { - return false; - } - // 自动启动事务支持 - $this->startTrans(); - try { - foreach ($sqlArray as $sql) { - $this->execute($sql, $bind, $query); - } - // 提交事务 - $this->commit(); - } catch (\Exception $e) { - $this->rollback(); - throw $e; - } - - return true; - } - - /** - * 获得查询次数 - * @access public - * @param boolean $execute 是否包含所有查询 - * @return integer - */ - public function getQueryTimes($execute = false) - { - return $execute ? Db::$queryTimes + Db::$executeTimes : Db::$queryTimes; - } - - /** - * 获得执行次数 - * @access public - * @return integer - */ - public function getExecuteTimes() - { - return Db::$executeTimes; - } - - /** - * 关闭数据库(或者重新连接) - * @access public - * @return $this - */ - public function close() - { - $this->linkID = null; - $this->linkWrite = null; - $this->linkRead = null; - $this->links = []; - // 释放查询 - $this->free(); - return $this; - } - - /** - * 是否断线 - * @access protected - * @param \PDOException|\Exception $e 异常对象 - * @return bool - */ - protected function isBreak($e) - { - if (!$this->config['break_reconnect']) { - return false; - } - - $info = [ - 'server has gone away', - 'no connection to the server', - 'Lost connection', - 'is dead or not enabled', - 'Error while sending', - 'decryption failed or bad record mac', - 'server closed the connection unexpectedly', - 'SSL connection has been closed unexpectedly', - 'Error writing data to the connection', - 'Resource deadlock avoided', - 'failed with errno', - ]; - - $error = $e->getMessage(); - - foreach ($info as $msg) { - if (false !== stripos($error, $msg)) { - return true; - } - } - return false; - } - - /** - * 获取最近一次查询的sql语句 - * @access public - * @return string - */ - public function getLastSql() - { - return $this->getRealSql($this->queryStr, $this->bind); - } - - /** - * 获取最近插入的ID - * @access public - * @param string $sequence 自增序列名 - * @return string - */ - public function getLastInsID($sequence = null) - { - return $this->linkID->lastInsertId($sequence); - } - - /** - * 获取返回或者影响的记录数 - * @access public - * @return integer - */ - public function getNumRows() - { - return $this->numRows; - } - - /** - * 获取最近的错误信息 - * @access public - * @return string - */ - public function getError() - { - if ($this->PDOStatement) { - $error = $this->PDOStatement->errorInfo(); - $error = $error[1] . ':' . $error[2]; - } else { - $error = ''; - } - if ('' != $this->queryStr) { - $error .= "\n [ SQL语句 ] : " . $this->getLastsql(); - } - return $error; - } - - /** - * SQL指令安全过滤 - * @access public - * @param string $str SQL字符串 - * @param bool $master 是否主库查询 - * @return string - */ - public function quote($str, $master = true) - { - $this->initConnect($master); - return $this->linkID ? $this->linkID->quote($str) : $str; - } - - /** - * 数据库调试 记录当前SQL及分析性能 - * @access protected - * @param boolean $start 调试开始标记 true 开始 false 结束 - * @param string $sql 执行的SQL语句 留空自动获取 - * @param boolean $master 主从标记 - * @return void - */ - protected function debug($start, $sql = '', $master = false) - { - if (!empty($this->config['debug'])) { - // 开启数据库调试模式 - if ($start) { - Debug::remark('queryStartTime', 'time'); - } else { - // 记录操作结束时间 - Debug::remark('queryEndTime', 'time'); - $runtime = Debug::getRangeTime('queryStartTime', 'queryEndTime'); - $sql = $sql ?: $this->getLastsql(); - $result = []; - // SQL性能分析 - if ($this->config['sql_explain'] && 0 === stripos(trim($sql), 'select')) { - $result = $this->getExplain($sql); - } - // SQL监听 - $this->trigger($sql, $runtime, $result, $master); - } - } - } - - /** - * 监听SQL执行 - * @access public - * @param callable $callback 回调方法 - * @return void - */ - public function listen($callback) - { - self::$event[] = $callback; - } - - /** - * 触发SQL事件 - * @access protected - * @param string $sql SQL语句 - * @param float $runtime SQL运行时间 - * @param mixed $explain SQL分析 - * @param bool $master 主从标记 - * @return void - */ - protected function trigger($sql, $runtime, $explain = [], $master = false) - { - if (!empty(self::$event)) { - foreach (self::$event as $callback) { - if (is_callable($callback)) { - call_user_func_array($callback, [$sql, $runtime, $explain, $master]); - } - } - } else { - // 未注册监听则记录到日志中 - if ($this->config['deploy']) { - // 分布式记录当前操作的主从 - $master = $master ? 'master|' : 'slave|'; - } else { - $master = ''; - } - - Log::record('[ SQL ] ' . $sql . ' [ ' . $master . 'RunTime:' . $runtime . 's ]', 'sql'); - if (!empty($explain)) { - Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql'); - } - } - } - - /** - * 初始化数据库连接 - * @access protected - * @param boolean $master 是否主服务器 - * @return void - */ - protected function initConnect($master = true) - { - if (!empty($this->config['deploy'])) { - // 采用分布式数据库 - if ($master || $this->transTimes) { - if (!$this->linkWrite) { - $this->linkWrite = $this->multiConnect(true); - } - $this->linkID = $this->linkWrite; - } else { - if (!$this->linkRead) { - $this->linkRead = $this->multiConnect(false); - } - $this->linkID = $this->linkRead; - } - } elseif (!$this->linkID) { - // 默认单数据库 - $this->linkID = $this->connect(); - } - } - - /** - * 连接分布式服务器 - * @access protected - * @param boolean $master 主服务器 - * @return PDO - */ - protected function multiConnect($master = false) - { - $_config = []; - // 分布式数据库配置解析 - foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) { - $_config[$name] = explode(',', $this->config[$name]); - } - - // 主服务器序号 - $m = floor(mt_rand(0, $this->config['master_num'] - 1)); - - if ($this->config['rw_separate']) { - // 主从式采用读写分离 - if ($master) // 主服务器写入 - { - $r = $m; - } elseif (is_numeric($this->config['slave_no'])) { - // 指定服务器读 - $r = $this->config['slave_no']; - } else { - // 读操作连接从服务器 每次随机连接的数据库 - $r = floor(mt_rand($this->config['master_num'], count($_config['hostname']) - 1)); - } - } else { - // 读写操作不区分服务器 每次随机连接的数据库 - $r = floor(mt_rand(0, count($_config['hostname']) - 1)); - } - $dbMaster = false; - if ($m != $r) { - $dbMaster = []; - foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) { - $dbMaster[$name] = isset($_config[$name][$m]) ? $_config[$name][$m] : $_config[$name][0]; - } - } - $dbConfig = []; - foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) { - $dbConfig[$name] = isset($_config[$name][$r]) ? $_config[$name][$r] : $_config[$name][0]; - } - return $this->connect($dbConfig, $r, $r == $m ? false : $dbMaster); - } - - /** - * 析构方法 - * @access public - */ - public function __destruct() - { - // 释放查询 - if ($this->PDOStatement) { - $this->free(); - } - // 关闭连接 - $this->close(); - } -} diff --git a/thinkphp/library/think/db/Expression.php b/thinkphp/library/think/db/Expression.php deleted file mode 100755 index f1b92ab..0000000 --- a/thinkphp/library/think/db/Expression.php +++ /dev/null @@ -1,48 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db; - -class Expression -{ - /** - * 查询表达式 - * - * @var string - */ - protected $value; - - /** - * 创建一个查询表达式 - * - * @param string $value - * @return void - */ - public function __construct($value) - { - $this->value = $value; - } - - /** - * 获取表达式 - * - * @return string - */ - public function getValue() - { - return $this->value; - } - - public function __toString() - { - return (string) $this->value; - } -} diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php deleted file mode 100755 index 75086bc..0000000 --- a/thinkphp/library/think/db/Query.php +++ /dev/null @@ -1,3045 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db; - -use PDO; -use think\App; -use think\Cache; -use think\Collection; -use think\Config; -use think\Db; -use think\db\exception\BindParamException; -use think\db\exception\DataNotFoundException; -use think\db\exception\ModelNotFoundException; -use think\Exception; -use think\exception\DbException; -use think\exception\PDOException; -use think\Loader; -use think\Model; -use think\model\Relation; -use think\model\relation\OneToOne; -use think\Paginator; - -class Query -{ - // 数据库Connection对象实例 - protected $connection; - // 数据库Builder对象实例 - protected $builder; - // 当前模型类名称 - protected $model; - // 当前数据表名称(含前缀) - protected $table = ''; - // 当前数据表名称(不含前缀) - protected $name = ''; - // 当前数据表主键 - protected $pk; - // 当前数据表前缀 - protected $prefix = ''; - // 查询参数 - protected $options = []; - // 参数绑定 - protected $bind = []; - // 数据表信息 - protected static $info = []; - // 回调事件 - private static $event = []; - // 读取主库 - private static $readMaster = []; - - /** - * 构造函数 - * @access public - * @param Connection $connection 数据库对象实例 - * @param Model $model 模型对象 - */ - public function __construct(Connection $connection = null, $model = null) - { - $this->connection = $connection ?: Db::connect([], true); - $this->prefix = $this->connection->getConfig('prefix'); - $this->model = $model; - // 设置当前连接的Builder对象 - $this->setBuilder(); - } - - /** - * 利用__call方法实现一些特殊的Model方法 - * @access public - * @param string $method 方法名称 - * @param array $args 调用参数 - * @return mixed - * @throws DbException - * @throws Exception - */ - public function __call($method, $args) - { - if (strtolower(substr($method, 0, 5)) == 'getby') { - // 根据某个字段获取记录 - $field = Loader::parseName(substr($method, 5)); - $where[$field] = $args[0]; - return $this->where($where)->find(); - } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') { - // 根据某个字段获取记录的某个值 - $name = Loader::parseName(substr($method, 10)); - $where[$name] = $args[0]; - return $this->where($where)->value($args[1]); - } elseif ($this->model && method_exists($this->model, 'scope' . $method)) { - // 动态调用命名范围 - $method = 'scope' . $method; - array_unshift($args, $this); - - call_user_func_array([$this->model, $method], $args); - return $this; - } else { - throw new Exception('method not exist:' . __CLASS__ . '->' . $method); - } - } - - /** - * 获取当前的数据库Connection对象 - * @access public - * @return Connection - */ - public function getConnection() - { - return $this->connection; - } - - /** - * 切换当前的数据库连接 - * @access public - * @param mixed $config - * @return $this - */ - public function connect($config) - { - $this->connection = Db::connect($config); - $this->setBuilder(); - $this->prefix = $this->connection->getConfig('prefix'); - return $this; - } - - /** - * 设置当前的数据库Builder对象 - * @access protected - * @return void - */ - protected function setBuilder() - { - $class = $this->connection->getBuilder(); - $this->builder = new $class($this->connection, $this); - } - - /** - * 获取当前的模型对象实例 - * @access public - * @return Model|null - */ - public function getModel() - { - return $this->model; - } - - /** - * 设置后续从主库读取数据 - * @access public - * @param bool $allTable - * @return void - */ - public function readMaster($allTable = false) - { - if ($allTable) { - $table = '*'; - } else { - $table = isset($this->options['table']) ? $this->options['table'] : $this->getTable(); - } - - static::$readMaster[$table] = true; - - return $this; - } - - /** - * 获取当前的builder实例对象 - * @access public - * @return Builder - */ - public function getBuilder() - { - return $this->builder; - } - - /** - * 指定默认的数据表名(不含前缀) - * @access public - * @param string $name - * @return $this - */ - public function name($name) - { - $this->name = $name; - return $this; - } - - /** - * 指定默认数据表名(含前缀) - * @access public - * @param string $table 表名 - * @return $this - */ - public function setTable($table) - { - $this->table = $table; - return $this; - } - - /** - * 得到当前或者指定名称的数据表 - * @access public - * @param string $name - * @return string - */ - public function getTable($name = '') - { - if ($name || empty($this->table)) { - $name = $name ?: $this->name; - $tableName = $this->prefix; - if ($name) { - $tableName .= Loader::parseName($name); - } - } else { - $tableName = $this->table; - } - return $tableName; - } - - /** - * 将SQL语句中的__TABLE_NAME__字符串替换成带前缀的表名(小写) - * @access public - * @param string $sql sql语句 - * @return string - */ - public function parseSqlTable($sql) - { - if (false !== strpos($sql, '__')) { - $prefix = $this->prefix; - $sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) { - return $prefix . strtolower($match[1]); - }, $sql); - } - return $sql; - } - - /** - * 执行查询 返回数据集 - * @access public - * @param string $sql sql指令 - * @param array $bind 参数绑定 - * @param boolean $master 是否在主服务器读操作 - * @param bool|string $class 指定返回的数据集对象 - * @return mixed - * @throws BindParamException - * @throws PDOException - */ - public function query($sql, $bind = [], $master = false, $class = false) - { - return $this->connection->query($sql, $bind, $master, $class); - } - - /** - * 执行语句 - * @access public - * @param string $sql sql指令 - * @param array $bind 参数绑定 - * @return int - * @throws BindParamException - * @throws PDOException - */ - public function execute($sql, $bind = []) - { - return $this->connection->execute($sql, $bind, $this); - } - - /** - * 获取最近插入的ID - * @access public - * @param string $sequence 自增序列名 - * @return string - */ - public function getLastInsID($sequence = null) - { - return $this->connection->getLastInsID($sequence); - } - - /** - * 获取最近一次查询的sql语句 - * @access public - * @return string - */ - public function getLastSql() - { - return $this->connection->getLastSql(); - } - - /** - * 执行数据库事务 - * @access public - * @param callable $callback 数据操作方法回调 - * @return mixed - */ - public function transaction($callback) - { - return $this->connection->transaction($callback); - } - - /** - * 启动事务 - * @access public - * @return void - */ - public function startTrans() - { - $this->connection->startTrans(); - } - - /** - * 用于非自动提交状态下面的查询提交 - * @access public - * @return void - * @throws PDOException - */ - public function commit() - { - $this->connection->commit(); - } - - /** - * 事务回滚 - * @access public - * @return void - * @throws PDOException - */ - public function rollback() - { - $this->connection->rollback(); - } - - /** - * 批处理执行SQL语句 - * 批处理的指令都认为是execute操作 - * @access public - * @param array $sql SQL批处理指令 - * @return boolean - */ - public function batchQuery($sql = [], $bind = []) - { - return $this->connection->batchQuery($sql, $bind); - } - - /** - * 获取数据库的配置参数 - * @access public - * @param string $name 参数名称 - * @return boolean - */ - public function getConfig($name = '') - { - return $this->connection->getConfig($name); - } - - /** - * 得到分表的的数据表名 - * @access public - * @param array $data 操作的数据 - * @param string $field 分表依据的字段 - * @param array $rule 分表规则 - * @return string - */ - public function getPartitionTableName($data, $field, $rule = []) - { - // 对数据表进行分区 - if ($field && isset($data[$field])) { - $value = $data[$field]; - $type = $rule['type']; - switch ($type) { - case 'id': - // 按照id范围分表 - $step = $rule['expr']; - $seq = floor($value / $step) + 1; - break; - case 'year': - // 按照年份分表 - if (!is_numeric($value)) { - $value = strtotime($value); - } - $seq = date('Y', $value) - $rule['expr'] + 1; - break; - case 'mod': - // 按照id的模数分表 - $seq = ($value % $rule['num']) + 1; - break; - case 'md5': - // 按照md5的序列分表 - $seq = (ord(substr(md5($value), 0, 1)) % $rule['num']) + 1; - break; - default: - if (function_exists($type)) { - // 支持指定函数哈希 - $seq = (ord(substr($type($value), 0, 1)) % $rule['num']) + 1; - } else { - // 按照字段的首字母的值分表 - $seq = (ord($value{0}) % $rule['num']) + 1; - } - } - return $this->getTable() . '_' . $seq; - } else { - // 当设置的分表字段不在查询条件或者数据中 - // 进行联合查询,必须设定 partition['num'] - $tableName = []; - for ($i = 0; $i < $rule['num']; $i++) { - $tableName[] = 'SELECT * FROM ' . $this->getTable() . '_' . ($i + 1); - } - - $tableName = '( ' . implode(" UNION ", $tableName) . ') AS ' . $this->name; - return $tableName; - } - } - - /** - * 得到某个字段的值 - * @access public - * @param string $field 字段名 - * @param mixed $default 默认值 - * @param bool $force 强制转为数字类型 - * @return mixed - */ - public function value($field, $default = null, $force = false) - { - $result = false; - if (empty($this->options['fetch_sql']) && !empty($this->options['cache'])) { - // 判断查询缓存 - $cache = $this->options['cache']; - if (empty($this->options['table'])) { - $this->options['table'] = $this->getTable(); - } - $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind)); - $result = Cache::get($key); - } - if (false === $result) { - if (isset($this->options['field'])) { - unset($this->options['field']); - } - $pdo = $this->field($field)->limit(1)->getPdo(); - if (is_string($pdo)) { - // 返回SQL语句 - return $pdo; - } - - $result = $pdo->fetchColumn(); - if ($force) { - $result = (float) $result; - } - - if (isset($cache) && false !== $result) { - // 缓存数据 - $this->cacheData($key, $result, $cache); - } - } else { - // 清空查询条件 - $this->options = []; - } - return false !== $result ? $result : $default; - } - - /** - * 得到某个列的数组 - * @access public - * @param string $field 字段名 多个字段用逗号分隔 - * @param string $key 索引 - * @return array - */ - public function column($field, $key = '') - { - $result = false; - if (empty($this->options['fetch_sql']) && !empty($this->options['cache'])) { - // 判断查询缓存 - $cache = $this->options['cache']; - if (empty($this->options['table'])) { - $this->options['table'] = $this->getTable(); - } - $guid = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind)); - $result = Cache::get($guid); - } - if (false === $result) { - if (isset($this->options['field'])) { - unset($this->options['field']); - } - if (is_null($field)) { - $field = '*'; - } elseif ($key && '*' != $field) { - $field = $key . ',' . $field; - } - $pdo = $this->field($field)->getPdo(); - if (is_string($pdo)) { - // 返回SQL语句 - return $pdo; - } - if (1 == $pdo->columnCount()) { - $result = $pdo->fetchAll(PDO::FETCH_COLUMN); - } else { - $resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC); - if ($resultSet) { - $fields = array_keys($resultSet[0]); - $count = count($fields); - $key1 = array_shift($fields); - $key2 = $fields ? array_shift($fields) : ''; - $key = $key ?: $key1; - if (strpos($key, '.')) { - list($alias, $key) = explode('.', $key); - } - foreach ($resultSet as $val) { - if ($count > 2) { - $result[$val[$key]] = $val; - } elseif (2 == $count) { - $result[$val[$key]] = $val[$key2]; - } elseif (1 == $count) { - $result[$val[$key]] = $val[$key1]; - } - } - } else { - $result = []; - } - } - if (isset($cache) && isset($guid)) { - // 缓存数据 - $this->cacheData($guid, $result, $cache); - } - } else { - // 清空查询条件 - $this->options = []; - } - return $result; - } - - /** - * COUNT查询 - * @access public - * @param string $field 字段名 - * @return integer|string - */ - public function count($field = '*') - { - if (isset($this->options['group'])) { - if (!preg_match('/^[\w\.\*]+$/', $field)) { - throw new Exception('not support data:' . $field); - } - // 支持GROUP - $options = $this->getOptions(); - $subSql = $this->options($options)->field('count(' . $field . ')')->bind($this->bind)->buildSql(); - - $count = $this->table([$subSql => '_group_count_'])->value('COUNT(*) AS tp_count', 0, true); - } else { - $count = $this->aggregate('COUNT', $field, true); - } - - return is_string($count) ? $count : (int) $count; - - } - - /** - * 聚合查询 - * @access public - * @param string $aggregate 聚合方法 - * @param string $field 字段名 - * @param bool $force 强制转为数字类型 - * @return mixed - */ - public function aggregate($aggregate, $field, $force = false) - { - if (0 === stripos($field, 'DISTINCT ')) { - list($distinct, $field) = explode(' ', $field); - } - - if (!preg_match('/^[\w\.\+\-\*]+$/', $field)) { - throw new Exception('not support data:' . $field); - } - - $result = $this->value($aggregate . '(' . (!empty($distinct) ? 'DISTINCT ' : '') . $field . ') AS tp_' . strtolower($aggregate), 0, $force); - - return $result; - } - - /** - * SUM查询 - * @access public - * @param string $field 字段名 - * @return float|int - */ - public function sum($field) - { - return $this->aggregate('SUM', $field, true); - } - - /** - * MIN查询 - * @access public - * @param string $field 字段名 - * @param bool $force 强制转为数字类型 - * @return mixed - */ - public function min($field, $force = true) - { - return $this->aggregate('MIN', $field, $force); - } - - /** - * MAX查询 - * @access public - * @param string $field 字段名 - * @param bool $force 强制转为数字类型 - * @return mixed - */ - public function max($field, $force = true) - { - return $this->aggregate('MAX', $field, $force); - } - - /** - * AVG查询 - * @access public - * @param string $field 字段名 - * @return float|int - */ - public function avg($field) - { - return $this->aggregate('AVG', $field, true); - } - - /** - * 设置记录的某个字段值 - * 支持使用数据库字段和方法 - * @access public - * @param string|array $field 字段名 - * @param mixed $value 字段值 - * @return integer - */ - public function setField($field, $value = '') - { - if (is_array($field)) { - $data = $field; - } else { - $data[$field] = $value; - } - return $this->update($data); - } - - /** - * 字段值(延迟)增长 - * @access public - * @param string $field 字段名 - * @param integer $step 增长值 - * @param integer $lazyTime 延时时间(s) - * @return integer|true - * @throws Exception - */ - public function setInc($field, $step = 1, $lazyTime = 0) - { - $condition = !empty($this->options['where']) ? $this->options['where'] : []; - if (empty($condition)) { - // 没有条件不做任何更新 - throw new Exception('no data to update'); - } - if ($lazyTime > 0) { - // 延迟写入 - $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition) . serialize($this->bind)); - $step = $this->lazyWrite('inc', $guid, $step, $lazyTime); - if (false === $step) { - // 清空查询条件 - $this->options = []; - return true; - } - } - return $this->setField($field, ['inc', $step]); - } - - /** - * 字段值(延迟)减少 - * @access public - * @param string $field 字段名 - * @param integer $step 减少值 - * @param integer $lazyTime 延时时间(s) - * @return integer|true - * @throws Exception - */ - public function setDec($field, $step = 1, $lazyTime = 0) - { - $condition = !empty($this->options['where']) ? $this->options['where'] : []; - if (empty($condition)) { - // 没有条件不做任何更新 - throw new Exception('no data to update'); - } - if ($lazyTime > 0) { - // 延迟写入 - $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition) . serialize($this->bind)); - $step = $this->lazyWrite('dec', $guid, $step, $lazyTime); - if (false === $step) { - // 清空查询条件 - $this->options = []; - return true; - } - return $this->setField($field, ['inc', $step]); - } - return $this->setField($field, ['dec', $step]); - } - - /** - * 延时更新检查 返回false表示需要延时 - * 否则返回实际写入的数值 - * @access protected - * @param string $type 自增或者自减 - * @param string $guid 写入标识 - * @param integer $step 写入步进值 - * @param integer $lazyTime 延时时间(s) - * @return false|integer - */ - protected function lazyWrite($type, $guid, $step, $lazyTime) - { - if (!Cache::has($guid . '_time')) { - // 计时开始 - Cache::set($guid . '_time', $_SERVER['REQUEST_TIME'], 0); - Cache::$type($guid, $step); - } elseif ($_SERVER['REQUEST_TIME'] > Cache::get($guid . '_time') + $lazyTime) { - // 删除缓存 - $value = Cache::$type($guid, $step); - Cache::rm($guid); - Cache::rm($guid . '_time'); - return 0 === $value ? false : $value; - } else { - // 更新缓存 - Cache::$type($guid, $step); - } - return false; - } - - /** - * 查询SQL组装 join - * @access public - * @param mixed $join 关联的表名 - * @param mixed $condition 条件 - * @param string $type JOIN类型 - * @return $this - */ - public function join($join, $condition = null, $type = 'INNER') - { - if (empty($condition)) { - // 如果为组数,则循环调用join - foreach ($join as $key => $value) { - if (is_array($value) && 2 <= count($value)) { - $this->join($value[0], $value[1], isset($value[2]) ? $value[2] : $type); - } - } - } else { - $table = $this->getJoinTable($join); - - $this->options['join'][] = [$table, strtoupper($type), $condition]; - } - return $this; - } - - /** - * 获取Join表名及别名 支持 - * ['prefix_table或者子查询'=>'alias'] 'prefix_table alias' 'table alias' - * @access public - * @param array|string $join - * @return array|string - */ - protected function getJoinTable($join, &$alias = null) - { - // 传入的表名为数组 - if (is_array($join)) { - $table = $join; - $alias = array_shift($join); - } else { - $join = trim($join); - if (false !== strpos($join, '(')) { - // 使用子查询 - $table = $join; - } else { - $prefix = $this->prefix; - if (strpos($join, ' ')) { - // 使用别名 - list($table, $alias) = explode(' ', $join); - } else { - $table = $join; - if (false === strpos($join, '.') && 0 !== strpos($join, '__')) { - $alias = $join; - } - } - if ($prefix && false === strpos($table, '.') && 0 !== strpos($table, $prefix) && 0 !== strpos($table, '__')) { - $table = $this->getTable($table); - } - } - if (isset($alias) && $table != $alias) { - $table = [$table => $alias]; - } - } - return $table; - } - - /** - * 查询SQL组装 union - * @access public - * @param mixed $union - * @param boolean $all - * @return $this - */ - public function union($union, $all = false) - { - $this->options['union']['type'] = $all ? 'UNION ALL' : 'UNION'; - - if (is_array($union)) { - $this->options['union'] = array_merge($this->options['union'], $union); - } else { - $this->options['union'][] = $union; - } - return $this; - } - - /** - * 指定查询字段 支持字段排除和指定数据表 - * @access public - * @param mixed $field - * @param boolean $except 是否排除 - * @param string $tableName 数据表名 - * @param string $prefix 字段前缀 - * @param string $alias 别名前缀 - * @return $this - */ - public function field($field, $except = false, $tableName = '', $prefix = '', $alias = '') - { - if (empty($field)) { - return $this; - } elseif ($field instanceof Expression) { - $this->options['field'][] = $field; - return $this; - } - - if (is_string($field)) { - if (preg_match('/[\<\'\"\(]/', $field)) { - return $this->fieldRaw($field); - } - $field = array_map('trim', explode(',', $field)); - } - if (true === $field) { - // 获取全部字段 - $fields = $this->getTableInfo($tableName ?: (isset($this->options['table']) ? $this->options['table'] : ''), 'fields'); - $field = $fields ?: ['*']; - } elseif ($except) { - // 字段排除 - $fields = $this->getTableInfo($tableName ?: (isset($this->options['table']) ? $this->options['table'] : ''), 'fields'); - $field = $fields ? array_diff($fields, $field) : $field; - } - if ($tableName) { - // 添加统一的前缀 - $prefix = $prefix ?: $tableName; - foreach ($field as $key => $val) { - if (is_numeric($key)) { - $val = $prefix . '.' . $val . ($alias ? ' AS ' . $alias . $val : ''); - } - $field[$key] = $val; - } - } - - if (isset($this->options['field'])) { - $field = array_merge((array) $this->options['field'], $field); - } - $this->options['field'] = array_unique($field); - return $this; - } - - /** - * 表达式方式指定查询字段 - * @access public - * @param string $field 字段名 - * @param array $bind 参数绑定 - * @return $this - */ - public function fieldRaw($field, array $bind = []) - { - $this->options['field'][] = $this->raw($field); - - if ($bind) { - $this->bind($bind); - } - - return $this; - } - - /** - * 设置数据 - * @access public - * @param mixed $field 字段名或者数据 - * @param mixed $value 字段值 - * @return $this - */ - public function data($field, $value = null) - { - if (is_array($field)) { - $this->options['data'] = isset($this->options['data']) ? array_merge($this->options['data'], $field) : $field; - } else { - $this->options['data'][$field] = $value; - } - return $this; - } - - /** - * 字段值增长 - * @access public - * @param string|array $field 字段名 - * @param integer $step 增长值 - * @return $this - */ - public function inc($field, $step = 1) - { - $fields = is_string($field) ? explode(',', $field) : $field; - foreach ($fields as $field) { - $this->data($field, ['inc', $step]); - } - return $this; - } - - /** - * 字段值减少 - * @access public - * @param string|array $field 字段名 - * @param integer $step 增长值 - * @return $this - */ - public function dec($field, $step = 1) - { - $fields = is_string($field) ? explode(',', $field) : $field; - foreach ($fields as $field) { - $this->data($field, ['dec', $step]); - } - return $this; - } - - /** - * 使用表达式设置数据 - * @access public - * @param string $field 字段名 - * @param string $value 字段值 - * @return $this - */ - public function exp($field, $value) - { - $this->data($field, $this->raw($value)); - return $this; - } - - /** - * 使用表达式设置数据 - * @access public - * @param mixed $value 表达式 - * @return Expression - */ - public function raw($value) - { - return new Expression($value); - } - - /** - * 指定JOIN查询字段 - * @access public - * @param string|array $table 数据表 - * @param string|array $field 查询字段 - * @param mixed $on JOIN条件 - * @param string $type JOIN类型 - * @return $this - */ - public function view($join, $field = true, $on = null, $type = 'INNER') - { - $this->options['view'] = true; - if (is_array($join) && key($join) === 0) { - foreach ($join as $key => $val) { - $this->view($val[0], $val[1], isset($val[2]) ? $val[2] : null, isset($val[3]) ? $val[3] : 'INNER'); - } - } else { - $fields = []; - $table = $this->getJoinTable($join, $alias); - - if (true === $field) { - $fields = $alias . '.*'; - } else { - if (is_string($field)) { - $field = explode(',', $field); - } - foreach ($field as $key => $val) { - if (is_numeric($key)) { - $fields[] = $alias . '.' . $val; - $this->options['map'][$val] = $alias . '.' . $val; - } else { - if (preg_match('/[,=\.\'\"\(\s]/', $key)) { - $name = $key; - } else { - $name = $alias . '.' . $key; - } - $fields[$name] = $val; - $this->options['map'][$val] = $name; - } - } - } - $this->field($fields); - if ($on) { - $this->join($table, $on, $type); - } else { - $this->table($table); - } - } - return $this; - } - - /** - * 设置分表规则 - * @access public - * @param array $data 操作的数据 - * @param string $field 分表依据的字段 - * @param array $rule 分表规则 - * @return $this - */ - public function partition($data, $field, $rule = []) - { - $this->options['table'] = $this->getPartitionTableName($data, $field, $rule); - return $this; - } - - /** - * 指定AND查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $op 查询表达式 - * @param mixed $condition 查询条件 - * @return $this - */ - public function where($field, $op = null, $condition = null) - { - $param = func_get_args(); - array_shift($param); - $this->parseWhereExp('AND', $field, $op, $condition, $param); - return $this; - } - - /** - * 指定OR查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $op 查询表达式 - * @param mixed $condition 查询条件 - * @return $this - */ - public function whereOr($field, $op = null, $condition = null) - { - $param = func_get_args(); - array_shift($param); - $this->parseWhereExp('OR', $field, $op, $condition, $param); - return $this; - } - - /** - * 指定XOR查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $op 查询表达式 - * @param mixed $condition 查询条件 - * @return $this - */ - public function whereXor($field, $op = null, $condition = null) - { - $param = func_get_args(); - array_shift($param); - $this->parseWhereExp('XOR', $field, $op, $condition, $param); - return $this; - } - - /** - * 指定表达式查询条件 - * @access public - * @param string $where 查询条件 - * @param array $bind 参数绑定 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereRaw($where, $bind = [], $logic = 'AND') - { - $this->options['where'][$logic][] = $this->raw($where); - - if ($bind) { - $this->bind($bind); - } - - return $this; - } - - /** - * 指定表达式查询条件 OR - * @access public - * @param string $where 查询条件 - * @param array $bind 参数绑定 - * @return $this - */ - public function whereOrRaw($where, $bind = []) - { - return $this->whereRaw($where, $bind, 'OR'); - } - - /** - * 指定Null查询条件 - * @access public - * @param mixed $field 查询字段 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereNull($field, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'null', null, [], true); - return $this; - } - - /** - * 指定NotNull查询条件 - * @access public - * @param mixed $field 查询字段 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereNotNull($field, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'notnull', null, [], true); - return $this; - } - - /** - * 指定Exists查询条件 - * @access public - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereExists($condition, $logic = 'AND') - { - $this->options['where'][strtoupper($logic)][] = ['exists', $condition]; - return $this; - } - - /** - * 指定NotExists查询条件 - * @access public - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereNotExists($condition, $logic = 'AND') - { - $this->options['where'][strtoupper($logic)][] = ['not exists', $condition]; - return $this; - } - - /** - * 指定In查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereIn($field, $condition, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'in', $condition, [], true); - return $this; - } - - /** - * 指定NotIn查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereNotIn($field, $condition, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'not in', $condition, [], true); - return $this; - } - - /** - * 指定Like查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereLike($field, $condition, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'like', $condition, [], true); - return $this; - } - - /** - * 指定NotLike查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereNotLike($field, $condition, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'not like', $condition, [], true); - return $this; - } - - /** - * 指定Between查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereBetween($field, $condition, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'between', $condition, [], true); - return $this; - } - - /** - * 指定NotBetween查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereNotBetween($field, $condition, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'not between', $condition, [], true); - return $this; - } - - /** - * 指定Exp查询条件 - * @access public - * @param mixed $field 查询字段 - * @param mixed $condition 查询条件 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereExp($field, $condition, $logic = 'AND') - { - $this->parseWhereExp($logic, $field, 'exp', $this->raw($condition), [], true); - return $this; - } - - /** - * 设置软删除字段及条件 - * @access public - * @param false|string $field 查询字段 - * @param mixed $condition 查询条件 - * @return $this - */ - public function useSoftDelete($field, $condition = null) - { - if ($field) { - $this->options['soft_delete'] = [$field, $condition ?: ['null', '']]; - } - return $this; - } - - /** - * 分析查询表达式 - * @access public - * @param string $logic 查询逻辑 and or xor - * @param string|array|\Closure $field 查询字段 - * @param mixed $op 查询表达式 - * @param mixed $condition 查询条件 - * @param array $param 查询参数 - * @param bool $strict 严格模式 - * @return void - */ - protected function parseWhereExp($logic, $field, $op, $condition, $param = [], $strict = false) - { - $logic = strtoupper($logic); - if ($field instanceof \Closure) { - $this->options['where'][$logic][] = is_string($op) ? [$op, $field] : $field; - return; - } - - if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) { - $field = $this->options['via'] . '.' . $field; - } - - if ($field instanceof Expression) { - return $this->whereRaw($field, is_array($op) ? $op : []); - } elseif ($strict) { - // 使用严格模式查询 - $where[$field] = [$op, $condition]; - - // 记录一个字段多次查询条件 - $this->options['multi'][$logic][$field][] = $where[$field]; - } elseif (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) { - $where[] = ['exp', $this->raw($field)]; - if (is_array($op)) { - // 参数绑定 - $this->bind($op); - } - } elseif (is_null($op) && is_null($condition)) { - if (is_array($field)) { - // 数组批量查询 - $where = $field; - foreach ($where as $k => $val) { - $this->options['multi'][$logic][$k][] = $val; - } - } elseif ($field && is_string($field)) { - // 字符串查询 - $where[$field] = ['null', '']; - $this->options['multi'][$logic][$field][] = $where[$field]; - } - } elseif (is_array($op)) { - $where[$field] = $param; - } elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) { - // null查询 - $where[$field] = [$op, '']; - - $this->options['multi'][$logic][$field][] = $where[$field]; - } elseif (is_null($condition)) { - // 字段相等查询 - $where[$field] = ['eq', $op]; - - $this->options['multi'][$logic][$field][] = $where[$field]; - } else { - if ('exp' == strtolower($op)) { - $where[$field] = ['exp', $this->raw($condition)]; - // 参数绑定 - if (isset($param[2]) && is_array($param[2])) { - $this->bind($param[2]); - } - } else { - $where[$field] = [$op, $condition]; - } - // 记录一个字段多次查询条件 - $this->options['multi'][$logic][$field][] = $where[$field]; - } - - if (!empty($where)) { - if (!isset($this->options['where'][$logic])) { - $this->options['where'][$logic] = []; - } - if (is_string($field) && $this->checkMultiField($field, $logic)) { - $where[$field] = $this->options['multi'][$logic][$field]; - } elseif (is_array($field)) { - foreach ($field as $key => $val) { - if ($this->checkMultiField($key, $logic)) { - $where[$key] = $this->options['multi'][$logic][$key]; - } - } - } - $this->options['where'][$logic] = array_merge($this->options['where'][$logic], $where); - } - } - - /** - * 检查是否存在一个字段多次查询条件 - * @access public - * @param string $field 查询字段 - * @param string $logic 查询逻辑 and or xor - * @return bool - */ - private function checkMultiField($field, $logic) - { - return isset($this->options['multi'][$logic][$field]) && count($this->options['multi'][$logic][$field]) > 1; - } - - /** - * 去除某个查询条件 - * @access public - * @param string $field 查询字段 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function removeWhereField($field, $logic = 'AND') - { - $logic = strtoupper($logic); - if (isset($this->options['where'][$logic][$field])) { - unset($this->options['where'][$logic][$field]); - unset($this->options['multi'][$logic][$field]); - } - return $this; - } - - /** - * 去除查询参数 - * @access public - * @param string|bool $option 参数名 true 表示去除所有参数 - * @return $this - */ - public function removeOption($option = true) - { - if (true === $option) { - $this->options = []; - } elseif (is_string($option) && isset($this->options[$option])) { - unset($this->options[$option]); - } - return $this; - } - - /** - * 指定查询数量 - * @access public - * @param mixed $offset 起始位置 - * @param mixed $length 查询数量 - * @return $this - */ - public function limit($offset, $length = null) - { - if (is_null($length) && strpos($offset, ',')) { - list($offset, $length) = explode(',', $offset); - } - $this->options['limit'] = intval($offset) . ($length ? ',' . intval($length) : ''); - return $this; - } - - /** - * 指定分页 - * @access public - * @param mixed $page 页数 - * @param mixed $listRows 每页数量 - * @return $this - */ - public function page($page, $listRows = null) - { - if (is_null($listRows) && strpos($page, ',')) { - list($page, $listRows) = explode(',', $page); - } - $this->options['page'] = [intval($page), intval($listRows)]; - return $this; - } - - /** - * 分页查询 - * @param int|array $listRows 每页数量 数组表示配置参数 - * @param int|bool $simple 是否简洁模式或者总记录数 - * @param array $config 配置参数 - * page:当前页, - * path:url路径, - * query:url额外参数, - * fragment:url锚点, - * var_page:分页变量, - * list_rows:每页数量 - * type:分页类名 - * @return \think\Paginator - * @throws DbException - */ - public function paginate($listRows = null, $simple = false, $config = []) - { - if (is_int($simple)) { - $total = $simple; - $simple = false; - } - if (is_array($listRows)) { - $config = array_merge(Config::get('paginate'), $listRows); - $listRows = $config['list_rows']; - } else { - $config = array_merge(Config::get('paginate'), $config); - $listRows = $listRows ?: $config['list_rows']; - } - - /** @var Paginator $class */ - $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']); - $page = isset($config['page']) ? (int) $config['page'] : call_user_func([ - $class, - 'getCurrentPage', - ], $config['var_page']); - - $page = $page < 1 ? 1 : $page; - - $config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']); - - if (!isset($total) && !$simple) { - $options = $this->getOptions(); - - unset($this->options['order'], $this->options['limit'], $this->options['page'], $this->options['field']); - - $bind = $this->bind; - $total = $this->count(); - $results = $this->options($options)->bind($bind)->page($page, $listRows)->select(); - } elseif ($simple) { - $results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select(); - $total = null; - } else { - $results = $this->page($page, $listRows)->select(); - } - return $class::make($results, $listRows, $page, $total, $simple, $config); - } - - /** - * 指定当前操作的数据表 - * @access public - * @param mixed $table 表名 - * @return $this - */ - public function table($table) - { - if (is_string($table)) { - if (strpos($table, ')')) { - // 子查询 - } elseif (strpos($table, ',')) { - $tables = explode(',', $table); - $table = []; - foreach ($tables as $item) { - list($item, $alias) = explode(' ', trim($item)); - if ($alias) { - $this->alias([$item => $alias]); - $table[$item] = $alias; - } else { - $table[] = $item; - } - } - } elseif (strpos($table, ' ')) { - list($table, $alias) = explode(' ', $table); - - $table = [$table => $alias]; - $this->alias($table); - } - } else { - $tables = $table; - $table = []; - foreach ($tables as $key => $val) { - if (is_numeric($key)) { - $table[] = $val; - } else { - $this->alias([$key => $val]); - $table[$key] = $val; - } - } - } - $this->options['table'] = $table; - return $this; - } - - /** - * USING支持 用于多表删除 - * @access public - * @param mixed $using - * @return $this - */ - public function using($using) - { - $this->options['using'] = $using; - return $this; - } - - /** - * 指定排序 order('id','desc') 或者 order(['id'=>'desc','create_time'=>'desc']) - * @access public - * @param string|array $field 排序字段 - * @param string $order 排序 - * @return $this - */ - public function order($field, $order = null) - { - if (empty($field)) { - return $this; - } elseif ($field instanceof Expression) { - $this->options['order'][] = $field; - return $this; - } - - if (is_string($field)) { - if (!empty($this->options['via'])) { - $field = $this->options['via'] . '.' . $field; - } - if (strpos($field, ',')) { - $field = array_map('trim', explode(',', $field)); - } else { - $field = empty($order) ? $field : [$field => $order]; - } - } elseif (!empty($this->options['via'])) { - foreach ($field as $key => $val) { - if (is_numeric($key)) { - $field[$key] = $this->options['via'] . '.' . $val; - } else { - $field[$this->options['via'] . '.' . $key] = $val; - unset($field[$key]); - } - } - } - if (!isset($this->options['order'])) { - $this->options['order'] = []; - } - if (is_array($field)) { - $this->options['order'] = array_merge($this->options['order'], $field); - } else { - $this->options['order'][] = $field; - } - - return $this; - } - - /** - * 表达式方式指定Field排序 - * @access public - * @param string $field 排序字段 - * @param array $bind 参数绑定 - * @return $this - */ - public function orderRaw($field, array $bind = []) - { - $this->options['order'][] = $this->raw($field); - - if ($bind) { - $this->bind($bind); - } - - return $this; - } - - /** - * 查询缓存 - * @access public - * @param mixed $key 缓存key - * @param integer|\DateTime $expire 缓存有效期 - * @param string $tag 缓存标签 - * @return $this - */ - public function cache($key = true, $expire = null, $tag = null) - { - // 增加快捷调用方式 cache(10) 等同于 cache(true, 10) - if ($key instanceof \DateTime || (is_numeric($key) && is_null($expire))) { - $expire = $key; - $key = true; - } - - if (false !== $key) { - $this->options['cache'] = ['key' => $key, 'expire' => $expire, 'tag' => $tag]; - } - return $this; - } - - /** - * 指定group查询 - * @access public - * @param string $group GROUP - * @return $this - */ - public function group($group) - { - $this->options['group'] = $group; - return $this; - } - - /** - * 指定having查询 - * @access public - * @param string $having having - * @return $this - */ - public function having($having) - { - $this->options['having'] = $having; - return $this; - } - - /** - * 指定查询lock - * @access public - * @param bool|string $lock 是否lock - * @return $this - */ - public function lock($lock = false) - { - $this->options['lock'] = $lock; - $this->options['master'] = true; - return $this; - } - - /** - * 指定distinct查询 - * @access public - * @param string $distinct 是否唯一 - * @return $this - */ - public function distinct($distinct) - { - $this->options['distinct'] = $distinct; - return $this; - } - - /** - * 指定数据表别名 - * @access public - * @param mixed $alias 数据表别名 - * @return $this - */ - public function alias($alias) - { - if (is_array($alias)) { - foreach ($alias as $key => $val) { - if (false !== strpos($key, '__')) { - $table = $this->parseSqlTable($key); - } else { - $table = $key; - } - $this->options['alias'][$table] = $val; - } - } else { - if (isset($this->options['table'])) { - $table = is_array($this->options['table']) ? key($this->options['table']) : $this->options['table']; - if (false !== strpos($table, '__')) { - $table = $this->parseSqlTable($table); - } - } else { - $table = $this->getTable(); - } - - $this->options['alias'][$table] = $alias; - } - return $this; - } - - /** - * 指定强制索引 - * @access public - * @param string $force 索引名称 - * @return $this - */ - public function force($force) - { - $this->options['force'] = $force; - return $this; - } - - /** - * 查询注释 - * @access public - * @param string $comment 注释 - * @return $this - */ - public function comment($comment) - { - $this->options['comment'] = $comment; - return $this; - } - - /** - * 获取执行的SQL语句 - * @access public - * @param boolean $fetch 是否返回sql - * @return $this - */ - public function fetchSql($fetch = true) - { - $this->options['fetch_sql'] = $fetch; - return $this; - } - - /** - * 不主动获取数据集 - * @access public - * @param bool $pdo 是否返回 PDOStatement 对象 - * @return $this - */ - public function fetchPdo($pdo = true) - { - $this->options['fetch_pdo'] = $pdo; - return $this; - } - - /** - * 设置从主服务器读取数据 - * @access public - * @return $this - */ - public function master() - { - $this->options['master'] = true; - return $this; - } - - /** - * 设置是否严格检查字段名 - * @access public - * @param bool $strict 是否严格检查字段 - * @return $this - */ - public function strict($strict = true) - { - $this->options['strict'] = $strict; - return $this; - } - - /** - * 设置查询数据不存在是否抛出异常 - * @access public - * @param bool $fail 数据不存在是否抛出异常 - * @return $this - */ - public function failException($fail = true) - { - $this->options['fail'] = $fail; - return $this; - } - - /** - * 设置自增序列名 - * @access public - * @param string $sequence 自增序列名 - * @return $this - */ - public function sequence($sequence = null) - { - $this->options['sequence'] = $sequence; - return $this; - } - - /** - * 指定数据表主键 - * @access public - * @param string $pk 主键 - * @return $this - */ - public function pk($pk) - { - $this->pk = $pk; - return $this; - } - - /** - * 查询日期或者时间 - * @access public - * @param string $field 日期字段名 - * @param string|array $op 比较运算符或者表达式 - * @param string|array $range 比较范围 - * @return $this - */ - public function whereTime($field, $op, $range = null) - { - if (is_null($range)) { - if (is_array($op)) { - $range = $op; - } else { - // 使用日期表达式 - switch (strtolower($op)) { - case 'today': - case 'd': - $range = ['today', 'tomorrow']; - break; - case 'week': - case 'w': - $range = ['this week 00:00:00', 'next week 00:00:00']; - break; - case 'month': - case 'm': - $range = ['first Day of this month 00:00:00', 'first Day of next month 00:00:00']; - break; - case 'year': - case 'y': - $range = ['this year 1/1', 'next year 1/1']; - break; - case 'yesterday': - $range = ['yesterday', 'today']; - break; - case 'last week': - $range = ['last week 00:00:00', 'this week 00:00:00']; - break; - case 'last month': - $range = ['first Day of last month 00:00:00', 'first Day of this month 00:00:00']; - break; - case 'last year': - $range = ['last year 1/1', 'this year 1/1']; - break; - default: - $range = $op; - } - } - $op = is_array($range) ? 'between' : '>'; - } - $this->where($field, strtolower($op) . ' time', $range); - return $this; - } - - /** - * 获取数据表信息 - * @access public - * @param mixed $tableName 数据表名 留空自动获取 - * @param string $fetch 获取信息类型 包括 fields type bind pk - * @return mixed - */ - public function getTableInfo($tableName = '', $fetch = '') - { - if (!$tableName) { - $tableName = $this->getTable(); - } - if (is_array($tableName)) { - $tableName = key($tableName) ?: current($tableName); - } - - if (strpos($tableName, ',')) { - // 多表不获取字段信息 - return false; - } else { - $tableName = $this->parseSqlTable($tableName); - } - - // 修正子查询作为表名的问题 - if (strpos($tableName, ')')) { - return []; - } - - list($guid) = explode(' ', $tableName); - $db = $this->getConfig('database'); - if (!isset(self::$info[$db . '.' . $guid])) { - if (!strpos($guid, '.')) { - $schema = $db . '.' . $guid; - } else { - $schema = $guid; - } - // 读取缓存 - if (!App::$debug && is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) { - $info = include RUNTIME_PATH . 'schema/' . $schema . '.php'; - } else { - $info = $this->connection->getFields($guid); - } - $fields = array_keys($info); - $bind = $type = []; - foreach ($info as $key => $val) { - // 记录字段类型 - $type[$key] = $val['type']; - $bind[$key] = $this->getFieldBindType($val['type']); - if (!empty($val['primary'])) { - $pk[] = $key; - } - } - if (isset($pk)) { - // 设置主键 - $pk = count($pk) > 1 ? $pk : $pk[0]; - } else { - $pk = null; - } - self::$info[$db . '.' . $guid] = ['fields' => $fields, 'type' => $type, 'bind' => $bind, 'pk' => $pk]; - } - return $fetch ? self::$info[$db . '.' . $guid][$fetch] : self::$info[$db . '.' . $guid]; - } - - /** - * 获取当前数据表的主键 - * @access public - * @param string|array $options 数据表名或者查询参数 - * @return string|array - */ - public function getPk($options = '') - { - if (!empty($this->pk)) { - $pk = $this->pk; - } else { - $pk = $this->getTableInfo(is_array($options) ? $options['table'] : $options, 'pk'); - } - return $pk; - } - - // 获取当前数据表字段信息 - public function getTableFields($table = '') - { - return $this->getTableInfo($table ?: $this->getOptions('table'), 'fields'); - } - - // 获取当前数据表字段类型 - public function getFieldsType($table = '') - { - return $this->getTableInfo($table ?: $this->getOptions('table'), 'type'); - } - - // 获取当前数据表绑定信息 - public function getFieldsBind($table = '') - { - $types = $this->getFieldsType($table); - $bind = []; - if ($types) { - foreach ($types as $key => $type) { - $bind[$key] = $this->getFieldBindType($type); - } - } - return $bind; - } - - /** - * 获取字段绑定类型 - * @access public - * @param string $type 字段类型 - * @return integer - */ - protected function getFieldBindType($type) - { - if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { - $bind = PDO::PARAM_STR; - } elseif (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) { - $bind = PDO::PARAM_INT; - } elseif (preg_match('/bool/is', $type)) { - $bind = PDO::PARAM_BOOL; - } else { - $bind = PDO::PARAM_STR; - } - return $bind; - } - - /** - * 参数绑定 - * @access public - * @param mixed $key 参数名 - * @param mixed $value 绑定变量值 - * @param integer $type 绑定类型 - * @return $this - */ - public function bind($key, $value = false, $type = PDO::PARAM_STR) - { - if (is_array($key)) { - $this->bind = array_merge($this->bind, $key); - } else { - $this->bind[$key] = [$value, $type]; - } - return $this; - } - - /** - * 检测参数是否已经绑定 - * @access public - * @param string $key 参数名 - * @return bool - */ - public function isBind($key) - { - return isset($this->bind[$key]); - } - - /** - * 查询参数赋值 - * @access protected - * @param array $options 表达式参数 - * @return $this - */ - protected function options(array $options) - { - $this->options = $options; - return $this; - } - - /** - * 获取当前的查询参数 - * @access public - * @param string $name 参数名 - * @return mixed - */ - public function getOptions($name = '') - { - if ('' === $name) { - return $this->options; - } else { - return isset($this->options[$name]) ? $this->options[$name] : null; - } - } - - /** - * 设置关联查询JOIN预查询 - * @access public - * @param string|array $with 关联方法名称 - * @return $this - */ - public function with($with) - { - if (empty($with)) { - return $this; - } - - if (is_string($with)) { - $with = explode(',', $with); - } - - $first = true; - - /** @var Model $class */ - $class = $this->model; - foreach ($with as $key => $relation) { - $subRelation = ''; - $closure = false; - if ($relation instanceof \Closure) { - // 支持闭包查询过滤关联条件 - $closure = $relation; - $relation = $key; - $with[$key] = $key; - } elseif (is_array($relation)) { - $subRelation = $relation; - $relation = $key; - } elseif (is_string($relation) && strpos($relation, '.')) { - $with[$key] = $relation; - list($relation, $subRelation) = explode('.', $relation, 2); - } - - /** @var Relation $model */ - $relation = Loader::parseName($relation, 1, false); - $model = $class->$relation(); - if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) { - $model->eagerly($this, $relation, $subRelation, $closure, $first); - $first = false; - } elseif ($closure) { - $with[$key] = $closure; - } - } - $this->via(); - if (isset($this->options['with'])) { - $this->options['with'] = array_merge($this->options['with'], $with); - } else { - $this->options['with'] = $with; - } - return $this; - } - - /** - * 关联统计 - * @access public - * @param string|array $relation 关联方法名 - * @param bool $subQuery 是否使用子查询 - * @return $this - */ - public function withCount($relation, $subQuery = true) - { - if (!$subQuery) { - $this->options['with_count'] = $relation; - } else { - $relations = is_string($relation) ? explode(',', $relation) : $relation; - if (!isset($this->options['field'])) { - $this->field('*'); - } - foreach ($relations as $key => $relation) { - $closure = $name = null; - if ($relation instanceof \Closure) { - $closure = $relation; - $relation = $key; - } elseif (!is_int($key)) { - $name = $relation; - $relation = $key; - } - $relation = Loader::parseName($relation, 1, false); - - $count = '(' . $this->model->$relation()->getRelationCountQuery($closure, $name) . ')'; - - if (empty($name)) { - $name = Loader::parseName($relation) . '_count'; - } - - $this->field([$count => $name]); - } - } - return $this; - } - - /** - * 关联预加载中 获取关联指定字段值 - * example: - * Model::with(['relation' => function($query){ - * $query->withField("id,name"); - * }]) - * - * @param string | array $field 指定获取的字段 - * @return $this - */ - public function withField($field) - { - $this->options['with_field'] = $field; - return $this; - } - - /** - * 设置当前字段添加的表别名 - * @access public - * @param string $via - * @return $this - */ - public function via($via = '') - { - $this->options['via'] = $via; - return $this; - } - - /** - * 设置关联查询 - * @access public - * @param string|array $relation 关联名称 - * @return $this - */ - public function relation($relation) - { - if (empty($relation)) { - return $this; - } - if (is_string($relation)) { - $relation = explode(',', $relation); - } - if (isset($this->options['relation'])) { - $this->options['relation'] = array_merge($this->options['relation'], $relation); - } else { - $this->options['relation'] = $relation; - } - return $this; - } - - /** - * 把主键值转换为查询条件 支持复合主键 - * @access public - * @param array|string $data 主键数据 - * @param mixed $options 表达式参数 - * @return void - * @throws Exception - */ - protected function parsePkWhere($data, &$options) - { - $pk = $this->getPk($options); - // 获取当前数据表 - $table = is_array($options['table']) ? key($options['table']) : $options['table']; - if (!empty($options['alias'][$table])) { - $alias = $options['alias'][$table]; - } - if (is_string($pk)) { - $key = isset($alias) ? $alias . '.' . $pk : $pk; - // 根据主键查询 - if (is_array($data)) { - $where[$key] = isset($data[$pk]) ? $data[$pk] : ['in', $data]; - } else { - $where[$key] = strpos($data, ',') ? ['IN', $data] : $data; - } - } elseif (is_array($pk) && is_array($data) && !empty($data)) { - // 根据复合主键查询 - foreach ($pk as $key) { - if (isset($data[$key])) { - $attr = isset($alias) ? $alias . '.' . $key : $key; - $where[$attr] = $data[$key]; - } else { - throw new Exception('miss complex primary data'); - } - } - } - - if (!empty($where)) { - if (isset($options['where']['AND'])) { - $options['where']['AND'] = array_merge($options['where']['AND'], $where); - } else { - $options['where']['AND'] = $where; - } - } - return; - } - - /** - * 插入记录 - * @access public - * @param mixed $data 数据 - * @param boolean $replace 是否replace - * @param boolean $getLastInsID 返回自增主键 - * @param string $sequence 自增序列名 - * @return integer|string - */ - public function insert(array $data = [], $replace = false, $getLastInsID = false, $sequence = null) - { - // 分析查询表达式 - $options = $this->parseExpress(); - $data = array_merge($options['data'], $data); - // 生成SQL语句 - $sql = $this->builder->insert($data, $options, $replace); - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } - - // 执行操作 - $result = 0 === $sql ? 0 : $this->execute($sql, $bind, $this); - if ($result) { - $sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null); - $lastInsId = $this->getLastInsID($sequence); - if ($lastInsId) { - $pk = $this->getPk($options); - if (is_string($pk)) { - $data[$pk] = $lastInsId; - } - } - $options['data'] = $data; - $this->trigger('after_insert', $options); - - if ($getLastInsID) { - return $lastInsId; - } - } - return $result; - } - - /** - * 插入记录并获取自增ID - * @access public - * @param mixed $data 数据 - * @param boolean $replace 是否replace - * @param string $sequence 自增序列名 - * @return integer|string - */ - public function insertGetId(array $data, $replace = false, $sequence = null) - { - return $this->insert($data, $replace, true, $sequence); - } - - /** - * 批量插入记录 - * @access public - * @param mixed $dataSet 数据集 - * @param boolean $replace 是否replace - * @param integer $limit 每次写入数据限制 - * @return integer|string - */ - public function insertAll(array $dataSet, $replace = false, $limit = null) - { - // 分析查询表达式 - $options = $this->parseExpress(); - if (!is_array(reset($dataSet))) { - return false; - } - - // 生成SQL语句 - if (is_null($limit)) { - $sql = $this->builder->insertAll($dataSet, $options, $replace); - } else { - $array = array_chunk($dataSet, $limit, true); - foreach ($array as $item) { - $sql[] = $this->builder->insertAll($item, $options, $replace); - } - } - - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } elseif (is_array($sql)) { - // 执行操作 - return $this->batchQuery($sql, $bind, $this); - } else { - // 执行操作 - return $this->execute($sql, $bind, $this); - } - } - - /** - * 通过Select方式插入记录 - * @access public - * @param string $fields 要插入的数据表字段名 - * @param string $table 要插入的数据表名 - * @return integer|string - * @throws PDOException - */ - public function selectInsert($fields, $table) - { - // 分析查询表达式 - $options = $this->parseExpress(); - // 生成SQL语句 - $table = $this->parseSqlTable($table); - $sql = $this->builder->selectInsert($fields, $table, $options); - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } else { - // 执行操作 - return $this->execute($sql, $bind, $this); - } - } - - /** - * 更新记录 - * @access public - * @param mixed $data 数据 - * @return integer|string - * @throws Exception - * @throws PDOException - */ - public function update(array $data = []) - { - $options = $this->parseExpress(); - $data = array_merge($options['data'], $data); - $pk = $this->getPk($options); - if (isset($options['cache']) && is_string($options['cache']['key'])) { - $key = $options['cache']['key']; - } - - if (empty($options['where'])) { - // 如果存在主键数据 则自动作为更新条件 - if (is_string($pk) && isset($data[$pk])) { - $where[$pk] = $data[$pk]; - if (!isset($key)) { - $key = 'think:' . $options['table'] . '|' . $data[$pk]; - } - unset($data[$pk]); - } elseif (is_array($pk)) { - // 增加复合主键支持 - foreach ($pk as $field) { - if (isset($data[$field])) { - $where[$field] = $data[$field]; - } else { - // 如果缺少复合主键数据则不执行 - throw new Exception('miss complex primary data'); - } - unset($data[$field]); - } - } - if (!isset($where)) { - // 如果没有任何更新条件则不执行 - throw new Exception('miss update condition'); - } else { - $options['where']['AND'] = $where; - } - } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); - } - - // 生成UPDATE SQL语句 - $sql = $this->builder->update($data, $options); - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } else { - // 检测缓存 - if (isset($key) && Cache::get($key)) { - // 删除缓存 - Cache::rm($key); - } elseif (!empty($options['cache']['tag'])) { - Cache::clear($options['cache']['tag']); - } - // 执行操作 - $result = '' == $sql ? 0 : $this->execute($sql, $bind, $this); - if ($result) { - if (is_string($pk) && isset($where[$pk])) { - $data[$pk] = $where[$pk]; - } elseif (is_string($pk) && isset($key) && strpos($key, '|')) { - list($a, $val) = explode('|', $key); - $data[$pk] = $val; - } - $options['data'] = $data; - $this->trigger('after_update', $options); - } - return $result; - } - } - - /** - * 执行查询但只返回PDOStatement对象 - * @access public - * @return \PDOStatement|string - */ - public function getPdo() - { - // 分析查询表达式 - $options = $this->parseExpress(); - // 生成查询SQL - $sql = $this->builder->select($options); - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } - // 执行查询操作 - return $this->query($sql, $bind, $options['master'], true); - } - - /** - * 查找记录 - * @access public - * @param array|string|Query|\Closure $data - * @return Collection|false|\PDOStatement|string - * @throws DbException - * @throws ModelNotFoundException - * @throws DataNotFoundException - */ - public function select($data = null) - { - if ($data instanceof Query) { - return $data->select(); - } elseif ($data instanceof \Closure) { - call_user_func_array($data, [ & $this]); - $data = null; - } - // 分析查询表达式 - $options = $this->parseExpress(); - - if (false === $data) { - // 用于子查询 不查询只返回SQL - $options['fetch_sql'] = true; - } elseif (!is_null($data)) { - // 主键条件分析 - $this->parsePkWhere($data, $options); - } - - $resultSet = false; - if (empty($options['fetch_sql']) && !empty($options['cache'])) { - // 判断查询缓存 - $cache = $options['cache']; - unset($options['cache']); - $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind)); - $resultSet = Cache::get($key); - } - if (false === $resultSet) { - // 生成查询SQL - $sql = $this->builder->select($options); - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } - - $options['data'] = $data; - if ($resultSet = $this->trigger('before_select', $options)) { - } else { - // 执行查询操作 - $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); - - if ($resultSet instanceof \PDOStatement) { - // 返回PDOStatement对象 - return $resultSet; - } - } - - if (isset($cache) && false !== $resultSet) { - // 缓存数据集 - $this->cacheData($key, $resultSet, $cache); - } - } - - // 数据列表读取后的处理 - if (!empty($this->model)) { - // 生成模型对象 - if (count($resultSet) > 0) { - foreach ($resultSet as $key => $result) { - /** @var Model $model */ - $model = $this->model->newInstance($result); - $model->isUpdate(true); - - // 关联查询 - if (!empty($options['relation'])) { - $model->relationQuery($options['relation']); - } - // 关联统计 - if (!empty($options['with_count'])) { - $model->relationCount($model, $options['with_count']); - } - $resultSet[$key] = $model; - } - if (!empty($options['with'])) { - // 预载入 - $model->eagerlyResultSet($resultSet, $options['with']); - } - // 模型数据集转换 - $resultSet = $model->toCollection($resultSet); - } else { - $resultSet = $this->model->toCollection($resultSet); - } - } elseif ('collection' == $this->connection->getConfig('resultset_type')) { - // 返回Collection对象 - $resultSet = new Collection($resultSet); - } - // 返回结果处理 - if (!empty($options['fail']) && count($resultSet) == 0) { - $this->throwNotFound($options); - } - return $resultSet; - } - - /** - * 缓存数据 - * @access public - * @param string $key 缓存标识 - * @param mixed $data 缓存数据 - * @param array $config 缓存参数 - */ - protected function cacheData($key, $data, $config = []) - { - if (isset($config['tag'])) { - Cache::tag($config['tag'])->set($key, $data, $config['expire']); - } else { - Cache::set($key, $data, $config['expire']); - } - } - - /** - * 生成缓存标识 - * @access public - * @param mixed $value 缓存数据 - * @param array $options 缓存参数 - * @param array $bind 绑定参数 - * @return string - */ - protected function getCacheKey($value, $options, $bind = []) - { - if (is_scalar($value)) { - $data = $value; - } elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) { - $data = $value[1]; - } - $prefix = $this->connection->getConfig('database') . '.'; - - if (isset($data)) { - return 'think:' . $prefix . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; - } - - try { - return md5($prefix . serialize($options) . serialize($bind)); - } catch (\Exception $e) { - throw new Exception('closure not support cache(true)'); - } - } - - /** - * 查找单条记录 - * @access public - * @param array|string|Query|\Closure $data - * @return array|false|\PDOStatement|string|Model - * @throws DbException - * @throws ModelNotFoundException - * @throws DataNotFoundException - */ - public function find($data = null) - { - if ($data instanceof Query) { - return $data->find(); - } elseif ($data instanceof \Closure) { - call_user_func_array($data, [ & $this]); - $data = null; - } - // 分析查询表达式 - $options = $this->parseExpress(); - $pk = $this->getPk($options); - if (!is_null($data)) { - // AR模式分析主键条件 - $this->parsePkWhere($data, $options); - } elseif (!empty($options['cache']) && true === $options['cache']['key'] && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); - } - - $options['limit'] = 1; - $result = false; - if (empty($options['fetch_sql']) && !empty($options['cache'])) { - // 判断查询缓存 - $cache = $options['cache']; - if (true === $cache['key'] && !is_null($data) && !is_array($data)) { - $key = 'think:' . $this->connection->getConfig('database') . '.' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; - } elseif (is_string($cache['key'])) { - $key = $cache['key']; - } elseif (!isset($key)) { - $key = md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind)); - } - $result = Cache::get($key); - } - if (false === $result) { - // 生成查询SQL - $sql = $this->builder->select($options); - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } - if (is_string($pk)) { - if (!is_array($data)) { - if (isset($key) && strpos($key, '|')) { - list($a, $val) = explode('|', $key); - $item[$pk] = $val; - } else { - $item[$pk] = $data; - } - $data = $item; - } - } - $options['data'] = $data; - // 事件回调 - if ($result = $this->trigger('before_find', $options)) { - } else { - // 执行查询 - $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); - - if ($resultSet instanceof \PDOStatement) { - // 返回PDOStatement对象 - return $resultSet; - } - $result = isset($resultSet[0]) ? $resultSet[0] : null; - } - - if (isset($cache) && $result) { - // 缓存数据 - $this->cacheData($key, $result, $cache); - } - } - - // 数据处理 - if (!empty($result)) { - if (!empty($this->model)) { - // 返回模型对象 - $result = $this->model->newInstance($result); - $result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); - // 关联查询 - if (!empty($options['relation'])) { - $result->relationQuery($options['relation']); - } - // 预载入查询 - if (!empty($options['with'])) { - $result->eagerlyResult($result, $options['with']); - } - // 关联统计 - if (!empty($options['with_count'])) { - $result->relationCount($result, $options['with_count']); - } - } - } elseif (!empty($options['fail'])) { - $this->throwNotFound($options); - } - return $result; - } - - /** - * 查询失败 抛出异常 - * @access public - * @param array $options 查询参数 - * @throws ModelNotFoundException - * @throws DataNotFoundException - */ - protected function throwNotFound($options = []) - { - if (!empty($this->model)) { - $class = get_class($this->model); - throw new ModelNotFoundException('model data Not Found:' . $class, $class, $options); - } else { - $table = is_array($options['table']) ? key($options['table']) : $options['table']; - throw new DataNotFoundException('table data not Found:' . $table, $table, $options); - } - } - - /** - * 查找多条记录 如果不存在则抛出异常 - * @access public - * @param array|string|Query|\Closure $data - * @return array|\PDOStatement|string|Model - * @throws DbException - * @throws ModelNotFoundException - * @throws DataNotFoundException - */ - public function selectOrFail($data = null) - { - return $this->failException(true)->select($data); - } - - /** - * 查找单条记录 如果不存在则抛出异常 - * @access public - * @param array|string|Query|\Closure $data - * @return array|\PDOStatement|string|Model - * @throws DbException - * @throws ModelNotFoundException - * @throws DataNotFoundException - */ - public function findOrFail($data = null) - { - return $this->failException(true)->find($data); - } - - /** - * 分批数据返回处理 - * @access public - * @param integer $count 每次处理的数据数量 - * @param callable $callback 处理回调方法 - * @param string $column 分批处理的字段名 - * @param string $order 排序规则 - * @return boolean - * @throws \LogicException - */ - public function chunk($count, $callback, $column = null, $order = 'asc') - { - $options = $this->getOptions(); - if (empty($options['table'])) { - $options['table'] = $this->getTable(); - } - $column = $column ?: $this->getPk($options); - - if (isset($options['order'])) { - if (App::$debug) { - throw new \LogicException('chunk not support call order'); - } - unset($options['order']); - } - $bind = $this->bind; - if (is_array($column)) { - $times = 1; - $query = $this->options($options)->page($times, $count); - } else { - if (strpos($column, '.')) { - list($alias, $key) = explode('.', $column); - } else { - $key = $column; - } - $query = $this->options($options)->limit($count); - } - $resultSet = $query->order($column, $order)->select(); - - while (count($resultSet) > 0) { - if ($resultSet instanceof Collection) { - $resultSet = $resultSet->all(); - } - - if (false === call_user_func($callback, $resultSet)) { - return false; - } - - if (is_array($column)) { - $times++; - $query = $this->options($options)->page($times, $count); - } else { - $end = end($resultSet); - $lastId = is_array($end) ? $end[$key] : $end->getData($key); - $query = $this->options($options) - ->limit($count) - ->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId); - } - - $resultSet = $query->bind($bind)->order($column, $order)->select(); - } - - return true; - } - - /** - * 获取绑定的参数 并清空 - * @access public - * @return array - */ - public function getBind() - { - $bind = $this->bind; - $this->bind = []; - return $bind; - } - - /** - * 创建子查询SQL - * @access public - * @param bool $sub - * @return string - * @throws DbException - */ - public function buildSql($sub = true) - { - return $sub ? '( ' . $this->select(false) . ' )' : $this->select(false); - } - - /** - * 删除记录 - * @access public - * @param mixed $data 表达式 true 表示强制删除 - * @return int - * @throws Exception - * @throws PDOException - */ - public function delete($data = null) - { - // 分析查询表达式 - $options = $this->parseExpress(); - $pk = $this->getPk($options); - if (isset($options['cache']) && is_string($options['cache']['key'])) { - $key = $options['cache']['key']; - } - - if (!is_null($data) && true !== $data) { - if (!isset($key) && !is_array($data)) { - // 缓存标识 - $key = 'think:' . $options['table'] . '|' . $data; - } - // AR模式分析主键条件 - $this->parsePkWhere($data, $options); - } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); - } - - if (true !== $data && empty($options['where'])) { - // 如果条件为空 不进行删除操作 除非设置 1=1 - throw new Exception('delete without condition'); - } - // 生成删除SQL语句 - $sql = $this->builder->delete($options); - // 获取参数绑定 - $bind = $this->getBind(); - if ($options['fetch_sql']) { - // 获取实际执行的SQL语句 - return $this->connection->getRealSql($sql, $bind); - } - - // 检测缓存 - if (isset($key) && Cache::get($key)) { - // 删除缓存 - Cache::rm($key); - } elseif (!empty($options['cache']['tag'])) { - Cache::clear($options['cache']['tag']); - } - // 执行操作 - $result = $this->execute($sql, $bind, $this); - if ($result) { - if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) { - list($a, $val) = explode('|', $key); - $item[$pk] = $val; - $data = $item; - } - $options['data'] = $data; - $this->trigger('after_delete', $options); - } - return $result; - } - - /** - * 分析表达式(可用于查询或者写入操作) - * @access protected - * @return array - */ - protected function parseExpress() - { - $options = $this->options; - - // 获取数据表 - if (empty($options['table'])) { - $options['table'] = $this->getTable(); - } - - if (!isset($options['where'])) { - $options['where'] = []; - } elseif (isset($options['view'])) { - // 视图查询条件处理 - foreach (['AND', 'OR'] as $logic) { - if (isset($options['where'][$logic])) { - foreach ($options['where'][$logic] as $key => $val) { - if (array_key_exists($key, $options['map'])) { - $options['where'][$logic][$options['map'][$key]] = $val; - unset($options['where'][$logic][$key]); - } - } - } - } - - if (isset($options['order'])) { - // 视图查询排序处理 - if (is_string($options['order'])) { - $options['order'] = explode(',', $options['order']); - } - foreach ($options['order'] as $key => $val) { - if (is_numeric($key)) { - if (strpos($val, ' ')) { - list($field, $sort) = explode(' ', $val); - if (array_key_exists($field, $options['map'])) { - $options['order'][$options['map'][$field]] = $sort; - unset($options['order'][$key]); - } - } elseif (array_key_exists($val, $options['map'])) { - $options['order'][$options['map'][$val]] = 'asc'; - unset($options['order'][$key]); - } - } elseif (array_key_exists($key, $options['map'])) { - $options['order'][$options['map'][$key]] = $val; - unset($options['order'][$key]); - } - } - } - } - - if (!isset($options['field'])) { - $options['field'] = '*'; - } - - if (!isset($options['data'])) { - $options['data'] = []; - } - - if (!isset($options['strict'])) { - $options['strict'] = $this->getConfig('fields_strict'); - } - - foreach (['master', 'lock', 'fetch_pdo', 'fetch_sql', 'distinct'] as $name) { - if (!isset($options[$name])) { - $options[$name] = false; - } - } - - if (isset(static::$readMaster['*']) || (is_string($options['table']) && isset(static::$readMaster[$options['table']]))) { - $options['master'] = true; - } - - foreach (['join', 'union', 'group', 'having', 'limit', 'order', 'force', 'comment'] as $name) { - if (!isset($options[$name])) { - $options[$name] = ''; - } - } - - if (isset($options['page'])) { - // 根据页数计算limit - list($page, $listRows) = $options['page']; - $page = $page > 0 ? $page : 1; - $listRows = $listRows > 0 ? $listRows : (is_numeric($options['limit']) ? $options['limit'] : 20); - $offset = $listRows * ($page - 1); - $options['limit'] = $offset . ',' . $listRows; - } - - $this->options = []; - return $options; - } - - /** - * 注册回调方法 - * @access public - * @param string $event 事件名 - * @param callable $callback 回调方法 - * @return void - */ - public static function event($event, $callback) - { - self::$event[$event] = $callback; - } - - /** - * 触发事件 - * @access protected - * @param string $event 事件名 - * @param mixed $params 额外参数 - * @return bool - */ - protected function trigger($event, $params = []) - { - $result = false; - if (isset(self::$event[$event])) { - $callback = self::$event[$event]; - $result = call_user_func_array($callback, [$params, $this]); - } - return $result; - } -} diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php deleted file mode 100755 index be2af71..0000000 --- a/thinkphp/library/think/db/builder/Mysql.php +++ /dev/null @@ -1,137 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\builder; - -use think\db\Builder; -use think\Exception; - -/** - * mysql数据库驱动 - */ -class Mysql extends Builder -{ - - protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%'; - protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; - - /** - * 生成insertall SQL - * @access public - * @param array $dataSet 数据集 - * @param array $options 表达式 - * @param bool $replace 是否replace - * @return string - * @throws Exception - */ - public function insertAll($dataSet, $options = [], $replace = false) - { - // 获取合法的字段 - if ('*' == $options['field']) { - $fields = array_keys($this->query->getFieldsType($options['table'])); - } else { - $fields = $options['field']; - } - - foreach ($dataSet as $data) { - foreach ($data as $key => $val) { - if (!in_array($key, $fields, true)) { - if ($options['strict']) { - throw new Exception('fields not exists:[' . $key . ']'); - } - unset($data[$key]); - } elseif (is_null($val)) { - $data[$key] = 'NULL'; - } elseif (is_scalar($val)) { - $data[$key] = $this->parseValue($val, $key); - } elseif (is_object($val) && method_exists($val, '__toString')) { - // 对象数据写入 - $data[$key] = $val->__toString(); - } else { - // 过滤掉非标量数据 - unset($data[$key]); - } - } - $value = array_values($data); - $values[] = '( ' . implode(',', $value) . ' )'; - - if (!isset($insertFields)) { - $insertFields = array_map([$this, 'parseKey'], array_keys($data)); - } - } - - return str_replace( - ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'], - [ - $replace ? 'REPLACE' : 'INSERT', - $this->parseTable($options['table'], $options), - implode(' , ', $insertFields), - implode(' , ', $values), - $this->parseComment($options['comment']), - ], $this->insertAllSql); - } - - /** - * 字段和表名处理 - * @access protected - * @param mixed $key - * @param array $options - * @return string - */ - protected function parseKey($key, $options = [], $strict = false) - { - if (is_numeric($key)) { - return $key; - } elseif ($key instanceof Expression) { - return $key->getValue(); - } - - $key = trim($key); - if (strpos($key, '$.') && false === strpos($key, '(')) { - // JSON字段支持 - list($field, $name) = explode('$.', $key); - return 'json_extract(' . $field . ', \'$.' . $name . '\')'; - } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) { - list($table, $key) = explode('.', $key, 2); - if ('__TABLE__' == $table) { - $table = $this->query->getTable(); - } - if (isset($options['alias'][$table])) { - $table = $options['alias'][$table]; - } - } - - if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) { - throw new Exception('not support data:' . $key); - } - if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) { - $key = '`' . $key . '`'; - } - if (isset($table)) { - if (strpos($table, '.')) { - $table = str_replace('.', '`.`', $table); - } - $key = '`' . $table . '`.' . $key; - } - return $key; - } - - /** - * 随机排序 - * @access protected - * @return string - */ - protected function parseRand() - { - return 'rand()'; - } - -} diff --git a/thinkphp/library/think/db/builder/Pgsql.php b/thinkphp/library/think/db/builder/Pgsql.php deleted file mode 100755 index acc2289..0000000 --- a/thinkphp/library/think/db/builder/Pgsql.php +++ /dev/null @@ -1,89 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\builder; - -use think\db\Builder; - -/** - * Pgsql数据库驱动 - */ -class Pgsql extends Builder -{ - protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; - protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; - - /** - * limit分析 - * @access protected - * @param mixed $limit - * @return string - */ - public function parseLimit($limit) - { - $limitStr = ''; - if (!empty($limit)) { - $limit = explode(',', $limit); - if (count($limit) > 1) { - $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; - } else { - $limitStr .= ' LIMIT ' . $limit[0] . ' '; - } - } - return $limitStr; - } - - /** - * 字段和表名处理 - * @access protected - * @param mixed $key - * @param array $options - * @return string - */ - protected function parseKey($key, $options = [], $strict = false) - { - if (is_numeric($key)) { - return $key; - } elseif ($key instanceof Expression) { - return $key->getValue(); - } - - $key = trim($key); - if (strpos($key, '$.') && false === strpos($key, '(')) { - // JSON字段支持 - list($field, $name) = explode('$.', $key); - $key = $field . '->>\'' . $name . '\''; - } elseif (strpos($key, '.')) { - list($table, $key) = explode('.', $key, 2); - if ('__TABLE__' == $table) { - $table = $this->query->getTable(); - } - if (isset($options['alias'][$table])) { - $table = $options['alias'][$table]; - } - } - if (isset($table)) { - $key = $table . '.' . $key; - } - return $key; - } - - /** - * 随机排序 - * @access protected - * @return string - */ - protected function parseRand() - { - return 'RANDOM()'; - } - -} diff --git a/thinkphp/library/think/db/builder/Sqlite.php b/thinkphp/library/think/db/builder/Sqlite.php deleted file mode 100755 index c727f04..0000000 --- a/thinkphp/library/think/db/builder/Sqlite.php +++ /dev/null @@ -1,82 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\builder; - -use think\db\Builder; - -/** - * Sqlite数据库驱动 - */ -class Sqlite extends Builder -{ - - /** - * limit - * @access public - * @param string $limit - * @return string - */ - public function parseLimit($limit) - { - $limitStr = ''; - if (!empty($limit)) { - $limit = explode(',', $limit); - if (count($limit) > 1) { - $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; - } else { - $limitStr .= ' LIMIT ' . $limit[0] . ' '; - } - } - return $limitStr; - } - - /** - * 随机排序 - * @access protected - * @return string - */ - protected function parseRand() - { - return 'RANDOM()'; - } - - /** - * 字段和表名处理 - * @access protected - * @param mixed $key - * @param array $options - * @return string - */ - protected function parseKey($key, $options = [], $strict = false) - { - if (is_numeric($key)) { - return $key; - } elseif ($key instanceof Expression) { - return $key->getValue(); - } - - $key = trim($key); - if (strpos($key, '.')) { - list($table, $key) = explode('.', $key, 2); - if ('__TABLE__' == $table) { - $table = $this->query->getTable(); - } - if (isset($options['alias'][$table])) { - $table = $options['alias'][$table]; - } - } - if (isset($table)) { - $key = $table . '.' . $key; - } - return $key; - } -} diff --git a/thinkphp/library/think/db/builder/Sqlsrv.php b/thinkphp/library/think/db/builder/Sqlsrv.php deleted file mode 100755 index dc425d9..0000000 --- a/thinkphp/library/think/db/builder/Sqlsrv.php +++ /dev/null @@ -1,137 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\builder; - -use think\db\Builder; -use think\db\Expression; - -/** - * Sqlsrv数据库驱动 - */ -class Sqlsrv extends Builder -{ - protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%) AS thinkphp) AS T1 %LIMIT%%COMMENT%'; - protected $selectInsertSql = 'SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%'; - protected $updateSql = 'UPDATE %TABLE% SET %SET% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%'; - protected $deleteSql = 'DELETE FROM %TABLE% %USING% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%'; - protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; - protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; - - /** - * order分析 - * @access protected - * @param mixed $order - * @param array $options - * @return string - */ - protected function parseOrder($order, $options = []) - { - if (empty($order)) { - return ' ORDER BY rand()'; - } - - $array = []; - foreach ($order as $key => $val) { - if ($val instanceof Expression) { - $array[] = $val->getValue(); - } elseif (is_numeric($key)) { - if (false === strpos($val, '(')) { - $array[] = $this->parseKey($val, $options); - } elseif ('[rand]' == $val) { - $array[] = $this->parseRand(); - } else { - $array[] = $val; - } - } else { - $sort = in_array(strtolower(trim($val)), ['asc', 'desc'], true) ? ' ' . $val : ''; - $array[] = $this->parseKey($key, $options, true) . ' ' . $sort; - } - } - - return ' ORDER BY ' . implode(',', $array); - } - - /** - * 随机排序 - * @access protected - * @return string - */ - protected function parseRand() - { - return 'rand()'; - } - - /** - * 字段和表名处理 - * @access protected - * @param mixed $key - * @param array $options - * @return string - */ - protected function parseKey($key, $options = [], $strict = false) - { - if (is_numeric($key)) { - return $key; - } elseif ($key instanceof Expression) { - return $key->getValue(); - } - $key = trim($key); - if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) { - list($table, $key) = explode('.', $key, 2); - if ('__TABLE__' == $table) { - $table = $this->query->getTable(); - } - if (isset($options['alias'][$table])) { - $table = $options['alias'][$table]; - } - } - - if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) { - throw new Exception('not support data:' . $key); - } - if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) { - $key = '[' . $key . ']'; - } - if (isset($table)) { - $key = '[' . $table . '].' . $key; - } - return $key; - } - - /** - * limit - * @access protected - * @param mixed $limit - * @return string - */ - protected function parseLimit($limit) - { - if (empty($limit)) { - return ''; - } - - $limit = explode(',', $limit); - if (count($limit) > 1) { - $limitStr = '(T1.ROW_NUMBER BETWEEN ' . $limit[0] . ' + 1 AND ' . $limit[0] . ' + ' . $limit[1] . ')'; - } else { - $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND ' . $limit[0] . ")"; - } - return 'WHERE ' . $limitStr; - } - - public function selectInsert($fields, $table, $options) - { - $this->selectSql = $this->selectInsertSql; - return parent::selectInsert($fields, $table, $options); - } - -} diff --git a/thinkphp/library/think/db/connector/Mysql.php b/thinkphp/library/think/db/connector/Mysql.php deleted file mode 100755 index be1a85c..0000000 --- a/thinkphp/library/think/db/connector/Mysql.php +++ /dev/null @@ -1,126 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\connector; - -use PDO; -use think\db\Connection; -use think\Log; - -/** - * mysql数据库驱动 - */ -class Mysql extends Connection -{ - - protected $builder = '\\think\\db\\builder\\Mysql'; - - /** - * 解析pdo连接的dsn信息 - * @access protected - * @param array $config 连接信息 - * @return string - */ - protected function parseDsn($config) - { - if (!empty($config['socket'])) { - $dsn = 'mysql:unix_socket=' . $config['socket']; - } elseif (!empty($config['hostport'])) { - $dsn = 'mysql:host=' . $config['hostname'] . ';port=' . $config['hostport']; - } else { - $dsn = 'mysql:host=' . $config['hostname']; - } - $dsn .= ';dbname=' . $config['database']; - - if (!empty($config['charset'])) { - $dsn .= ';charset=' . $config['charset']; - } - return $dsn; - } - - /** - * 取得数据表的字段信息 - * @access public - * @param string $tableName - * @return array - */ - public function getFields($tableName) - { - list($tableName) = explode(' ', $tableName); - if (false === strpos($tableName, '`')) { - if (strpos($tableName, '.')) { - $tableName = str_replace('.', '`.`', $tableName); - } - $tableName = '`' . $tableName . '`'; - } - $sql = 'SHOW COLUMNS FROM ' . $tableName; - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - if ($result) { - foreach ($result as $key => $val) { - $val = array_change_key_case($val); - $info[$val['field']] = [ - 'name' => $val['field'], - 'type' => $val['type'], - 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes - 'default' => $val['default'], - 'primary' => (strtolower($val['key']) == 'pri'), - 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), - ]; - } - } - return $this->fieldCase($info); - } - - /** - * 取得数据库的表信息 - * @access public - * @param string $dbName - * @return array - */ - public function getTables($dbName = '') - { - $sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES '; - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - foreach ($result as $key => $val) { - $info[$key] = current($val); - } - return $info; - } - - /** - * SQL性能分析 - * @access protected - * @param string $sql - * @return array - */ - protected function getExplain($sql) - { - $pdo = $this->linkID->query("EXPLAIN " . $sql); - $result = $pdo->fetch(PDO::FETCH_ASSOC); - $result = array_change_key_case($result); - if (isset($result['extra'])) { - if (strpos($result['extra'], 'filesort') || strpos($result['extra'], 'temporary')) { - Log::record('SQL:' . $this->queryStr . '[' . $result['extra'] . ']', 'warn'); - } - } - return $result; - } - - protected function supportSavepoint() - { - return true; - } - -} diff --git a/thinkphp/library/think/db/connector/Pgsql.php b/thinkphp/library/think/db/connector/Pgsql.php deleted file mode 100755 index bbcf576..0000000 --- a/thinkphp/library/think/db/connector/Pgsql.php +++ /dev/null @@ -1,103 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\connector; - -use PDO; -use think\db\Connection; - -/** - * Pgsql数据库驱动 - */ -class Pgsql extends Connection -{ - protected $builder = '\\think\\db\\builder\\Pgsql'; - - /** - * 解析pdo连接的dsn信息 - * @access protected - * @param array $config 连接信息 - * @return string - */ - protected function parseDsn($config) - { - $dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname']; - if (!empty($config['hostport'])) { - $dsn .= ';port=' . $config['hostport']; - } - return $dsn; - } - - /** - * 取得数据表的字段信息 - * @access public - * @param string $tableName - * @return array - */ - public function getFields($tableName) - { - - list($tableName) = explode(' ', $tableName); - $sql = 'select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(\'' . $tableName . '\');'; - - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - if ($result) { - foreach ($result as $key => $val) { - $val = array_change_key_case($val); - $info[$val['field']] = [ - 'name' => $val['field'], - 'type' => $val['type'], - 'notnull' => (bool) ('' !== $val['null']), - 'default' => $val['default'], - 'primary' => !empty($val['key']), - 'autoinc' => (0 === strpos($val['extra'], 'nextval(')), - ]; - } - } - return $this->fieldCase($info); - } - - /** - * 取得数据库的表信息 - * @access public - * @param string $dbName - * @return array - */ - public function getTables($dbName = '') - { - $sql = "select tablename as Tables_in_test from pg_tables where schemaname ='public'"; - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - foreach ($result as $key => $val) { - $info[$key] = current($val); - } - return $info; - } - - /** - * SQL性能分析 - * @access protected - * @param string $sql - * @return array - */ - protected function getExplain($sql) - { - return []; - } - - protected function supportSavepoint() - { - return true; - } -} diff --git a/thinkphp/library/think/db/connector/Sqlite.php b/thinkphp/library/think/db/connector/Sqlite.php deleted file mode 100755 index c4e3a72..0000000 --- a/thinkphp/library/think/db/connector/Sqlite.php +++ /dev/null @@ -1,104 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\connector; - -use PDO; -use think\db\Connection; - -/** - * Sqlite数据库驱动 - */ -class Sqlite extends Connection -{ - - protected $builder = '\\think\\db\\builder\\Sqlite'; - - /** - * 解析pdo连接的dsn信息 - * @access protected - * @param array $config 连接信息 - * @return string - */ - protected function parseDsn($config) - { - $dsn = 'sqlite:' . $config['database']; - return $dsn; - } - - /** - * 取得数据表的字段信息 - * @access public - * @param string $tableName - * @return array - */ - public function getFields($tableName) - { - list($tableName) = explode(' ', $tableName); - $sql = 'PRAGMA table_info( ' . $tableName . ' )'; - - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - if ($result) { - foreach ($result as $key => $val) { - $val = array_change_key_case($val); - $info[$val['name']] = [ - 'name' => $val['name'], - 'type' => $val['type'], - 'notnull' => 1 === $val['notnull'], - 'default' => $val['dflt_value'], - 'primary' => '1' == $val['pk'], - 'autoinc' => '1' == $val['pk'], - ]; - } - } - return $this->fieldCase($info); - } - - /** - * 取得数据库的表信息 - * @access public - * @param string $dbName - * @return array - */ - public function getTables($dbName = '') - { - - $sql = "SELECT name FROM sqlite_master WHERE type='table' " - . "UNION ALL SELECT name FROM sqlite_temp_master " - . "WHERE type='table' ORDER BY name"; - - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - foreach ($result as $key => $val) { - $info[$key] = current($val); - } - return $info; - } - - /** - * SQL性能分析 - * @access protected - * @param string $sql - * @return array - */ - protected function getExplain($sql) - { - return []; - } - - protected function supportSavepoint() - { - return true; - } -} diff --git a/thinkphp/library/think/db/connector/Sqlsrv.php b/thinkphp/library/think/db/connector/Sqlsrv.php deleted file mode 100755 index 35c6600..0000000 --- a/thinkphp/library/think/db/connector/Sqlsrv.php +++ /dev/null @@ -1,125 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\connector; - -use PDO; -use think\db\Connection; - -/** - * Sqlsrv数据库驱动 - */ -class Sqlsrv extends Connection -{ - // PDO连接参数 - protected $params = [ - PDO::ATTR_CASE => PDO::CASE_NATURAL, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_STRINGIFY_FETCHES => false, - ]; - protected $builder = '\\think\\db\\builder\\Sqlsrv'; - /** - * 解析pdo连接的dsn信息 - * @access protected - * @param array $config 连接信息 - * @return string - */ - protected function parseDsn($config) - { - $dsn = 'sqlsrv:Database=' . $config['database'] . ';Server=' . $config['hostname']; - if (!empty($config['hostport'])) { - $dsn .= ',' . $config['hostport']; - } - return $dsn; - } - - /** - * 取得数据表的字段信息 - * @access public - * @param string $tableName - * @return array - */ - public function getFields($tableName) - { - list($tableName) = explode(' ', $tableName); - $tableNames = explode('.', $tableName); - $tableName = isset($tableNames[1]) ? $tableNames[1] : $tableNames[0]; - - $sql = "SELECT column_name, data_type, column_default, is_nullable - FROM information_schema.tables AS t - JOIN information_schema.columns AS c - ON t.table_catalog = c.table_catalog - AND t.table_schema = c.table_schema - AND t.table_name = c.table_name - WHERE t.table_name = '$tableName'"; - - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - if ($result) { - foreach ($result as $key => $val) { - $val = array_change_key_case($val); - $info[$val['column_name']] = [ - 'name' => $val['column_name'], - 'type' => $val['data_type'], - 'notnull' => (bool) ('' === $val['is_nullable']), // not null is empty, null is yes - 'default' => $val['column_default'], - 'primary' => false, - 'autoinc' => false, - ]; - } - } - $sql = "SELECT column_name FROM information_schema.key_column_usage WHERE table_name='$tableName'"; - // 调试开始 - $this->debug(true); - $pdo = $this->linkID->query($sql); - // 调试结束 - $this->debug(false, $sql); - $result = $pdo->fetch(PDO::FETCH_ASSOC); - if ($result) { - $info[$result['column_name']]['primary'] = true; - } - return $this->fieldCase($info); - } - - /** - * 取得数据表的字段信息 - * @access public - * @param string $dbName - * @return array - */ - public function getTables($dbName = '') - { - $sql = "SELECT TABLE_NAME - FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_TYPE = 'BASE TABLE' - "; - - $pdo = $this->query($sql, [], false, true); - $result = $pdo->fetchAll(PDO::FETCH_ASSOC); - $info = []; - foreach ($result as $key => $val) { - $info[$key] = current($val); - } - return $info; - } - - /** - * SQL性能分析 - * @access protected - * @param string $sql - * @return array - */ - protected function getExplain($sql) - { - return []; - } -} diff --git a/thinkphp/library/think/db/connector/pgsql.sql b/thinkphp/library/think/db/connector/pgsql.sql deleted file mode 100755 index e1a09a3..0000000 --- a/thinkphp/library/think/db/connector/pgsql.sql +++ /dev/null @@ -1,117 +0,0 @@ -CREATE OR REPLACE FUNCTION pgsql_type(a_type varchar) RETURNS varchar AS -$BODY$ -DECLARE - v_type varchar; -BEGIN - IF a_type='int8' THEN - v_type:='bigint'; - ELSIF a_type='int4' THEN - v_type:='integer'; - ELSIF a_type='int2' THEN - v_type:='smallint'; - ELSIF a_type='bpchar' THEN - v_type:='char'; - ELSE - v_type:=a_type; - END IF; - RETURN v_type; -END; -$BODY$ -LANGUAGE PLPGSQL; - -CREATE TYPE "public"."tablestruct" AS ( - "fields_key_name" varchar(100), - "fields_name" VARCHAR(200), - "fields_type" VARCHAR(20), - "fields_length" BIGINT, - "fields_not_null" VARCHAR(10), - "fields_default" VARCHAR(500), - "fields_comment" VARCHAR(1000) -); - -CREATE OR REPLACE FUNCTION "public"."table_msg" (a_schema_name varchar, a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS -$body$ -DECLARE - v_ret tablestruct; - v_oid oid; - v_sql varchar; - v_rec RECORD; - v_key varchar; -BEGIN - SELECT - pg_class.oid INTO v_oid - FROM - pg_class - INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid AND lower(pg_namespace.nspname) = a_schema_name) - WHERE - pg_class.relname=a_table_name; - IF NOT FOUND THEN - RETURN; - END IF; - - v_sql=' - SELECT - pg_attribute.attname AS fields_name, - pg_attribute.attnum AS fields_index, - pgsql_type(pg_type.typname::varchar) AS fields_type, - pg_attribute.atttypmod-4 as fields_length, - CASE WHEN pg_attribute.attnotnull THEN ''not null'' - ELSE '''' - END AS fields_not_null, - pg_attrdef.adsrc AS fields_default, - pg_description.description AS fields_comment - FROM - pg_attribute - INNER JOIN pg_class ON pg_attribute.attrelid = pg_class.oid - INNER JOIN pg_type ON pg_attribute.atttypid = pg_type.oid - LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid = pg_class.oid AND pg_attrdef.adnum = pg_attribute.attnum - LEFT OUTER JOIN pg_description ON pg_description.objoid = pg_class.oid AND pg_description.objsubid = pg_attribute.attnum - WHERE - pg_attribute.attnum > 0 - AND attisdropped <> ''t'' - AND pg_class.oid = ' || v_oid || ' - ORDER BY pg_attribute.attnum' ; - - FOR v_rec IN EXECUTE v_sql LOOP - v_ret.fields_name=v_rec.fields_name; - v_ret.fields_type=v_rec.fields_type; - IF v_rec.fields_length > 0 THEN - v_ret.fields_length:=v_rec.fields_length; - ELSE - v_ret.fields_length:=NULL; - END IF; - v_ret.fields_not_null=v_rec.fields_not_null; - v_ret.fields_default=v_rec.fields_default; - v_ret.fields_comment=v_rec.fields_comment; - SELECT constraint_name INTO v_key FROM information_schema.key_column_usage WHERE table_schema=a_schema_name AND table_name=a_table_name AND column_name=v_rec.fields_name; - IF FOUND THEN - v_ret.fields_key_name=v_key; - ELSE - v_ret.fields_key_name=''; - END IF; - RETURN NEXT v_ret; - END LOOP; - RETURN ; -END; -$body$ -LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER; - -COMMENT ON FUNCTION "public"."table_msg"(a_schema_name varchar, a_table_name varchar) -IS '获得表信息'; - ----重载一个函数 -CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS -$body$ -DECLARE - v_ret tablestruct; -BEGIN - FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP - RETURN NEXT v_ret; - END LOOP; - RETURN; -END; -$body$ -LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER; - -COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar) -IS '获得表信息'; \ No newline at end of file diff --git a/thinkphp/library/think/db/exception/BindParamException.php b/thinkphp/library/think/db/exception/BindParamException.php deleted file mode 100755 index 4ed1954..0000000 --- a/thinkphp/library/think/db/exception/BindParamException.php +++ /dev/null @@ -1,35 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\exception; - -use think\exception\DbException; - -/** - * PDO参数绑定异常 - */ -class BindParamException extends DbException -{ - - /** - * BindParamException constructor. - * @param string $message - * @param array $config - * @param string $sql - * @param array $bind - * @param int $code - */ - public function __construct($message, $config, $sql, $bind, $code = 10502) - { - $this->setData('Bind Param', $bind); - parent::__construct($message, $config, $sql, $code); - } -} diff --git a/thinkphp/library/think/db/exception/DataNotFoundException.php b/thinkphp/library/think/db/exception/DataNotFoundException.php deleted file mode 100755 index f2542ac..0000000 --- a/thinkphp/library/think/db/exception/DataNotFoundException.php +++ /dev/null @@ -1,43 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\exception; - -use think\exception\DbException; - -class DataNotFoundException extends DbException -{ - protected $table; - - /** - * DbException constructor. - * @param string $message - * @param string $table - * @param array $config - */ - public function __construct($message, $table = '', array $config = []) - { - $this->message = $message; - $this->table = $table; - - $this->setData('Database Config', $config); - } - - /** - * 获取数据表名 - * @access public - * @return string - */ - public function getTable() - { - return $this->table; - } -} diff --git a/thinkphp/library/think/db/exception/ModelNotFoundException.php b/thinkphp/library/think/db/exception/ModelNotFoundException.php deleted file mode 100755 index 6e5f930..0000000 --- a/thinkphp/library/think/db/exception/ModelNotFoundException.php +++ /dev/null @@ -1,43 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\db\exception; - -use think\exception\DbException; - -class ModelNotFoundException extends DbException -{ - protected $model; - - /** - * 构造方法 - * @param string $message - * @param string $model - */ - public function __construct($message, $model = '', array $config = []) - { - $this->message = $message; - $this->model = $model; - - $this->setData('Database Config', $config); - } - - /** - * 获取模型类名 - * @access public - * @return string - */ - public function getModel() - { - return $this->model; - } - -} diff --git a/thinkphp/library/think/debug/Console.php b/thinkphp/library/think/debug/Console.php deleted file mode 100755 index c17911b..0000000 --- a/thinkphp/library/think/debug/Console.php +++ /dev/null @@ -1,160 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\debug; - -use think\Cache; -use think\Config; -use think\Db; -use think\Debug; -use think\Request; -use think\Response; - -/** - * 浏览器调试输出 - */ -class Console -{ - protected $config = [ - 'trace_tabs' => ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'], - ]; - - // 实例化并传入参数 - public function __construct($config = []) - { - if (is_array($config)) { - $this->config = array_merge($this->config, $config); - } - } - - /** - * 调试输出接口 - * @access public - * @param Response $response Response对象 - * @param array $log 日志信息 - * @return bool - */ - public function output(Response $response, array $log = []) - { - $request = Request::instance(); - $contentType = $response->getHeader('Content-Type'); - $accept = $request->header('accept'); - if (strpos($accept, 'application/json') === 0 || $request->isAjax()) { - return false; - } elseif (!empty($contentType) && strpos($contentType, 'html') === false) { - return false; - } - // 获取基本信息 - $runtime = number_format(microtime(true) - THINK_START_TIME, 10); - $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; - $mem = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); - - if (isset($_SERVER['HTTP_HOST'])) { - $uri = $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - } else { - $uri = 'cmd:' . implode(' ', $_SERVER['argv']); - } - - // 页面Trace信息 - $base = [ - '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $uri, - '运行时间' => number_format($runtime, 6) . 's [ 吞吐率:' . $reqs . 'req/s ] 内存消耗:' . $mem . 'kb 文件加载:' . count(get_included_files()), - '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ', - '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes', - '配置加载' => count(Config::get()), - ]; - - if (session_id()) { - $base['会话信息'] = 'SESSION_ID=' . session_id(); - } - - $info = Debug::getFile(true); - - // 页面Trace信息 - $trace = []; - foreach ($this->config['trace_tabs'] as $name => $title) { - $name = strtolower($name); - switch ($name) { - case 'base': // 基本信息 - $trace[$title] = $base; - break; - case 'file': // 文件信息 - $trace[$title] = $info; - break; - default: // 调试信息 - if (strpos($name, '|')) { - // 多组信息 - $names = explode('|', $name); - $result = []; - foreach ($names as $name) { - $result = array_merge($result, isset($log[$name]) ? $log[$name] : []); - } - $trace[$title] = $result; - } else { - $trace[$title] = isset($log[$name]) ? $log[$name] : ''; - } - } - } - - //输出到控制台 - $lines = ''; - foreach ($trace as $type => $msg) { - $lines .= $this->console($type, $msg); - } - $js = << -{$lines} - -JS; - return $js; - } - - protected function console($type, $msg) - { - $type = strtolower($type); - $trace_tabs = array_values($this->config['trace_tabs']); - $line[] = ($type == $trace_tabs[0] || '调试' == $type || '错误' == $type) - ? "console.group('{$type}');" - : "console.groupCollapsed('{$type}');"; - - foreach ((array) $msg as $key => $m) { - switch ($type) { - case '调试': - $var_type = gettype($m); - if (in_array($var_type, ['array', 'string'])) { - $line[] = "console.log(" . json_encode($m) . ");"; - } else { - $line[] = "console.log(" . json_encode(var_export($m, 1)) . ");"; - } - break; - case '错误': - $msg = str_replace("\n", '\n', json_encode($m)); - $style = 'color:#F4006B;font-size:14px;'; - $line[] = "console.error(\"%c{$msg}\", \"{$style}\");"; - break; - case 'sql': - $msg = str_replace("\n", '\n', $m); - $style = "color:#009bb4;"; - $line[] = "console.log(\"%c{$msg}\", \"{$style}\");"; - break; - default: - $m = is_string($key) ? $key . ' ' . $m : $key + 1 . ' ' . $m; - $msg = json_encode($m); - $line[] = "console.log({$msg});"; - break; - } - } - $line[] = "console.groupEnd();"; - return implode(PHP_EOL, $line); - } - -} diff --git a/thinkphp/library/think/debug/Html.php b/thinkphp/library/think/debug/Html.php deleted file mode 100755 index b6be7ad..0000000 --- a/thinkphp/library/think/debug/Html.php +++ /dev/null @@ -1,111 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\debug; - -use think\Cache; -use think\Config; -use think\Db; -use think\Debug; -use think\Request; -use think\Response; - -/** - * 页面Trace调试 - */ -class Html -{ - protected $config = [ - 'trace_file' => '', - 'trace_tabs' => ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'], - ]; - - // 实例化并传入参数 - public function __construct(array $config = []) - { - $this->config['trace_file'] = THINK_PATH . 'tpl/page_trace.tpl'; - $this->config = array_merge($this->config, $config); - } - - /** - * 调试输出接口 - * @access public - * @param Response $response Response对象 - * @param array $log 日志信息 - * @return bool - */ - public function output(Response $response, array $log = []) - { - $request = Request::instance(); - $contentType = $response->getHeader('Content-Type'); - $accept = $request->header('accept'); - if (strpos($accept, 'application/json') === 0 || $request->isAjax()) { - return false; - } elseif (!empty($contentType) && strpos($contentType, 'html') === false) { - return false; - } - // 获取基本信息 - $runtime = number_format(microtime(true) - THINK_START_TIME, 10, '.', ''); - $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; - $mem = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); - - // 页面Trace信息 - if (isset($_SERVER['HTTP_HOST'])) { - $uri = $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - } else { - $uri = 'cmd:' . implode(' ', $_SERVER['argv']); - } - $base = [ - '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $uri, - '运行时间' => number_format($runtime, 6) . 's [ 吞吐率:' . $reqs . 'req/s ] 内存消耗:' . $mem . 'kb 文件加载:' . count(get_included_files()), - '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ', - '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes', - '配置加载' => count(Config::get()), - ]; - - if (session_id()) { - $base['会话信息'] = 'SESSION_ID=' . session_id(); - } - - $info = Debug::getFile(true); - - // 页面Trace信息 - $trace = []; - foreach ($this->config['trace_tabs'] as $name => $title) { - $name = strtolower($name); - switch ($name) { - case 'base': // 基本信息 - $trace[$title] = $base; - break; - case 'file': // 文件信息 - $trace[$title] = $info; - break; - default: // 调试信息 - if (strpos($name, '|')) { - // 多组信息 - $names = explode('|', $name); - $result = []; - foreach ($names as $name) { - $result = array_merge($result, isset($log[$name]) ? $log[$name] : []); - } - $trace[$title] = $result; - } else { - $trace[$title] = isset($log[$name]) ? $log[$name] : ''; - } - } - } - // 调用Trace页面模板 - ob_start(); - include $this->config['trace_file']; - return ob_get_clean(); - } - -} diff --git a/thinkphp/library/think/exception/ClassNotFoundException.php b/thinkphp/library/think/exception/ClassNotFoundException.php deleted file mode 100755 index eb22e73..0000000 --- a/thinkphp/library/think/exception/ClassNotFoundException.php +++ /dev/null @@ -1,32 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -class ClassNotFoundException extends \RuntimeException -{ - protected $class; - public function __construct($message, $class = '') - { - $this->message = $message; - $this->class = $class; - } - - /** - * 获取类名 - * @access public - * @return string - */ - public function getClass() - { - return $this->class; - } -} diff --git a/thinkphp/library/think/exception/DbException.php b/thinkphp/library/think/exception/DbException.php deleted file mode 100755 index 0ae80ad..0000000 --- a/thinkphp/library/think/exception/DbException.php +++ /dev/null @@ -1,43 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -use think\Exception; - -/** - * Database相关异常处理类 - */ -class DbException extends Exception -{ - /** - * DbException constructor. - * @param string $message - * @param array $config - * @param string $sql - * @param int $code - */ - public function __construct($message, array $config, $sql, $code = 10500) - { - $this->message = $message; - $this->code = $code; - - $this->setData('Database Status', [ - 'Error Code' => $code, - 'Error Message' => $message, - 'Error SQL' => $sql, - ]); - - unset($config['username'], $config['password']); - $this->setData('Database Config', $config); - } - -} diff --git a/thinkphp/library/think/exception/ErrorException.php b/thinkphp/library/think/exception/ErrorException.php deleted file mode 100755 index b3a9a30..0000000 --- a/thinkphp/library/think/exception/ErrorException.php +++ /dev/null @@ -1,57 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -use think\Exception; - -/** - * ThinkPHP错误异常 - * 主要用于封装 set_error_handler 和 register_shutdown_function 得到的错误 - * 除开从 think\Exception 继承的功能 - * 其他和PHP系统\ErrorException功能基本一样 - */ -class ErrorException extends Exception -{ - /** - * 用于保存错误级别 - * @var integer - */ - protected $severity; - - /** - * 错误异常构造函数 - * @param integer $severity 错误级别 - * @param string $message 错误详细信息 - * @param string $file 出错文件路径 - * @param integer $line 出错行号 - * @param array $context 错误上下文,会包含错误触发处作用域内所有变量的数组 - */ - public function __construct($severity, $message, $file, $line, array $context = []) - { - $this->severity = $severity; - $this->message = $message; - $this->file = $file; - $this->line = $line; - $this->code = 0; - - empty($context) || $this->setData('Error Context', $context); - } - - /** - * 获取错误级别 - * @return integer 错误级别 - */ - final public function getSeverity() - { - return $this->severity; - } -} diff --git a/thinkphp/library/think/exception/Handle.php b/thinkphp/library/think/exception/Handle.php deleted file mode 100755 index f523db0..0000000 --- a/thinkphp/library/think/exception/Handle.php +++ /dev/null @@ -1,282 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -use Exception; -use think\App; -use think\Config; -use think\console\Output; -use think\Lang; -use think\Log; -use think\Response; - -class Handle -{ - protected $render; - protected $ignoreReport = [ - '\\think\\exception\\HttpException', - ]; - - public function setRender($render) - { - $this->render = $render; - } - - /** - * Report or log an exception. - * - * @param \Exception $exception - * @return void - */ - public function report(Exception $exception) - { - if (!$this->isIgnoreReport($exception)) { - // 收集异常数据 - if (App::$debug) { - $data = [ - 'file' => $exception->getFile(), - 'line' => $exception->getLine(), - 'message' => $this->getMessage($exception), - 'code' => $this->getCode($exception), - ]; - $log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]"; - } else { - $data = [ - 'code' => $this->getCode($exception), - 'message' => $this->getMessage($exception), - ]; - $log = "[{$data['code']}]{$data['message']}"; - } - - if (Config::get('record_trace')) { - $log .= "\r\n" . $exception->getTraceAsString(); - } - - Log::record($log, 'error'); - } - } - - protected function isIgnoreReport(Exception $exception) - { - foreach ($this->ignoreReport as $class) { - if ($exception instanceof $class) { - return true; - } - } - return false; - } - - /** - * Render an exception into an HTTP response. - * - * @param \Exception $e - * @return Response - */ - public function render(Exception $e) - { - if ($this->render && $this->render instanceof \Closure) { - $result = call_user_func_array($this->render, [$e]); - if ($result) { - return $result; - } - } - - if ($e instanceof HttpException) { - return $this->renderHttpException($e); - } else { - return $this->convertExceptionToResponse($e); - } - } - - /** - * @param Output $output - * @param Exception $e - */ - public function renderForConsole(Output $output, Exception $e) - { - if (App::$debug) { - $output->setVerbosity(Output::VERBOSITY_DEBUG); - } - $output->renderException($e); - } - - /** - * @param HttpException $e - * @return Response - */ - protected function renderHttpException(HttpException $e) - { - $status = $e->getStatusCode(); - $template = Config::get('http_exception_template'); - if (!App::$debug && !empty($template[$status])) { - return Response::create($template[$status], 'view', $status)->assign(['e' => $e]); - } else { - return $this->convertExceptionToResponse($e); - } - } - - /** - * @param Exception $exception - * @return Response - */ - protected function convertExceptionToResponse(Exception $exception) - { - // 收集异常数据 - if (App::$debug) { - // 调试模式,获取详细的错误信息 - $data = [ - 'name' => get_class($exception), - 'file' => $exception->getFile(), - 'line' => $exception->getLine(), - 'message' => $this->getMessage($exception), - 'trace' => $exception->getTrace(), - 'code' => $this->getCode($exception), - 'source' => $this->getSourceCode($exception), - 'datas' => $this->getExtendData($exception), - 'tables' => [ - 'GET Data' => $_GET, - 'POST Data' => $_POST, - 'Files' => $_FILES, - 'Cookies' => $_COOKIE, - 'Session' => isset($_SESSION) ? $_SESSION : [], - 'Server/Request Data' => $_SERVER, - 'Environment Variables' => $_ENV, - 'ThinkPHP Constants' => $this->getConst(), - ], - ]; - } else { - // 部署模式仅显示 Code 和 Message - $data = [ - 'code' => $this->getCode($exception), - 'message' => $this->getMessage($exception), - ]; - - if (!Config::get('show_error_msg')) { - // 不显示详细错误信息 - $data['message'] = Config::get('error_message'); - } - } - - //保留一层 - while (ob_get_level() > 1) { - ob_end_clean(); - } - - $data['echo'] = ob_get_clean(); - - ob_start(); - extract($data); - include Config::get('exception_tmpl'); - // 获取并清空缓存 - $content = ob_get_clean(); - $response = new Response($content, 'html'); - - if ($exception instanceof HttpException) { - $statusCode = $exception->getStatusCode(); - $response->header($exception->getHeaders()); - } - - if (!isset($statusCode)) { - $statusCode = 500; - } - $response->code($statusCode); - return $response; - } - - /** - * 获取错误编码 - * ErrorException则使用错误级别作为错误编码 - * @param \Exception $exception - * @return integer 错误编码 - */ - protected function getCode(Exception $exception) - { - $code = $exception->getCode(); - if (!$code && $exception instanceof ErrorException) { - $code = $exception->getSeverity(); - } - return $code; - } - - /** - * 获取错误信息 - * ErrorException则使用错误级别作为错误编码 - * @param \Exception $exception - * @return string 错误信息 - */ - protected function getMessage(Exception $exception) - { - $message = $exception->getMessage(); - if (IS_CLI) { - return $message; - } - - if (strpos($message, ':')) { - $name = strstr($message, ':', true); - $message = Lang::has($name) ? Lang::get($name) . strstr($message, ':') : $message; - } elseif (strpos($message, ',')) { - $name = strstr($message, ',', true); - $message = Lang::has($name) ? Lang::get($name) . ':' . substr(strstr($message, ','), 1) : $message; - } elseif (Lang::has($message)) { - $message = Lang::get($message); - } - return $message; - } - - /** - * 获取出错文件内容 - * 获取错误的前9行和后9行 - * @param \Exception $exception - * @return array 错误文件内容 - */ - protected function getSourceCode(Exception $exception) - { - // 读取前9行和后9行 - $line = $exception->getLine(); - $first = ($line - 9 > 0) ? $line - 9 : 1; - - try { - $contents = file($exception->getFile()); - $source = [ - 'first' => $first, - 'source' => array_slice($contents, $first - 1, 19), - ]; - } catch (Exception $e) { - $source = []; - } - return $source; - } - - /** - * 获取异常扩展信息 - * 用于非调试模式html返回类型显示 - * @param \Exception $exception - * @return array 异常类定义的扩展数据 - */ - protected function getExtendData(Exception $exception) - { - $data = []; - if ($exception instanceof \think\Exception) { - $data = $exception->getData(); - } - return $data; - } - - /** - * 获取常量列表 - * @return array 常量列表 - */ - private static function getConst() - { - return get_defined_constants(true)['user']; - } -} diff --git a/thinkphp/library/think/exception/HttpException.php b/thinkphp/library/think/exception/HttpException.php deleted file mode 100755 index 01a27fc..0000000 --- a/thinkphp/library/think/exception/HttpException.php +++ /dev/null @@ -1,36 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -class HttpException extends \RuntimeException -{ - private $statusCode; - private $headers; - - public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = [], $code = 0) - { - $this->statusCode = $statusCode; - $this->headers = $headers; - - parent::__construct($message, $code, $previous); - } - - public function getStatusCode() - { - return $this->statusCode; - } - - public function getHeaders() - { - return $this->headers; - } -} diff --git a/thinkphp/library/think/exception/HttpResponseException.php b/thinkphp/library/think/exception/HttpResponseException.php deleted file mode 100755 index 5297286..0000000 --- a/thinkphp/library/think/exception/HttpResponseException.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -use think\Response; - -class HttpResponseException extends \RuntimeException -{ - /** - * @var Response - */ - protected $response; - - public function __construct(Response $response) - { - $this->response = $response; - } - - public function getResponse() - { - return $this->response; - } - -} diff --git a/thinkphp/library/think/exception/PDOException.php b/thinkphp/library/think/exception/PDOException.php deleted file mode 100755 index 044f82a..0000000 --- a/thinkphp/library/think/exception/PDOException.php +++ /dev/null @@ -1,39 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -/** - * PDO异常处理类 - * 重新封装了系统的\PDOException类 - */ -class PDOException extends DbException -{ - /** - * PDOException constructor. - * @param \PDOException $exception - * @param array $config - * @param string $sql - * @param int $code - */ - public function __construct(\PDOException $exception, array $config, $sql, $code = 10501) - { - $error = $exception->errorInfo; - - $this->setData('PDO Error Info', [ - 'SQLSTATE' => $error[0], - 'Driver Error Code' => isset($error[1]) ? $error[1] : 0, - 'Driver Error Message' => isset($error[2]) ? $error[2] : '', - ]); - - parent::__construct($exception->getMessage(), $config, $sql, $code); - } -} diff --git a/thinkphp/library/think/exception/RouteNotFoundException.php b/thinkphp/library/think/exception/RouteNotFoundException.php deleted file mode 100755 index d22e3a6..0000000 --- a/thinkphp/library/think/exception/RouteNotFoundException.php +++ /dev/null @@ -1,22 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -class RouteNotFoundException extends HttpException -{ - - public function __construct() - { - parent::__construct(404, 'Route Not Found'); - } - -} diff --git a/thinkphp/library/think/exception/TemplateNotFoundException.php b/thinkphp/library/think/exception/TemplateNotFoundException.php deleted file mode 100755 index 4202069..0000000 --- a/thinkphp/library/think/exception/TemplateNotFoundException.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -class TemplateNotFoundException extends \RuntimeException -{ - protected $template; - - public function __construct($message, $template = '') - { - $this->message = $message; - $this->template = $template; - } - - /** - * 获取模板文件 - * @access public - * @return string - */ - public function getTemplate() - { - return $this->template; - } -} diff --git a/thinkphp/library/think/exception/ThrowableError.php b/thinkphp/library/think/exception/ThrowableError.php deleted file mode 100755 index 87b6b9d..0000000 --- a/thinkphp/library/think/exception/ThrowableError.php +++ /dev/null @@ -1,47 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -class ThrowableError extends \ErrorException -{ - public function __construct(\Throwable $e) - { - - if ($e instanceof \ParseError) { - $message = 'Parse error: ' . $e->getMessage(); - $severity = E_PARSE; - } elseif ($e instanceof \TypeError) { - $message = 'Type error: ' . $e->getMessage(); - $severity = E_RECOVERABLE_ERROR; - } else { - $message = 'Fatal error: ' . $e->getMessage(); - $severity = E_ERROR; - } - - parent::__construct( - $message, - $e->getCode(), - $severity, - $e->getFile(), - $e->getLine() - ); - - $this->setTrace($e->getTrace()); - } - - protected function setTrace($trace) - { - $traceReflector = new \ReflectionProperty('Exception', 'trace'); - $traceReflector->setAccessible(true); - $traceReflector->setValue($this, $trace); - } -} diff --git a/thinkphp/library/think/exception/ValidateException.php b/thinkphp/library/think/exception/ValidateException.php deleted file mode 100755 index b368416..0000000 --- a/thinkphp/library/think/exception/ValidateException.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\exception; - -class ValidateException extends \RuntimeException -{ - protected $error; - - public function __construct($error) - { - $this->error = $error; - $this->message = is_array($error) ? implode("\n\r", $error) : $error; - } - - /** - * 获取验证错误信息 - * @access public - * @return array|string - */ - public function getError() - { - return $this->error; - } -} diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php deleted file mode 100755 index f2296cf..0000000 --- a/thinkphp/library/think/log/driver/File.php +++ /dev/null @@ -1,270 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\log\driver; - -use think\App; -use think\Request; - -/** - * 本地化调试输出到文件 - */ -class File -{ - protected $config = [ - 'time_format' => ' c ', - 'single' => false, - 'file_size' => 2097152, - 'path' => LOG_PATH, - 'apart_level' => [], - 'max_files' => 0, - 'json' => false, - ]; - - // 实例化并传入参数 - public function __construct($config = []) - { - if (is_array($config)) { - $this->config = array_merge($this->config, $config); - } - } - - /** - * 日志写入接口 - * @access public - * @param array $log 日志信息 - * @param bool $append 是否追加请求信息 - * @return bool - */ - public function save(array $log = [], $append = false) - { - $destination = $this->getMasterLogFile(); - - $path = dirname($destination); - !is_dir($path) && mkdir($path, 0755, true); - - $info = []; - foreach ($log as $type => $val) { - - foreach ($val as $msg) { - if (!is_string($msg)) { - $msg = var_export($msg, true); - } - - $info[$type][] = $this->config['json'] ? $msg : '[ ' . $type . ' ] ' . $msg; - } - - if (!$this->config['json'] && (true === $this->config['apart_level'] || in_array($type, $this->config['apart_level']))) { - // 独立记录的日志级别 - $filename = $this->getApartLevelFile($path, $type); - - $this->write($info[$type], $filename, true, $append); - unset($info[$type]); - } - } - - if ($info) { - return $this->write($info, $destination, false, $append); - } - - return true; - } - - /** - * 获取主日志文件名 - * @access public - * @return string - */ - protected function getMasterLogFile() - { - if ($this->config['single']) { - $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; - - $destination = $this->config['path'] . $name . '.log'; - } else { - $cli = PHP_SAPI == 'cli' ? '_cli' : ''; - - if ($this->config['max_files']) { - $filename = date('Ymd') . $cli . '.log'; - $files = glob($this->config['path'] . '*.log'); - - try { - if (count($files) > $this->config['max_files']) { - unlink($files[0]); - } - } catch (\Exception $e) { - } - } else { - $filename = date('Ym') . DIRECTORY_SEPARATOR . date('d') . $cli . '.log'; - } - - $destination = $this->config['path'] . $filename; - } - - return $destination; - } - - /** - * 获取独立日志文件名 - * @access public - * @param string $path 日志目录 - * @param string $type 日志类型 - * @return string - */ - protected function getApartLevelFile($path, $type) - { - $cli = PHP_SAPI == 'cli' ? '_cli' : ''; - - if ($this->config['single']) { - $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; - - $name .= '_' . $type; - } elseif ($this->config['max_files']) { - $name = date('Ymd') . '_' . $type . $cli; - } else { - $name = date('d') . '_' . $type . $cli; - } - - return $path . DIRECTORY_SEPARATOR . $name . '.log'; - } - - /** - * 日志写入 - * @access protected - * @param array $message 日志信息 - * @param string $destination 日志文件 - * @param bool $apart 是否独立文件写入 - * @param bool $append 是否追加请求信息 - * @return bool - */ - protected function write($message, $destination, $apart = false, $append = false) - { - // 检测日志文件大小,超过配置大小则备份日志文件重新生成 - $this->checkLogSize($destination); - - // 日志信息封装 - $info['timestamp'] = date($this->config['time_format']); - - foreach ($message as $type => $msg) { - $info[$type] = is_array($msg) ? implode("\r\n", $msg) : $msg; - } - - if (PHP_SAPI == 'cli') { - $message = $this->parseCliLog($info); - } else { - // 添加调试日志 - $this->getDebugLog($info, $append, $apart); - - $message = $this->parseLog($info); - } - - return error_log($message, 3, $destination); - } - - /** - * 检查日志文件大小并自动生成备份文件 - * @access protected - * @param string $destination 日志文件 - * @return void - */ - protected function checkLogSize($destination) - { - if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) { - try { - rename($destination, dirname($destination) . DIRECTORY_SEPARATOR . time() . '-' . basename($destination)); - } catch (\Exception $e) { - } - } - } - - /** - * CLI日志解析 - * @access protected - * @param array $info 日志信息 - * @return string - */ - protected function parseCliLog($info) - { - if ($this->config['json']) { - $message = json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n"; - } else { - $now = $info['timestamp']; - unset($info['timestamp']); - - $message = implode("\r\n", $info); - - $message = "[{$now}]" . $message . "\r\n"; - } - - return $message; - } - - /** - * 解析日志 - * @access protected - * @param array $info 日志信息 - * @return string - */ - protected function parseLog($info) - { - $request = Request::instance(); - $requestInfo = [ - 'ip' => $request->ip(), - 'method' => $request->method(), - 'host' => $request->host(), - 'uri' => $request->url(), - ]; - - if ($this->config['json']) { - $info = $requestInfo + $info; - return json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n"; - } - - array_unshift($info, "---------------------------------------------------------------\r\n[{$info['timestamp']}] {$requestInfo['ip']} {$requestInfo['method']} {$requestInfo['host']}{$requestInfo['uri']}"); - unset($info['timestamp']); - - return implode("\r\n", $info) . "\r\n"; - } - - protected function getDebugLog(&$info, $append, $apart) - { - if (App::$debug && $append) { - - if ($this->config['json']) { - // 获取基本信息 - $runtime = round(microtime(true) - THINK_START_TIME, 10); - $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; - - $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); - - $info = [ - 'runtime' => number_format($runtime, 6) . 's', - 'reqs' => $reqs . 'req/s', - 'memory' => $memory_use . 'kb', - 'file' => count(get_included_files()), - ] + $info; - - } elseif (!$apart) { - // 增加额外的调试信息 - $runtime = round(microtime(true) - THINK_START_TIME, 10); - $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; - - $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); - - $time_str = '[运行时间:' . number_format($runtime, 6) . 's] [吞吐率:' . $reqs . 'req/s]'; - $memory_str = ' [内存消耗:' . $memory_use . 'kb]'; - $file_load = ' [文件加载:' . count(get_included_files()) . ']'; - - array_unshift($info, $time_str . $memory_str . $file_load); - } - } - } -} diff --git a/thinkphp/library/think/log/driver/Socket.php b/thinkphp/library/think/log/driver/Socket.php deleted file mode 100755 index 4f62915..0000000 --- a/thinkphp/library/think/log/driver/Socket.php +++ /dev/null @@ -1,250 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\log\driver; - -use think\App; - -/** - * github: https://github.com/luofei614/SocketLog - * @author luofei614 - */ -class Socket -{ - public $port = 1116; //SocketLog 服务的http的端口号 - - protected $config = [ - // socket服务器地址 - 'host' => 'localhost', - // 是否显示加载的文件列表 - 'show_included_files' => false, - // 日志强制记录到配置的client_id - 'force_client_ids' => [], - // 限制允许读取日志的client_id - 'allow_client_ids' => [], - ]; - - protected $css = [ - 'sql' => 'color:#009bb4;', - 'sql_warn' => 'color:#009bb4;font-size:14px;', - 'error' => 'color:#f4006b;font-size:14px;', - 'page' => 'color:#40e2ff;background:#171717;', - 'big' => 'font-size:20px;color:red;', - ]; - - protected $allowForceClientIds = []; //配置强制推送且被授权的client_id - - /** - * 构造函数 - * @param array $config 缓存参数 - * @access public - */ - public function __construct(array $config = []) - { - if (!empty($config)) { - $this->config = array_merge($this->config, $config); - } - } - - /** - * 调试输出接口 - * @access public - * @param array $log 日志信息 - * @return bool - */ - public function save(array $log = [], $append = false) - { - if (!$this->check()) { - return false; - } - $trace = []; - if (App::$debug) { - $runtime = round(microtime(true) - THINK_START_TIME, 10); - $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; - $time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]'; - $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); - $memory_str = ' [内存消耗:' . $memory_use . 'kb]'; - $file_load = ' [文件加载:' . count(get_included_files()) . ']'; - - if (isset($_SERVER['HTTP_HOST'])) { - $current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - } else { - $current_uri = 'cmd:' . implode(' ', $_SERVER['argv']); - } - // 基本信息 - $trace[] = [ - 'type' => 'group', - 'msg' => $current_uri . $time_str . $memory_str . $file_load, - 'css' => $this->css['page'], - ]; - } - - foreach ($log as $type => $val) { - $trace[] = [ - 'type' => 'groupCollapsed', - 'msg' => '[ ' . $type . ' ]', - 'css' => isset($this->css[$type]) ? $this->css[$type] : '', - ]; - foreach ($val as $msg) { - if (!is_string($msg)) { - $msg = var_export($msg, true); - } - $trace[] = [ - 'type' => 'log', - 'msg' => $msg, - 'css' => '', - ]; - } - $trace[] = [ - 'type' => 'groupEnd', - 'msg' => '', - 'css' => '', - ]; - } - - if ($this->config['show_included_files']) { - $trace[] = [ - 'type' => 'groupCollapsed', - 'msg' => '[ file ]', - 'css' => '', - ]; - $trace[] = [ - 'type' => 'log', - 'msg' => implode("\n", get_included_files()), - 'css' => '', - ]; - $trace[] = [ - 'type' => 'groupEnd', - 'msg' => '', - 'css' => '', - ]; - } - - $trace[] = [ - 'type' => 'groupEnd', - 'msg' => '', - 'css' => '', - ]; - - $tabid = $this->getClientArg('tabid'); - if (!$client_id = $this->getClientArg('client_id')) { - $client_id = ''; - } - - if (!empty($this->allowForceClientIds)) { - //强制推送到多个client_id - foreach ($this->allowForceClientIds as $force_client_id) { - $client_id = $force_client_id; - $this->sendToClient($tabid, $client_id, $trace, $force_client_id); - } - } else { - $this->sendToClient($tabid, $client_id, $trace, ''); - } - return true; - } - - /** - * 发送给指定客户端 - * @author Zjmainstay - * @param $tabid - * @param $client_id - * @param $logs - * @param $force_client_id - */ - protected function sendToClient($tabid, $client_id, $logs, $force_client_id) - { - $logs = [ - 'tabid' => $tabid, - 'client_id' => $client_id, - 'logs' => $logs, - 'force_client_id' => $force_client_id, - ]; - $msg = @json_encode($logs); - $address = '/' . $client_id; //将client_id作为地址, server端通过地址判断将日志发布给谁 - $this->send($this->config['host'], $msg, $address); - } - - protected function check() - { - $tabid = $this->getClientArg('tabid'); - //是否记录日志的检查 - if (!$tabid && !$this->config['force_client_ids']) { - return false; - } - //用户认证 - $allow_client_ids = $this->config['allow_client_ids']; - if (!empty($allow_client_ids)) { - //通过数组交集得出授权强制推送的client_id - $this->allowForceClientIds = array_intersect($allow_client_ids, $this->config['force_client_ids']); - if (!$tabid && count($this->allowForceClientIds)) { - return true; - } - - $client_id = $this->getClientArg('client_id'); - if (!in_array($client_id, $allow_client_ids)) { - return false; - } - } else { - $this->allowForceClientIds = $this->config['force_client_ids']; - } - return true; - } - - protected function getClientArg($name) - { - static $args = []; - - $key = 'HTTP_USER_AGENT'; - - if (isset($_SERVER['HTTP_SOCKETLOG'])) { - $key = 'HTTP_SOCKETLOG'; - } - - if (!isset($_SERVER[$key])) { - return; - } - if (empty($args)) { - if (!preg_match('/SocketLog\((.*?)\)/', $_SERVER[$key], $match)) { - $args = ['tabid' => null]; - return; - } - parse_str($match[1], $args); - } - if (isset($args[$name])) { - return $args[$name]; - } - return; - } - - /** - * @param string $host - $host of socket server - * @param string $message - 发送的消息 - * @param string $address - 地址 - * @return bool - */ - protected function send($host, $message = '', $address = '/') - { - $url = 'http://' . $host . ':' . $this->port . $address; - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $message); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - $headers = [ - "Content-Type: application/json;charset=UTF-8", - ]; - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //设置header - return curl_exec($ch); - } - -} diff --git a/thinkphp/library/think/log/driver/Test.php b/thinkphp/library/think/log/driver/Test.php deleted file mode 100755 index 7f66338..0000000 --- a/thinkphp/library/think/log/driver/Test.php +++ /dev/null @@ -1,30 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\log\driver; - -/** - * 模拟测试输出 - */ -class Test -{ - /** - * 日志写入接口 - * @access public - * @param array $log 日志信息 - * @return bool - */ - public function save(array $log = []) - { - return true; - } - -} diff --git a/thinkphp/library/think/model/Collection.php b/thinkphp/library/think/model/Collection.php deleted file mode 100755 index 0406533..0000000 --- a/thinkphp/library/think/model/Collection.php +++ /dev/null @@ -1,79 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model; - -use think\Collection as BaseCollection; -use think\Model; - -class Collection extends BaseCollection -{ - /** - * 延迟预载入关联查询 - * @access public - * @param mixed $relation 关联 - * @return $this - */ - public function load($relation) - { - $item = current($this->items); - $item->eagerlyResultSet($this->items, $relation); - return $this; - } - - /** - * 设置需要隐藏的输出属性 - * @access public - * @param array $hidden 属性列表 - * @param bool $override 是否覆盖 - * @return $this - */ - public function hidden($hidden = [], $override = false) - { - $this->each(function ($model) use ($hidden, $override) { - /** @var Model $model */ - $model->hidden($hidden, $override); - }); - return $this; - } - - /** - * 设置需要输出的属性 - * @param array $visible - * @param bool $override 是否覆盖 - * @return $this - */ - public function visible($visible = [], $override = false) - { - $this->each(function ($model) use ($visible, $override) { - /** @var Model $model */ - $model->visible($visible, $override); - }); - return $this; - } - - /** - * 设置需要追加的输出属性 - * @access public - * @param array $append 属性列表 - * @param bool $override 是否覆盖 - * @return $this - */ - public function append($append = [], $override = false) - { - $this->each(function ($model) use ($append, $override) { - /** @var Model $model */ - $model && $model->append($append, $override); - }); - return $this; - } - -} diff --git a/thinkphp/library/think/model/Merge.php b/thinkphp/library/think/model/Merge.php deleted file mode 100755 index 4a9da81..0000000 --- a/thinkphp/library/think/model/Merge.php +++ /dev/null @@ -1,322 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model; - -use think\Db; -use think\db\Query; -use think\Model; - -class Merge extends Model -{ - - protected $relationModel = []; // HAS ONE 关联的模型列表 - protected $fk = ''; // 外键名 默认为主表名_id - protected $mapFields = []; // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' ) - - /** - * 构造函数 - * @access public - * @param array|object $data 数据 - */ - public function __construct($data = []) - { - parent::__construct($data); - - // 设置默认外键名 仅支持单一外键 - if (empty($this->fk)) { - $this->fk = strtolower($this->name) . '_id'; - } - } - - /** - * 查找单条记录 - * @access public - * @param mixed $data 主键值或者查询条件(闭包) - * @param string|array $with 关联预查询 - * @param bool $cache 是否缓存 - * @return \think\Model - */ - public static function get($data = null, $with = [], $cache = false) - { - $query = self::parseQuery($data, $with, $cache); - $query = self::attachQuery($query); - return $query->find($data); - } - - /** - * 附加查询表达式 - * @access protected - * @param \think\db\Query $query 查询对象 - * @return \think\db\Query - */ - protected static function attachQuery($query) - { - $class = new static(); - $master = $class->name; - $fields = self::getModelField($query, $master, '', $class->mapFields, $class->field); - $query->alias($master)->field($fields); - - foreach ($class->relationModel as $key => $model) { - $name = is_int($key) ? $model : $key; - $table = is_int($key) ? $query->getTable($name) : $model; - $query->join($table . ' ' . $name, $name . '.' . $class->fk . '=' . $master . '.' . $class->getPk()); - $fields = self::getModelField($query, $name, $table, $class->mapFields, $class->field); - $query->field($fields); - } - return $query; - } - - /** - * 获取关联模型的字段 并解决混淆 - * @access protected - * @param \think\db\Query $query 查询对象 - * @param string $name 模型名称 - * @param string $table 关联表名称 - * @param array $map 字段映射 - * @param array $fields 查询字段 - * @return array - */ - protected static function getModelField($query, $name, $table = '', $map = [], $fields = []) - { - // 获取模型的字段信息 - $fields = $fields ?: $query->getTableInfo($table, 'fields'); - $array = []; - foreach ($fields as $field) { - if ($key = array_search($name . '.' . $field, $map)) { - // 需要处理映射字段 - $array[] = $name . '.' . $field . ' AS ' . $key; - } else { - $array[] = $field; - } - } - return $array; - } - - /** - * 查找所有记录 - * @access public - * @param mixed $data 主键列表或者查询条件(闭包) - * @param array|string $with 关联预查询 - * @param bool $cache - * @return array|false|string - */ - public static function all($data = null, $with = [], $cache = false) - { - $query = self::parseQuery($data, $with, $cache); - $query = self::attachQuery($query); - return $query->select($data); - } - - /** - * 处理写入的模型数据 - * @access public - * @param string $model 模型名称 - * @param array $data 数据 - * @return array - */ - protected function parseData($model, $data) - { - $item = []; - foreach ($data as $key => $val) { - if ($this->fk != $key && array_key_exists($key, $this->mapFields)) { - list($name, $key) = explode('.', $this->mapFields[$key]); - if ($model == $name) { - $item[$key] = $val; - } - } else { - $item[$key] = $val; - } - } - return $item; - } - - /** - * 保存模型数据 以及关联数据 - * @access public - * @param mixed $data 数据 - * @param array $where 更新条件 - * @param string $sequence 自增序列名 - * @return false|int - * @throws \Exception - */ - public function save($data = [], $where = [], $sequence = null) - { - if (!empty($data)) { - // 数据自动验证 - if (!$this->validateData($data)) { - return false; - } - // 数据对象赋值 - foreach ($data as $key => $value) { - $this->setAttr($key, $value, $data); - } - if (!empty($where)) { - $this->isUpdate = true; - } - } - - // 数据自动完成 - $this->autoCompleteData($this->auto); - - // 自动写入更新时间 - if ($this->autoWriteTimestamp && $this->updateTime && !isset($this->data[$this->updateTime])) { - $this->setAttr($this->updateTime, null); - } - - // 事件回调 - if (false === $this->trigger('before_write', $this)) { - return false; - } - - $db = $this->db(); - $db->startTrans(); - $pk = $this->getPk(); - try { - if ($this->isUpdate) { - // 自动写入 - $this->autoCompleteData($this->update); - - if (false === $this->trigger('before_update', $this)) { - return false; - } - - if (empty($where) && !empty($this->updateWhere)) { - $where = $this->updateWhere; - } - - // 获取有更新的数据 - $data = $this->getChangedData(); - // 保留主键数据 - foreach ($this->data as $key => $val) { - if ($this->isPk($key)) { - $data[$key] = $val; - } - } - // 处理模型数据 - $data = $this->parseData($this->name, $data); - if (is_string($pk) && isset($data[$pk])) { - if (!isset($where[$pk])) { - unset($where); - $where[$pk] = $data[$pk]; - } - unset($data[$pk]); - } - // 写入主表数据 - $result = $db->strict(false)->where($where)->update($data); - - // 写入附表数据 - foreach ($this->relationModel as $key => $model) { - $name = is_int($key) ? $model : $key; - $table = is_int($key) ? $db->getTable($model) : $model; - // 处理关联模型数据 - $data = $this->parseData($name, $data); - if (Db::table($table)->strict(false)->where($this->fk, $this->data[$this->getPk()])->update($data)) { - $result = 1; - } - } - - // 新增回调 - $this->trigger('after_update', $this); - } else { - // 自动写入 - $this->autoCompleteData($this->insert); - - // 自动写入创建时间 - if ($this->autoWriteTimestamp && $this->createTime && !isset($this->data[$this->createTime])) { - $this->setAttr($this->createTime, null); - } - - if (false === $this->trigger('before_insert', $this)) { - return false; - } - - // 处理模型数据 - $data = $this->parseData($this->name, $this->data); - // 写入主表数据 - $result = $db->name($this->name)->strict(false)->insert($data); - if ($result) { - $insertId = $db->getLastInsID($sequence); - // 写入外键数据 - if ($insertId) { - if (is_string($pk)) { - $this->data[$pk] = $insertId; - } - $this->data[$this->fk] = $insertId; - } - - // 写入附表数据 - $source = $this->data; - if ($insertId && is_string($pk) && isset($source[$pk]) && $this->fk != $pk) { - unset($source[$pk]); - } - foreach ($this->relationModel as $key => $model) { - $name = is_int($key) ? $model : $key; - $table = is_int($key) ? $db->getTable($model) : $model; - // 处理关联模型数据 - $data = $this->parseData($name, $source); - Db::table($table)->strict(false)->insert($data); - } - } - // 标记为更新 - $this->isUpdate = true; - // 新增回调 - $this->trigger('after_insert', $this); - } - $db->commit(); - // 写入回调 - $this->trigger('after_write', $this); - - $this->origin = $this->data; - return $result; - } catch (\Exception $e) { - $db->rollback(); - throw $e; - } - } - - /** - * 删除当前的记录 并删除关联数据 - * @access public - * @return int - * @throws \Exception - */ - public function delete() - { - if (false === $this->trigger('before_delete', $this)) { - return false; - } - - $db = $this->db(); - $db->startTrans(); - try { - $result = $db->delete($this->data); - if ($result) { - // 获取主键数据 - $pk = $this->data[$this->getPk()]; - - // 删除关联数据 - foreach ($this->relationModel as $key => $model) { - $table = is_int($key) ? $db->getTable($model) : $model; - $query = new Query; - $query->table($table)->where($this->fk, $pk)->delete(); - } - } - $this->trigger('after_delete', $this); - $db->commit(); - return $result; - } catch (\Exception $e) { - $db->rollback(); - throw $e; - } - } - -} diff --git a/thinkphp/library/think/model/Pivot.php b/thinkphp/library/think/model/Pivot.php deleted file mode 100755 index 13525cd..0000000 --- a/thinkphp/library/think/model/Pivot.php +++ /dev/null @@ -1,42 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model; - -use think\Model; - -class Pivot extends Model -{ - - /** @var Model */ - public $parent; - - protected $autoWriteTimestamp = false; - - /** - * 架构函数 - * @access public - * @param array|object $data 数据 - * @param Model $parent 上级模型 - * @param string $table 中间数据表名 - */ - public function __construct($data = [], Model $parent = null, $table = '') - { - $this->parent = $parent; - - if (is_null($this->name)) { - $this->name = $table; - } - - parent::__construct($data); - } - -} diff --git a/thinkphp/library/think/model/Relation.php b/thinkphp/library/think/model/Relation.php deleted file mode 100755 index 25fe88d..0000000 --- a/thinkphp/library/think/model/Relation.php +++ /dev/null @@ -1,155 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model; - -use think\db\Query; -use think\Exception; -use think\Model; - -/** - * Class Relation - * @package think\model - * - * @mixin Query - */ -abstract class Relation -{ - // 父模型对象 - protected $parent; - /** @var Model 当前关联的模型类 */ - protected $model; - /** @var Query 关联模型查询对象 */ - protected $query; - // 关联表外键 - protected $foreignKey; - // 关联表主键 - protected $localKey; - // 基础查询 - protected $baseQuery; - // 是否为自关联 - protected $selfRelation; - - /** - * 获取关联的所属模型 - * @access public - * @return Model - */ - public function getParent() - { - return $this->parent; - } - - /** - * 获取当前的关联模型对象实例 - * @access public - * @return Model - */ - public function getModel() - { - return $this->query->getModel(); - } - - /** - * 获取关联的查询对象 - * @access public - * @return Query - */ - public function getQuery() - { - return $this->query; - } - - /** - * 设置当前关联为自关联 - * @access public - * @param bool $self 是否自关联 - * @return $this - */ - public function selfRelation($self = true) - { - $this->selfRelation = $self; - return $this; - } - - /** - * 当前关联是否为自关联 - * @access public - * @return bool - */ - public function isSelfRelation() - { - return $this->selfRelation; - } - - /** - * 封装关联数据集 - * @access public - * @param array $resultSet 数据集 - * @return mixed - */ - protected function resultSetBuild($resultSet) - { - return (new $this->model)->toCollection($resultSet); - } - - protected function getQueryFields($model) - { - $fields = $this->query->getOptions('field'); - return $this->getRelationQueryFields($fields, $model); - } - - protected function getRelationQueryFields($fields, $model) - { - if ($fields) { - - if (is_string($fields)) { - $fields = explode(',', $fields); - } - - foreach ($fields as &$field) { - if (false === strpos($field, '.')) { - $field = $model . '.' . $field; - } - } - } else { - $fields = $model . '.*'; - } - - return $fields; - } - - /** - * 执行基础查询(仅执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - {} - - public function __call($method, $args) - { - if ($this->query) { - // 执行基础查询 - $this->baseQuery(); - - $result = call_user_func_array([$this->query, $method], $args); - if ($result instanceof Query) { - return $this; - } else { - $this->baseQuery = false; - return $result; - } - } else { - throw new Exception('method not exists:' . __CLASS__ . '->' . $method); - } - } -} diff --git a/thinkphp/library/think/model/relation/BelongsTo.php b/thinkphp/library/think/model/relation/BelongsTo.php deleted file mode 100755 index c1cbab9..0000000 --- a/thinkphp/library/think/model/relation/BelongsTo.php +++ /dev/null @@ -1,243 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\db\Query; -use think\Loader; -use think\Model; - -class BelongsTo extends OneToOne -{ - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $model 模型名 - * @param string $foreignKey 关联外键 - * @param string $localKey 关联主键 - * @param string $joinType JOIN类型 - * @param string $relation 关联名 - */ - public function __construct(Model $parent, $model, $foreignKey, $localKey, $joinType = 'INNER', $relation = null) - { - $this->parent = $parent; - $this->model = $model; - $this->foreignKey = $foreignKey; - $this->localKey = $localKey; - $this->joinType = $joinType; - $this->query = (new $model)->db(); - $this->relation = $relation; - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @access public - * @return array|false|\PDOStatement|string|Model - */ - public function getRelation($subRelation = '', $closure = null) - { - $foreignKey = $this->foreignKey; - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - $relationModel = $this->query - ->removeWhereField($this->localKey) - ->where($this->localKey, $this->parent->$foreignKey) - ->relation($subRelation) - ->find(); - - if ($relationModel) { - $relationModel->setParent(clone $this->parent); - } - - return $relationModel; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @return Query - */ - public function has($operator = '>=', $count = 1, $id = '*') - { - return $this->parent; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - */ - public function hasWhere($where = [], $fields = null) - { - $table = $this->query->getTable(); - $model = basename(str_replace('\\', '/', get_class($this->parent))); - $relation = basename(str_replace('\\', '/', $this->model)); - - if (is_array($where)) { - foreach ($where as $key => $val) { - if (false === strpos($key, '.')) { - $where[$relation . '.' . $key] = $val; - unset($where[$key]); - } - } - } - $fields = $this->getRelationQueryFields($fields, $model); - - return $this->parent->db()->alias($model) - ->field($fields) - ->join([$table => $relation], $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $this->joinType) - ->where($where); - } - - /** - * 预载入关联查询(数据集) - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure) - { - $localKey = $this->localKey; - $foreignKey = $this->foreignKey; - - $range = []; - foreach ($resultSet as $result) { - // 获取关联外键列表 - if (isset($result->$foreignKey)) { - $range[] = $result->$foreignKey; - } - } - - if (!empty($range)) { - $this->query->removeWhereField($localKey); - $data = $this->eagerlyWhere($this->query, [ - $localKey => [ - 'in', - $range, - ], - ], $localKey, $relation, $subRelation, $closure); - // 关联属性名 - $attr = Loader::parseName($relation); - // 关联数据封装 - foreach ($resultSet as $result) { - // 关联模型 - if (!isset($data[$result->$foreignKey])) { - $relationModel = null; - } else { - $relationModel = $data[$result->$foreignKey]; - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } - - if (!empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); - } else { - // 设置关联属性 - $result->setRelation($attr, $relationModel); - } - } - } - } - - /** - * 预载入关联查询(数据) - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - protected function eagerlyOne(&$result, $relation, $subRelation, $closure) - { - $localKey = $this->localKey; - $foreignKey = $this->foreignKey; - $this->query->removeWhereField($localKey); - $data = $this->eagerlyWhere($this->query, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure); - // 关联模型 - if (!isset($data[$result->$foreignKey])) { - $relationModel = null; - } else { - $relationModel = $data[$result->$foreignKey]; - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } - if (!empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); - } else { - // 设置关联属性 - $result->setRelation(Loader::parseName($relation), $relationModel); - } - } - - /** - * 添加关联数据 - * @access public - * @param Model $model 关联模型对象 - * @return Model - */ - public function associate($model) - { - $foreignKey = $this->foreignKey; - $pk = $model->getPk(); - - $this->parent->setAttr($foreignKey, $model->$pk); - $this->parent->save(); - - return $this->parent->setRelation($this->relation, $model); - } - - /** - * 注销关联数据 - * @access public - * @return Model - */ - public function dissociate() - { - $foreignKey = $this->foreignKey; - - $this->parent->setAttr($foreignKey, null); - $this->parent->save(); - - return $this->parent->setRelation($this->relation, null); - } - - /** - * 执行基础查询(仅执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery)) { - if (isset($this->parent->{$this->foreignKey})) { - // 关联查询带入关联条件 - $this->query->where($this->localKey, '=', $this->parent->{$this->foreignKey}); - } - - $this->baseQuery = true; - } - } -} diff --git a/thinkphp/library/think/model/relation/BelongsToMany.php b/thinkphp/library/think/model/relation/BelongsToMany.php deleted file mode 100755 index a41c45c..0000000 --- a/thinkphp/library/think/model/relation/BelongsToMany.php +++ /dev/null @@ -1,644 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\Collection; -use think\Db; -use think\db\Query; -use think\Exception; -use think\Loader; -use think\Model; -use think\model\Pivot; -use think\model\Relation; -use think\Paginator; - -class BelongsToMany extends Relation -{ - // 中间表表名 - protected $middle; - // 中间表模型名称 - protected $pivotName; - // 中间表模型对象 - protected $pivot; - // 中间表数据名称 - protected $pivotDataName = 'pivot'; - - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $model 模型名 - * @param string $table 中间表名 - * @param string $foreignKey 关联模型外键 - * @param string $localKey 当前模型关联键 - */ - public function __construct(Model $parent, $model, $table, $foreignKey, $localKey) - { - $this->parent = $parent; - $this->model = $model; - $this->foreignKey = $foreignKey; - $this->localKey = $localKey; - if (false !== strpos($table, '\\')) { - $this->pivotName = $table; - $this->middle = basename(str_replace('\\', '/', $table)); - } else { - $this->middle = $table; - } - $this->query = (new $model)->db(); - $this->pivot = $this->newPivot(); - - if ('think\model\Pivot' == get_class($this->pivot)) { - $this->pivot->name($this->middle); - } - } - - /** - * 设置中间表模型 - * @param $pivot - * @return $this - */ - public function pivot($pivot) - { - $this->pivotName = $pivot; - return $this; - } - - /** - * 设置中间表数据名称 - * @access public - * @param string $name - * @return $this - */ - public function pivotDataName($name) - { - $this->pivotDataName = $name; - return $this; - } - - /** - * 获取中间表更新条件 - * @param $data - * @return array - */ - protected function getUpdateWhere($data) - { - return [ - $this->localKey => $data[$this->localKey], - $this->foreignKey => $data[$this->foreignKey], - ]; - } - - /** - * 实例化中间表模型 - * @param array $data - * @param bool $isUpdate - * @return Pivot - * @throws Exception - */ - protected function newPivot($data = [], $isUpdate = false) - { - $class = $this->pivotName ?: '\\think\\model\\Pivot'; - $pivot = new $class($data, $this->parent, $this->middle); - if ($pivot instanceof Pivot) { - return $isUpdate ? $pivot->isUpdate(true, $this->getUpdateWhere($data)) : $pivot; - } else { - throw new Exception('pivot model must extends: \think\model\Pivot'); - } - } - - /** - * 合成中间表模型 - * @param array|Collection|Paginator $models - */ - protected function hydratePivot($models) - { - foreach ($models as $model) { - $pivot = []; - foreach ($model->getData() as $key => $val) { - if (strpos($key, '__')) { - list($name, $attr) = explode('__', $key, 2); - if ('pivot' == $name) { - $pivot[$attr] = $val; - unset($model->$key); - } - } - } - $model->setRelation($this->pivotDataName, $this->newPivot($pivot, true)); - } - } - - /** - * 创建关联查询Query对象 - * @return Query - */ - protected function buildQuery() - { - $foreignKey = $this->foreignKey; - $localKey = $this->localKey; - $pk = $this->parent->getPk(); - // 关联查询 - $condition['pivot.' . $localKey] = $this->parent->$pk; - return $this->belongsToManyQuery($foreignKey, $localKey, $condition); - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @return false|\PDOStatement|string|\think\Collection - */ - public function getRelation($subRelation = '', $closure = null) - { - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - $result = $this->buildQuery()->relation($subRelation)->select(); - $this->hydratePivot($result); - return $result; - } - - /** - * 重载select方法 - * @param null $data - * @return false|\PDOStatement|string|Collection - */ - public function select($data = null) - { - $result = $this->buildQuery()->select($data); - $this->hydratePivot($result); - return $result; - } - - /** - * 重载paginate方法 - * @param null $listRows - * @param bool $simple - * @param array $config - * @return Paginator - */ - public function paginate($listRows = null, $simple = false, $config = []) - { - $result = $this->buildQuery()->paginate($listRows, $simple, $config); - $this->hydratePivot($result); - return $result; - } - - /** - * 重载find方法 - * @param null $data - * @return array|false|\PDOStatement|string|Model - */ - public function find($data = null) - { - $result = $this->buildQuery()->find($data); - if ($result) { - $this->hydratePivot([$result]); - } - return $result; - } - - /** - * 查找多条记录 如果不存在则抛出异常 - * @access public - * @param array|string|Query|\Closure $data - * @return array|\PDOStatement|string|Model - */ - public function selectOrFail($data = null) - { - return $this->failException(true)->select($data); - } - - /** - * 查找单条记录 如果不存在则抛出异常 - * @access public - * @param array|string|Query|\Closure $data - * @return array|\PDOStatement|string|Model - */ - public function findOrFail($data = null) - { - return $this->failException(true)->find($data); - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 - * @return Query - */ - public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') - { - return $this->parent; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - * @throws Exception - */ - public function hasWhere($where = [], $fields = null) - { - throw new Exception('relation not support: hasWhere'); - } - - /** - * 设置中间表的查询条件 - * @param $field - * @param null $op - * @param null $condition - * @return $this - */ - public function wherePivot($field, $op = null, $condition = null) - { - $field = 'pivot.' . $field; - $this->query->where($field, $op, $condition); - return $this; - } - - /** - * 预载入关联查询(数据集) - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) - { - $localKey = $this->localKey; - $foreignKey = $this->foreignKey; - - $pk = $resultSet[0]->getPk(); - $range = []; - foreach ($resultSet as $result) { - // 获取关联外键列表 - if (isset($result->$pk)) { - $range[] = $result->$pk; - } - } - - if (!empty($range)) { - // 查询关联数据 - $data = $this->eagerlyManyToMany([ - 'pivot.' . $localKey => [ - 'in', - $range, - ], - ], $relation, $subRelation); - // 关联属性名 - $attr = Loader::parseName($relation); - // 关联数据封装 - foreach ($resultSet as $result) { - if (!isset($data[$result->$pk])) { - $data[$result->$pk] = []; - } - - $result->setRelation($attr, $this->resultSetBuild($data[$result->$pk])); - } - } - } - - /** - * 预载入关联查询(单个数据) - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure) - { - $pk = $result->getPk(); - if (isset($result->$pk)) { - $pk = $result->$pk; - // 查询管理数据 - $data = $this->eagerlyManyToMany(['pivot.' . $this->localKey => $pk], $relation, $subRelation); - - // 关联数据封装 - if (!isset($data[$pk])) { - $data[$pk] = []; - } - $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$pk])); - } - } - - /** - * 关联统计 - * @access public - * @param Model $result 数据对象 - * @param \Closure $closure 闭包 - * @return integer - */ - public function relationCount($result, $closure) - { - $pk = $result->getPk(); - $count = 0; - if (isset($result->$pk)) { - $pk = $result->$pk; - $count = $this->belongsToManyQuery($this->foreignKey, $this->localKey, ['pivot.' . $this->localKey => $pk])->count(); - } - return $count; - } - - /** - * 获取关联统计子查询 - * @access public - * @param \Closure $closure 闭包 - * @param string $name 统计数据别名 - * @return string - */ - public function getRelationCountQuery($closure, &$name = null) - { - if ($closure) { - $return = call_user_func_array($closure, [ & $this->query]); - if ($return && is_string($return)) { - $name = $return; - } - } - - return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [ - 'pivot.' . $this->localKey => [ - 'exp', - Db::raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk()), - ], - ])->fetchSql()->count(); - } - - /** - * 多对多 关联模型预查询 - * @access public - * @param array $where 关联预查询条件 - * @param string $relation 关联名 - * @param string $subRelation 子关联 - * @return array - */ - protected function eagerlyManyToMany($where, $relation, $subRelation = '') - { - // 预载入关联查询 支持嵌套预载入 - $list = $this->belongsToManyQuery($this->foreignKey, $this->localKey, $where)->with($subRelation)->select(); - - // 组装模型数据 - $data = []; - foreach ($list as $set) { - $pivot = []; - foreach ($set->getData() as $key => $val) { - if (strpos($key, '__')) { - list($name, $attr) = explode('__', $key, 2); - if ('pivot' == $name) { - $pivot[$attr] = $val; - unset($set->$key); - } - } - } - $set->setRelation($this->pivotDataName, $this->newPivot($pivot, true)); - $data[$pivot[$this->localKey]][] = $set; - } - return $data; - } - - /** - * BELONGS TO MANY 关联查询 - * @access public - * @param string $foreignKey 关联模型关联键 - * @param string $localKey 当前模型关联键 - * @param array $condition 关联查询条件 - * @return Query - */ - protected function belongsToManyQuery($foreignKey, $localKey, $condition = []) - { - // 关联查询封装 - $tableName = $this->query->getTable(); - $table = $this->pivot->getTable(); - $fields = $this->getQueryFields($tableName); - - $query = $this->query->field($fields) - ->field(true, false, $table, 'pivot', 'pivot__'); - - if (empty($this->baseQuery)) { - $relationFk = $this->query->getPk(); - $query->join([$table => 'pivot'], 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk) - ->where($condition); - } - return $query; - } - - /** - * 保存(新增)当前关联数据对象 - * @access public - * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 - * @param array $pivot 中间表额外数据 - * @return integer - */ - public function save($data, array $pivot = []) - { - // 保存关联表/中间表数据 - return $this->attach($data, $pivot); - } - - /** - * 批量保存当前关联数据对象 - * @access public - * @param array $dataSet 数据集 - * @param array $pivot 中间表额外数据 - * @param bool $samePivot 额外数据是否相同 - * @return integer - */ - public function saveAll(array $dataSet, array $pivot = [], $samePivot = false) - { - $result = false; - foreach ($dataSet as $key => $data) { - if (!$samePivot) { - $pivotData = isset($pivot[$key]) ? $pivot[$key] : []; - } else { - $pivotData = $pivot; - } - $result = $this->attach($data, $pivotData); - } - return $result; - } - - /** - * 附加关联的一个中间表数据 - * @access public - * @param mixed $data 数据 可以使用数组、关联模型对象 或者 关联对象的主键 - * @param array $pivot 中间表额外数据 - * @return array|Pivot - * @throws Exception - */ - public function attach($data, $pivot = []) - { - if (is_array($data)) { - if (key($data) === 0) { - $id = $data; - } else { - // 保存关联表数据 - $model = new $this->model; - $model->save($data); - $id = $model->getLastInsID(); - } - } elseif (is_numeric($data) || is_string($data)) { - // 根据关联表主键直接写入中间表 - $id = $data; - } elseif ($data instanceof Model) { - // 根据关联表主键直接写入中间表 - $relationFk = $data->getPk(); - $id = $data->$relationFk; - } - - if ($id) { - // 保存中间表数据 - $pk = $this->parent->getPk(); - $pivot[$this->localKey] = $this->parent->$pk; - $ids = (array) $id; - foreach ($ids as $id) { - $pivot[$this->foreignKey] = $id; - $this->pivot->insert($pivot, true); - $result[] = $this->newPivot($pivot, true); - } - if (count($result) == 1) { - // 返回中间表模型对象 - $result = $result[0]; - } - return $result; - } else { - throw new Exception('miss relation data'); - } - } - - /** - * 判断是否存在关联数据 - * @access public - * @param mixed $data 数据 可以使用关联模型对象 或者 关联对象的主键 - * @return Pivot - * @throws Exception - */ - public function attached($data) - { - if ($data instanceof Model) { - $relationFk = $data->getPk(); - $id = $data->$relationFk; - } else { - $id = $data; - } - - $pk = $this->parent->getPk(); - - $pivot = $this->pivot->where($this->localKey, $this->parent->$pk)->where($this->foreignKey, $id)->find(); - - return $pivot ?: false; - } - - /** - * 解除关联的一个中间表数据 - * @access public - * @param integer|array $data 数据 可以使用关联对象的主键 - * @param bool $relationDel 是否同时删除关联表数据 - * @return integer - */ - public function detach($data = null, $relationDel = false) - { - if (is_array($data)) { - $id = $data; - } elseif (is_numeric($data) || is_string($data)) { - // 根据关联表主键直接写入中间表 - $id = $data; - } elseif ($data instanceof Model) { - // 根据关联表主键直接写入中间表 - $relationFk = $data->getPk(); - $id = $data->$relationFk; - } - // 删除中间表数据 - $pk = $this->parent->getPk(); - $pivot[$this->localKey] = $this->parent->$pk; - if (isset($id)) { - $pivot[$this->foreignKey] = is_array($id) ? ['in', $id] : $id; - } - $this->pivot->where($pivot)->delete(); - // 删除关联表数据 - if (isset($id) && $relationDel) { - $model = $this->model; - $model::destroy($id); - } - } - - /** - * 数据同步 - * @param array $ids - * @param bool $detaching - * @return array - */ - public function sync($ids, $detaching = true) - { - $changes = [ - 'attached' => [], - 'detached' => [], - 'updated' => [], - ]; - $pk = $this->parent->getPk(); - $current = $this->pivot->where($this->localKey, $this->parent->$pk) - ->column($this->foreignKey); - $records = []; - - foreach ($ids as $key => $value) { - if (!is_array($value)) { - $records[$value] = []; - } else { - $records[$key] = $value; - } - } - - $detach = array_diff($current, array_keys($records)); - - if ($detaching && count($detach) > 0) { - $this->detach($detach); - - $changes['detached'] = $detach; - } - - foreach ($records as $id => $attributes) { - if (!in_array($id, $current)) { - $this->attach($id, $attributes); - $changes['attached'][] = $id; - } elseif (count($attributes) > 0 && - $this->attach($id, $attributes) - ) { - $changes['updated'][] = $id; - } - } - - return $changes; - - } - - /** - * 执行基础查询(进执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery) && $this->parent->getData()) { - $pk = $this->parent->getPk(); - $table = $this->pivot->getTable(); - $this->query->join([$table => 'pivot'], 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk); - $this->baseQuery = true; - } - } - -} diff --git a/thinkphp/library/think/model/relation/HasMany.php b/thinkphp/library/think/model/relation/HasMany.php deleted file mode 100755 index c4b31af..0000000 --- a/thinkphp/library/think/model/relation/HasMany.php +++ /dev/null @@ -1,311 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\db\Query; -use think\Loader; -use think\Model; -use think\model\Relation; - -class HasMany extends Relation -{ - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $model 模型名 - * @param string $foreignKey 关联外键 - * @param string $localKey 当前模型主键 - */ - public function __construct(Model $parent, $model, $foreignKey, $localKey) - { - $this->parent = $parent; - $this->model = $model; - $this->foreignKey = $foreignKey; - $this->localKey = $localKey; - $this->query = (new $model)->db(); - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @return false|\PDOStatement|string|\think\Collection - */ - public function getRelation($subRelation = '', $closure = null) - { - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - $list = $this->relation($subRelation)->select(); - $parent = clone $this->parent; - - foreach ($list as &$model) { - $model->setParent($parent); - } - - return $list; - } - - /** - * 预载入关联查询 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) - { - $localKey = $this->localKey; - $range = []; - foreach ($resultSet as $result) { - // 获取关联外键列表 - if (isset($result->$localKey)) { - $range[] = $result->$localKey; - } - } - - if (!empty($range)) { - $data = $this->eagerlyOneToMany($this->query, [ - $this->foreignKey => [ - 'in', - $range, - ], - ], $relation, $subRelation, $closure); - // 关联属性名 - $attr = Loader::parseName($relation); - // 关联数据封装 - foreach ($resultSet as $result) { - if (!isset($data[$result->$localKey])) { - $data[$result->$localKey] = []; - } - - foreach ($data[$result->$localKey] as &$relationModel) { - $relationModel->setParent(clone $result); - } - - $result->setRelation($attr, $this->resultSetBuild($data[$result->$localKey])); - } - } - } - - /** - * 预载入关联查询 - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure) - { - $localKey = $this->localKey; - - if (isset($result->$localKey)) { - $data = $this->eagerlyOneToMany($this->query, [$this->foreignKey => $result->$localKey], $relation, $subRelation, $closure); - // 关联数据封装 - if (!isset($data[$result->$localKey])) { - $data[$result->$localKey] = []; - } - - foreach ($data[$result->$localKey] as &$relationModel) { - $relationModel->setParent(clone $result); - } - - $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$result->$localKey])); - } - } - - /** - * 关联统计 - * @access public - * @param Model $result 数据对象 - * @param \Closure $closure 闭包 - * @return integer - */ - public function relationCount($result, $closure) - { - $localKey = $this->localKey; - $count = 0; - if (isset($result->$localKey)) { - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - $count = $this->query->where($this->foreignKey, $result->$localKey)->count(); - } - return $count; - } - - /** - * 创建关联统计子查询 - * @access public - * @param \Closure $closure 闭包 - * @param string $name 统计数据别名 - * @return string - */ - public function getRelationCountQuery($closure, &$name = null) - { - if ($closure) { - $return = call_user_func_array($closure, [ & $this->query]); - if ($return && is_string($return)) { - $name = $return; - } - } - $localKey = $this->localKey ?: $this->parent->getPk(); - return $this->query->whereExp($this->foreignKey, '=' . $this->parent->getTable() . '.' . $localKey)->fetchSql()->count(); - } - - /** - * 一对多 关联模型预查询 - * @access public - * @param object $model 关联模型对象 - * @param array $where 关联预查询条件 - * @param string $relation 关联名 - * @param string $subRelation 子关联 - * @param bool $closure - * @return array - */ - protected function eagerlyOneToMany($model, $where, $relation, $subRelation = '', $closure = false) - { - $foreignKey = $this->foreignKey; - // 预载入关联查询 支持嵌套预载入 - if ($closure) { - call_user_func_array($closure, [ & $model]); - } - $list = $model->removeWhereField($foreignKey)->where($where)->with($subRelation)->select(); - - // 组装模型数据 - $data = []; - foreach ($list as $set) { - $data[$set->$foreignKey][] = $set; - } - return $data; - } - - /** - * 保存(新增)当前关联数据对象 - * @access public - * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 - * @return Model|false - */ - public function save($data) - { - $model = $this->make($data); - return $model->save($data) ? $model : false; - } - - /** - * 创建关联对象实例 - * @param array $data - * @return Model - */ - public function make($data = []) - { - if ($data instanceof Model) { - $data = $data->getData(); - } - - // 保存关联表数据 - $data[$this->foreignKey] = $this->parent->{$this->localKey}; - - return new $this->model($data); - } - - /** - * 批量保存当前关联数据对象 - * @access public - * @param array $dataSet 数据集 - * @return integer - */ - public function saveAll(array $dataSet) - { - $result = false; - foreach ($dataSet as $key => $data) { - $result = $this->save($data); - } - return $result; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 - * @return Query - */ - public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') - { - $table = $this->query->getTable(); - $model = basename(str_replace('\\', '/', get_class($this->parent))); - $relation = basename(str_replace('\\', '/', $this->model)); - - return $this->parent->db() - ->alias($model) - ->field($model . '.*') - ->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType) - ->group($relation . '.' . $this->foreignKey) - ->having('count(' . $id . ')' . $operator . $count); - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - */ - public function hasWhere($where = [], $fields = null) - { - $table = $this->query->getTable(); - $model = basename(str_replace('\\', '/', get_class($this->parent))); - $relation = basename(str_replace('\\', '/', $this->model)); - - if (is_array($where)) { - foreach ($where as $key => $val) { - if (false === strpos($key, '.')) { - $where[$relation . '.' . $key] = $val; - unset($where[$key]); - } - } - } - - $fields = $this->getRelationQueryFields($fields, $model); - - return $this->parent->db()->alias($model) - ->field($fields) - ->group($model . '.' . $this->localKey) - ->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey) - ->where($where); - } - - /** - * 执行基础查询(进执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery)) { - if (isset($this->parent->{$this->localKey})) { - // 关联查询带入关联条件 - $this->query->where($this->foreignKey, $this->parent->{$this->localKey}); - } - $this->baseQuery = true; - } - } - -} diff --git a/thinkphp/library/think/model/relation/HasManyThrough.php b/thinkphp/library/think/model/relation/HasManyThrough.php deleted file mode 100755 index 3a9a548..0000000 --- a/thinkphp/library/think/model/relation/HasManyThrough.php +++ /dev/null @@ -1,157 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\db\Query; -use think\Exception; -use think\Loader; -use think\Model; -use think\model\Relation; - -class HasManyThrough extends Relation -{ - // 中间关联表外键 - protected $throughKey; - // 中间表模型 - protected $through; - - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $model 模型名 - * @param string $through 中间模型名 - * @param string $foreignKey 关联外键 - * @param string $throughKey 关联外键 - * @param string $localKey 关联主键 - */ - public function __construct(Model $parent, $model, $through, $foreignKey, $throughKey, $localKey) - { - $this->parent = $parent; - $this->model = $model; - $this->through = $through; - $this->foreignKey = $foreignKey; - $this->throughKey = $throughKey; - $this->localKey = $localKey; - $this->query = (new $model)->db(); - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @return false|\PDOStatement|string|\think\Collection - */ - public function getRelation($subRelation = '', $closure = null) - { - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - - return $this->relation($subRelation)->select(); - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 - * @return Query - */ - public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') - { - return $this->parent; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - */ - public function hasWhere($where = [], $fields = null) - { - throw new Exception('relation not support: hasWhere'); - } - - /** - * 预载入关联查询 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) - {} - - /** - * 预载入关联查询 返回模型对象 - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure) - {} - - /** - * 关联统计 - * @access public - * @param Model $result 数据对象 - * @param \Closure $closure 闭包 - * @return integer - */ - public function relationCount($result, $closure) - {} - - /** - * 创建关联统计子查询 - * @access public - * @param \Closure $closure 闭包 - * @param string $name 统计数据别名 - * @return string - */ - public function getRelationCountQuery($closure, &$name = null) - { - throw new Exception('relation not support: withCount'); - } - - /** - * 执行基础查询(进执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery) && $this->parent->getData()) { - $through = $this->through; - $alias = Loader::parseName(basename(str_replace('\\', '/', $this->model))); - $throughTable = $through::getTable(); - $pk = (new $through)->getPk(); - $throughKey = $this->throughKey; - $modelTable = $this->parent->getTable(); - $this->query->field($alias . '.*')->alias($alias) - ->join($throughTable, $throughTable . '.' . $pk . '=' . $alias . '.' . $throughKey) - ->join($modelTable, $modelTable . '.' . $this->localKey . '=' . $throughTable . '.' . $this->foreignKey) - ->where($throughTable . '.' . $this->foreignKey, $this->parent->{$this->localKey}); - $this->baseQuery = true; - } - } - -} diff --git a/thinkphp/library/think/model/relation/HasOne.php b/thinkphp/library/think/model/relation/HasOne.php deleted file mode 100755 index db74e4a..0000000 --- a/thinkphp/library/think/model/relation/HasOne.php +++ /dev/null @@ -1,215 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\db\Query; -use think\Loader; -use think\Model; - -class HasOne extends OneToOne -{ - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $model 模型名 - * @param string $foreignKey 关联外键 - * @param string $localKey 当前模型主键 - * @param string $joinType JOIN类型 - */ - public function __construct(Model $parent, $model, $foreignKey, $localKey, $joinType = 'INNER') - { - $this->parent = $parent; - $this->model = $model; - $this->foreignKey = $foreignKey; - $this->localKey = $localKey; - $this->joinType = $joinType; - $this->query = (new $model)->db(); - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @return array|false|\PDOStatement|string|Model - */ - public function getRelation($subRelation = '', $closure = null) - { - // 执行关联定义方法 - $localKey = $this->localKey; - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - // 判断关联类型执行查询 - $relationModel = $this->query - ->removeWhereField($this->foreignKey) - ->where($this->foreignKey, $this->parent->$localKey) - ->relation($subRelation) - ->find(); - - if ($relationModel) { - $relationModel->setParent(clone $this->parent); - } - - return $relationModel; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @return Query - */ - public function has() - { - $table = $this->query->getTable(); - $model = basename(str_replace('\\', '/', get_class($this->parent))); - $relation = basename(str_replace('\\', '/', $this->model)); - $localKey = $this->localKey; - $foreignKey = $this->foreignKey; - return $this->parent->db() - ->alias($model) - ->whereExists(function ($query) use ($table, $model, $relation, $localKey, $foreignKey) { - $query->table([$table => $relation])->field($relation . '.' . $foreignKey)->whereExp($model . '.' . $localKey, '=' . $relation . '.' . $foreignKey); - }); - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - */ - public function hasWhere($where = [], $fields = null) - { - $table = $this->query->getTable(); - $model = basename(str_replace('\\', '/', get_class($this->parent))); - $relation = basename(str_replace('\\', '/', $this->model)); - - if (is_array($where)) { - foreach ($where as $key => $val) { - if (false === strpos($key, '.')) { - $where[$relation . '.' . $key] = $val; - unset($where[$key]); - } - } - } - $fields = $this->getRelationQueryFields($fields, $model); - - return $this->parent->db()->alias($model) - ->field($fields) - ->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $this->joinType) - ->where($where); - } - - /** - * 预载入关联查询(数据集) - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure) - { - $localKey = $this->localKey; - $foreignKey = $this->foreignKey; - - $range = []; - foreach ($resultSet as $result) { - // 获取关联外键列表 - if (isset($result->$localKey)) { - $range[] = $result->$localKey; - } - } - - if (!empty($range)) { - $this->query->removeWhereField($foreignKey); - $data = $this->eagerlyWhere($this->query, [ - $foreignKey => [ - 'in', - $range, - ], - ], $foreignKey, $relation, $subRelation, $closure); - // 关联属性名 - $attr = Loader::parseName($relation); - // 关联数据封装 - foreach ($resultSet as $result) { - // 关联模型 - if (!isset($data[$result->$localKey])) { - $relationModel = null; - } else { - $relationModel = $data[$result->$localKey]; - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } - if (!empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); - } else { - // 设置关联属性 - $result->setRelation($attr, $relationModel); - } - } - } - } - - /** - * 预载入关联查询(数据) - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - protected function eagerlyOne(&$result, $relation, $subRelation, $closure) - { - $localKey = $this->localKey; - $foreignKey = $this->foreignKey; - $this->query->removeWhereField($foreignKey); - $data = $this->eagerlyWhere($this->query, [$foreignKey => $result->$localKey], $foreignKey, $relation, $subRelation, $closure); - - // 关联模型 - if (!isset($data[$result->$localKey])) { - $relationModel = null; - } else { - $relationModel = $data[$result->$localKey]; - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } - if (!empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); - } else { - $result->setRelation(Loader::parseName($relation), $relationModel); - } - } - - /** - * 执行基础查询(仅执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery)) { - if (isset($this->parent->{$this->localKey})) { - // 关联查询带入关联条件 - $this->query->where($this->foreignKey, '=', $this->parent->{$this->localKey}); - } - - $this->baseQuery = true; - } - } -} diff --git a/thinkphp/library/think/model/relation/MorphMany.php b/thinkphp/library/think/model/relation/MorphMany.php deleted file mode 100755 index 941ebe8..0000000 --- a/thinkphp/library/think/model/relation/MorphMany.php +++ /dev/null @@ -1,304 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\Db; -use think\db\Query; -use think\Exception; -use think\Loader; -use think\Model; -use think\model\Relation; - -class MorphMany extends Relation -{ - // 多态字段 - protected $morphKey; - protected $morphType; - // 多态类型 - protected $type; - - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $model 模型名 - * @param string $morphKey 关联外键 - * @param string $morphType 多态字段名 - * @param string $type 多态类型 - */ - public function __construct(Model $parent, $model, $morphKey, $morphType, $type) - { - $this->parent = $parent; - $this->model = $model; - $this->type = $type; - $this->morphKey = $morphKey; - $this->morphType = $morphType; - $this->query = (new $model)->db(); - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @return false|\PDOStatement|string|\think\Collection - */ - public function getRelation($subRelation = '', $closure = null) - { - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - $list = $this->relation($subRelation)->select(); - $parent = clone $this->parent; - - foreach ($list as &$model) { - $model->setParent($parent); - } - - return $list; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 - * @return Query - */ - public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') - { - throw new Exception('relation not support: has'); - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - */ - public function hasWhere($where = [], $fields = null) - { - throw new Exception('relation not support: hasWhere'); - } - - /** - * 预载入关联查询 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) - { - $morphType = $this->morphType; - $morphKey = $this->morphKey; - $type = $this->type; - $range = []; - foreach ($resultSet as $result) { - $pk = $result->getPk(); - // 获取关联外键列表 - if (isset($result->$pk)) { - $range[] = $result->$pk; - } - } - - if (!empty($range)) { - $data = $this->eagerlyMorphToMany([ - $morphKey => ['in', $range], - $morphType => $type, - ], $relation, $subRelation, $closure); - // 关联属性名 - $attr = Loader::parseName($relation); - // 关联数据封装 - foreach ($resultSet as $result) { - if (!isset($data[$result->$pk])) { - $data[$result->$pk] = []; - } - foreach ($data[$result->$pk] as &$relationModel) { - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } - $result->setRelation($attr, $this->resultSetBuild($data[$result->$pk])); - } - } - } - - /** - * 预载入关联查询 - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure) - { - $pk = $result->getPk(); - if (isset($result->$pk)) { - $data = $this->eagerlyMorphToMany([ - $this->morphKey => $result->$pk, - $this->morphType => $this->type, - ], $relation, $subRelation, $closure); - - if (!isset($data[$result->$pk])) { - $data[$result->$pk] = []; - } - - foreach ($data[$result->$pk] as &$relationModel) { - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } - - $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk])); - } - } - - /** - * 关联统计 - * @access public - * @param Model $result 数据对象 - * @param \Closure $closure 闭包 - * @return integer - */ - public function relationCount($result, $closure) - { - $pk = $result->getPk(); - $count = 0; - if (isset($result->$pk)) { - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - $count = $this->query->where([$this->morphKey => $result->$pk, $this->morphType => $this->type])->count(); - } - return $count; - } - - /** - * 创建关联统计子查询 - * @access public - * @param \Closure $closure 闭包 - * @param string $name 统计数据别名 - * @return string - */ - public function getRelationCountQuery($closure, &$name = null) - { - if ($closure) { - $return = call_user_func_array($closure, [ & $this->query]); - if ($return && is_string($return)) { - $name = $return; - } - } - - return $this->query->where([ - $this->morphKey => [ - 'exp', - Db::raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk()), - ], - $this->morphType => $this->type, - ])->fetchSql()->count(); - } - - /** - * 多态一对多 关联模型预查询 - * @access public - * @param array $where 关联预查询条件 - * @param string $relation 关联名 - * @param string $subRelation 子关联 - * @param bool|\Closure $closure 闭包 - * @return array - */ - protected function eagerlyMorphToMany($where, $relation, $subRelation = '', $closure = false) - { - // 预载入关联查询 支持嵌套预载入 - if ($closure) { - call_user_func_array($closure, [ & $this]); - } - $list = $this->query->where($where)->with($subRelation)->select(); - $morphKey = $this->morphKey; - // 组装模型数据 - $data = []; - foreach ($list as $set) { - $data[$set->$morphKey][] = $set; - } - return $data; - } - - /** - * 保存(新增)当前关联数据对象 - * @access public - * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 - * @return Model|false - */ - public function save($data) - { - $model = $this->make($data); - - return $model->save($data) ? $model : false; - } - - /** - * 创建关联对象实例 - * @param array $data - * @return Model - */ - public function make($data = []) - { - if ($data instanceof Model) { - $data = $data->getData(); - } - - // 保存关联表数据 - $pk = $this->parent->getPk(); - - $data[$this->morphKey] = $this->parent->$pk; - $data[$this->morphType] = $this->type; - - return new $this->model($data); - } - - /** - * 批量保存当前关联数据对象 - * @access public - * @param array $dataSet 数据集 - * @return integer - */ - public function saveAll(array $dataSet) - { - $result = false; - foreach ($dataSet as $key => $data) { - $result = $this->save($data); - } - return $result; - } - - /** - * 执行基础查询(进执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery) && $this->parent->getData()) { - $pk = $this->parent->getPk(); - $map[$this->morphKey] = $this->parent->$pk; - $map[$this->morphType] = $this->type; - $this->query->where($map); - $this->baseQuery = true; - } - } - -} diff --git a/thinkphp/library/think/model/relation/MorphOne.php b/thinkphp/library/think/model/relation/MorphOne.php deleted file mode 100755 index 1f4bffd..0000000 --- a/thinkphp/library/think/model/relation/MorphOne.php +++ /dev/null @@ -1,252 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\db\Query; -use think\Exception; -use think\Loader; -use think\Model; -use think\model\Relation; - -class MorphOne extends Relation -{ - // 多态字段 - protected $morphKey; - protected $morphType; - // 多态类型 - protected $type; - - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $model 模型名 - * @param string $morphKey 关联外键 - * @param string $morphType 多态字段名 - * @param string $type 多态类型 - */ - public function __construct(Model $parent, $model, $morphKey, $morphType, $type) - { - $this->parent = $parent; - $this->model = $model; - $this->type = $type; - $this->morphKey = $morphKey; - $this->morphType = $morphType; - $this->query = (new $model)->db(); - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @return false|\PDOStatement|string|\think\Collection - */ - public function getRelation($subRelation = '', $closure = null) - { - if ($closure) { - call_user_func_array($closure, [ & $this->query]); - } - $relationModel = $this->relation($subRelation)->find(); - - if ($relationModel) { - $relationModel->setParent(clone $this->parent); - } - - return $relationModel; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 - * @return Query - */ - public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') - { - return $this->parent; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - */ - public function hasWhere($where = [], $fields = null) - { - throw new Exception('relation not support: hasWhere'); - } - - /** - * 预载入关联查询 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) - { - $morphType = $this->morphType; - $morphKey = $this->morphKey; - $type = $this->type; - $range = []; - foreach ($resultSet as $result) { - $pk = $result->getPk(); - // 获取关联外键列表 - if (isset($result->$pk)) { - $range[] = $result->$pk; - } - } - - if (!empty($range)) { - $data = $this->eagerlyMorphToOne([ - $morphKey => ['in', $range], - $morphType => $type, - ], $relation, $subRelation, $closure); - // 关联属性名 - $attr = Loader::parseName($relation); - // 关联数据封装 - foreach ($resultSet as $result) { - if (!isset($data[$result->$pk])) { - $relationModel = null; - } else { - $relationModel = $data[$result->$pk]; - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } - - $result->setRelation($attr, $relationModel); - } - } - } - - /** - * 预载入关联查询 - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure) - { - $pk = $result->getPk(); - if (isset($result->$pk)) { - $pk = $result->$pk; - $data = $this->eagerlyMorphToOne([ - $this->morphKey => $pk, - $this->morphType => $this->type, - ], $relation, $subRelation, $closure); - - if (isset($data[$pk])) { - $relationModel = $data[$pk]; - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - } else { - $relationModel = null; - } - - $result->setRelation(Loader::parseName($relation), $relationModel); - } - } - - /** - * 多态一对一 关联模型预查询 - * @access public - * @param array $where 关联预查询条件 - * @param string $relation 关联名 - * @param string $subRelation 子关联 - * @param bool|\Closure $closure 闭包 - * @return array - */ - protected function eagerlyMorphToOne($where, $relation, $subRelation = '', $closure = false) - { - // 预载入关联查询 支持嵌套预载入 - if ($closure) { - call_user_func_array($closure, [ & $this]); - } - $list = $this->query->where($where)->with($subRelation)->find(); - $morphKey = $this->morphKey; - // 组装模型数据 - $data = []; - foreach ($list as $set) { - $data[$set->$morphKey][] = $set; - } - return $data; - } - - /** - * 保存(新增)当前关联数据对象 - * @access public - * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 - * @return Model|false - */ - public function save($data) - { - $model = $this->make($data); - return $model->save() ? $model : false; - } - - /** - * 创建关联对象实例 - * @param array $data - * @return Model - */ - public function make($data = []) - { - if ($data instanceof Model) { - $data = $data->getData(); - } - // 保存关联表数据 - $pk = $this->parent->getPk(); - - $data[$this->morphKey] = $this->parent->$pk; - $data[$this->morphType] = $this->type; - - return new $this->model($data); - } - - /** - * 执行基础查询(进执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery) && $this->parent->getData()) { - $pk = $this->parent->getPk(); - $map[$this->morphKey] = $this->parent->$pk; - $map[$this->morphType] = $this->type; - $this->query->where($map); - $this->baseQuery = true; - } - } - - /** - * 创建关联统计子查询 - * @access public - * @param \Closure $closure 闭包 - * @param string $name 统计数据别名 - * @return string - */ - public function getRelationCountQuery($closure, &$name = null) - { - throw new Exception('relation not support: withCount'); - } -} diff --git a/thinkphp/library/think/model/relation/MorphTo.php b/thinkphp/library/think/model/relation/MorphTo.php deleted file mode 100755 index 7d45265..0000000 --- a/thinkphp/library/think/model/relation/MorphTo.php +++ /dev/null @@ -1,299 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\Exception; -use think\Loader; -use think\Model; -use think\model\Relation; - -class MorphTo extends Relation -{ - // 多态字段 - protected $morphKey; - protected $morphType; - // 多态别名 - protected $alias; - protected $relation; - - /** - * 构造函数 - * @access public - * @param Model $parent 上级模型对象 - * @param string $morphType 多态字段名 - * @param string $morphKey 外键名 - * @param array $alias 多态别名定义 - * @param string $relation 关联名 - */ - public function __construct(Model $parent, $morphType, $morphKey, $alias = [], $relation = null) - { - $this->parent = $parent; - $this->morphType = $morphType; - $this->morphKey = $morphKey; - $this->alias = $alias; - $this->relation = $relation; - } - - /** - * 获取当前的关联模型类的实例 - * @access public - * @return Model - */ - public function getModel() - { - $morphType = $this->morphType; - $model = $this->parseModel($this->parent->$morphType); - return (new $model); - } - - /** - * 延迟获取关联数据 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包查询条件 - * @return mixed - */ - public function getRelation($subRelation = '', $closure = null) - { - $morphKey = $this->morphKey; - $morphType = $this->morphType; - // 多态模型 - $model = $this->parseModel($this->parent->$morphType); - // 主键数据 - $pk = $this->parent->$morphKey; - $relationModel = (new $model)->relation($subRelation)->find($pk); - - if ($relationModel) { - $relationModel->setParent(clone $this->parent); - } - return $relationModel; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param string $operator 比较操作符 - * @param integer $count 个数 - * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 - * @return Query - */ - public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') - { - return $this->parent; - } - - /** - * 根据关联条件查询当前模型 - * @access public - * @param mixed $where 查询条件(数组或者闭包) - * @param mixed $fields 字段 - * @return Query - */ - public function hasWhere($where = [], $fields = null) - { - throw new Exception('relation not support: hasWhere'); - } - - /** - * 解析模型的完整命名空间 - * @access protected - * @param string $model 模型名(或者完整类名) - * @return string - */ - protected function parseModel($model) - { - if (isset($this->alias[$model])) { - $model = $this->alias[$model]; - } - if (false === strpos($model, '\\')) { - $path = explode('\\', get_class($this->parent)); - array_pop($path); - array_push($path, Loader::parseName($model, 1)); - $model = implode('\\', $path); - } - return $model; - } - - /** - * 设置多态别名 - * @access public - * @param array $alias 别名定义 - * @return $this - */ - public function setAlias($alias) - { - $this->alias = $alias; - return $this; - } - - /** - * 移除关联查询参数 - * @access public - * @return $this - */ - public function removeOption() - { - return $this; - } - - /** - * 预载入关联查询 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - * @throws Exception - */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) - { - $morphKey = $this->morphKey; - $morphType = $this->morphType; - $range = []; - foreach ($resultSet as $result) { - // 获取关联外键列表 - if (!empty($result->$morphKey)) { - $range[$result->$morphType][] = $result->$morphKey; - } - } - - if (!empty($range)) { - // 关联属性名 - $attr = Loader::parseName($relation); - foreach ($range as $key => $val) { - // 多态类型映射 - $model = $this->parseModel($key); - $obj = new $model; - $pk = $obj->getPk(); - $list = $obj->all($val, $subRelation); - $data = []; - foreach ($list as $k => $vo) { - $data[$vo->$pk] = $vo; - } - foreach ($resultSet as $result) { - if ($key == $result->$morphType) { - // 关联模型 - if (!isset($data[$result->$morphKey])) { - throw new Exception('relation data not exists :' . $this->model); - } else { - $relationModel = $data[$result->$morphKey]; - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - - $result->setRelation($attr, $relationModel); - } - } - } - } - } - } - - /** - * 预载入关联查询 - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure) - { - $morphKey = $this->morphKey; - $morphType = $this->morphType; - // 多态类型映射 - $model = $this->parseModel($result->{$this->morphType}); - $this->eagerlyMorphToOne($model, $relation, $result, $subRelation); - } - - /** - * 关联统计 - * @access public - * @param Model $result 数据对象 - * @param \Closure $closure 闭包 - * @return integer - */ - public function relationCount($result, $closure) - { - } - - /** - * 多态MorphTo 关联模型预查询 - * @access public - * @param object $model 关联模型对象 - * @param string $relation 关联名 - * @param $result - * @param string $subRelation 子关联 - * @return void - */ - protected function eagerlyMorphToOne($model, $relation, &$result, $subRelation = '') - { - // 预载入关联查询 支持嵌套预载入 - $pk = $this->parent->{$this->morphKey}; - $data = (new $model)->with($subRelation)->find($pk); - if ($data) { - $data->setParent(clone $result); - $data->isUpdate(true); - } - $result->setRelation(Loader::parseName($relation), $data ?: null); - } - - /** - * 添加关联数据 - * @access public - * @param Model $model 关联模型对象 - * @param string $type 多态类型 - * @return Model - */ - public function associate($model, $type = '') - { - $morphKey = $this->morphKey; - $morphType = $this->morphType; - $pk = $model->getPk(); - - $this->parent->setAttr($morphKey, $model->$pk); - $this->parent->setAttr($morphType, $type ?: get_class($model)); - $this->parent->save(); - - return $this->parent->setRelation($this->relation, $model); - } - - /** - * 注销关联数据 - * @access public - * @return Model - */ - public function dissociate() - { - $morphKey = $this->morphKey; - $morphType = $this->morphType; - - $this->parent->setAttr($morphKey, null); - $this->parent->setAttr($morphType, null); - $this->parent->save(); - - return $this->parent->setRelation($this->relation, null); - } - - /** - * 创建关联统计子查询 - * @access public - * @param \Closure $closure 闭包 - * @param string $name 统计数据别名 - * @return string - */ - public function getRelationCountQuery($closure, &$name = null) - { - throw new Exception('relation not support: withCount'); - } -} diff --git a/thinkphp/library/think/model/relation/OneToOne.php b/thinkphp/library/think/model/relation/OneToOne.php deleted file mode 100755 index 353ce21..0000000 --- a/thinkphp/library/think/model/relation/OneToOne.php +++ /dev/null @@ -1,337 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\model\relation; - -use think\db\Query; -use think\Exception; -use think\Loader; -use think\Model; -use think\model\Relation; - -/** - * Class OneToOne - * @package think\model\relation - * - */ -abstract class OneToOne extends Relation -{ - // 预载入方式 0 -JOIN 1 -IN - protected $eagerlyType = 1; - // 当前关联的JOIN类型 - protected $joinType; - // 要绑定的属性 - protected $bindAttr = []; - // 关联方法名 - protected $relation; - - /** - * 设置join类型 - * @access public - * @param string $type JOIN类型 - * @return $this - */ - public function joinType($type) - { - $this->joinType = $type; - return $this; - } - - /** - * 预载入关联查询(JOIN方式) - * @access public - * @param Query $query 查询对象 - * @param string $relation 关联名 - * @param string $subRelation 子关联 - * @param \Closure $closure 闭包条件 - * @param bool $first - * @return void - */ - public function eagerly(Query $query, $relation, $subRelation, $closure, $first) - { - $name = Loader::parseName(basename(str_replace('\\', '/', get_class($query->getModel())))); - - if ($first) { - $table = $query->getTable(); - $query->table([$table => $name]); - if ($query->getOptions('field')) { - $field = $query->getOptions('field'); - $query->removeOption('field'); - } else { - $field = true; - } - $query->field($field, false, $table, $name); - $field = null; - } - - // 预载入封装 - $joinTable = $this->query->getTable(); - $joinAlias = $relation; - $query->via($joinAlias); - - if ($this instanceof BelongsTo) { - $query->join([$joinTable => $joinAlias], $name . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); - } else { - $query->join([$joinTable => $joinAlias], $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); - } - - if ($closure) { - // 执行闭包查询 - call_user_func_array($closure, [ & $query]); - // 使用withField指定获取关联的字段,如 - // $query->where(['id'=>1])->withField('id,name'); - if ($query->getOptions('with_field')) { - $field = $query->getOptions('with_field'); - $query->removeOption('with_field'); - } - } elseif (isset($this->option['field'])) { - $field = $this->option['field']; - } - $query->field(isset($field) ? $field : true, false, $joinTable, $joinAlias, $relation . '__'); - } - - /** - * 预载入关联查询(数据集) - * @param array $resultSet - * @param string $relation - * @param string $subRelation - * @param \Closure $closure - * @return mixed - */ - abstract protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure); - - /** - * 预载入关联查询(数据) - * @param Model $result - * @param string $relation - * @param string $subRelation - * @param \Closure $closure - * @return mixed - */ - abstract protected function eagerlyOne(&$result, $relation, $subRelation, $closure); - - /** - * 预载入关联查询(数据集) - * @access public - * @param array $resultSet 数据集 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) - { - if (1 == $this->eagerlyType) { - // IN查询 - $this->eagerlySet($resultSet, $relation, $subRelation, $closure); - } else { - // 模型关联组装 - foreach ($resultSet as $result) { - $this->match($this->model, $relation, $result); - } - } - } - - /** - * 预载入关联查询(数据) - * @access public - * @param Model $result 数据对象 - * @param string $relation 当前关联名 - * @param string $subRelation 子关联名 - * @param \Closure $closure 闭包 - * @return void - */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure) - { - if (1 == $this->eagerlyType) { - // IN查询 - $this->eagerlyOne($result, $relation, $subRelation, $closure); - } else { - // 模型关联组装 - $this->match($this->model, $relation, $result); - } - } - - /** - * 保存(新增)当前关联数据对象 - * @access public - * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 - * @return Model|false - */ - public function save($data) - { - if ($data instanceof Model) { - $data = $data->getData(); - } - $model = new $this->model; - // 保存关联表数据 - $data[$this->foreignKey] = $this->parent->{$this->localKey}; - return $model->save($data) ? $model : false; - } - - /** - * 设置预载入方式 - * @access public - * @param integer $type 预载入方式 0 JOIN查询 1 IN查询 - * @return $this - */ - public function setEagerlyType($type) - { - $this->eagerlyType = $type; - return $this; - } - - /** - * 获取预载入方式 - * @access public - * @return integer - */ - public function getEagerlyType() - { - return $this->eagerlyType; - } - - /** - * 绑定关联表的属性到父模型属性 - * @access public - * @param mixed $attr 要绑定的属性列表 - * @return $this - */ - public function bind($attr) - { - if (is_string($attr)) { - $attr = explode(',', $attr); - } - $this->bindAttr = $attr; - return $this; - } - - /** - * 获取绑定属性 - * @access public - * @return array - */ - public function getBindAttr() - { - return $this->bindAttr; - } - - /** - * 关联统计 - * @access public - * @param Model $result 数据对象 - * @param \Closure $closure 闭包 - * @return integer - */ - public function relationCount($result, $closure) - { - } - - /** - * 一对一 关联模型预查询拼装 - * @access public - * @param string $model 模型名称 - * @param string $relation 关联名 - * @param Model $result 模型对象实例 - * @return void - */ - protected function match($model, $relation, &$result) - { - // 重新组装模型数据 - foreach ($result->getData() as $key => $val) { - if (strpos($key, '__')) { - list($name, $attr) = explode('__', $key, 2); - if ($name == $relation) { - $list[$name][$attr] = $val; - unset($result->$key); - } - } - } - - if (isset($list[$relation])) { - $relationModel = new $model($list[$relation]); - $relationModel->setParent(clone $result); - $relationModel->isUpdate(true); - - if (!empty($this->bindAttr)) { - $this->bindAttr($relationModel, $result, $this->bindAttr); - } - } else { - $relationModel = null; - } - $result->setRelation(Loader::parseName($relation), $relationModel); - } - - /** - * 绑定关联属性到父模型 - * @access protected - * @param Model $model 关联模型对象 - * @param Model $result 父模型对象 - * @param array $bindAttr 绑定属性 - * @return void - * @throws Exception - */ - protected function bindAttr($model, &$result, $bindAttr) - { - foreach ($bindAttr as $key => $attr) { - $key = is_numeric($key) ? $attr : $key; - if (isset($result->$key)) { - throw new Exception('bind attr has exists:' . $key); - } else { - $result->setAttr($key, $model ? $model->$attr : null); - } - } - } - - /** - * 一对一 关联模型预查询(IN方式) - * @access public - * @param object $model 关联模型对象 - * @param array $where 关联预查询条件 - * @param string $key 关联键名 - * @param string $relation 关联名 - * @param string $subRelation 子关联 - * @param bool|\Closure $closure - * @return array - */ - protected function eagerlyWhere($model, $where, $key, $relation, $subRelation = '', $closure = false) - { - $this->baseQuery = true; - - // 预载入关联查询 支持嵌套预载入 - if ($closure) { - call_user_func_array($closure, [ & $model]); - if ($field = $model->getOptions('with_field')) { - $model->field($field)->removeOption('with_field'); - } - } - $list = $model->where($where)->with($subRelation)->select(); - - // 组装模型数据 - $data = []; - foreach ($list as $set) { - $data[$set->$key] = $set; - } - return $data; - } - - /** - * 创建关联统计子查询 - * @access public - * @param \Closure $closure 闭包 - * @param string $name 统计数据别名 - * @return string - */ - public function getRelationCountQuery($closure, &$name = null) - { - throw new Exception('relation not support: withCount'); - } -} diff --git a/thinkphp/library/think/paginator/driver/Bootstrap.php b/thinkphp/library/think/paginator/driver/Bootstrap.php deleted file mode 100755 index c5ac60d..0000000 --- a/thinkphp/library/think/paginator/driver/Bootstrap.php +++ /dev/null @@ -1,205 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\paginator\driver; - -use think\Paginator; - -class Bootstrap extends Paginator -{ - - /** - * 上一页按钮 - * @param string $text - * @return string - */ - protected function getPreviousButton($text = "«") - { - - if ($this->currentPage() <= 1) { - return $this->getDisabledTextWrapper($text); - } - - $url = $this->url( - $this->currentPage() - 1 - ); - - return $this->getPageLinkWrapper($url, $text); - } - - /** - * 下一页按钮 - * @param string $text - * @return string - */ - protected function getNextButton($text = '»') - { - if (!$this->hasMore) { - return $this->getDisabledTextWrapper($text); - } - - $url = $this->url($this->currentPage() + 1); - - return $this->getPageLinkWrapper($url, $text); - } - - /** - * 页码按钮 - * @return string - */ - protected function getLinks() - { - if ($this->simple) - return ''; - - $block = [ - 'first' => null, - 'slider' => null, - 'last' => null - ]; - - $side = 3; - $window = $side * 2; - - if ($this->lastPage < $window + 6) { - $block['first'] = $this->getUrlRange(1, $this->lastPage); - } elseif ($this->currentPage <= $window) { - $block['first'] = $this->getUrlRange(1, $window + 2); - $block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage); - } elseif ($this->currentPage > ($this->lastPage - $window)) { - $block['first'] = $this->getUrlRange(1, 2); - $block['last'] = $this->getUrlRange($this->lastPage - ($window + 2), $this->lastPage); - } else { - $block['first'] = $this->getUrlRange(1, 2); - $block['slider'] = $this->getUrlRange($this->currentPage - $side, $this->currentPage + $side); - $block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage); - } - - $html = ''; - - if (is_array($block['first'])) { - $html .= $this->getUrlLinks($block['first']); - } - - if (is_array($block['slider'])) { - $html .= $this->getDots(); - $html .= $this->getUrlLinks($block['slider']); - } - - if (is_array($block['last'])) { - $html .= $this->getDots(); - $html .= $this->getUrlLinks($block['last']); - } - - return $html; - } - - /** - * 渲染分页html - * @return mixed - */ - public function render() - { - if ($this->hasPages()) { - if ($this->simple) { - return sprintf( - '
    %s %s
', - $this->getPreviousButton(), - $this->getNextButton() - ); - } else { - return sprintf( - '
    %s %s %s
', - $this->getPreviousButton(), - $this->getLinks(), - $this->getNextButton() - ); - } - } - } - - /** - * 生成一个可点击的按钮 - * - * @param string $url - * @param int $page - * @return string - */ - protected function getAvailablePageWrapper($url, $page) - { - return '
  • ' . $page . '
  • '; - } - - /** - * 生成一个禁用的按钮 - * - * @param string $text - * @return string - */ - protected function getDisabledTextWrapper($text) - { - return '
  • ' . $text . '
  • '; - } - - /** - * 生成一个激活的按钮 - * - * @param string $text - * @return string - */ - protected function getActivePageWrapper($text) - { - return '
  • ' . $text . '
  • '; - } - - /** - * 生成省略号按钮 - * - * @return string - */ - protected function getDots() - { - return $this->getDisabledTextWrapper('...'); - } - - /** - * 批量生成页码按钮. - * - * @param array $urls - * @return string - */ - protected function getUrlLinks(array $urls) - { - $html = ''; - - foreach ($urls as $page => $url) { - $html .= $this->getPageLinkWrapper($url, $page); - } - - return $html; - } - - /** - * 生成普通页码按钮 - * - * @param string $url - * @param int $page - * @return string - */ - protected function getPageLinkWrapper($url, $page) - { - if ($page == $this->currentPage()) { - return $this->getActivePageWrapper($page); - } - - return $this->getAvailablePageWrapper($url, $page); - } -} diff --git a/thinkphp/library/think/process/Builder.php b/thinkphp/library/think/process/Builder.php deleted file mode 100755 index da56163..0000000 --- a/thinkphp/library/think/process/Builder.php +++ /dev/null @@ -1,233 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\process; - -use think\Process; - -class Builder -{ - private $arguments; - private $cwd; - private $env = null; - private $input; - private $timeout = 60; - private $options = []; - private $inheritEnv = true; - private $prefix = []; - private $outputDisabled = false; - - /** - * 构造方法 - * @param string[] $arguments 参数 - */ - public function __construct(array $arguments = []) - { - $this->arguments = $arguments; - } - - /** - * 创建一个实例 - * @param string[] $arguments 参数 - * @return self - */ - public static function create(array $arguments = []) - { - return new static($arguments); - } - - /** - * 添加一个参数 - * @param string $argument 参数 - * @return self - */ - public function add($argument) - { - $this->arguments[] = $argument; - - return $this; - } - - /** - * 添加一个前缀 - * @param string|array $prefix - * @return self - */ - public function setPrefix($prefix) - { - $this->prefix = is_array($prefix) ? $prefix : [$prefix]; - - return $this; - } - - /** - * 设置参数 - * @param string[] $arguments - * @return self - */ - public function setArguments(array $arguments) - { - $this->arguments = $arguments; - - return $this; - } - - /** - * 设置工作目录 - * @param null|string $cwd - * @return self - */ - public function setWorkingDirectory($cwd) - { - $this->cwd = $cwd; - - return $this; - } - - /** - * 是否初始化环境变量 - * @param bool $inheritEnv - * @return self - */ - public function inheritEnvironmentVariables($inheritEnv = true) - { - $this->inheritEnv = $inheritEnv; - - return $this; - } - - /** - * 设置环境变量 - * @param string $name - * @param null|string $value - * @return self - */ - public function setEnv($name, $value) - { - $this->env[$name] = $value; - - return $this; - } - - /** - * 添加环境变量 - * @param array $variables - * @return self - */ - public function addEnvironmentVariables(array $variables) - { - $this->env = array_replace($this->env, $variables); - - return $this; - } - - /** - * 设置输入 - * @param mixed $input - * @return self - */ - public function setInput($input) - { - $this->input = Utils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input); - - return $this; - } - - /** - * 设置超时时间 - * @param float|null $timeout - * @return self - */ - public function setTimeout($timeout) - { - if (null === $timeout) { - $this->timeout = null; - - return $this; - } - - $timeout = (float) $timeout; - - if ($timeout < 0) { - throw new \InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); - } - - $this->timeout = $timeout; - - return $this; - } - - /** - * 设置proc_open选项 - * @param string $name - * @param string $value - * @return self - */ - public function setOption($name, $value) - { - $this->options[$name] = $value; - - return $this; - } - - /** - * 禁止输出 - * @return self - */ - public function disableOutput() - { - $this->outputDisabled = true; - - return $this; - } - - /** - * 开启输出 - * @return self - */ - public function enableOutput() - { - $this->outputDisabled = false; - - return $this; - } - - /** - * 创建一个Process实例 - * @return Process - */ - public function getProcess() - { - if (0 === count($this->prefix) && 0 === count($this->arguments)) { - throw new \LogicException('You must add() command arguments before calling getProcess().'); - } - - $options = $this->options; - - $arguments = array_merge($this->prefix, $this->arguments); - $script = implode(' ', array_map([__NAMESPACE__ . '\\Utils', 'escapeArgument'], $arguments)); - - if ($this->inheritEnv) { - // include $_ENV for BC purposes - $env = array_replace($_ENV, $_SERVER, $this->env); - } else { - $env = $this->env; - } - - $process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options); - - if ($this->outputDisabled) { - $process->disableOutput(); - } - - return $process; - } -} diff --git a/thinkphp/library/think/process/Utils.php b/thinkphp/library/think/process/Utils.php deleted file mode 100755 index f94c648..0000000 --- a/thinkphp/library/think/process/Utils.php +++ /dev/null @@ -1,75 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\process; - -class Utils -{ - - /** - * 转义字符串 - * @param string $argument - * @return string - */ - public static function escapeArgument($argument) - { - - if ('' === $argument) { - return escapeshellarg($argument); - } - $escapedArgument = ''; - $quote = false; - foreach (preg_split('/(")/i', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { - if ('"' === $part) { - $escapedArgument .= '\\"'; - } elseif (self::isSurroundedBy($part, '%')) { - // Avoid environment variable expansion - $escapedArgument .= '^%"' . substr($part, 1, -1) . '"^%'; - } else { - // escape trailing backslash - if ('\\' === substr($part, -1)) { - $part .= '\\'; - } - $quote = true; - $escapedArgument .= $part; - } - } - if ($quote) { - $escapedArgument = '"' . $escapedArgument . '"'; - } - return $escapedArgument; - } - - /** - * 验证并进行规范化Process输入。 - * @param string $caller - * @param mixed $input - * @return string - * @throws \InvalidArgumentException - */ - public static function validateInput($caller, $input) - { - if (null !== $input) { - if (is_resource($input)) { - return $input; - } - if (is_scalar($input)) { - return (string) $input; - } - throw new \InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller)); - } - return $input; - } - - private static function isSurroundedBy($arg, $char) - { - return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; - } - -} diff --git a/thinkphp/library/think/process/exception/Failed.php b/thinkphp/library/think/process/exception/Failed.php deleted file mode 100755 index 5295082..0000000 --- a/thinkphp/library/think/process/exception/Failed.php +++ /dev/null @@ -1,42 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\process\exception; - -use think\Process; - -class Failed extends \RuntimeException -{ - - private $process; - - public function __construct(Process $process) - { - if ($process->isSuccessful()) { - throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.'); - } - - $error = sprintf('The command "%s" failed.' . "\nExit Code: %s(%s)", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText()); - - if (!$process->isOutputDisabled()) { - $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", $process->getOutput(), $process->getErrorOutput()); - } - - parent::__construct($error); - - $this->process = $process; - } - - public function getProcess() - { - return $this->process; - } -} diff --git a/thinkphp/library/think/process/exception/Timeout.php b/thinkphp/library/think/process/exception/Timeout.php deleted file mode 100755 index d5f1162..0000000 --- a/thinkphp/library/think/process/exception/Timeout.php +++ /dev/null @@ -1,61 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\process\exception; - -use think\Process; - -class Timeout extends \RuntimeException -{ - - const TYPE_GENERAL = 1; - const TYPE_IDLE = 2; - - private $process; - private $timeoutType; - - public function __construct(Process $process, $timeoutType) - { - $this->process = $process; - $this->timeoutType = $timeoutType; - - parent::__construct(sprintf('The process "%s" exceeded the timeout of %s seconds.', $process->getCommandLine(), $this->getExceededTimeout())); - } - - public function getProcess() - { - return $this->process; - } - - public function isGeneralTimeout() - { - return $this->timeoutType === self::TYPE_GENERAL; - } - - public function isIdleTimeout() - { - return $this->timeoutType === self::TYPE_IDLE; - } - - public function getExceededTimeout() - { - switch ($this->timeoutType) { - case self::TYPE_GENERAL: - return $this->process->getTimeout(); - - case self::TYPE_IDLE: - return $this->process->getIdleTimeout(); - - default: - throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)); - } - } -} diff --git a/thinkphp/library/think/process/pipes/Pipes.php b/thinkphp/library/think/process/pipes/Pipes.php deleted file mode 100755 index 82396b8..0000000 --- a/thinkphp/library/think/process/pipes/Pipes.php +++ /dev/null @@ -1,93 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\process\pipes; - -abstract class Pipes -{ - - /** @var array */ - public $pipes = []; - - /** @var string */ - protected $inputBuffer = ''; - /** @var resource|null */ - protected $input; - - /** @var bool */ - private $blocked = true; - - const CHUNK_SIZE = 16384; - - /** - * 返回用于 proc_open 描述符的数组 - * @return array - */ - abstract public function getDescriptors(); - - /** - * 返回一个数组的索引由其相关的流,以防这些管道使用的临时文件的文件名。 - * @return string[] - */ - abstract public function getFiles(); - - /** - * 文件句柄和管道中读取数据。 - * @param bool $blocking 是否使用阻塞调用 - * @param bool $close 是否要关闭管道,如果他们已经到达 EOF。 - * @return string[] - */ - abstract public function readAndWrite($blocking, $close = false); - - /** - * 返回当前状态如果有打开的文件句柄或管道。 - * @return bool - */ - abstract public function areOpen(); - - /** - * {@inheritdoc} - */ - public function close() - { - foreach ($this->pipes as $pipe) { - fclose($pipe); - } - $this->pipes = []; - } - - /** - * 检查系统调用已被中断 - * @return bool - */ - protected function hasSystemCallBeenInterrupted() - { - $lastError = error_get_last(); - - return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call'); - } - - protected function unblock() - { - if (!$this->blocked) { - return; - } - - foreach ($this->pipes as $pipe) { - stream_set_blocking($pipe, 0); - } - if (null !== $this->input) { - stream_set_blocking($this->input, 0); - } - - $this->blocked = false; - } -} diff --git a/thinkphp/library/think/process/pipes/Unix.php b/thinkphp/library/think/process/pipes/Unix.php deleted file mode 100755 index fd99a5d..0000000 --- a/thinkphp/library/think/process/pipes/Unix.php +++ /dev/null @@ -1,196 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\process\pipes; - -use think\Process; - -class Unix extends Pipes -{ - - /** @var bool */ - private $ttyMode; - /** @var bool */ - private $ptyMode; - /** @var bool */ - private $disableOutput; - - public function __construct($ttyMode, $ptyMode, $input, $disableOutput) - { - $this->ttyMode = (bool) $ttyMode; - $this->ptyMode = (bool) $ptyMode; - $this->disableOutput = (bool) $disableOutput; - - if (is_resource($input)) { - $this->input = $input; - } else { - $this->inputBuffer = (string) $input; - } - } - - public function __destruct() - { - $this->close(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors() - { - if ($this->disableOutput) { - $nullstream = fopen('/dev/null', 'c'); - - return [ - ['pipe', 'r'], - $nullstream, - $nullstream, - ]; - } - - if ($this->ttyMode) { - return [ - ['file', '/dev/tty', 'r'], - ['file', '/dev/tty', 'w'], - ['file', '/dev/tty', 'w'], - ]; - } - - if ($this->ptyMode && Process::isPtySupported()) { - return [ - ['pty'], - ['pty'], - ['pty'], - ]; - } - - return [ - ['pipe', 'r'], - ['pipe', 'w'], // stdout - ['pipe', 'w'], // stderr - ]; - } - - /** - * {@inheritdoc} - */ - public function getFiles() - { - return []; - } - - /** - * {@inheritdoc} - */ - public function readAndWrite($blocking, $close = false) - { - - if (1 === count($this->pipes) && [0] === array_keys($this->pipes)) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - - if (empty($this->pipes)) { - return []; - } - - $this->unblock(); - - $read = []; - - if (null !== $this->input) { - $r = array_merge($this->pipes, ['input' => $this->input]); - } else { - $r = $this->pipes; - } - - unset($r[0]); - - $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null; - $e = null; - - if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { - - if (!$this->hasSystemCallBeenInterrupted()) { - $this->pipes = []; - } - - return $read; - } - - if (0 === $n) { - return $read; - } - - foreach ($r as $pipe) { - - $type = (false !== $found = array_search($pipe, $this->pipes)) ? $found : 'input'; - $data = ''; - while ('' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) { - $data .= $dataread; - } - - if ('' !== $data) { - if ('input' === $type) { - $this->inputBuffer .= $data; - } else { - $read[$type] = $data; - } - } - - if (false === $data || (true === $close && feof($pipe) && '' === $data)) { - if ('input' === $type) { - $this->input = null; - } else { - fclose($this->pipes[$type]); - unset($this->pipes[$type]); - } - } - } - - if (null !== $w && 0 < count($w)) { - while (strlen($this->inputBuffer)) { - $written = fwrite($w[0], $this->inputBuffer, 2 << 18); // write 512k - if ($written > 0) { - $this->inputBuffer = (string) substr($this->inputBuffer, $written); - } else { - break; - } - } - } - - if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function areOpen() - { - return (bool) $this->pipes; - } - - /** - * 创建一个新的 UnixPipes 实例 - * @param Process $process - * @param string|resource $input - * @return self - */ - public static function create(Process $process, $input) - { - return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled()); - } -} diff --git a/thinkphp/library/think/process/pipes/Windows.php b/thinkphp/library/think/process/pipes/Windows.php deleted file mode 100755 index bba7e9b..0000000 --- a/thinkphp/library/think/process/pipes/Windows.php +++ /dev/null @@ -1,228 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\process\pipes; - -use think\Process; - -class Windows extends Pipes -{ - - /** @var array */ - private $files = []; - /** @var array */ - private $fileHandles = []; - /** @var array */ - private $readBytes = [ - Process::STDOUT => 0, - Process::STDERR => 0, - ]; - /** @var bool */ - private $disableOutput; - - public function __construct($disableOutput, $input) - { - $this->disableOutput = (bool) $disableOutput; - - if (!$this->disableOutput) { - - $this->files = [ - Process::STDOUT => tempnam(sys_get_temp_dir(), 'sf_proc_stdout'), - Process::STDERR => tempnam(sys_get_temp_dir(), 'sf_proc_stderr'), - ]; - foreach ($this->files as $offset => $file) { - $this->fileHandles[$offset] = fopen($this->files[$offset], 'rb'); - if (false === $this->fileHandles[$offset]) { - throw new \RuntimeException('A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable'); - } - } - } - - if (is_resource($input)) { - $this->input = $input; - } else { - $this->inputBuffer = $input; - } - } - - public function __destruct() - { - $this->close(); - $this->removeFiles(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors() - { - if ($this->disableOutput) { - $nullstream = fopen('NUL', 'c'); - - return [ - ['pipe', 'r'], - $nullstream, - $nullstream, - ]; - } - - return [ - ['pipe', 'r'], - ['file', 'NUL', 'w'], - ['file', 'NUL', 'w'], - ]; - } - - /** - * {@inheritdoc} - */ - public function getFiles() - { - return $this->files; - } - - /** - * {@inheritdoc} - */ - public function readAndWrite($blocking, $close = false) - { - $this->write($blocking, $close); - - $read = []; - $fh = $this->fileHandles; - foreach ($fh as $type => $fileHandle) { - if (0 !== fseek($fileHandle, $this->readBytes[$type])) { - continue; - } - $data = ''; - $dataread = null; - while (!feof($fileHandle)) { - if (false !== $dataread = fread($fileHandle, self::CHUNK_SIZE)) { - $data .= $dataread; - } - } - if (0 < $length = strlen($data)) { - $this->readBytes[$type] += $length; - $read[$type] = $data; - } - - if (false === $dataread || (true === $close && feof($fileHandle) && '' === $data)) { - fclose($this->fileHandles[$type]); - unset($this->fileHandles[$type]); - } - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function areOpen() - { - return (bool) $this->pipes && (bool) $this->fileHandles; - } - - /** - * {@inheritdoc} - */ - public function close() - { - parent::close(); - foreach ($this->fileHandles as $handle) { - fclose($handle); - } - $this->fileHandles = []; - } - - /** - * 创建一个新的 WindowsPipes 实例。 - * @param Process $process - * @param $input - * @return self - */ - public static function create(Process $process, $input) - { - return new static($process->isOutputDisabled(), $input); - } - - /** - * 删除临时文件 - */ - private function removeFiles() - { - foreach ($this->files as $filename) { - if (file_exists($filename)) { - @unlink($filename); - } - } - $this->files = []; - } - - /** - * 写入到 stdin 输入 - * @param bool $blocking - * @param bool $close - */ - private function write($blocking, $close) - { - if (empty($this->pipes)) { - return; - } - - $this->unblock(); - - $r = null !== $this->input ? ['input' => $this->input] : null; - $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null; - $e = null; - - if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { - if (!$this->hasSystemCallBeenInterrupted()) { - $this->pipes = []; - } - - return; - } - - if (0 === $n) { - return; - } - - if (null !== $w && 0 < count($r)) { - $data = ''; - while ($dataread = fread($r['input'], self::CHUNK_SIZE)) { - $data .= $dataread; - } - - $this->inputBuffer .= $data; - - if (false === $data || (true === $close && feof($r['input']) && '' === $data)) { - $this->input = null; - } - } - - if (null !== $w && 0 < count($w)) { - while (strlen($this->inputBuffer)) { - $written = fwrite($w[0], $this->inputBuffer, 2 << 18); - if ($written > 0) { - $this->inputBuffer = (string) substr($this->inputBuffer, $written); - } else { - break; - } - } - } - - if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - } -} diff --git a/thinkphp/library/think/response/Json.php b/thinkphp/library/think/response/Json.php deleted file mode 100755 index c906bfc..0000000 --- a/thinkphp/library/think/response/Json.php +++ /dev/null @@ -1,51 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\response; - -use think\Response; - -class Json extends Response -{ - // 输出参数 - protected $options = [ - 'json_encode_param' => JSON_UNESCAPED_UNICODE, - ]; - - protected $contentType = 'application/json'; - - /** - * 处理数据 - * @access protected - * @param mixed $data 要处理的数据 - * @return mixed - * @throws \Exception - */ - protected function output($data) - { - try { - // 返回JSON数据格式到客户端 包含状态信息 - $data = json_encode($data, $this->options['json_encode_param']); - - if ($data === false) { - throw new \InvalidArgumentException(json_last_error_msg()); - } - - return $data; - } catch (\Exception $e) { - if ($e->getPrevious()) { - throw $e->getPrevious(); - } - throw $e; - } - } - -} diff --git a/thinkphp/library/think/response/Jsonp.php b/thinkphp/library/think/response/Jsonp.php deleted file mode 100755 index 404bacb..0000000 --- a/thinkphp/library/think/response/Jsonp.php +++ /dev/null @@ -1,58 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\response; - -use think\Request; -use think\Response; - -class Jsonp extends Response -{ - // 输出参数 - protected $options = [ - 'var_jsonp_handler' => 'callback', - 'default_jsonp_handler' => 'jsonpReturn', - 'json_encode_param' => JSON_UNESCAPED_UNICODE, - ]; - - protected $contentType = 'application/javascript'; - - /** - * 处理数据 - * @access protected - * @param mixed $data 要处理的数据 - * @return mixed - * @throws \Exception - */ - protected function output($data) - { - try { - // 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的,故使用Request来获取] - $var_jsonp_handler = Request::instance()->param($this->options['var_jsonp_handler'], ""); - $handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler']; - - $data = json_encode($data, $this->options['json_encode_param']); - - if ($data === false) { - throw new \InvalidArgumentException(json_last_error_msg()); - } - - $data = $handler . '(' . $data . ');'; - return $data; - } catch (\Exception $e) { - if ($e->getPrevious()) { - throw $e->getPrevious(); - } - throw $e; - } - } - -} diff --git a/thinkphp/library/think/response/Redirect.php b/thinkphp/library/think/response/Redirect.php deleted file mode 100755 index 91694cb..0000000 --- a/thinkphp/library/think/response/Redirect.php +++ /dev/null @@ -1,105 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\response; - -use think\Request; -use think\Response; -use think\Session; -use think\Url; - -class Redirect extends Response -{ - - protected $options = []; - - // URL参数 - protected $params = []; - - public function __construct($data = '', $code = 302, array $header = [], array $options = []) - { - parent::__construct($data, $code, $header, $options); - $this->cacheControl('no-cache,must-revalidate'); - } - - /** - * 处理数据 - * @access protected - * @param mixed $data 要处理的数据 - * @return mixed - */ - protected function output($data) - { - $this->header['Location'] = $this->getTargetUrl(); - return; - } - - /** - * 重定向传值(通过Session) - * @access protected - * @param string|array $name 变量名或者数组 - * @param mixed $value 值 - * @return $this - */ - public function with($name, $value = null) - { - if (is_array($name)) { - foreach ($name as $key => $val) { - Session::flash($key, $val); - } - } else { - Session::flash($name, $value); - } - return $this; - } - - /** - * 获取跳转地址 - * @return string - */ - public function getTargetUrl() - { - if (strpos($this->data, '://') || (0 === strpos($this->data, '/') && empty($this->params))) { - return $this->data; - } else { - return Url::build($this->data, $this->params); - } - } - - public function params($params = []) - { - $this->params = $params; - return $this; - } - - /** - * 记住当前url后跳转 - * @return $this - */ - public function remember() - { - Session::set('redirect_url', Request::instance()->url()); - return $this; - } - - /** - * 跳转到上次记住的url - * @return $this - */ - public function restore() - { - if (Session::has('redirect_url')) { - $this->data = Session::get('redirect_url'); - Session::delete('redirect_url'); - } - return $this; - } -} diff --git a/thinkphp/library/think/response/View.php b/thinkphp/library/think/response/View.php deleted file mode 100755 index 48f944a..0000000 --- a/thinkphp/library/think/response/View.php +++ /dev/null @@ -1,89 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\response; - -use think\Config; -use think\Response; -use think\View as ViewTemplate; - -class View extends Response -{ - // 输出参数 - protected $options = []; - protected $vars = []; - protected $replace = []; - protected $contentType = 'text/html'; - - /** - * 处理数据 - * @access protected - * @param mixed $data 要处理的数据 - * @return mixed - */ - protected function output($data) - { - // 渲染模板输出 - return ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str')) - ->fetch($data, $this->vars, $this->replace); - } - - /** - * 获取视图变量 - * @access public - * @param string $name 模板变量 - * @return mixed - */ - public function getVars($name = null) - { - if (is_null($name)) { - return $this->vars; - } else { - return isset($this->vars[$name]) ? $this->vars[$name] : null; - } - } - - /** - * 模板变量赋值 - * @access public - * @param mixed $name 变量名 - * @param mixed $value 变量值 - * @return $this - */ - public function assign($name, $value = '') - { - if (is_array($name)) { - $this->vars = array_merge($this->vars, $name); - return $this; - } else { - $this->vars[$name] = $value; - } - return $this; - } - - /** - * 视图内容替换 - * @access public - * @param string|array $content 被替换内容(支持批量替换) - * @param string $replace 替换内容 - * @return $this - */ - public function replace($content, $replace = '') - { - if (is_array($content)) { - $this->replace = array_merge($this->replace, $content); - } else { - $this->replace[$content] = $replace; - } - return $this; - } - -} diff --git a/thinkphp/library/think/response/Xml.php b/thinkphp/library/think/response/Xml.php deleted file mode 100755 index 3bdc052..0000000 --- a/thinkphp/library/think/response/Xml.php +++ /dev/null @@ -1,102 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\response; - -use think\Collection; -use think\Model; -use think\Response; - -class Xml extends Response -{ - // 输出参数 - protected $options = [ - // 根节点名 - 'root_node' => 'think', - // 根节点属性 - 'root_attr' => '', - //数字索引的子节点名 - 'item_node' => 'item', - // 数字索引子节点key转换的属性名 - 'item_key' => 'id', - // 数据编码 - 'encoding' => 'utf-8', - ]; - - protected $contentType = 'text/xml'; - - /** - * 处理数据 - * @access protected - * @param mixed $data 要处理的数据 - * @return mixed - */ - protected function output($data) - { - // XML数据转换 - return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']); - } - - /** - * XML编码 - * @param mixed $data 数据 - * @param string $root 根节点名 - * @param string $item 数字索引的子节点名 - * @param string $attr 根节点属性 - * @param string $id 数字索引子节点key转换的属性名 - * @param string $encoding 数据编码 - * @return string - */ - protected function xmlEncode($data, $root, $item, $attr, $id, $encoding) - { - if (is_array($attr)) { - $array = []; - foreach ($attr as $key => $value) { - $array[] = "{$key}=\"{$value}\""; - } - $attr = implode(' ', $array); - } - $attr = trim($attr); - $attr = empty($attr) ? '' : " {$attr}"; - $xml = ""; - $xml .= "<{$root}{$attr}>"; - $xml .= $this->dataToXml($data, $item, $id); - $xml .= ""; - return $xml; - } - - /** - * 数据XML编码 - * @param mixed $data 数据 - * @param string $item 数字索引时的节点名称 - * @param string $id 数字索引key转换为的属性名 - * @return string - */ - protected function dataToXml($data, $item, $id) - { - $xml = $attr = ''; - - if ($data instanceof Collection || $data instanceof Model) { - $data = $data->toArray(); - } - - foreach ($data as $key => $val) { - if (is_numeric($key)) { - $id && $attr = " {$id}=\"{$key}\""; - $key = $item; - } - $xml .= "<{$key}{$attr}>"; - $xml .= (is_array($val) || is_object($val)) ? $this->dataToXml($val, $item, $id) : $val; - $xml .= ""; - } - return $xml; - } -} diff --git a/thinkphp/library/think/session/driver/Memcache.php b/thinkphp/library/think/session/driver/Memcache.php deleted file mode 100755 index 877d7bd..0000000 --- a/thinkphp/library/think/session/driver/Memcache.php +++ /dev/null @@ -1,118 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\session\driver; - -use SessionHandler; -use think\Exception; - -class Memcache extends SessionHandler -{ - protected $handler = null; - protected $config = [ - 'host' => '127.0.0.1', // memcache主机 - 'port' => 11211, // memcache端口 - 'expire' => 3600, // session有效期 - 'timeout' => 0, // 连接超时时间(单位:毫秒) - 'persistent' => true, // 长连接 - 'session_name' => '', // memcache key前缀 - ]; - - public function __construct($config = []) - { - $this->config = array_merge($this->config, $config); - } - - /** - * 打开Session - * @access public - * @param string $savePath - * @param mixed $sessName - */ - public function open($savePath, $sessName) - { - // 检测php环境 - if (!extension_loaded('memcache')) { - throw new Exception('not support:memcache'); - } - $this->handler = new \Memcache; - // 支持集群 - $hosts = explode(',', $this->config['host']); - $ports = explode(',', $this->config['port']); - if (empty($ports[0])) { - $ports[0] = 11211; - } - // 建立连接 - foreach ((array) $hosts as $i => $host) { - $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; - $this->config['timeout'] > 0 ? - $this->handler->addServer($host, $port, $this->config['persistent'], 1, $this->config['timeout']) : - $this->handler->addServer($host, $port, $this->config['persistent'], 1); - } - return true; - } - - /** - * 关闭Session - * @access public - */ - public function close() - { - $this->gc(ini_get('session.gc_maxlifetime')); - $this->handler->close(); - $this->handler = null; - return true; - } - - /** - * 读取Session - * @access public - * @param string $sessID - */ - public function read($sessID) - { - return (string) $this->handler->get($this->config['session_name'] . $sessID); - } - - /** - * 写入Session - * @access public - * @param string $sessID - * @param String $sessData - * @return bool - */ - public function write($sessID, $sessData) - { - return $this->handler->set($this->config['session_name'] . $sessID, $sessData, 0, $this->config['expire']); - } - - /** - * 删除Session - * @access public - * @param string $sessID - * @return bool - */ - public function destroy($sessID) - { - return $this->handler->delete($this->config['session_name'] . $sessID); - } - - /** - * Session 垃圾回收 - * @access public - * @param string $sessMaxLifeTime - * @return true - */ - public function gc($sessMaxLifeTime) - { - return true; - } -} diff --git a/thinkphp/library/think/session/driver/Memcached.php b/thinkphp/library/think/session/driver/Memcached.php deleted file mode 100755 index 2994a07..0000000 --- a/thinkphp/library/think/session/driver/Memcached.php +++ /dev/null @@ -1,126 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\session\driver; - -use SessionHandler; -use think\Exception; - -class Memcached extends SessionHandler -{ - protected $handler = null; - protected $config = [ - 'host' => '127.0.0.1', // memcache主机 - 'port' => 11211, // memcache端口 - 'expire' => 3600, // session有效期 - 'timeout' => 0, // 连接超时时间(单位:毫秒) - 'session_name' => '', // memcache key前缀 - 'username' => '', //账号 - 'password' => '', //密码 - ]; - - public function __construct($config = []) - { - $this->config = array_merge($this->config, $config); - } - - /** - * 打开Session - * @access public - * @param string $savePath - * @param mixed $sessName - */ - public function open($savePath, $sessName) - { - // 检测php环境 - if (!extension_loaded('memcached')) { - throw new Exception('not support:memcached'); - } - $this->handler = new \Memcached; - // 设置连接超时时间(单位:毫秒) - if ($this->config['timeout'] > 0) { - $this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->config['timeout']); - } - // 支持集群 - $hosts = explode(',', $this->config['host']); - $ports = explode(',', $this->config['port']); - if (empty($ports[0])) { - $ports[0] = 11211; - } - // 建立连接 - $servers = []; - foreach ((array) $hosts as $i => $host) { - $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1]; - } - $this->handler->addServers($servers); - if ('' != $this->config['username']) { - $this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); - $this->handler->setSaslAuthData($this->config['username'], $this->config['password']); - } - return true; - } - - /** - * 关闭Session - * @access public - */ - public function close() - { - $this->gc(ini_get('session.gc_maxlifetime')); - $this->handler->quit(); - $this->handler = null; - return true; - } - - /** - * 读取Session - * @access public - * @param string $sessID - */ - public function read($sessID) - { - return (string) $this->handler->get($this->config['session_name'] . $sessID); - } - - /** - * 写入Session - * @access public - * @param string $sessID - * @param String $sessData - * @return bool - */ - public function write($sessID, $sessData) - { - return $this->handler->set($this->config['session_name'] . $sessID, $sessData, $this->config['expire']); - } - - /** - * 删除Session - * @access public - * @param string $sessID - * @return bool - */ - public function destroy($sessID) - { - return $this->handler->delete($this->config['session_name'] . $sessID); - } - - /** - * Session 垃圾回收 - * @access public - * @param string $sessMaxLifeTime - * @return true - */ - public function gc($sessMaxLifeTime) - { - return true; - } -} diff --git a/thinkphp/library/think/session/driver/Redis.php b/thinkphp/library/think/session/driver/Redis.php deleted file mode 100755 index 8d05126..0000000 --- a/thinkphp/library/think/session/driver/Redis.php +++ /dev/null @@ -1,128 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\session\driver; - -use SessionHandler; -use think\Exception; - -class Redis extends SessionHandler -{ - /** @var \Redis */ - protected $handler = null; - protected $config = [ - 'host' => '127.0.0.1', // redis主机 - 'port' => 6379, // redis端口 - 'password' => '', // 密码 - 'select' => 0, // 操作库 - 'expire' => 3600, // 有效期(秒) - 'timeout' => 0, // 超时时间(秒) - 'persistent' => true, // 是否长连接 - 'session_name' => '', // sessionkey前缀 - ]; - - public function __construct($config = []) - { - $this->config = array_merge($this->config, $config); - } - - /** - * 打开Session - * @access public - * @param string $savePath - * @param mixed $sessName - * @return bool - * @throws Exception - */ - public function open($savePath, $sessName) - { - // 检测php环境 - if (!extension_loaded('redis')) { - throw new Exception('not support:redis'); - } - $this->handler = new \Redis; - - // 建立连接 - $func = $this->config['persistent'] ? 'pconnect' : 'connect'; - $this->handler->$func($this->config['host'], $this->config['port'], $this->config['timeout']); - - if ('' != $this->config['password']) { - $this->handler->auth($this->config['password']); - } - - if (0 != $this->config['select']) { - $this->handler->select($this->config['select']); - } - - return true; - } - - /** - * 关闭Session - * @access public - */ - public function close() - { - $this->gc(ini_get('session.gc_maxlifetime')); - $this->handler->close(); - $this->handler = null; - return true; - } - - /** - * 读取Session - * @access public - * @param string $sessID - * @return string - */ - public function read($sessID) - { - return (string) $this->handler->get($this->config['session_name'] . $sessID); - } - - /** - * 写入Session - * @access public - * @param string $sessID - * @param String $sessData - * @return bool - */ - public function write($sessID, $sessData) - { - if ($this->config['expire'] > 0) { - return $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData); - } else { - return $this->handler->set($this->config['session_name'] . $sessID, $sessData); - } - } - - /** - * 删除Session - * @access public - * @param string $sessID - * @return bool - */ - public function destroy($sessID) - { - return $this->handler->delete($this->config['session_name'] . $sessID) > 0; - } - - /** - * Session 垃圾回收 - * @access public - * @param string $sessMaxLifeTime - * @return bool - */ - public function gc($sessMaxLifeTime) - { - return true; - } -} diff --git a/thinkphp/library/think/template/TagLib.php b/thinkphp/library/think/template/TagLib.php deleted file mode 100755 index c5b72f9..0000000 --- a/thinkphp/library/think/template/TagLib.php +++ /dev/null @@ -1,334 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\template; - -use think\Exception; - -/** - * ThinkPHP标签库TagLib解析基类 - * @category Think - * @package Think - * @subpackage Template - * @author liu21st - */ -class TagLib -{ - - /** - * 标签库定义XML文件 - * @var string - * @access protected - */ - protected $xml = ''; - protected $tags = []; // 标签定义 - /** - * 标签库名称 - * @var string - * @access protected - */ - protected $tagLib = ''; - - /** - * 标签库标签列表 - * @var array - * @access protected - */ - protected $tagList = []; - - /** - * 标签库分析数组 - * @var array - * @access protected - */ - protected $parse = []; - - /** - * 标签库是否有效 - * @var bool - * @access protected - */ - protected $valid = false; - - /** - * 当前模板对象 - * @var object - * @access protected - */ - protected $tpl; - - protected $comparison = [' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < ']; - - /** - * 构造函数 - * @access public - * @param \stdClass $template 模板引擎对象 - */ - public function __construct($template) - { - $this->tpl = $template; - } - - /** - * 按签标库替换页面中的标签 - * @access public - * @param string $content 模板内容 - * @param string $lib 标签库名 - * @return void - */ - public function parseTag(&$content, $lib = '') - { - $tags = []; - $lib = $lib ? strtolower($lib) . ':' : ''; - foreach ($this->tags as $name => $val) { - $close = !isset($val['close']) || $val['close'] ? 1 : 0; - $tags[$close][$lib . $name] = $name; - if (isset($val['alias'])) { - // 别名设置 - $array = (array) $val['alias']; - foreach (explode(',', $array[0]) as $v) { - $tags[$close][$lib . $v] = $name; - } - } - } - - // 闭合标签 - if (!empty($tags[1])) { - $nodes = []; - $regex = $this->getRegex(array_keys($tags[1]), 1); - if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { - $right = []; - foreach ($matches as $match) { - if ('' == $match[1][0]) { - $name = strtolower($match[2][0]); - // 如果有没闭合的标签头则取出最后一个 - if (!empty($right[$name])) { - // $match[0][1]为标签结束符在模板中的位置 - $nodes[$match[0][1]] = [ - 'name' => $name, - 'begin' => array_pop($right[$name]), // 标签开始符 - 'end' => $match[0], // 标签结束符 - ]; - } - } else { - // 标签头压入栈 - $right[strtolower($match[1][0])][] = $match[0]; - } - } - unset($right, $matches); - // 按标签在模板中的位置从后向前排序 - krsort($nodes); - } - - $break = ''; - if ($nodes) { - $beginArray = []; - // 标签替换 从后向前 - foreach ($nodes as $pos => $node) { - // 对应的标签名 - $name = $tags[1][$node['name']]; - $alias = $lib . $name != $node['name'] ? ($lib ? strstr($node['name'], $lib) : $node['name']) : ''; - // 解析标签属性 - $attrs = $this->parseAttr($node['begin'][0], $name, $alias); - $method = 'tag' . $name; - // 读取标签库中对应的标签内容 replace[0]用来替换标签头,replace[1]用来替换标签尾 - $replace = explode($break, $this->$method($attrs, $break)); - if (count($replace) > 1) { - while ($beginArray) { - $begin = end($beginArray); - // 判断当前标签尾的位置是否在栈中最后一个标签头的后面,是则为子标签 - if ($node['end'][1] > $begin['pos']) { - break; - } else { - // 不为子标签时,取出栈中最后一个标签头 - $begin = array_pop($beginArray); - // 替换标签头部 - $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']); - } - } - // 替换标签尾部 - $content = substr_replace($content, $replace[1], $node['end'][1], strlen($node['end'][0])); - // 把标签头压入栈 - $beginArray[] = ['pos' => $node['begin'][1], 'len' => strlen($node['begin'][0]), 'str' => $replace[0]]; - } - } - while ($beginArray) { - $begin = array_pop($beginArray); - // 替换标签头部 - $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']); - } - } - } - // 自闭合标签 - if (!empty($tags[0])) { - $regex = $this->getRegex(array_keys($tags[0]), 0); - $content = preg_replace_callback($regex, function ($matches) use (&$tags, &$lib) { - // 对应的标签名 - $name = $tags[0][strtolower($matches[1])]; - $alias = $lib . $name != $matches[1] ? ($lib ? strstr($matches[1], $lib) : $matches[1]) : ''; - // 解析标签属性 - $attrs = $this->parseAttr($matches[0], $name, $alias); - $method = 'tag' . $name; - return $this->$method($attrs, ''); - }, $content); - } - return; - } - - /** - * 按标签生成正则 - * @access private - * @param array|string $tags 标签名 - * @param boolean $close 是否为闭合标签 - * @return string - */ - public function getRegex($tags, $close) - { - $begin = $this->tpl->config('taglib_begin'); - $end = $this->tpl->config('taglib_end'); - $single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false; - $tagName = is_array($tags) ? implode('|', $tags) : $tags; - if ($single) { - if ($close) { - // 如果是闭合标签 - $regex = $begin . '(?:(' . $tagName . ')\b(?>[^' . $end . ']*)|\/(' . $tagName . '))' . $end; - } else { - $regex = $begin . '(' . $tagName . ')\b(?>[^' . $end . ']*)' . $end; - } - } else { - if ($close) { - // 如果是闭合标签 - $regex = $begin . '(?:(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)|\/(' . $tagName . '))' . $end; - } else { - $regex = $begin . '(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)' . $end; - } - } - return '/' . $regex . '/is'; - } - - /** - * 分析标签属性 正则方式 - * @access public - * @param string $str 标签属性字符串 - * @param string $name 标签名 - * @param string $alias 别名 - * @return array - */ - public function parseAttr($str, $name, $alias = '') - { - $regex = '/\s+(?>(?P[\w-]+)\s*)=(?>\s*)([\"\'])(?P(?:(?!\\2).)*)\\2/is'; - $result = []; - if (preg_match_all($regex, $str, $matches)) { - foreach ($matches['name'] as $key => $val) { - $result[$val] = $matches['value'][$key]; - } - if (!isset($this->tags[$name])) { - // 检测是否存在别名定义 - foreach ($this->tags as $key => $val) { - if (isset($val['alias'])) { - $array = (array) $val['alias']; - if (in_array($name, explode(',', $array[0]))) { - $tag = $val; - $type = !empty($array[1]) ? $array[1] : 'type'; - $result[$type] = $name; - break; - } - } - } - } else { - $tag = $this->tags[$name]; - // 设置了标签别名 - if (!empty($alias) && isset($tag['alias'])) { - $type = !empty($tag['alias'][1]) ? $tag['alias'][1] : 'type'; - $result[$type] = $alias; - } - } - if (!empty($tag['must'])) { - $must = explode(',', $tag['must']); - foreach ($must as $name) { - if (!isset($result[$name])) { - throw new Exception('tag attr must:' . $name); - } - } - } - } else { - // 允许直接使用表达式的标签 - if (!empty($this->tags[$name]['expression'])) { - static $_taglibs; - if (!isset($_taglibs[$name])) { - $_taglibs[$name][0] = strlen($this->tpl->config('taglib_begin_origin') . $name); - $_taglibs[$name][1] = strlen($this->tpl->config('taglib_end_origin')); - } - $result['expression'] = substr($str, $_taglibs[$name][0], -$_taglibs[$name][1]); - // 清除自闭合标签尾部/ - $result['expression'] = rtrim($result['expression'], '/'); - $result['expression'] = trim($result['expression']); - } elseif (empty($this->tags[$name]) || !empty($this->tags[$name]['attr'])) { - throw new Exception('tag error:' . $name); - } - } - return $result; - } - - /** - * 解析条件表达式 - * @access public - * @param string $condition 表达式标签内容 - * @return string - */ - public function parseCondition($condition) - { - if (strpos($condition, ':')) { - $condition = ' ' . substr(strstr($condition, ':'), 1); - } - $condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition); - $this->tpl->parseVar($condition); - // $this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数,但表达式中如果有|、||这样的逻辑运算就产生了歧异 - return $condition; - } - - /** - * 自动识别构建变量 - * @access public - * @param string $name 变量描述 - * @return string - */ - public function autoBuildVar(&$name) - { - $flag = substr($name, 0, 1); - if (':' == $flag) { - // 以:开头为函数调用,解析前去掉: - $name = substr($name, 1); - } elseif ('$' != $flag && preg_match('/[a-zA-Z_]/', $flag)) { - // XXX: 这句的写法可能还需要改进 - // 常量不需要解析 - if (defined($name)) { - return $name; - } - // 不以$开头并且也不是常量,自动补上$前缀 - $name = '$' . $name; - } - $this->tpl->parseVar($name); - $this->tpl->parseVarFunction($name); - return $name; - } - - /** - * 获取标签列表 - * @access public - * @return array - */ - // 获取标签定义 - public function getTags() - { - return $this->tags; - } -} diff --git a/thinkphp/library/think/template/driver/File.php b/thinkphp/library/think/template/driver/File.php deleted file mode 100755 index a9a86bf..0000000 --- a/thinkphp/library/think/template/driver/File.php +++ /dev/null @@ -1,74 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\template\driver; - -use think\Exception; - -class File -{ - protected $cacheFile; - - /** - * 写入编译缓存 - * @param string $cacheFile 缓存的文件名 - * @param string $content 缓存的内容 - * @return void|array - */ - public function write($cacheFile, $content) - { - // 检测模板目录 - $dir = dirname($cacheFile); - if (!is_dir($dir)) { - mkdir($dir, 0755, true); - } - // 生成模板缓存文件 - if (false === file_put_contents($cacheFile, $content)) { - throw new Exception('cache write error:' . $cacheFile, 11602); - } - } - - /** - * 读取编译编译 - * @param string $cacheFile 缓存的文件名 - * @param array $vars 变量数组 - * @return void - */ - public function read($cacheFile, $vars = []) - { - $this->cacheFile = $cacheFile; - if (!empty($vars) && is_array($vars)) { - // 模板阵列变量分解成为独立变量 - extract($vars, EXTR_OVERWRITE); - } - //载入模版缓存文件 - include $this->cacheFile; - } - - /** - * 检查编译缓存是否有效 - * @param string $cacheFile 缓存的文件名 - * @param int $cacheTime 缓存时间 - * @return boolean - */ - public function check($cacheFile, $cacheTime) - { - // 缓存文件不存在, 直接返回false - if (!file_exists($cacheFile)) { - return false; - } - if (0 != $cacheTime && $_SERVER['REQUEST_TIME'] > filemtime($cacheFile) + $cacheTime) { - // 缓存是否在有效期 - return false; - } - return true; - } -} diff --git a/thinkphp/library/think/template/taglib/Cx.php b/thinkphp/library/think/template/taglib/Cx.php deleted file mode 100755 index 31e0698..0000000 --- a/thinkphp/library/think/template/taglib/Cx.php +++ /dev/null @@ -1,673 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\template\taglib; - -use think\template\TagLib; - -/** - * CX标签库解析类 - * @category Think - * @package Think - * @subpackage Driver.Taglib - * @author liu21st - */ -class Cx extends Taglib -{ - - // 标签定义 - protected $tags = [ - // 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次 - 'php' => ['attr' => ''], - 'volist' => ['attr' => 'name,id,offset,length,key,mod', 'alias' => 'iterate'], - 'foreach' => ['attr' => 'name,id,item,key,offset,length,mod', 'expression' => true], - 'if' => ['attr' => 'condition', 'expression' => true], - 'elseif' => ['attr' => 'condition', 'close' => 0, 'expression' => true], - 'else' => ['attr' => '', 'close' => 0], - 'switch' => ['attr' => 'name', 'expression' => true], - 'case' => ['attr' => 'value,break', 'expression' => true], - 'default' => ['attr' => '', 'close' => 0], - 'compare' => ['attr' => 'name,value,type', 'alias' => ['eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq', 'type']], - 'range' => ['attr' => 'name,value,type', 'alias' => ['in,notin,between,notbetween', 'type']], - 'empty' => ['attr' => 'name'], - 'notempty' => ['attr' => 'name'], - 'present' => ['attr' => 'name'], - 'notpresent' => ['attr' => 'name'], - 'defined' => ['attr' => 'name'], - 'notdefined' => ['attr' => 'name'], - 'load' => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => ['import,css,js', 'type']], - 'assign' => ['attr' => 'name,value', 'close' => 0], - 'define' => ['attr' => 'name,value', 'close' => 0], - 'for' => ['attr' => 'start,end,name,comparison,step'], - 'url' => ['attr' => 'link,vars,suffix,domain', 'close' => 0, 'expression' => true], - 'function' => ['attr' => 'name,vars,use,call'], - ]; - - /** - * php标签解析 - * 格式: - * {php}echo $name{/php} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagPhp($tag, $content) - { - $parseStr = ''; - return $parseStr; - } - - /** - * volist标签解析 循环输出数据集 - * 格式: - * {volist name="userList" id="user" empty=""} - * {user.username} - * {user.email} - * {/volist} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string|void - */ - public function tagVolist($tag, $content) - { - $name = $tag['name']; - $id = $tag['id']; - $empty = isset($tag['empty']) ? $tag['empty'] : ''; - $key = !empty($tag['key']) ? $tag['key'] : 'i'; - $mod = isset($tag['mod']) ? $tag['mod'] : '2'; - $offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0; - $length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null'; - // 允许使用函数设定数据集 {$vo.name} - $parseStr = 'autoBuildVar($name); - $parseStr .= '$_result=' . $name . ';'; - $name = '$_result'; - } else { - $name = $this->autoBuildVar($name); - } - - $parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator): $' . $key . ' = 0;'; - // 设置了输出数组长度 - if (0 != $offset || 'null' != $length) { - $parseStr .= '$__LIST__ = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); '; - } else { - $parseStr .= ' $__LIST__ = ' . $name . ';'; - } - $parseStr .= 'if( count($__LIST__)==0 ) : echo "' . $empty . '" ;'; - $parseStr .= 'else: '; - $parseStr .= 'foreach($__LIST__ as $key=>$' . $id . '): '; - $parseStr .= '$mod = ($' . $key . ' % ' . $mod . ' );'; - $parseStr .= '++$' . $key . ';?>'; - $parseStr .= $content; - $parseStr .= ''; - - if (!empty($parseStr)) { - return $parseStr; - } - return; - } - - /** - * foreach标签解析 循环输出数据集 - * 格式: - * {foreach name="userList" id="user" key="key" index="i" mod="2" offset="3" length="5" empty=""} - * {user.username} - * {/foreach} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string|void - */ - public function tagForeach($tag, $content) - { - // 直接使用表达式 - if (!empty($tag['expression'])) { - $expression = ltrim(rtrim($tag['expression'], ')'), '('); - $expression = $this->autoBuildVar($expression); - $parseStr = ''; - $parseStr .= $content; - $parseStr .= ''; - return $parseStr; - } - $name = $tag['name']; - $key = !empty($tag['key']) ? $tag['key'] : 'key'; - $item = !empty($tag['id']) ? $tag['id'] : $tag['item']; - $empty = isset($tag['empty']) ? $tag['empty'] : ''; - $offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0; - $length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null'; - - $parseStr = 'autoBuildVar($name); - $parseStr .= $var . '=' . $name . '; '; - $name = $var; - } else { - $name = $this->autoBuildVar($name); - } - $parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator): '; - // 设置了输出数组长度 - if (0 != $offset || 'null' != $length) { - if (!isset($var)) { - $var = '$_' . uniqid(); - } - $parseStr .= $var . ' = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); '; - } else { - $var = &$name; - } - - $parseStr .= 'if( count(' . $var . ')==0 ) : echo "' . $empty . '" ;'; - $parseStr .= 'else: '; - - // 设置了索引项 - if (isset($tag['index'])) { - $index = $tag['index']; - $parseStr .= '$' . $index . '=0; '; - } - $parseStr .= 'foreach(' . $var . ' as $' . $key . '=>$' . $item . '): '; - // 设置了索引项 - if (isset($tag['index'])) { - $index = $tag['index']; - if (isset($tag['mod'])) { - $mod = (int) $tag['mod']; - $parseStr .= '$mod = ($' . $index . ' % ' . $mod . '); '; - } - $parseStr .= '++$' . $index . '; '; - } - $parseStr .= '?>'; - // 循环体中的内容 - $parseStr .= $content; - $parseStr .= ''; - - if (!empty($parseStr)) { - return $parseStr; - } - return; - } - - /** - * if标签解析 - * 格式: - * {if condition=" $a eq 1"} - * {elseif condition="$a eq 2" /} - * {else /} - * {/if} - * 表达式支持 eq neq gt egt lt elt == > >= < <= or and || && - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagIf($tag, $content) - { - $condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition']; - $condition = $this->parseCondition($condition); - $parseStr = '' . $content . ''; - return $parseStr; - } - - /** - * elseif标签解析 - * 格式:见if标签 - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagElseif($tag, $content) - { - $condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition']; - $condition = $this->parseCondition($condition); - $parseStr = ''; - return $parseStr; - } - - /** - * else标签解析 - * 格式:见if标签 - * @access public - * @param array $tag 标签属性 - * @return string - */ - public function tagElse($tag) - { - $parseStr = ''; - return $parseStr; - } - - /** - * switch标签解析 - * 格式: - * {switch name="a.name"} - * {case value="1" break="false"}1{/case} - * {case value="2" }2{/case} - * {default /}other - * {/switch} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagSwitch($tag, $content) - { - $name = !empty($tag['expression']) ? $tag['expression'] : $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = '' . $content . ''; - return $parseStr; - } - - /** - * case标签解析 需要配合switch才有效 - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagCase($tag, $content) - { - $value = isset($tag['expression']) ? $tag['expression'] : $tag['value']; - $flag = substr($value, 0, 1); - if ('$' == $flag || ':' == $flag) { - $value = $this->autoBuildVar($value); - $value = 'case ' . $value . ':'; - } elseif (strpos($value, '|')) { - $values = explode('|', $value); - $value = ''; - foreach ($values as $val) { - $value .= 'case "' . addslashes($val) . '":'; - } - } else { - $value = 'case "' . $value . '":'; - } - $parseStr = '' . $content; - $isBreak = isset($tag['break']) ? $tag['break'] : ''; - if ('' == $isBreak || $isBreak) { - $parseStr .= ''; - } - return $parseStr; - } - - /** - * default标签解析 需要配合switch才有效 - * 使用: {default /}ddfdf - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagDefault($tag) - { - $parseStr = ''; - return $parseStr; - } - - /** - * compare标签解析 - * 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq - * 格式: {compare name="" type="eq" value="" }content{/compare} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagCompare($tag, $content) - { - $name = $tag['name']; - $value = $tag['value']; - $type = isset($tag['type']) ? $tag['type'] : 'eq'; // 比较类型 - $name = $this->autoBuildVar($name); - $flag = substr($value, 0, 1); - if ('$' == $flag || ':' == $flag) { - $value = $this->autoBuildVar($value); - } else { - $value = '\'' . $value . '\''; - } - switch ($type) { - case 'equal': - $type = 'eq'; - break; - case 'notequal': - $type = 'neq'; - break; - } - $type = $this->parseCondition(' ' . $type . ' '); - $parseStr = '' . $content . ''; - return $parseStr; - } - - /** - * range标签解析 - * 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外 - * 格式: {range name="var|function" value="val" type='in|notin' }content{/range} - * example: {range name="a" value="1,2,3" type='in' }content{/range} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagRange($tag, $content) - { - $name = $tag['name']; - $value = $tag['value']; - $type = isset($tag['type']) ? $tag['type'] : 'in'; // 比较类型 - - $name = $this->autoBuildVar($name); - $flag = substr($value, 0, 1); - if ('$' == $flag || ':' == $flag) { - $value = $this->autoBuildVar($value); - $str = 'is_array(' . $value . ')?' . $value . ':explode(\',\',' . $value . ')'; - } else { - $value = '"' . $value . '"'; - $str = 'explode(\',\',' . $value . ')'; - } - if ('between' == $type) { - $parseStr = '= $_RANGE_VAR_[0] && ' . $name . '<= $_RANGE_VAR_[1]):?>' . $content . ''; - } elseif ('notbetween' == $type) { - $parseStr = '$_RANGE_VAR_[1]):?>' . $content . ''; - } else { - $fun = ('in' == $type) ? 'in_array' : '!in_array'; - $parseStr = '' . $content . ''; - } - return $parseStr; - } - - /** - * present标签解析 - * 如果某个变量已经设置 则输出内容 - * 格式: {present name="" }content{/present} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagPresent($tag, $content) - { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = '' . $content . ''; - return $parseStr; - } - - /** - * notpresent标签解析 - * 如果某个变量没有设置,则输出内容 - * 格式: {notpresent name="" }content{/notpresent} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagNotpresent($tag, $content) - { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = '' . $content . ''; - return $parseStr; - } - - /** - * empty标签解析 - * 如果某个变量为empty 则输出内容 - * 格式: {empty name="" }content{/empty} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagEmpty($tag, $content) - { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = 'isEmpty())): ?>' . $content . ''; - return $parseStr; - } - - /** - * notempty标签解析 - * 如果某个变量不为empty 则输出内容 - * 格式: {notempty name="" }content{/notempty} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagNotempty($tag, $content) - { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = 'isEmpty()))): ?>' . $content . ''; - return $parseStr; - } - - /** - * 判断是否已经定义了该常量 - * {defined name='TXT'}已定义{/defined} - * @param array $tag - * @param string $content - * @return string - */ - public function tagDefined($tag, $content) - { - $name = $tag['name']; - $parseStr = '' . $content . ''; - return $parseStr; - } - - /** - * 判断是否没有定义了该常量 - * {notdefined name='TXT'}已定义{/notdefined} - * @param array $tag - * @param string $content - * @return string - */ - public function tagNotdefined($tag, $content) - { - $name = $tag['name']; - $parseStr = '' . $content . ''; - return $parseStr; - } - - /** - * load 标签解析 {load file="/static/js/base.js" /} - * 格式:{load file="/static/css/base.css" /} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagLoad($tag, $content) - { - $file = isset($tag['file']) ? $tag['file'] : $tag['href']; - $type = isset($tag['type']) ? strtolower($tag['type']) : ''; - $parseStr = ''; - $endStr = ''; - // 判断是否存在加载条件 允许使用函数判断(默认为isset) - if (isset($tag['value'])) { - $name = $tag['value']; - $name = $this->autoBuildVar($name); - $name = 'isset(' . $name . ')'; - $parseStr .= ''; - $endStr = ''; - } - - // 文件方式导入 - $array = explode(',', $file); - foreach ($array as $val) { - $type = strtolower(substr(strrchr($val, '.'), 1)); - switch ($type) { - case 'js': - $parseStr .= ''; - break; - case 'css': - $parseStr .= ''; - break; - case 'php': - $parseStr .= ''; - break; - } - } - return $parseStr . $endStr; - } - - /** - * assign标签解析 - * 在模板中给某个变量赋值 支持变量赋值 - * 格式: {assign name="" value="" /} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagAssign($tag, $content) - { - $name = $this->autoBuildVar($tag['name']); - $flag = substr($tag['value'], 0, 1); - if ('$' == $flag || ':' == $flag) { - $value = $this->autoBuildVar($tag['value']); - } else { - $value = '\'' . $tag['value'] . '\''; - } - $parseStr = ''; - return $parseStr; - } - - /** - * define标签解析 - * 在模板中定义常量 支持变量赋值 - * 格式: {define name="" value="" /} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagDefine($tag, $content) - { - $name = '\'' . $tag['name'] . '\''; - $flag = substr($tag['value'], 0, 1); - if ('$' == $flag || ':' == $flag) { - $value = $this->autoBuildVar($tag['value']); - } else { - $value = '\'' . $tag['value'] . '\''; - } - $parseStr = ''; - return $parseStr; - } - - /** - * for标签解析 - * 格式: - * {for start="" end="" comparison="" step="" name=""} - * content - * {/for} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagFor($tag, $content) - { - //设置默认值 - $start = 0; - $end = 0; - $step = 1; - $comparison = 'lt'; - $name = 'i'; - $rand = rand(); //添加随机数,防止嵌套变量冲突 - //获取属性 - foreach ($tag as $key => $value) { - $value = trim($value); - $flag = substr($value, 0, 1); - if ('$' == $flag || ':' == $flag) { - $value = $this->autoBuildVar($value); - } - - switch ($key) { - case 'start': - $start = $value; - break; - case 'end': - $end = $value; - break; - case 'step': - $step = $value; - break; - case 'comparison': - $comparison = $value; - break; - case 'name': - $name = $value; - break; - } - } - - $parseStr = 'parseCondition('$' . $name . ' ' . $comparison . ' $__FOR_END_' . $rand . '__') . ';$' . $name . '+=' . $step . '){ ?>'; - $parseStr .= $content; - $parseStr .= ''; - return $parseStr; - } - - /** - * url函数的tag标签 - * 格式:{url link="模块/控制器/方法" vars="参数" suffix="true或者false 是否带有后缀" domain="true或者false 是否携带域名" /} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagUrl($tag, $content) - { - $url = isset($tag['link']) ? $tag['link'] : ''; - $vars = isset($tag['vars']) ? $tag['vars'] : ''; - $suffix = isset($tag['suffix']) ? $tag['suffix'] : 'true'; - $domain = isset($tag['domain']) ? $tag['domain'] : 'false'; - return ''; - } - - /** - * function标签解析 匿名函数,可实现递归 - * 使用: - * {function name="func" vars="$data" call="$list" use="&$a,&$b"} - * {if is_array($data)} - * {foreach $data as $val} - * {~func($val) /} - * {/foreach} - * {else /} - * {$data} - * {/if} - * {/function} - * @access public - * @param array $tag 标签属性 - * @param string $content 标签内容 - * @return string - */ - public function tagFunction($tag, $content) - { - $name = !empty($tag['name']) ? $tag['name'] : 'func'; - $vars = !empty($tag['vars']) ? $tag['vars'] : ''; - $call = !empty($tag['call']) ? $tag['call'] : ''; - $use = ['&$' . $name]; - if (!empty($tag['use'])) { - foreach (explode(',', $tag['use']) as $val) { - $use[] = '&' . ltrim(trim($val), '&'); - } - } - $parseStr = '' . $content . '' : '?>'; - return $parseStr; - } -} diff --git a/thinkphp/library/think/view/driver/Php.php b/thinkphp/library/think/view/driver/Php.php deleted file mode 100755 index f594a43..0000000 --- a/thinkphp/library/think/view/driver/Php.php +++ /dev/null @@ -1,160 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\view\driver; - -use think\App; -use think\exception\TemplateNotFoundException; -use think\Loader; -use think\Log; -use think\Request; - -class Php -{ - // 模板引擎参数 - protected $config = [ - // 视图基础目录(集中式) - 'view_base' => '', - // 模板起始路径 - 'view_path' => '', - // 模板文件后缀 - 'view_suffix' => 'php', - // 模板文件名分隔符 - 'view_depr' => DS, - // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 - 'auto_rule' => 1, - ]; - protected $template; - protected $content; - - public function __construct($config = []) - { - $this->config = array_merge($this->config, $config); - } - - /** - * 检测是否存在模板文件 - * @access public - * @param string $template 模板文件或者模板规则 - * @return bool - */ - public function exists($template) - { - if ('' == pathinfo($template, PATHINFO_EXTENSION)) { - // 获取模板文件名 - $template = $this->parseTemplate($template); - } - return is_file($template); - } - - /** - * 渲染模板文件 - * @access public - * @param string $template 模板文件 - * @param array $data 模板变量 - * @return void - */ - public function fetch($template, $data = []) - { - if ('' == pathinfo($template, PATHINFO_EXTENSION)) { - // 获取模板文件名 - $template = $this->parseTemplate($template); - } - // 模板不存在 抛出异常 - if (!is_file($template)) { - throw new TemplateNotFoundException('template not exists:' . $template, $template); - } - $this->template = $template; - // 记录视图信息 - App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info'); - - extract($data, EXTR_OVERWRITE); - include $this->template; - } - - /** - * 渲染模板内容 - * @access public - * @param string $content 模板内容 - * @param array $data 模板变量 - * @return void - */ - public function display($content, $data = []) - { - $this->content = $content; - - extract($data, EXTR_OVERWRITE); - eval('?>' . $this->content); - } - - /** - * 自动定位模板文件 - * @access private - * @param string $template 模板文件规则 - * @return string - */ - private function parseTemplate($template) - { - if (empty($this->config['view_path'])) { - $this->config['view_path'] = App::$modulePath . 'view' . DS; - } - - $request = Request::instance(); - // 获取视图根目录 - if (strpos($template, '@')) { - // 跨模块调用 - list($module, $template) = explode('@', $template); - } - if ($this->config['view_base']) { - // 基础视图目录 - $module = isset($module) ? $module : $request->module(); - $path = $this->config['view_base'] . ($module ? $module . DS : ''); - } else { - $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path']; - } - - $depr = $this->config['view_depr']; - if (0 !== strpos($template, '/')) { - $template = str_replace(['/', ':'], $depr, $template); - $controller = Loader::parseName($request->controller()); - if ($controller) { - if ('' == $template) { - // 如果模板文件名为空 按照默认规则定位 - $template = str_replace('.', DS, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action()); - } elseif (false === strpos($template, $depr)) { - $template = str_replace('.', DS, $controller) . $depr . $template; - } - } - } else { - $template = str_replace(['/', ':'], $depr, substr($template, 1)); - } - return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.'); - } - - /** - * 配置模板引擎 - * @access private - * @param string|array $name 参数名 - * @param mixed $value 参数值 - * @return void - */ - public function config($name, $value = null) - { - if (is_array($name)) { - $this->config = array_merge($this->config, $name); - } elseif (is_null($value)) { - return isset($this->config[$name]) ? $this->config[$name] : null; - } else { - $this->config[$name] = $value; - } - } - -} diff --git a/thinkphp/library/think/view/driver/Think.php b/thinkphp/library/think/view/driver/Think.php deleted file mode 100755 index a314ad6..0000000 --- a/thinkphp/library/think/view/driver/Think.php +++ /dev/null @@ -1,167 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\view\driver; - -use think\App; -use think\exception\TemplateNotFoundException; -use think\Loader; -use think\Log; -use think\Request; -use think\Template; - -class Think -{ - // 模板引擎实例 - private $template; - // 模板引擎参数 - protected $config = [ - // 视图基础目录(集中式) - 'view_base' => '', - // 模板起始路径 - 'view_path' => '', - // 模板文件后缀 - 'view_suffix' => 'html', - // 模板文件名分隔符 - 'view_depr' => DS, - // 是否开启模板编译缓存,设为false则每次都会重新编译 - 'tpl_cache' => true, - // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 - 'auto_rule' => 1, - ]; - - public function __construct($config = []) - { - $this->config = array_merge($this->config, $config); - if (empty($this->config['view_path'])) { - $this->config['view_path'] = App::$modulePath . 'view' . DS; - } - - $this->template = new Template($this->config); - } - - /** - * 检测是否存在模板文件 - * @access public - * @param string $template 模板文件或者模板规则 - * @return bool - */ - public function exists($template) - { - if ('' == pathinfo($template, PATHINFO_EXTENSION)) { - // 获取模板文件名 - $template = $this->parseTemplate($template); - } - return is_file($template); - } - - /** - * 渲染模板文件 - * @access public - * @param string $template 模板文件 - * @param array $data 模板变量 - * @param array $config 模板参数 - * @return void - */ - public function fetch($template, $data = [], $config = []) - { - if ('' == pathinfo($template, PATHINFO_EXTENSION)) { - // 获取模板文件名 - $template = $this->parseTemplate($template); - } - // 模板不存在 抛出异常 - if (!is_file($template)) { - throw new TemplateNotFoundException('template not exists:' . $template, $template); - } - // 记录视图信息 - App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info'); - $this->template->fetch($template, $data, $config); - } - - /** - * 渲染模板内容 - * @access public - * @param string $template 模板内容 - * @param array $data 模板变量 - * @param array $config 模板参数 - * @return void - */ - public function display($template, $data = [], $config = []) - { - $this->template->display($template, $data, $config); - } - - /** - * 自动定位模板文件 - * @access private - * @param string $template 模板文件规则 - * @return string - */ - private function parseTemplate($template) - { - // 分析模板文件规则 - $request = Request::instance(); - // 获取视图根目录 - if (strpos($template, '@')) { - // 跨模块调用 - list($module, $template) = explode('@', $template); - } - if ($this->config['view_base']) { - // 基础视图目录 - $module = isset($module) ? $module : $request->module(); - $path = $this->config['view_base'] . ($module ? $module . DS : ''); - } else { - $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path']; - } - - $depr = $this->config['view_depr']; - if (0 !== strpos($template, '/')) { - $template = str_replace(['/', ':'], $depr, $template); - $controller = Loader::parseName($request->controller()); - if ($controller) { - if ('' == $template) { - // 如果模板文件名为空 按照默认规则定位 - $template = str_replace('.', DS, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action()); - } elseif (false === strpos($template, $depr)) { - $template = str_replace('.', DS, $controller) . $depr . $template; - } - } - } else { - $template = str_replace(['/', ':'], $depr, substr($template, 1)); - } - return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.'); - } - - /** - * 配置或者获取模板引擎参数 - * @access private - * @param string|array $name 参数名 - * @param mixed $value 参数值 - * @return mixed - */ - public function config($name, $value = null) - { - if (is_array($name)) { - $this->template->config($name); - $this->config = array_merge($this->config, $name); - } elseif (is_null($value)) { - return $this->template->config($name); - } else { - $this->template->$name = $value; - $this->config[$name] = $value; - } - } - - public function __call($method, $params) - { - return call_user_func_array([$this->template, $method], $params); - } -} diff --git a/thinkphp/library/traits/controller/Jump.php b/thinkphp/library/traits/controller/Jump.php deleted file mode 100755 index 6a57224..0000000 --- a/thinkphp/library/traits/controller/Jump.php +++ /dev/null @@ -1,167 +0,0 @@ -error(); - * $this->redirect(); - * } - * } - */ -namespace traits\controller; - -use think\Config; -use think\exception\HttpResponseException; -use think\Request; -use think\Response; -use think\response\Redirect; -use think\Url; -use think\View as ViewTemplate; - -trait Jump -{ - /** - * 操作成功跳转的快捷方法 - * @access protected - * @param mixed $msg 提示信息 - * @param string $url 跳转的 URL 地址 - * @param mixed $data 返回的数据 - * @param int $wait 跳转等待时间 - * @param array $header 发送的 Header 信息 - * @return void - * @throws HttpResponseException - */ - protected function success($msg = '', $url = null, $data = '', $wait = 3, array $header = []) - { - if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) { - $url = Request::instance()->server('HTTP_REFERER'); - } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { - $url = Url::build($url); - } - - $type = $this->getResponseType(); - $result = [ - 'code' => 1, - 'msg' => $msg, - 'data' => $data, - 'url' => $url, - 'wait' => $wait, - ]; - - if ('html' == strtolower($type)) { - $template = Config::get('template'); - $view = Config::get('view_replace_str'); - - $result = ViewTemplate::instance($template, $view) - ->fetch(Config::get('dispatch_success_tmpl'), $result); - } - - $response = Response::create($result, $type)->header($header); - - throw new HttpResponseException($response); - } - - /** - * 操作错误跳转的快捷方法 - * @access protected - * @param mixed $msg 提示信息 - * @param string $url 跳转的 URL 地址 - * @param mixed $data 返回的数据 - * @param int $wait 跳转等待时间 - * @param array $header 发送的 Header 信息 - * @return void - * @throws HttpResponseException - */ - protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = []) - { - if (is_null($url)) { - $url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);'; - } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { - $url = Url::build($url); - } - - $type = $this->getResponseType(); - $result = [ - 'code' => 0, - 'msg' => $msg, - 'data' => $data, - 'url' => $url, - 'wait' => $wait, - ]; - - if ('html' == strtolower($type)) { - $template = Config::get('template'); - $view = Config::get('view_replace_str'); - - $result = ViewTemplate::instance($template, $view) - ->fetch(Config::get('dispatch_error_tmpl'), $result); - } - - $response = Response::create($result, $type)->header($header); - - throw new HttpResponseException($response); - } - - /** - * 返回封装后的 API 数据到客户端 - * @access protected - * @param mixed $data 要返回的数据 - * @param int $code 返回的 code - * @param mixed $msg 提示信息 - * @param string $type 返回数据格式 - * @param array $header 发送的 Header 信息 - * @return void - * @throws HttpResponseException - */ - protected function result($data, $code = 0, $msg = '', $type = '', array $header = []) - { - $result = [ - 'code' => $code, - 'msg' => $msg, - 'time' => Request::instance()->server('REQUEST_TIME'), - 'data' => $data, - ]; - $type = $type ?: $this->getResponseType(); - $response = Response::create($result, $type)->header($header); - - throw new HttpResponseException($response); - } - - /** - * URL 重定向 - * @access protected - * @param string $url 跳转的 URL 表达式 - * @param array|int $params 其它 URL 参数 - * @param int $code http code - * @param array $with 隐式传参 - * @return void - * @throws HttpResponseException - */ - protected function redirect($url, $params = [], $code = 302, $with = []) - { - if (is_integer($params)) { - $code = $params; - $params = []; - } - - $response = new Redirect($url); - $response->code($code)->params($params)->with($with); - - throw new HttpResponseException($response); - } - - /** - * 获取当前的 response 输出类型 - * @access protected - * @return string - */ - protected function getResponseType() - { - return Request::instance()->isAjax() - ? Config::get('default_ajax_return') - : Config::get('default_return_type'); - } -} diff --git a/thinkphp/library/traits/model/SoftDelete.php b/thinkphp/library/traits/model/SoftDelete.php deleted file mode 100755 index 70f31ba..0000000 --- a/thinkphp/library/traits/model/SoftDelete.php +++ /dev/null @@ -1,200 +0,0 @@ -getDeleteTimeField(); - - if ($field && !empty($this->data[$field])) { - return true; - } - return false; - } - - /** - * 查询包含软删除的数据 - * @access public - * @return Query - */ - public static function withTrashed() - { - return (new static )->getQuery(); - } - - /** - * 只查询软删除数据 - * @access public - * @return Query - */ - public static function onlyTrashed() - { - $model = new static(); - $field = $model->getDeleteTimeField(true); - - if ($field) { - return $model->getQuery()->useSoftDelete($field, ['not null', '']); - } else { - return $model->getQuery(); - } - } - - /** - * 删除当前的记录 - * @access public - * @param bool $force 是否强制删除 - * @return integer - */ - public function delete($force = false) - { - if (false === $this->trigger('before_delete', $this)) { - return false; - } - - $name = $this->getDeleteTimeField(); - if ($name && !$force) { - // 软删除 - $this->data[$name] = $this->autoWriteTimestamp($name); - $result = $this->isUpdate()->save(); - } else { - // 强制删除当前模型数据 - $result = $this->getQuery()->where($this->getWhere())->delete(); - } - - // 关联删除 - if (!empty($this->relationWrite)) { - foreach ($this->relationWrite as $key => $name) { - $name = is_numeric($key) ? $name : $key; - $result = $this->getRelation($name); - if ($result instanceof Model) { - $result->delete(); - } elseif ($result instanceof Collection || is_array($result)) { - foreach ($result as $model) { - $model->delete(); - } - } - } - } - - $this->trigger('after_delete', $this); - - // 清空原始数据 - $this->origin = []; - - return $result; - } - - /** - * 删除记录 - * @access public - * @param mixed $data 主键列表(支持闭包查询条件) - * @param bool $force 是否强制删除 - * @return integer 成功删除的记录数 - */ - public static function destroy($data, $force = false) - { - if (is_null($data)) { - return 0; - } - - // 包含软删除数据 - $query = (new static())->db(false); - if (is_array($data) && key($data) !== 0) { - $query->where($data); - $data = null; - } elseif ($data instanceof \Closure) { - call_user_func_array($data, [ & $query]); - $data = null; - } - - $count = 0; - if ($resultSet = $query->select($data)) { - foreach ($resultSet as $data) { - $result = $data->delete($force); - $count += $result; - } - } - - return $count; - } - - /** - * 恢复被软删除的记录 - * @access public - * @param array $where 更新条件 - * @return integer - */ - public function restore($where = []) - { - if (empty($where)) { - $pk = $this->getPk(); - $where[$pk] = $this->getData($pk); - } - - $name = $this->getDeleteTimeField(); - - if ($name) { - // 恢复删除 - return $this->getQuery() - ->useSoftDelete($name, ['not null', '']) - ->where($where) - ->update([$name => null]); - } else { - return 0; - } - } - - /** - * 查询默认不包含软删除数据 - * @access protected - * @param Query $query 查询对象 - * @return Query - */ - protected function base($query) - { - $field = $this->getDeleteTimeField(true); - return $field ? $query->useSoftDelete($field) : $query; - } - - /** - * 获取软删除字段 - * @access public - * @param bool $read 是否查询操作(写操作的时候会自动去掉表别名) - * @return string - */ - protected function getDeleteTimeField($read = false) - { - $field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? - $this->deleteTime : - 'delete_time'; - - if (false === $field) { - return false; - } - - if (!strpos($field, '.')) { - $field = '__TABLE__.' . $field; - } - - if (!$read && strpos($field, '.')) { - $array = explode('.', $field); - $field = array_pop($array); - } - - return $field; - } -} diff --git a/thinkphp/library/traits/think/Instance.php b/thinkphp/library/traits/think/Instance.php deleted file mode 100755 index 428c8fd..0000000 --- a/thinkphp/library/traits/think/Instance.php +++ /dev/null @@ -1,54 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace traits\think; - -use think\Exception; - -trait Instance -{ - /** - * @var null|static 实例对象 - */ - protected static $instance = null; - - /** - * 获取示例 - * @param array $options 实例配置 - * @return static - */ - public static function instance($options = []) - { - if (is_null(self::$instance)) self::$instance = new self($options); - - return self::$instance; - } - - /** - * 静态调用 - * @param string $method 调用方法 - * @param array $params 调用参数 - * @return mixed - * @throws Exception - */ - public static function __callStatic($method, array $params) - { - if (is_null(self::$instance)) self::$instance = new self(); - - $call = substr($method, 1); - - if (0 !== strpos($method, '_') || !is_callable([self::$instance, $call])) { - throw new Exception("method not exists:" . $method); - } - - return call_user_func_array([self::$instance, $call], $params); - } -} diff --git a/thinkphp/logo.png b/thinkphp/logo.png deleted file mode 100755 index 25fd0593688de5c9f4cd321da1a72ab9566fe331..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6995 zcmV-Z8?5AsP)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z5P(TUK~#9!?3{UYROQ`(pS#SOWU`Z$BxDa^-w_0qRROJ_;)fy#YSH7?R(p-EbfAWiV7kMvdB&nAVk8FL`WvH-R=7$piE{anUI+fzQgaoxpU{e z?>zT?fBU_{y(@BL2)I=z*^UwhrBB4Gy1NZP^@0FsfM9?m zni!jV17^vBVHn-U3SSTeCDDXMvXbQ}q9l1ZKFxCxV26x|C7C!&G6175J~lZPfZnN>kQrBS-YxP4wF1jhNB;QPBv~1dJ^|$-!0_NXtSR(MALn;`VETA$ z^7(aXE(m~L%}u|waU@wY{ElZiiph2qqiV`UfT35Pj!ll`@?JLub*@WOMxYuO0frQh z+RW&jnPkNk1^vD_c_=2)f`M@nU~5q{FPU)#Tv2#?$aAtCB_vpTpzGR2fUOOOAc)NB z^B^(i_>kw>O%Bpx^U%)IHtv=H4Gg@Ri|HkIQkF8Z-SabJ3(?P0nyXs^^e9fo42dL=^itc4<@j~YGe*{@Hcl=KXB7)F%YR0E| zC`jth!1M`tHTVAyfIiKQMYeNu|3|s1%ujjLW)#gE8lurskdj3+!)iSOO%F;6rfMmMxJ)Pzb#T)~f@M`T}3q>QoLm63&4b&(U_o1c~4M|tX~ zh>d;d)Q)z~DNg>WTctd86lt-&sB_hH$l9Nm6=-1KQJaxPGgFK2;8&Nt6j69y%}v!0 z+d>*2-Oz})rc#ErqI!0Q+o=WM*922j;~sJcRa;sCBFyp_IbW21JH)>SV@50Q~J z(6LG}T$VRG;JcpjWu(RCanxCLPOei_0BX95Pxp`!o6m&&xs1rZs?$2Az16qt_&Usz zErfgH;?kUJ$#w+xhnhq)g-L@r+_>lb1Jn%-ujVGnmciKES&YfO9=pjARo$xUKHlE@ zESjMqVG8oSLZUT|D~lF}9HS_C2%jBV(&8wd<2LRTKm!A>>LSJz&zRin8J~YMiPo;^ zko#c&3sf|0`LWE|dS0sT;B{v;e$%hp$VwHl&%xZ&pqf0*>z$)uWf(ibo?9Wg}GHHy;Cn?X7Bsk|MQ}ml$dO48uuZKQPzPi+qIcQ zTLx1KZ)J4PnMk7CrSP^L{e+jdJ%plrgDQTH+Dwk4jQIl}#}dM@w3ZZmPjt?`o+5|4 z>U2Y8c-C~TF1?2&TSk}1&z~N6oj3RV72VK7!pnA)uyE)zI4mh)kLxfeb*js&U4UNI zg~OV{jIv)aJZpNFgLA7+R_uC;b=Au;NtU2)ky~++o6wtuL;i;(TV{vGx0@V@f*2iu zZq-R);y~u~e}wedUR@4vf5T>$?tFqnr*>kMV*(-u0|U3>q)(60%p34W9H%?CIwF!F z1&u^>Lu<24&@Mo?;$%?fB8K5GA{21uIv3k z$WSgEA2txGOp+~~I@kB@LX<=OfgxE_m^a{$m^$I5pNo83yPEg+KSxdDUMx}!<{)6a znj5QR=eoWRFeZ0ar>@tmoI+~_(W|*APaVy7$3LgueFRC6!w2ZqT$CgaV{ZRPyA)pa zsokusc!6z4KS4mmCdUO?Ejk{xnf%25%i2NS_%hPc=&j?U%9mJQy#lxD#3I{+>Lj1$Mi$LnQFI$u7T(_B z!c!=zZK?>^rUC*kAe&t502OzPI*pH>#Pc}>;^hkIfhts0z)&eV9kM7 zLasvj>`Y3EJ)28<{w(V7wjW!|2m7Dr;K}chMGH1lY|!oM)m$W5)0t2(kFmM4BA(gV zQ@@c$&j~E8Zk&MlV@y9PX9nvJufQ<$pplRK)4umok}@o+S(I9574PqRj&EyM17Ho2 z2=J;dta3{pZ&JZ6QFGkCu6Zv2ieVU-B^#NJmUg<#xI#)(MzHPZCqdPQ{1bJ^OXw4| z?fP-mt9*Rm6`a14ZR$BukQkUgo+*X5k(*E+wVS!O{%iKue;wfdXofVc2GpS$!eR_KC1jDislKb z=hV|(2|123Cgk7Du&inAb{Iq?u0Hr0d+WXqxS0km+jm&@G{56EIhL~2k*qzqqz!-u zGV7VDZ-9py*yqq9tHknB_n{lw=@RF{poO03!mHxBP51DFyB4!#r*&(BS8Zl|{+y7}O^i8# zp7CXDJN7A(6a=6wnmOFKo0`VG^mLSVc!KZm|2yyPdk$GNVUjF?EZO|xN=;YL43$fBuI1{Idx*1i{aaMNs(F{CyZ($@aR!B_87d~p z%b-zSr3<=fhim{PcaSaV`n6I`+TX+Erc5t}K_Z|nOs4>6{A zt}Va+yd+{>N+WOYd6qA#mmvxAX`^8TglwwjV|KsaQWQprm~79+Zi>UFd4F6eer~uV z$~3r-@Xe8xVNG&X#UfT$F2*MN!}F>x(qnsZ_wc`;7kE35uj8o=x3KomzcERcptYMb zs^!X}+qpF7+OWorx1?Y*IWW#je+7&zi6*{0{3fGwW(HWQvt`qfmAtd}ZZ?H0GdP#HH~}OaqM#jW=sqj)4s9uaYRA#bH06=n~b;u77lra1Z$5j1E(7r>kq%l zs)|L_xoWUV_K=AO-O%xAE+!W)U`E+5I&>XT5V4!${Ccc|rdkCAzNlUn6rg6Pys_g? zG`xTQ4ZaK#*3T{jYq`|GM+B@v7+Ym5OMe{Jd_zrU8%ew^Jk){e(R{Vo4wX4xj-@LZO ztGTh89Nf_7zZsf&MJKKt20#G;RaaPh;NN}#J!&(nD_;(%%c{CUdTcMogNsgXR-kXI2bDXH4EK zW|aN1&FvkIcr`aoz6QjzoR^RQTO8|V)>OU9ya9gzV9U|f2(7w;4Gd(_OmXs%sKGmM zayxJDd6qqO8<9m5wsy*_#_8fykJvn}DZP(DA&g;1rQY>DPHzLED7O#r%qrY+bPbc6 z=96O2;_#_G$dbABY_Z68lI@Xy0g_vF@?pgyK0WX{KHbxEi<7SoFFBtC-4 ziUTLN<5rveR(_iR1wlN$3SZ{R;)OITr~H;LfR2tuvPHa#x37K^OLzX6LyfzzO7?cs zU1z$+3X=vgt@zHUbdBve{sls-oN2qgF&4?rmZNJ(kITm_Spy!E5)koe9@GeQyr0>A zD=QYUs$vnU?!zv}wUfA2@u_Zl#O5+Fe;%W9X0%xdKUb-BRfxm4Sf`6WCq2hmvf~eIsa=Cbwg*jmp6w8OH5U#`G86LWa(S;C zi8DtpS@GGyCAgKQ05uZUtr7(Zx6*hzfEEH=9z}OkeQFo^i384gf`?A+WbxMDaHOfC zO(XGB)y~eCoa>lSFqgELyr{ZP)s4IPs^;CGJ%?eh^|tCIq9C#B#0JI%d7K~|*?w#- zuWtJ-&C01ZT@9b+Mi3+hWlUsJ!ThLI5nJolq1T z@6c~Ie*Yf-+Ws(xp@%d?ita<#Rf>`aGo|o0dZ%8}WufA`d;i9s`i-G(Y-DsV9a+V=ytZTF{SBLW?YrNf{+<66G+jl}z4T2R%QdCAJy|3W|cn}vBt^p-4q|69C(dY6^rnw&bHjBoxo$j zlGbia9T9w!ulcNG?AcF=H!G+3uwqd_Z;7g_Oe~nk%(DBteAONJVLQurKgIrr&7tCX lAFv5{16U3OylCP71_0o>R4vh7BrN~{002ovPDHLkV1liRoDKj0 diff --git a/thinkphp/phpunit.xml b/thinkphp/phpunit.xml deleted file mode 100755 index 7c6ef03..0000000 --- a/thinkphp/phpunit.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - ./tests/thinkphp/ - - - - - - - - ./ - - tests - vendor - - - - - - - - - - diff --git a/thinkphp/start.php b/thinkphp/start.php deleted file mode 100755 index adb1bc6..0000000 --- a/thinkphp/start.php +++ /dev/null @@ -1,19 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think; - -// ThinkPHP 引导文件 -// 1. 加载基础文件 -require __DIR__ . '/base.php'; - -// 2. 执行应用 -App::run()->send(); diff --git a/thinkphp/tpl/default_index.tpl b/thinkphp/tpl/default_index.tpl deleted file mode 100755 index 8538b4d..0000000 --- a/thinkphp/tpl/default_index.tpl +++ /dev/null @@ -1,10 +0,0 @@ -*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }

    :)

    ThinkPHP V5
    十年磨一剑 - 为API开发设计的高性能框架

    [ V5.0 版本由 七牛云 独家赞助发布 ]
    '; - } -} diff --git a/thinkphp/tpl/dispatch_jump.tpl b/thinkphp/tpl/dispatch_jump.tpl deleted file mode 100755 index 583376b..0000000 --- a/thinkphp/tpl/dispatch_jump.tpl +++ /dev/null @@ -1,49 +0,0 @@ -{__NOLAYOUT__} - - - - - 跳转提示 - - - -
    - - -

    :)

    -

    - - -

    :(

    -

    - - -

    -

    - 页面自动 跳转 等待时间: -

    -
    - - - diff --git a/thinkphp/tpl/page_trace.tpl b/thinkphp/tpl/page_trace.tpl deleted file mode 100755 index 7c5df6f..0000000 --- a/thinkphp/tpl/page_trace.tpl +++ /dev/null @@ -1,71 +0,0 @@ -
    - - -
    -
    -
    - -
    - - diff --git a/thinkphp/tpl/think_exception.tpl b/thinkphp/tpl/think_exception.tpl deleted file mode 100755 index 21bbafc..0000000 --- a/thinkphp/tpl/think_exception.tpl +++ /dev/null @@ -1,537 +0,0 @@ -'.end($names).''; - } - } - - if(!function_exists('parse_file')){ - function parse_file($file, $line) - { - return ''.basename($file)." line {$line}".''; - } - } - - if(!function_exists('parse_args')){ - function parse_args($args) - { - $result = []; - - foreach ($args as $key => $item) { - switch (true) { - case is_object($item): - $value = sprintf('object(%s)', parse_class(get_class($item))); - break; - case is_array($item): - if(count($item) > 3){ - $value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3))); - } else { - $value = sprintf('[%s]', parse_args($item)); - } - break; - case is_string($item): - if(strlen($item) > 20){ - $value = sprintf( - '\'%s...\'', - htmlentities($item), - htmlentities(substr($item, 0, 20)) - ); - } else { - $value = sprintf("'%s'", htmlentities($item)); - } - break; - case is_int($item): - case is_float($item): - $value = $item; - break; - case is_null($item): - $value = 'null'; - break; - case is_bool($item): - $value = '' . ($item ? 'true' : 'false') . ''; - break; - case is_resource($item): - $value = 'resource'; - break; - default: - $value = htmlentities(str_replace("\n", '', var_export(strval($item), true))); - break; - } - - $result[] = is_int($key) ? $value : "'{$key}' => {$value}"; - } - - return implode(', ', $result); - } - } -?> - - - - - <?php echo \think\Lang::get('System Error'); ?> - - - - - -
    - -
    - -
    -
    - -
    -
    -

    [

    -
    -

    -
    - -
    - -
    -
      $value) { ?>
    -
    - -
    -

    Call Stack

    -
      -
    1. - -
    2. - -
    3. - -
    -
    -
    - -
    - -

    - -
    - - - -
    -

    Exception Datas

    - $value) { ?> - - - - - - - $val) { ?> - - - - - - - -
    empty
    - -
    - -
    - - - -
    -

    Environment Variables

    - $value) { ?> -
    - -
    -
    -
    empty
    -
    - -

    -
    - $val) { ?> -
    -
    -
    - -
    -
    - -
    - -
    - -
    - - - - - - - - diff --git a/vendor/.gitignore b/vendor/.gitignore deleted file mode 100644 index c96a04f..0000000 --- a/vendor/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file