├── .github └── hypertrons.json ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTING_CN.md ├── DEPLOY_WITH_BT.md ├── DEPLOY_WITH_DOCKER.md ├── Dockerfile ├── LICENSE ├── README.md ├── TimingDiagram.md ├── docker_configs ├── php.ini ├── site.conf ├── sources.list └── start.sh ├── src ├── application │ ├── .htaccess │ ├── command.php │ ├── common.php │ ├── config.php │ ├── database.php │ ├── extra │ │ └── queue.php │ ├── index │ │ ├── controller │ │ │ ├── Base.php │ │ │ ├── District.php │ │ │ ├── Getwxcode.php │ │ │ ├── Index.php │ │ │ ├── Info.php │ │ │ ├── Login.php │ │ │ ├── Notify.php │ │ │ ├── Report.php │ │ │ ├── Reportweb.php │ │ │ └── Template.php │ │ └── service │ │ │ ├── Http.php │ │ │ └── WxBizDataCrypt.php │ ├── route.php │ └── tags.php ├── public │ ├── .htaccess │ ├── .well-known │ │ └── pki-validation │ │ │ └── fileauth.txt │ ├── index.php │ ├── robots.txt │ ├── router.php │ └── static │ │ └── .gitignore └── thinkphp │ ├── .gitignore │ ├── .htaccess │ ├── .travis.yml │ ├── CONTRIBUTING.md │ ├── LICENSE.txt │ ├── README.md │ ├── base.php │ ├── codecov.yml │ ├── composer.json │ ├── console.php │ ├── convention.php │ ├── helper.php │ ├── lang │ └── zh-cn.php │ ├── library │ ├── think │ │ ├── App.php │ │ ├── Build.php │ │ ├── Cache.php │ │ ├── Collection.php │ │ ├── Config.php │ │ ├── Console.php │ │ ├── Controller.php │ │ ├── Cookie.php │ │ ├── Db.php │ │ ├── Debug.php │ │ ├── Env.php │ │ ├── Error.php │ │ ├── Exception.php │ │ ├── File.php │ │ ├── Hook.php │ │ ├── Lang.php │ │ ├── Loader.php │ │ ├── Log.php │ │ ├── Model.php │ │ ├── Paginator.php │ │ ├── Process.php │ │ ├── Request.php │ │ ├── Response.php │ │ ├── Route.php │ │ ├── Session.php │ │ ├── Template.php │ │ ├── Url.php │ │ ├── Validate.php │ │ ├── View.php │ │ ├── cache │ │ │ ├── Driver.php │ │ │ └── driver │ │ │ │ ├── File.php │ │ │ │ ├── Lite.php │ │ │ │ ├── Memcache.php │ │ │ │ ├── Memcached.php │ │ │ │ ├── Redis.php │ │ │ │ ├── Sqlite.php │ │ │ │ ├── Wincache.php │ │ │ │ └── Xcache.php │ │ ├── config │ │ │ └── driver │ │ │ │ ├── Ini.php │ │ │ │ ├── Json.php │ │ │ │ └── Xml.php │ │ ├── console │ │ │ ├── Command.php │ │ │ ├── Input.php │ │ │ ├── LICENSE │ │ │ ├── Output.php │ │ │ ├── bin │ │ │ │ ├── README.md │ │ │ │ └── hiddeninput.exe │ │ │ ├── command │ │ │ │ ├── Build.php │ │ │ │ ├── Clear.php │ │ │ │ ├── Help.php │ │ │ │ ├── Lists.php │ │ │ │ ├── Make.php │ │ │ │ ├── make │ │ │ │ │ ├── Controller.php │ │ │ │ │ ├── Model.php │ │ │ │ │ └── stubs │ │ │ │ │ │ ├── controller.plain.stub │ │ │ │ │ │ ├── controller.stub │ │ │ │ │ │ └── model.stub │ │ │ │ └── optimize │ │ │ │ │ ├── Autoload.php │ │ │ │ │ ├── Config.php │ │ │ │ │ ├── Route.php │ │ │ │ │ └── Schema.php │ │ │ ├── input │ │ │ │ ├── Argument.php │ │ │ │ ├── Definition.php │ │ │ │ └── Option.php │ │ │ └── output │ │ │ │ ├── Ask.php │ │ │ │ ├── Descriptor.php │ │ │ │ ├── Formatter.php │ │ │ │ ├── Question.php │ │ │ │ ├── descriptor │ │ │ │ └── Console.php │ │ │ │ ├── driver │ │ │ │ ├── Buffer.php │ │ │ │ ├── Console.php │ │ │ │ └── Nothing.php │ │ │ │ ├── formatter │ │ │ │ ├── Stack.php │ │ │ │ └── Style.php │ │ │ │ └── question │ │ │ │ ├── Choice.php │ │ │ │ └── Confirmation.php │ │ ├── controller │ │ │ ├── Rest.php │ │ │ └── Yar.php │ │ ├── db │ │ │ ├── Builder.php │ │ │ ├── Connection.php │ │ │ ├── Expression.php │ │ │ ├── Query.php │ │ │ ├── builder │ │ │ │ ├── Mysql.php │ │ │ │ ├── Pgsql.php │ │ │ │ ├── Sqlite.php │ │ │ │ └── Sqlsrv.php │ │ │ ├── connector │ │ │ │ ├── Mysql.php │ │ │ │ ├── Pgsql.php │ │ │ │ ├── Sqlite.php │ │ │ │ ├── Sqlsrv.php │ │ │ │ └── pgsql.sql │ │ │ └── exception │ │ │ │ ├── BindParamException.php │ │ │ │ ├── DataNotFoundException.php │ │ │ │ └── ModelNotFoundException.php │ │ ├── debug │ │ │ ├── Console.php │ │ │ └── Html.php │ │ ├── exception │ │ │ ├── ClassNotFoundException.php │ │ │ ├── DbException.php │ │ │ ├── ErrorException.php │ │ │ ├── Handle.php │ │ │ ├── HttpException.php │ │ │ ├── HttpResponseException.php │ │ │ ├── PDOException.php │ │ │ ├── RouteNotFoundException.php │ │ │ ├── TemplateNotFoundException.php │ │ │ ├── ThrowableError.php │ │ │ └── ValidateException.php │ │ ├── log │ │ │ └── driver │ │ │ │ ├── File.php │ │ │ │ ├── Socket.php │ │ │ │ └── Test.php │ │ ├── model │ │ │ ├── Collection.php │ │ │ ├── Merge.php │ │ │ ├── Pivot.php │ │ │ ├── Relation.php │ │ │ └── relation │ │ │ │ ├── BelongsTo.php │ │ │ │ ├── BelongsToMany.php │ │ │ │ ├── HasMany.php │ │ │ │ ├── HasManyThrough.php │ │ │ │ ├── HasOne.php │ │ │ │ ├── MorphMany.php │ │ │ │ ├── MorphOne.php │ │ │ │ ├── MorphTo.php │ │ │ │ └── OneToOne.php │ │ ├── paginator │ │ │ └── driver │ │ │ │ └── Bootstrap.php │ │ ├── process │ │ │ ├── Builder.php │ │ │ ├── Utils.php │ │ │ ├── exception │ │ │ │ ├── Failed.php │ │ │ │ └── Timeout.php │ │ │ └── pipes │ │ │ │ ├── Pipes.php │ │ │ │ ├── Unix.php │ │ │ │ └── Windows.php │ │ ├── response │ │ │ ├── Json.php │ │ │ ├── Jsonp.php │ │ │ ├── Redirect.php │ │ │ ├── View.php │ │ │ └── Xml.php │ │ ├── session │ │ │ └── driver │ │ │ │ ├── Memcache.php │ │ │ │ ├── Memcached.php │ │ │ │ └── Redis.php │ │ ├── template │ │ │ ├── TagLib.php │ │ │ ├── driver │ │ │ │ └── File.php │ │ │ └── taglib │ │ │ │ └── Cx.php │ │ └── view │ │ │ └── driver │ │ │ ├── Php.php │ │ │ └── Think.php │ └── traits │ │ ├── controller │ │ └── Jump.php │ │ ├── model │ │ └── SoftDelete.php │ │ └── think │ │ └── Instance.php │ ├── logo.png │ ├── phpunit.xml │ ├── start.php │ └── tpl │ ├── default_index.tpl │ ├── dispatch_jump.tpl │ ├── page_trace.tpl │ └── think_exception.tpl ├── swagger.html └── swagger.yaml /.github/hypertrons.json: -------------------------------------------------------------------------------- 1 | { 2 | "label_setup": { 3 | "version": 1, 4 | "labels": [ 5 | { 6 | "__merge__": true 7 | }, 8 | { 9 | "name": "difficulty/1", 10 | "description": "Difficulty score for issue or pull, 1 score", 11 | "color": "008672" 12 | }, 13 | { 14 | "name": "difficulty/2", 15 | "description": "Difficulty score for issue or pull, 2 score", 16 | "color": "f1ee18" 17 | }, 18 | { 19 | "name": "difficulty/3", 20 | "description": "Difficulty score for issue or pull, 3 score", 21 | "color": "67a8f7" 22 | }, 23 | { 24 | "name": "difficulty/5", 25 | "description": "Difficulty score for issue or pull, 5 score", 26 | "color": "f7be99" 27 | }, 28 | { 29 | "name": "difficulty/8", 30 | "description": "Difficulty score for issue or pull, 8 score, should split the issue", 31 | "color": "e11d21" 32 | }, 33 | { 34 | "name": "pull/approved", 35 | "description": "If a pull is approved, it will be automatically merged", 36 | "color": "008672" 37 | } 38 | ] 39 | }, 40 | "weekly_report": { 41 | "version": 1, 42 | "generateTime": "0 0 12 * * 1" 43 | }, 44 | "role": { 45 | "version": 1, 46 | "roles": [ 47 | { 48 | "name": "committer", 49 | "description": "Committer of the project", 50 | "users": [ "zhangqixun", "frank-zsy" ], 51 | "commands": [ "/difficulty" ] 52 | }, 53 | { 54 | "name": "replier", 55 | "description": "Replier is responsible for reply issues in time", 56 | "users": [ "zhangqixun", "frank-zsy" ], 57 | "commands": [] 58 | }, 59 | { 60 | "name": "approver", 61 | "description": "After approvers' approve, pulls should be merged automatically", 62 | "users": [ "zhangqixun", "frank-zsy" ], 63 | "commands": [ "/approve" ] 64 | }, 65 | { 66 | "name": "author", 67 | "description": "Author of the issue or pull", 68 | "users": [], 69 | "commands": [ ] 70 | }, 71 | { 72 | "name": "notauthor", 73 | "description": "Not author of the issue or pull", 74 | "users": [], 75 | "commands": [ "/approve" ] 76 | }, 77 | { 78 | "name": "anyone", 79 | "description": "Anyone", 80 | "users": [], 81 | "commands": [ "/self-assign" ] 82 | } 83 | ] 84 | }, 85 | "command": { 86 | "version": 1, 87 | "commands": [ 88 | { 89 | "name": "/approve", 90 | "scopes": [ "review", "review_comment", "pull_comment" ] 91 | } 92 | ] 93 | }, 94 | "approve": { 95 | "version": 1 96 | }, 97 | "auto_merge": { 98 | "version": 1, 99 | "sched": "0 */5 * * * *" 100 | }, 101 | "difficulty": { 102 | "version": 1 103 | }, 104 | "rerun": { 105 | "version": 1 106 | }, 107 | "auto_label": { 108 | "version": 1 109 | }, 110 | "self_assign": { 111 | "version": 1 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows 2 | [Dd]esktop.ini 3 | Thumbs.db 4 | $RECYCLE.BIN/ 5 | 6 | # macOS 7 | .DS_Store 8 | .fseventsd 9 | .Spotlight-V100 10 | .TemporaryItems 11 | .Trashes 12 | 13 | # Node.js 14 | node_modules/ 15 | 16 | #thinkphp 17 | /.idea 18 | /.vscode 19 | *.log 20 | .env 21 | /runtime 22 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | 28 | * Trolling, insulting/derogatory comments, and personal or political attacks 29 | 30 | * Public or private harassment 31 | 32 | * Publishing others' private information, such as a physical or electronic 33 | address, without explicit permission 34 | 35 | * Other conduct which could reasonably be considered inappropriate in a 36 | professional setting 37 | 38 | ## Our Responsibilities 39 | 40 | Project maintainers are responsible for clarifying the standards of acceptable 41 | behavior and are expected to take appropriate and fair corrective action in 42 | response to any instances of unacceptable behavior. 43 | 44 | Project maintainers have the right and responsibility to remove, edit, or 45 | reject comments, commits, code, wiki edits, issues, and other contributions 46 | that are not aligned to this Code of Conduct, or to ban temporarily or 47 | permanently any contributor for other behaviors that they deem inappropriate, 48 | threatening, offensive, or harmful. 49 | 50 | ## Scope 51 | 52 | This Code of Conduct applies both within project spaces and in public spaces 53 | when an individual is representing the project or its community. Examples of 54 | representing a project or community include using an official project e-mail 55 | address, posting via an official social media account, or acting as an appointed 56 | representative at an online or offline event. Representation of a project may be 57 | further defined and clarified by project maintainers. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported by contacting the project team at zhangqx@ss.pku.edu.cn. All 63 | complaints will be reviewed and investigated and will result in a response that 64 | is deemed necessary and appropriate to the circumstances. The project team is 65 | obligated to maintain confidentiality with regard to the reporter of an incident. 66 | Further details of specific enforcement policies may be posted separately. 67 | 68 | Project maintainers who do not follow or enforce the Code of Conduct in good 69 | faith may face temporary or permanent repercussions as determined by other 70 | members of the project's leadership. 71 | 72 | ## Attribution 73 | 74 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, 75 | available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html). 76 | 77 | For answers to common questions about this code of conduct, see 78 | [FAQ](https://www.contributor-covenant.org/faq). 79 | -------------------------------------------------------------------------------- /CONTRIBUTING_CN.md: -------------------------------------------------------------------------------- 1 | # 贡献指导 2 | 3 | 如果您有兴趣为这个项目做出贡献使之变得更好,我们将热烈欢迎! 以下是一系列的贡献准则 4 | 5 | - [行为准则](#coc) 6 | - [提交一个issue](#issue) 7 | - [提交一个PR](#pr) 8 | 9 | ## 行为准则 10 | 11 | 我们采用了《行为准则》 [coc],以保证该项目的开放性和包容性。 请阅读全文,以便您了解可被接纳的行为。 12 | 13 | ## 如何提交一个issue 14 | 15 | 如果您有任何问题或者功能建议,请随时提交issue。 16 | 17 | 当您提交issue之前,请参考以下准则: 18 | 19 | - 请搜索相关issue,以确保您不会打开重复的issue。 20 | 21 | - 请指定issue的类型,并在标题或内容中说明问题,如:功能、故障、文档、讨论、需要的帮助…该issue将由项目的机器人(Menbotics)自动标记。请参阅支持的issue标签。 22 | 23 | 为了使issue的详细尽可能标准,我们为issue报告者设置了issue模板。请确保按照说明填写模板中的字段。 24 | 25 | 在很多情况下,您可以打开一个issue: 26 | 27 | - 故障报告 28 | 29 | - 功能建议 30 | 31 | - 性能问题 32 | 33 | - 功能设计 34 | 35 | - 需要的帮助 36 | 37 | - 文档不完整 38 | 39 | - 测试改进 40 | 41 | - 关于项目的任何问题 42 | 43 | - 等等 44 | 45 | 另外,我们必须提醒您,在填写新issue时,请记住从您的帖子中删除敏感数据。敏感数据可以是密码,密钥,网络位置,私人业务数据等。 46 | 47 | 48 | ## 提交一个PR 49 | 50 | 为帮助您熟悉我们贡献的过程,我们已经收集了一些相对较小的包含bug或者有特色的issue。这是迈向开始的很好的一步。 51 | 52 | 在您提交pr之前,请参考以下准则: 53 | 54 | ### 1. 提出一个issue 55 | 56 | 确定一个issue描述清楚了要解决的问题或您想添加的文档特点。 57 | 58 | 如果您决定要解决一个issue,请确认并检查评论,以防已经有人解决了这个问题。如果没有人解决这个问题,您可以留下一个以 /self-assign 为开头的评论,这样其他人不会再重复操作。项目的机器人会自动为您认领任务。 59 | 60 | ```shell 61 | /self-assign 62 | ``` 63 | 如果两周以上没有人跟进这个问题,您可以解决这个问题,但您仍应该留下一个评论。 64 | 65 | ### 2. Fork并clone 仓库 66 | 67 | 访问名为2020NCOV/ncov-report-mini-program-server 的报告,并通过forking在您的仓库中克隆。并从仓库中克隆到本地。例子如下: 68 | 69 | ```shell 70 | # replace the XXX with your own user name 71 | git clone git@github.com:XXX/ncov-report-mini-program-server.git 72 | cd ncov-report-mini-program-server 73 | ``` 74 | 75 | ### 3. 创建一个新分支 76 | 77 | 创建一个新的开发分支。 78 | 79 | ```shell 80 | git checkout -b branch-name 81 | ``` 82 | 83 | 分支的名字应该有明确的含义,应避免使用诸如“update“或 “tmp”这些词。 如果修改将要实现新功能,我们建议使用`feature/xxx` 84 | 85 | ### 4. 进行更改 86 | 87 | 现在,您可以创建补丁,包括在新分支中包含适当的测试用例。 88 | 89 | ### 5. 提交您的更改 90 | 91 | 如果您的更改通过了测试,您就可以提交更改。我们鼓励您使用 [angular commit-message-format][angular-commit-message-format] 来编写提交信息。这样,我们可以拥有更可追踪的历史记录和自动生成的变更日志。 92 | 93 | ```shell 94 | git add . 95 | git commit -m "fix: add license headers (#264)" 96 | ``` 97 | 98 | ### 6. 将您的本地库与上游同步 99 | 100 | 通过以下命令更新您的本地库,使本地库与上游库保持同步: 101 | 102 | ```shell 103 | git remote add upstream git@github.com:2020NCOV/ncov-report-mini-program-server.git 104 | git fetch upstream master 105 | git rebase upstream/master 106 | ``` 107 | 108 | 如果发生冲突,则需要手动解决冲突,然后使用以下命令: 109 | 110 | ```shell 111 | git add my-fix-file 112 | git rebase --continue 113 | ``` 114 | 115 | 116 | ### 7. 个人分支推送至github 117 | 118 | ```shell 119 | git push -f origin branch-name 120 | ``` 121 | 122 | ### 8. 提交PR 123 | 124 | 在github中,向项目`2020NCOV:ncov-report-mini-program-server`提交PR。 125 | 126 | 为了确保我们能容易地理解大家提出的问题,我们提供了一个【PR模板】,您只需要在此模板的基础上进行完善即可。 127 | 128 | 我们的核心团队会关注你的PR并进行审核。如果符合要求,我们会将它们合并到主分支上(或给出一些简单的修改意见),或者将其关闭并给出修改意见。 129 | 130 | 如果我们给出修改意见,那么我们会请您: 131 | 132 | - 完成我们需求的更新。 133 | - 重新运行测试用例,并确保测试仍能通过。 134 | - 用“commit --amend”的方式来提交代码,并强制推送到您的github仓库(git push -f)(这也会更新你的PR). 135 | 136 | ```shell 137 | git add . 138 | git commit --amend 139 | git push -f origin branch-name 140 | ``` 141 | 142 | 这就足够了,感谢您的贡献! 143 | 144 | ### 9. 在您的PR被合并后 145 | 当您的PR得到合并(merge)后,您可以放心删除您用来进行修改的分支并将修改的内容提交到upstream仓库中: 146 | 147 | - 在github网页端或者本地的git bash客户端中的命令行用如下的方式来删除远程分支: 148 | 149 | ```shell 150 | git push origin --delete branch-name 151 | ``` 152 | 153 | - 检查本地仓库的主分支(master): 154 | 155 | ```shell 156 | git checkout master -f 157 | ``` 158 | 159 | - 删除本地分支: 160 | 161 | ```shell 162 | git branch -D my-fix-branch 163 | ``` 164 | 165 | - 用最新的upstream版本来更新本地主分支(master): 166 | 167 | ```shell 168 | git pull --ff upstream master 169 | ``` 170 | 171 | [coc]: ./CODE_OF_CONDUCT.md 172 | 173 | [new-issue]: https://github.com/2020NCOV/ncov-report-mini-program-server/issues/new 174 | 175 | [issue-label]: https://github.com/2020NCOV/ncov-report-mini-program-server/labels 176 | 177 | [good-first-issues]: https://github.com/2020NCOV/ncov-report-mini-program-server/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+ 178 | 179 | [repo]: https://github.com/2020NCOV/ncov-report-mini-program-server 180 | 181 | [angular-commit-message-format]: https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines 182 | 183 | [pr-template]: ./.github/pull_request_template.md 184 | 185 | [issue-template]: ./.github/issue_template.md. 186 | 187 | -------------------------------------------------------------------------------- /DEPLOY_WITH_BT.md: -------------------------------------------------------------------------------- 1 | # 通过宝塔运维面板进行部署 2 | 3 | 感谢您关注我们的项目!本文档主要内容为:如何通过宝塔运维面板进行后端程序的快速部署。 4 | 5 | - [宝塔简介](#btjj) 6 | - [环境准备](#hjzb) 7 | - [面板安装](#mbaz) 8 | - [环境配置](#hjpz) 9 | - [参数设置](#cssz) 10 | 11 | ## 宝塔简介 12 | 13 | - 简介:宝塔面板是一款服务器管理软件,支持windows和linux系统,可以通过Web端轻松管理服务器,提升运维效率。例如:创建管理网站、FTP、数据库,拥有可视化文件管理器,可视化软件管理器,可视化CPU、内存、流量监控图表,计划任务等功能。 14 | 15 | - 功能:宝塔面板拥有极速方便的一键配置与管理,可一键配置服务器环境(LAMP/LNMP/Tomcat/Node.js),一键部署SSL,异地备份;提供SSH开启关闭服务,SSH端口更改,禁ping,防火墙端口放行以及操作日志查看;CPU、内存、磁盘IO、网络IO数据监测,可设置记录保存天数以及任意查看某天数据;计划任务可按周期添加执行,支持SHELL脚本,提供网站、数据库备份以及日志切割,且支持一键备份到又拍云存储空间,或者其他云存储空间里;通过web界面就可以轻松管理安装所用的服务器软件,还有实用的扩展插件;集成方便高效的文件管理器,支持上传、下载、打包、解压以及文件编辑查看。 16 | 17 | - 域名:https://www.bt.cn/ 18 | 19 | ## 环境准备 20 | 21 | - 服务器,内存:512M以上,推荐768M以上(纯面板约占系统60M内存),硬盘:100M以上可用硬盘空间(纯面板约占20M磁盘空间) 22 | 23 | - 系统:CentOS 7.1+ (Ubuntu16.04+.、Debian9.0+),**确保是干净的操作系统**,没有安装过其它环境带的Apache/Nginx/php/MySQL,**已有环境不可安装** 24 | 25 | - 打开服务器端口:**以下主机商必看** 26 | 27 | - 腾讯云:https://www.bt.cn/bbs/thread-1229-1-1.html 28 | 29 | - 阿里云:https://www.bt.cn/bbs/thread-2897-1-1.html 30 | 31 | - 华为云:https://www.bt.cn/bbs/thread-3923-1-1.html 32 | 33 | ## 宝塔面板安装命令 34 | 35 | 在相应服务器终端环境下执行: 36 | 37 | - Centos安装命令:yum install -y wget && wget -O install.sh [http://download.bt.cn/install/install_6.0.sh](http://download.bt.cn/install/install_6.0.sh) && sh install.sh 38 | 39 | - Ubuntu/Deepin安装命令:wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh 40 | 41 | - Debian安装命令:wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh 42 | 43 | - Fedora安装命令:wget -O install.sh http://download.bt.cn/install/install_6.0.sh && bash install.sh 44 | 45 | ## 宝塔环境配置 46 | 47 | - 安装完毕后,使用生成的URL和账户密码就可以进入宝塔面板 48 | 49 | - 安装套件:一键安装LNMP 50 | 51 | - 在软件商店中搜索并安装:宝塔一键部署源码1.1 52 | 53 | - 在宝塔一键部署源码1.1中搜索并安装:ThinkPHP-5.0 54 | 55 | - 将已申请好的域名填入 56 | 57 | - 记录下生成的数据库名、用户名、密码 58 | 59 | - 打开面板左侧的 **文件** 标签将本项目中 ncov-report-mini-program-server/src下的文件上传至 60 | 服务器中,路径为:根目录/www/wwwroot/您的项目名/,与服务器中原有文件夹名相对应即可。 61 | 62 | ## 数据导入与参数设置 63 | 64 | - 在面板左侧 **数据库** 中可导入文件,数据文件请移步:https://github.com/2020NCOV/ncov-report 65 | 66 | - 根据自身情况修改以下文件:(若已修改,请忽略) 67 | 68 | applicaiton/config.php文件 69 | 70 | ``` 71 | //修改以下内容为实际数据 72 | 'wechat_appid' => '小程序ID', 73 | 'wechat_secret' => '秘钥', 74 | ``` 75 | 76 | applicaiton/database.php文件 77 | 78 | ``` 79 | //修改以下内容为实际数据 80 | // 数据库类型 81 | 'type' => 'mysql', 82 | // 服务器地址 83 | 'hostname' => '127.0.0.1', 84 | // 数据库名 85 | 'database' => '数据库名', 86 | // 用户名 87 | 'username' => '用户名', 88 | // 密码 89 | 'password' => '密码', 90 | ``` 91 | 92 | 93 | 94 | 至此,小程序后端部分部署完成 -------------------------------------------------------------------------------- /DEPLOY_WITH_DOCKER.md: -------------------------------------------------------------------------------- 1 | # 通过 Docker 进行部署 2 | 3 | 本项目提供了 Dockerfile 供用户自主构建容器镜像并进行容器化部署。 4 | 5 | ## Dockerfile 解析 6 | 7 | [Dockerfile](./Dockerfile) 见项目。本构建项目使用 Ubuntu 16.04 为基础镜像,并提供了一系列相关[配置文件](./docker_configs/)用于构建容器镜像,包括: 8 | 9 | - [sources.list](./docker_configs/sources.list):该文件为 apt-get 安装源配置文件,为加速国内用户镜像构建,使用阿里云安装源替换原始安装源,若为海外用户,可以删除 [Dockerfile 相关命令](./Dockerfile#L7)以避免安装源被替换。 10 | - [site.conf](./docker_configs/site.conf):该文件为 Apache 服务器配置文件,该文件将容器中的 `/var/www/html` 文件夹挂载到 80 端口,并赋予相关权限。 11 | - [php.ini](./docker_configs/php.ini):该文件为 PHP7 配置文件。 12 | - [start.sh](./docker_configs/start.sh):该文件为容器启动脚本,容器启动时会先打开 Apache2 服务器的 rewrite 模块,并在前台启动服务器并输出日志到前台以供调试。 13 | 14 | 镜像的构建过程为: 15 | 16 | - 以 Ubuntu 16.04 作为基础镜像,使用 daocloud 镜像源以加速国内构建过程,海外用户可以使用 Docker Hub 官方源。 17 | - 替换 apt-get 安装源为阿里云安装源,海外用户可以使用官方源。 18 | - 安装相关依赖,主要是 Apache2 Web 服务器与 PHP7 及 MySQL 与 Curl 扩展。 19 | - 拷贝 Apache 与 PHP 配置文件覆盖默认配置。 20 | - 将当前文件拷贝到 `/app` 文件夹。 21 | - 将 `public` 创建软链接到 `/var/www/html` 以便可以被服务器访问。 22 | - 创建日志目录 `/app/src/runtime` 并赋予相关权限。 23 | - 对镜像启动入口 `/app/docker_configs/start.sh` 赋予执行权限。 24 | - 设定默认暴露端口为 80 端口,并设置启动入口。 25 | 26 | ## Docker 容器镜像构建 27 | 28 | 由于该项目已提供了完整的 Dockerfile 及构建所需的相关配置文件,故可直接通过命令行一键构建容器镜像,可通过命令: 29 | 30 | `sudo docker build -t ncov-mini-server .` 31 | 32 | 来构建镜像,执行该命令后会在本地构建出名为 `ncov-mini-server` 的 Docker 容器镜像。 33 | 34 | ## Docker 镜像启动 35 | 36 | 本项目中的数据库及微信小程序相关配置,可以通过容器镜像启动时的环境变量直接置入,程序会通过环境变量读取[数据库配置](./src/application/database.php#L16)和[微信小程序配置](./src/application/config.php#L17),本项目目前支持的环境变量包括: 37 | 38 | ``` 39 | DB_HOST: 数据库地址,默认为 127.0.0.1 40 | DB_DB: 数据库名称,默认为 ncov 41 | DB_USER: 数据库用户名,默认为 ncov 42 | DB_PASS: 数据库密码,默认为 ncov 43 | DB_PORT: 数据库端口,默认为 3306 44 | 45 | WECHAT_APPID: 小程序的 AppID 46 | WECHAT_SECRET: 小程序的 Secret 47 | ``` 48 | 49 | 例如,在构建容器镜像后可以通过以下命令启动容器镜像: 50 | 51 | `sudo docker run -d -p 8088:80 --env WECHAT_APPID=YOUR_WECHAT_APPID --env WECHAT_SECRET=YOUR_WECHAT_SECRET ncov-mini-server` 52 | 53 | 以上命令会使用传入的环境变量覆盖微信小程序相关配置,并使用默认数据库配置启动镜像,镜像将以守护进程方式启动在后台,并将端口映射到本地 8080 端口,则可以通过 8080 端口访问容器服务。 54 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Ubuntu 16.04 2 | FROM daocloud.io/ubuntu:xenial 3 | 4 | MAINTAINER Frank Zhao 5 | 6 | # 替换镜像源 7 | COPY docker_configs/sources.list /etc/apt/sources.list 8 | 9 | # 安装依赖 10 | RUN apt-get -y update \ 11 | && apt-get -y install \ 12 | apache2 \ 13 | libapache2-mod-php \ 14 | php7.0 \ 15 | php7.0-mysql \ 16 | php7.0-curl \ 17 | # 清理工作 18 | && apt-get clean \ 19 | && apt-get autoclean \ 20 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 21 | 22 | # 拷贝 Apache 与 PHP 配置文件 23 | COPY docker_configs/site.conf /etc/apache2/sites-enabled/000-default.conf 24 | COPY docker_configs/php.ini /etc/php/7.0/apache2/php.ini 25 | 26 | # 配置默认放置 App 的目录 27 | RUN mkdir -p /app && rm -rf /var/www/html 28 | COPY . /app 29 | WORKDIR /app 30 | # 链接 public 目录、创建 Log 目录并赋予权限 31 | RUN ln -s /app/src/public /var/www/html && mkdir ./src/runtime && chmod -R 777 ./src/runtime && chmod -R 777 ./src/public && chmod 755 ./docker_configs/start.sh 32 | 33 | EXPOSE 80 34 | CMD ["./docker_configs/start.sh"] 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2020NCOV-小程序服务端程序介绍 2 | [![image](https://img.shields.io/badge/-Thinkphp-blue.svg)](https://github.com/top-think/think) 3 | [![image](https://img.shields.io/badge/license-Apache2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 4 | - [项目详细介绍](#项目详细介绍) 5 | - [项目框架](#项目框架) 6 | - [环境说明](#环境说明) 7 | - [配置说明](#配置说明) 8 | - [主要功能](#主要功能) 9 | - [如何部署](#如何部署) 10 | - [使用Docker部署](#使用docker部署) 11 | - [使用宝塔部署](#使用宝塔部署) 12 | - [交流方式](#交流方式) 13 | - [在线Demo](#在线demo) 14 | - [贡献指南](#贡献指南) 15 | - [共享者指南](#共享者指南) 16 | - [License](#license) 17 | ## 项目详细介绍 18 | [2020NCOV-小程序服务端程序](https://github.com/2020NCOV/ncov-report-mini-program-server)与[2020NCOV-小程序端程序](https://github.com/2020NCOV/ncov-report-mini-program)所配套部署,形成一个基于微信小程序来进行疫情上报和人员健康管理的平台,旨在帮助各高校及企事业单位,在自己的服务器上本地部署一套人员健康管理系统,以满足机构的数据安全策略。 19 | ## 项目框架 20 | 小程序后端使用[Thinkphp5.0框架](https://github.com/top-think/think)进行编写。 21 | 时序图见[TimingDiagram](https://github.com/2020NCOV/ncov-report-mini-program-server/blob/master/TimingDiagram.md)。 22 | ## 环境说明 23 | - `PHP`版本不低于`PHP5.4` 24 | - 项目运行需支持`PATHINFO` 25 | - `Apache`:已在项目根目录加入`.htaccess`文件,只需开启`rewrite`模块 26 | ## 配置说明 27 | 1. 导入数据库文件`db.sql`,数据库文件见[这里](https://github.com/2020NCOV/ncov-report/tree/master/database)。 28 | 29 | 2. 配置`application/config.php`文件 30 | ``` 31 | 'wechat_appid' => getenv('WECHAT_APPID')?getenv('WECHAT_APPID'):'your AppID', 32 | 'wechat_secret' => getenv('WECHAT_SECRET')?getenv('WECHAT_SECRET'):'your AppSecret', 33 | ``` 34 | 3. 配置`application/database.php`文件 35 | ``` 36 | // 数据库类型 37 | 'type' => 'mysql', 38 | // 服务器地址 39 | 'hostname' => getenv('DB_HOST')?getenv('DB_HOST'):'127.0.0.1', 40 | // 数据库名 41 | 'database' => getenv('DB_DB')?getenv('DB_DB'):'your database name', 42 | // 用户名 43 | 'username' => getenv('DB_USER')?getenv('DB_USER'):'your username', 44 | // 密码 45 | 'password' => getenv('DB_PASS')?getenv('DB_PASS'):'your password', 46 | // 端口 47 | 'hostport' => getenv('DB_PORT')?getenv('DB_PORT'):'', 48 | ``` 49 | ## 主要功能 50 | - 每日上报 51 | - 个人健康码 52 | - 人员管理 53 | - 上报统计 54 | - 数据下载 55 | - 预警信息 56 | ## 如何部署 57 | 目前提供两种部署方式: 58 | ### 使用Docker部署 59 | 2020NCOV-小程序服务端程序可通过Docker进行部署,具体部署指南详见[使用Docker部署](./DEPLOY_WITH_DOCKER.md)。 60 | ### 使用宝塔部署 61 | 2020NCOV-小程序服务端程序可通过宝塔进行部署,具体部署指南详见[DEPLOY_WITH_BT](https://github.com/2020NCOV/ncov-report-mini-program-server/blob/master/DEPLOY_WITH_BT.md)。 62 | 部署指南:https://blog.csdn.net/weixin_44735933/article/details/104895492 63 | ## 交流方式 64 | 点击加入[钉钉群组]()。 65 | 线上交流,后期课程以及相关资源将会在钉钉群组进行发布,请及时加入并关注信息更新。 66 | ## 在线Demo 67 | 68 | ## 贡献指南 69 | 欢迎贡献您的代码或者参与讨论! 70 | 在此之前请您阅读我们的[贡献指南](https://github.com/2020NCOV/ncov-report-mini-program-server/blob/master/CONTRIBUTING_CN.md)。 71 | ## 共享者指南 72 | 如果您希望使用我们的项目,请在钉钉群组中与项目的核心成员取得联系,我们会尽快对于您的咨询进行回复。 73 | ## License 74 | [Apache 2.0 License.](https://opensource.org/licenses/Apache-2.0) 75 | -------------------------------------------------------------------------------- /TimingDiagram.md: -------------------------------------------------------------------------------- 1 | # 时序图 2 | 前后端交互示意 3 | 4 | ![](http://www.plantuml.com/plantuml/png/fPRTSYer7C3lynIPSttESBypE8UFL_2QMTd8sUcokswoLUyEzMCG-K1RfIejCeeohItLpaYbrZwC9E2Lhs2oOMa8ANMqCuLi_j-__3T_Nc9YHoIkUi0kao22Rs8KGH3oFRViXhPFu3DwrLcCFwMppZDeOvZJf5n_7qMByqaYpMjIziKLQrtIsM4YBUYU_xYStmzPlqKRG_hRDUrS9Mf50B9Pk3WQi_fqEJkVtzxzTTPSJcemcmKWIV356p1d6JH44Uw-JP184_W1NtZeRG8WPECXFUbPqFKTz9vuRlz8wx_IhyOMz8AAwukjmzRyha-xBGjM42a73lhpTQty2fNtIYukHQZYOe8Yv02O_abXp3FYcga2Nxx5em3aEr1a0238YOJp5epGEp72f1G6c5YP96vc5GhIpW679PRh8WHDa1UsHSrMAjjXw3ey74Rb216-sBGkyiX5-28DZSF0nyXQtX_HRqvZrw6VDp72s0tyqXvw7m87APOoR25bB4wfDg4Nn_ma4vay0ADJ4kmXN_MMLnzoO2SD0swud8na5knuGhi_iEin_RZva24RZ9R3yKhM_qIg0c1x1CerdVwIseX3AwH8jFtjgXG5v66a9D8_CtfalM_PnVTf1cQdmhPTPoSVg6gvH4sqjiMZJ5NdbIY8Grb9kY-sbTU0VVUQCr0HqPzFvxCs6tHPVyPEFqmCZDIXWbqsyheF8zvRV__Uv6Sgyr1mIwygz3KPgIlOIoMLo1Qh1oipAirOnsJ6iOrAxJtnlAl_PDjf69x7_D-tg-Xv-2hmKScFgvkEyvk8-7l2uJpM038pLk_InY1HKLyLlHsCsbezeZTJtF8eJBXLYJanyNhtnu_ZNjn-HY-_1cRUKgZpVWgtk2WtKKF16eOsnky6aRCRyqSZVXrfc6KU_vQkMLt3wplhRo0-n71YamxhZUOt3TOOcSSIhV7iLXUdrFjFmob2OH29kztXVHcvPR8rg3mR4yScDjVXJxRdYObWxwEd1v3qdL5yhCuYJiPASf7pAq2VH-gr-o0h0B1kDb7lJqDPjVm5e8w0Wcc2YEYxpVBRawE2U1Kfc8oi7YxRKzhvaWxQzEP0ujSBq6D3gKphFLwHEQIPdC2yGhOw0OMS6Pkixd_EKw2syFosmLjHRJJPpfjJzoNlXhZg_GC0) 5 | -------------------------------------------------------------------------------- /docker_configs/site.conf: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | ServerAdmin syzhao1988@126.com 12 | DocumentRoot /var/www/html 13 | 14 | AllowOverride All 15 | allow from all 16 | Options All 17 | Require all granted 18 | 19 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 20 | # error, crit, alert, emerg. 21 | # It is also possible to configure the loglevel for particular 22 | # modules, e.g. 23 | #LogLevel info ssl:warn 24 | 25 | ErrorLog ${APACHE_LOG_DIR}/error.log 26 | CustomLog ${APACHE_LOG_DIR}/access.log combined 27 | 28 | # For most configuration files from conf-available/, which are 29 | # enabled or disabled at a global level, it is possible to 30 | # include a line for only one particular virtual host. For example the 31 | # following line enables the CGI configuration for this host only 32 | # after it has been globally disabled with "a2disconf". 33 | #Include conf-available/serve-cgi-bin.conf 34 | 35 | 36 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 37 | -------------------------------------------------------------------------------- /docker_configs/sources.list: -------------------------------------------------------------------------------- 1 | deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse 2 | deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse 3 | deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse 4 | deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse 5 | deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse 6 | deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse 7 | deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse 8 | deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse 9 | deb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse 10 | deb-src http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse 11 | -------------------------------------------------------------------------------- /docker_configs/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # enable mod_rewrite 4 | a2enmod rewrite 5 | source /etc/apache2/envvars 6 | tail -F /var/log/apache2/* & 7 | exec apache2 -D FOREGROUND 8 | -------------------------------------------------------------------------------- /src/application/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /src/application/command.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | return []; 13 | -------------------------------------------------------------------------------- /src/application/common.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | // 应用公共文件 13 | -------------------------------------------------------------------------------- /src/application/database.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | return [ 13 | // 数据库类型 14 | 'type' => 'mysql', 15 | // 服务器地址 16 | 'hostname' => getenv('DB_HOST') ? getenv('DB_HOST') : '127.0.0.1', 17 | // 数据库名 18 | 'database' => getenv('DB_DB') ? getenv('DB_DB') : 'ncov', 19 | // 用户名 20 | 'username' => getenv('DB_USER') ? getenv('DB_USER') : 'ncov', 21 | // 密码 22 | 'password' => getenv('DB_PASS') ? getenv('DB_PASS') : 'ncov', 23 | // 端口 24 | 'hostport' => getenv('DB_PORT') ? getenv('DB_PORT') : '', 25 | // 连接dsn 26 | 'dsn' => '', 27 | // 数据库连接参数 28 | 'params' => [], 29 | // 数据库编码默认采用utf8 30 | 'charset' => 'utf8', 31 | // 数据库表前缀 32 | 'prefix' => '', 33 | // 数据库调试模式 34 | 'debug' => true, 35 | // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 36 | 'deploy' => 0, 37 | // 数据库读写是否分离 主从式有效 38 | 'rw_separate' => false, 39 | // 读写分离后 主服务器数量 40 | 'master_num' => 1, 41 | // 指定从服务器序号 42 | 'slave_no' => '', 43 | // 自动读取主库数据 44 | 'read_master' => false, 45 | // 是否严格检查字段是否存在 46 | 'fields_strict' => true, 47 | // 数据集返回类型 48 | 'resultset_type' => 'array', 49 | // 自动写入时间戳字段 50 | 'auto_timestamp' => false, 51 | // 时间字段取出后的默认时间格式 52 | 'datetime_format' => 'Y-m-d H:i:s', 53 | // 是否需要进行SQL性能分析 54 | 'sql_explain' => false, 55 | ]; 56 | -------------------------------------------------------------------------------- /src/application/extra/queue.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | return [ 13 | 'connector' => 'Sync' 14 | ]; 15 | -------------------------------------------------------------------------------- /src/application/index/controller/Base.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace app\index\controller; 11 | 12 | use think\Controller; 13 | use think\Request; 14 | use think\Db; 15 | use app\index\service\Http; 16 | 17 | class Base extends Controller 18 | { 19 | 20 | public function _initialize() 21 | { 22 | if ((Request::instance()->module() == 'index' && 23 | Request::instance()->controller() == 'Login' && 24 | Request::instance()->action() == "getcode") || 25 | (Request::instance()->module() == 'index' && 26 | Request::instance()->controller() == 'Report' && 27 | Request::instance()->action() == "get_district_path")) { 28 | return; 29 | } else { 30 | //检测token 31 | $paramCheckRes = Http::checkParams('post.uid', 'post.token'); 32 | if (!is_array($paramCheckRes)) { 33 | return $paramCheckRes; 34 | } 35 | list($uid, $token) = $paramCheckRes; 36 | 37 | //记录用户访问日志 38 | Db::table('wx_mp_log')->insert([ 39 | 'uid' => $uid, 40 | 'token' => $token, 41 | 'url' => Request::instance()->module() . "/" . Request::instance()->controller() . "/" . Request::instance()->action(), 42 | 'time' => date('Y-m-d H:i:s'), 43 | ]); 44 | 45 | if (strlen($token) < 20) { 46 | json(array("errcode" => 1107, "msg" => "token为空"))->send(); 47 | exit(); 48 | } 49 | $user = Db::table('wx_mp_user')->where(['wid' => $uid, 'token' => $token])->find(); 50 | if (empty($user)) { 51 | json(array("errcode" => 1106, "msg" => "token过期,请尝试重新扫码激活并绑定个人信息"))->send(); 52 | exit(); 53 | } 54 | 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/application/index/controller/Getwxcode.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace app\index\controller; 11 | 12 | use think\Request; 13 | use think\Db; 14 | use think\Session; 15 | use think\Controller; 16 | use \think\Config; 17 | use app\index\service\Http; 18 | 19 | class Getwxcode extends Controller 20 | { 21 | 22 | public function index() 23 | { 24 | return; 25 | } 26 | 27 | public function getAccessToken() 28 | { 29 | $appid = Config::get('wechat_appid'); 30 | $secret = Config::get('wechat_secret'); 31 | $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret; 32 | $res = json_decode(Http::get_request($url)); 33 | $access_token = @$res->access_token; 34 | return $access_token; 35 | } 36 | 37 | public function get_image() 38 | { 39 | $id = trim($this->request->param('id', '100000001', 'intval')); 40 | $access_token = $this->getAccessToken(); 41 | $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $access_token; 42 | $data['scene'] = $id; 43 | //小程序路径 44 | $data['path'] = 'pages/info/info'; 45 | //二维码大小 46 | $data['width'] = '430'; 47 | $res = $this->postUrl($url, json_encode($data)); 48 | $path = $id . '.jpg'; 49 | file_put_contents($path, $res); 50 | $return['status_code'] = 2000; 51 | $return['msg'] = 'ok'; 52 | $return['img'] = "/" . $path; 53 | echo ""; 54 | exit; 55 | } 56 | 57 | // 实现Post请求 58 | public function postUrl($url, $data) 59 | { 60 | $curl = curl_init(); 61 | curl_setopt($curl, CURLOPT_URL, $url); 62 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 63 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 64 | if (!empty($data)) { 65 | curl_setopt($curl, CURLOPT_POST, 1); 66 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); 67 | } 68 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 69 | $output = curl_exec($curl); 70 | curl_close($curl); 71 | return $output; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/application/index/controller/Index.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace app\index\controller; 11 | 12 | class Index 13 | { 14 | public function index() 15 | { 16 | echo "https://github.com/2020NCOV/ncov-report-mini-program-server"; 17 | return; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/application/index/controller/Notify.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace app\index\controller; 11 | 12 | use think\Request; 13 | use think\Db; 14 | use think\Session; 15 | use think\Controller; 16 | use \think\Config; 17 | 18 | //该功能还未完成 19 | class Notify extends Controller 20 | { 21 | 22 | public function index() 23 | { 24 | //重置session 25 | Session::clear(); 26 | return $this->fetch(); 27 | } 28 | 29 | public function getAccessToken() 30 | { 31 | $appid = Config::get('wechat_appid'); 32 | $secret = Config::get('wechat_secret'); 33 | $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret; 34 | $HttpService = new \app\index\service\Http(); 35 | $res = json_decode($HttpService->get_request($url)); 36 | $access_token = @$res->access_token; 37 | return $access_token; 38 | } 39 | 40 | public function sendmsg() 41 | { 42 | $access_token = $this->getAccessToken(); 43 | $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" . $access_token; 44 | 45 | //接收者(用户)的 openid 46 | $data['touser'] = 'axyABtv3vllZqVqTKdS3FTYpoMePOplgPuVccRno6HQ'; 47 | //所需下发的订阅模板id 48 | $data['template_id'] = 'axyABtv3vllZqVqTKdS3FTYpoMePOplgPuVccRno6HQ'; 49 | //点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 50 | //$data['page'] = ''; 51 | 52 | $data['data'] = '430'; 53 | $res = $this->postUrl($url, json_encode($data)); 54 | exit; 55 | } 56 | 57 | // 实现Post请求 58 | public function postUrl($url, $data) 59 | { 60 | $curl = curl_init(); 61 | curl_setopt($curl, CURLOPT_URL, $url); 62 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 63 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 64 | if (!empty($data)) { 65 | curl_setopt($curl, CURLOPT_POST, 1); 66 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data); 67 | } 68 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 69 | $output = curl_exec($curl); 70 | //var_dump($output); 71 | curl_close($curl); 72 | return $output; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/application/index/controller/Reportweb.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace app\index\controller; 11 | 12 | use think\Request; 13 | use think\Db; 14 | use think\Session; 15 | use think\Controller; 16 | use \think\Config; 17 | 18 | //该功能为测试功能用。 19 | class Reportweb extends Controller 20 | { 21 | 22 | //通过web方式传递的数据,参数为get 23 | public function index() 24 | { 25 | $paramCheckRes = Http::checkParams('param.uid', 'param:token', 'get.corp_code'); 26 | if (!is_array($paramCheckRes)) { 27 | return $paramCheckRes; 28 | } 29 | list($uid, $token, $corp_code) = $paramCheckRes; 30 | echo $uid; 31 | echo $token; 32 | echo $corp_code; 33 | echo "999"; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/application/index/controller/Template.php: -------------------------------------------------------------------------------- 1 | param('uid')); 17 | $token = trim(Request::instance()->param('token')); 18 | $user = Db::table('wx_mp_user')->where(['wid' => $uid,'token'=> $token ])->find(); 19 | if(empty($user)){ 20 | $this->error("token无效"); 21 | } 22 | return; 23 | //可以通过view增加新的模板文件 24 | //return $this->fetch(); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /src/application/index/service/Http.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace app\index\service; 11 | 12 | use think\Request; 13 | use think\Db; 14 | use think\Session; 15 | 16 | class Http 17 | { 18 | 19 | public static function get_request($url) 20 | { 21 | //初始化 22 | $curl = curl_init(); 23 | //设置抓取的url 24 | curl_setopt($curl, CURLOPT_URL, $url); 25 | //设置头文件的信息作为数据流输出 26 | curl_setopt($curl, CURLOPT_HEADER, false); //返回response头部信息 27 | //设置获取的信息以文件流的形式返回,而不是直接输出。 28 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 29 | //执行命令 30 | $data = curl_exec($curl); 31 | //关闭URL请求 32 | curl_close($curl); 33 | //显示获得的数据 34 | return $data; 35 | } 36 | 37 | /** 38 | * 用于进行请求的参数检查,输入为一系列参数,格式为 'post:xxx' 或 'get:xxx' 39 | * 统一使用 input 进行检查,错误时返回 1003 错误信息,某则返回参数数组,可用 is_array 判断是否有错 40 | */ 41 | public static function checkParams(...$paramStr) 42 | { 43 | $res = []; 44 | foreach ($paramStr as $p) { 45 | $param = input($p); 46 | if (empty($param)) { 47 | return json([ 48 | 'errcode' => 1003, 49 | 'msg' => '参数错误:' . $p 50 | ]); 51 | } 52 | array_push($res, $param); 53 | } 54 | return $res; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/application/index/service/WxBizDataCrypt.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace app\index\service; 11 | 12 | use think\Request; 13 | use think\Db; 14 | use think\Session; 15 | class WxBizDataCrypt { 16 | 17 | /** 18 | * @var int 19 | * 定义错误码 20 | */ 21 | public static $OK = 0; 22 | public static $IllegalAesKey = -41001; 23 | public static $IllegalIv = -41002; 24 | public static $IllegalBuffer = -41003; 25 | public static $DecodeBase64Error = -41004; 26 | private $appid; 27 | private $sessionKey; 28 | public function __construct($appid, $session_key) 29 | { 30 | $this->sessionKey = $session_key; 31 | $this->appid = $appid; 32 | } 33 | 34 | /** 35 | * @param $encryptedData 36 | * @param $iv 37 | * @param $data 38 | * @return mixed 39 | */ 40 | public function decryptData($encryptedData, $iv, &$data) 41 | { 42 | if (strlen($this->sessionKey) != 24) { 43 | return self::$IllegalAesKey; 44 | } 45 | $aesKey=base64_decode($this->sessionKey); 46 | 47 | if (strlen($iv) != 24) { 48 | return self::$IllegalIv; 49 | } 50 | $aesIV=base64_decode($iv); 51 | 52 | $aesCipher=base64_decode($encryptedData); 53 | 54 | $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); 55 | 56 | $dataObj=json_decode( $result ); 57 | if ($dataObj == NULL) { 58 | return self::$IllegalBuffer; 59 | } 60 | if ($dataObj->watermark->appid != $this->appid) { 61 | return self::$IllegalBuffer; 62 | } 63 | $data = $result; 64 | return self::$OK; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/application/route.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | return [ 13 | '__pattern__' => [ 14 | 'name' => '\w+', 15 | ], 16 | '[hello]' => [ 17 | ':id' => ['index/hello', ['method' => 'get'], ['id' => '\d+']], 18 | ':name' => ['index/hello', ['method' => 'post']], 19 | ], 20 | 21 | ]; 22 | -------------------------------------------------------------------------------- /src/application/tags.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | // 应用行为扩展定义文件 13 | return [ 14 | // 应用初始化 15 | 'app_init' => [], 16 | // 应用开始 17 | 'app_begin' => [], 18 | // 模块初始化 19 | 'module_init' => [], 20 | // 操作开始执行 21 | 'action_begin' => [], 22 | // 视图内容过滤 23 | 'view_filter' => [], 24 | // 日志写入 25 | 'log_write' => [], 26 | // 应用结束 27 | 'app_end' => [], 28 | ]; 29 | -------------------------------------------------------------------------------- /src/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Options +FollowSymlinks -Multiviews 3 | RewriteEngine On 4 | 5 | RewriteCond %{REQUEST_FILENAME} !-d 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 8 | 9 | -------------------------------------------------------------------------------- /src/public/.well-known/pki-validation/fileauth.txt: -------------------------------------------------------------------------------- 1 | 20200228064528386bqwlqhrgvwda54zcc3dqnun8o1goaaz8ugjjfmnewj78qc9 -------------------------------------------------------------------------------- /src/public/index.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | // [ 应用入口文件 ] 13 | 14 | // 定义应用目录 15 | define('APP_PATH', __DIR__ . '/../application/'); 16 | // 加载框架引导文件 17 | require __DIR__ . '/../thinkphp/start.php'; 18 | -------------------------------------------------------------------------------- /src/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /src/public/router.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | // $Id$ 12 | 13 | if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SCRIPT_NAME"])) { 14 | return false; 15 | } else { 16 | if (!isset($_SERVER['PATH_INFO'])) { 17 | $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI']; 18 | } 19 | require __DIR__ . "/index.php"; 20 | } 21 | -------------------------------------------------------------------------------- /src/public/static/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /src/thinkphp/.gitignore: -------------------------------------------------------------------------------- 1 | /composer.lock 2 | /vendor 3 | .idea 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /src/thinkphp/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /src/thinkphp/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: php 4 | 5 | services: 6 | - memcached 7 | - mongodb 8 | - mysql 9 | - postgresql 10 | - redis-server 11 | 12 | matrix: 13 | fast_finish: true 14 | include: 15 | - php: 5.4 16 | - php: 5.5 17 | - php: 5.6 18 | - php: 7.0 19 | - php: hhvm 20 | allow_failures: 21 | - php: hhvm 22 | 23 | cache: 24 | directories: 25 | - $HOME/.composer/cache 26 | 27 | before_install: 28 | - composer self-update 29 | - mysql -e "create database IF NOT EXISTS test;" -uroot 30 | - psql -c 'DROP DATABASE IF EXISTS test;' -U postgres 31 | - psql -c 'create database test;' -U postgres 32 | 33 | install: 34 | - ./tests/script/install.sh 35 | 36 | script: 37 | ## LINT 38 | - find . -path ./vendor -prune -o -type f -name \*.php -exec php -l {} \; 39 | ## PHP Copy/Paste Detector 40 | - vendor/bin/phpcpd --verbose --exclude vendor ./ || true 41 | ## PHPLOC 42 | - vendor/bin/phploc --exclude vendor ./ 43 | ## PHPUNIT 44 | - vendor/bin/phpunit --coverage-clover=coverage.xml --configuration=phpunit.xml 45 | 46 | after_success: 47 | - bash <(curl -s https://codecov.io/bash) 48 | -------------------------------------------------------------------------------- /src/thinkphp/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 如何贡献我的源代码 2 | === 3 | 4 | 此文档介绍了 ThinkPHP 团队的组成以及运转机制,您提交的代码将给 ThinkPHP 项目带来什么好处,以及如何才能加入我们的行列。 5 | 6 | ## 通过 Github 贡献代码 7 | 8 | ThinkPHP 目前使用 Git 来控制程序版本,如果你想为 ThinkPHP 贡献源代码,请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上,任何 GitHub 用户都可以向我们贡献代码。 9 | 10 | 参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。 11 | 12 | 我们希望你贡献的代码符合: 13 | 14 | * ThinkPHP 的编码规范 15 | * 适当的注释,能让其他人读懂 16 | * 遵循 Apache2 开源协议 17 | 18 | **如果想要了解更多细节或有任何疑问,请继续阅读下面的内容** 19 | 20 | ### 注意事项 21 | 22 | * 本项目代码格式化标准选用 [**PSR-2**](http://www.kancloud.cn/thinkphp/php-fig-psr/3141); 23 | * 类名和类文件名遵循 [**PSR-4**](http://www.kancloud.cn/thinkphp/php-fig-psr/3144); 24 | * 对于 Issues 的处理,请使用诸如 `fix #xxx(Issue ID)` 的 commit title 直接关闭 issue。 25 | * 系统会自动在 PHP 5.4 5.5 5.6 7.0 和 HHVM 上测试修改,其中 HHVM 下的测试容许报错,请确保你的修改符合 PHP 5.4 ~ 5.6 和 PHP 7.0 的语法规范; 26 | * 管理员不会合并造成 CI faild 的修改,若出现 CI faild 请检查自己的源代码或修改相应的[单元测试文件](tests); 27 | 28 | ## GitHub Issue 29 | 30 | GitHub 提供了 Issue 功能,该功能可以用于: 31 | 32 | * 提出 bug 33 | * 提出功能改进 34 | * 反馈使用体验 35 | 36 | 该功能不应该用于: 37 | 38 | * 提出修改意见(涉及代码署名和修订追溯问题) 39 | * 不友善的言论 40 | 41 | ## 快速修改 42 | 43 | **GitHub 提供了快速编辑文件的功能** 44 | 45 | 1. 登录 GitHub 帐号; 46 | 2. 浏览项目文件,找到要进行修改的文件; 47 | 3. 点击右上角铅笔图标进行修改; 48 | 4. 填写 `Commit changes` 相关内容(Title 必填); 49 | 5. 提交修改,等待 CI 验证和管理员合并。 50 | 51 | **若您需要一次提交大量修改,请继续阅读下面的内容** 52 | 53 | ## 完整流程 54 | 55 | 1. `fork`本项目; 56 | 2. 克隆(`clone`)你 `fork` 的项目到本地; 57 | 3. 新建分支(`branch`)并检出(`checkout`)新分支; 58 | 4. 添加本项目到你的本地 git 仓库作为上游(`upstream`); 59 | 5. 进行修改,若你的修改包含方法或函数的增减,请记得修改[单元测试文件](tests); 60 | 6. 变基(衍合 `rebase`)你的分支到上游 master 分支; 61 | 7. `push` 你的本地仓库到 GitHub; 62 | 8. 提交 `pull request`; 63 | 9. 等待 CI 验证(若不通过则重复 5~7,不需要重新提交 `pull request`,GitHub 会自动更新你的 `pull request`); 64 | 10. 等待管理员处理,并及时 `rebase` 你的分支到上游 master 分支(若上游 master 分支有修改)。 65 | 66 | *若有必要,可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`* 67 | 68 | *绝对不可以使用 `git push -f` 强行推送修改到上游* 69 | 70 | ### 注意事项 71 | 72 | * 若对上述流程有任何不清楚的地方,请查阅 GIT 教程,如 [这个](http://backlogtool.com/git-guide/cn/); 73 | * 对于代码**不同方面**的修改,请在自己 `fork` 的项目中**创建不同的分支**(原因参见`完整流程`第9条备注部分); 74 | * 变基及交互式变基操作参见 [Git 交互式变基](http://pakchoi.me/2015/03/17/git-interactive-rebase/) 75 | 76 | ## 推荐资源 77 | 78 | ### 开发环境 79 | 80 | * XAMPP for Windows 5.5.x 81 | * WampServer (for Windows) 82 | * upupw Apache PHP5.4 ( for Windows) 83 | 84 | 或自行安装 85 | 86 | - Apache / Nginx 87 | - PHP 5.4 ~ 5.6 88 | - MySQL / MariaDB 89 | 90 | *Windows 用户推荐添加 PHP bin 目录到 PATH,方便使用 composer* 91 | 92 | *Linux 用户自行配置环境, Mac 用户推荐使用内置 Apache 配合 Homebrew 安装 PHP 和 MariaDB* 93 | 94 | ### 编辑器 95 | 96 | Sublime Text 3 + phpfmt 插件 97 | 98 | phpfmt 插件参数 99 | 100 | ```json 101 | { 102 | "autocomplete": true, 103 | "enable_auto_align": true, 104 | "format_on_save": true, 105 | "indent_with_space": true, 106 | "psr1_naming": false, 107 | "psr2": true, 108 | "version": 4 109 | } 110 | ``` 111 | 112 | 或其他 编辑器 / IDE 配合 PSR2 自动格式化工具 113 | 114 | ### Git GUI 115 | 116 | * SourceTree 117 | * GitHub Desktop 118 | 119 | 或其他 Git 图形界面客户端 120 | -------------------------------------------------------------------------------- /src/thinkphp/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 3 | 版权所有Copyright © 2006-2017 by ThinkPHP (http://thinkphp.cn) 4 | All rights reserved。 5 | ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 6 | 7 | Apache Licence是著名的非盈利开源组织Apache采用的协议。 8 | 该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, 9 | 允许代码修改,再作为开源或商业软件发布。需要满足 10 | 的条件: 11 | 1. 需要给代码的用户一份Apache Licence ; 12 | 2. 如果你修改了代码,需要在被修改的文件中说明; 13 | 3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 14 | 带有原来代码中的协议,商标,专利声明和其他原来作者规 15 | 定需要包含的说明; 16 | 4. 如果再发布的产品中包含一个Notice文件,则在Notice文 17 | 件中需要带有本协议内容。你可以在Notice中增加自己的 18 | 许可,但不可以表现为对Apache Licence构成更改。 19 | 具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /src/thinkphp/README.md: -------------------------------------------------------------------------------- 1 | ThinkPHP 5.0 2 | =============== 3 | 4 | [![StyleCI](https://styleci.io/repos/48530411/shield?style=flat&branch=master)](https://styleci.io/repos/48530411) 5 | [![Build Status](https://travis-ci.org/top-think/framework.svg?branch=master)](https://travis-ci.org/top-think/framework) 6 | [![codecov.io](http://codecov.io/github/top-think/framework/coverage.svg?branch=master)](http://codecov.io/github/github/top-think/framework?branch=master) 7 | [![Total Downloads](https://poser.pugx.org/topthink/framework/downloads)](https://packagist.org/packages/topthink/framework) 8 | [![Latest Stable Version](https://poser.pugx.org/topthink/framework/v/stable)](https://packagist.org/packages/topthink/framework) 9 | [![Latest Unstable Version](https://poser.pugx.org/topthink/framework/v/unstable)](https://packagist.org/packages/topthink/framework) 10 | [![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework) 11 | 12 | ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PHP版本要求提升到5.4,优化核心,减少依赖,基于全新的架构思想和命名空间实现,是ThinkPHP突破原有框架思路的颠覆之作,其主要特性包括: 13 | 14 | + 基于命名空间和众多PHP新特性 15 | + 核心功能组件化 16 | + 强化路由功能 17 | + 更灵活的控制器 18 | + 重构的模型和数据库类 19 | + 配置文件可分离 20 | + 重写的自动验证和完成 21 | + 简化扩展机制 22 | + API支持完善 23 | + 改进的Log类 24 | + 命令行访问支持 25 | + REST支持 26 | + 引导文件支持 27 | + 方便的自动生成定义 28 | + 真正惰性加载 29 | + 分布式环境支持 30 | + 支持Composer 31 | + 支持MongoDb 32 | 33 | > ThinkPHP5的运行环境要求PHP5.4以上。 34 | 35 | 详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) 以及[ThinkPHP5入门系列教程](http://www.kancloud.cn/special/thinkphp5_quickstart) 36 | 37 | ## 目录结构 38 | 39 | 初始的目录结构如下: 40 | 41 | ~~~ 42 | www WEB部署目录(或者子目录) 43 | ├─application 应用目录 44 | │ ├─common 公共模块目录(可以更改) 45 | │ ├─module_name 模块目录 46 | │ │ ├─config.php 模块配置文件 47 | │ │ ├─common.php 模块函数文件 48 | │ │ ├─controller 控制器目录 49 | │ │ ├─model 模型目录 50 | │ │ ├─view 视图目录 51 | │ │ └─ ... 更多类库目录 52 | │ │ 53 | │ ├─command.php 命令行工具配置文件 54 | │ ├─common.php 公共函数文件 55 | │ ├─config.php 公共配置文件 56 | │ ├─route.php 路由配置文件 57 | │ ├─tags.php 应用行为扩展定义文件 58 | │ └─database.php 数据库配置文件 59 | │ 60 | ├─public WEB目录(对外访问目录) 61 | │ ├─index.php 入口文件 62 | │ ├─router.php 快速测试文件 63 | │ └─.htaccess 用于apache的重写 64 | │ 65 | ├─thinkphp 框架系统目录 66 | │ ├─lang 语言文件目录 67 | │ ├─library 框架类库目录 68 | │ │ ├─think Think类库包目录 69 | │ │ └─traits 系统Trait目录 70 | │ │ 71 | │ ├─tpl 系统模板目录 72 | │ ├─base.php 基础定义文件 73 | │ ├─console.php 控制台入口文件 74 | │ ├─convention.php 框架惯例配置文件 75 | │ ├─helper.php 助手函数文件 76 | │ ├─phpunit.xml phpunit配置文件 77 | │ └─start.php 框架入口文件 78 | │ 79 | ├─extend 扩展类库目录 80 | ├─runtime 应用的运行时目录(可写,可定制) 81 | ├─vendor 第三方类库目录(Composer依赖库) 82 | ├─build.php 自动生成定义文件(参考) 83 | ├─composer.json composer 定义文件 84 | ├─LICENSE.txt 授权说明文件 85 | ├─README.md README 文件 86 | ├─think 命令行入口文件 87 | ~~~ 88 | 89 | > router.php用于php自带webserver支持,可用于快速测试 90 | > 切换到public目录后,启动命令:php -S localhost:8888 router.php 91 | > 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。 92 | 93 | ## 命名规范 94 | 95 | ThinkPHP5的命名规范遵循`PSR-2`规范以及`PSR-4`自动加载规范。 96 | 97 | ## 参与开发 98 | 注册并登录 Github 帐号, fork 本项目并进行改动。 99 | 100 | 更多细节参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 101 | 102 | ## 版权信息 103 | 104 | ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 105 | 106 | 本项目包含的第三方源码和二进制文件之版权信息另行标注。 107 | 108 | 版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn) 109 | 110 | All rights reserved。 111 | 112 | ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 113 | 114 | 更多细节参阅 [LICENSE.txt](LICENSE.txt) 115 | -------------------------------------------------------------------------------- /src/thinkphp/base.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | define('THINK_VERSION', '5.0.24'); 13 | define('THINK_START_TIME', microtime(true)); 14 | define('THINK_START_MEM', memory_get_usage()); 15 | define('EXT', '.php'); 16 | define('DS', DIRECTORY_SEPARATOR); 17 | defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS); 18 | define('LIB_PATH', THINK_PATH . 'library' . DS); 19 | define('CORE_PATH', LIB_PATH . 'think' . DS); 20 | define('TRAIT_PATH', LIB_PATH . 'traits' . DS); 21 | defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS); 22 | defined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS); 23 | defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS); 24 | defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS); 25 | defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS); 26 | defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS); 27 | defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS); 28 | defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS); 29 | defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录 30 | defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀 31 | defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀 32 | 33 | // 环境常量 34 | define('IS_CLI', PHP_SAPI == 'cli' ? true : false); 35 | define('IS_WIN', strpos(PHP_OS, 'WIN') !== false); 36 | 37 | // 载入Loader类 38 | require CORE_PATH . 'Loader.php'; 39 | 40 | // 加载环境变量配置文件 41 | if (is_file(ROOT_PATH . '.env')) { 42 | $env = parse_ini_file(ROOT_PATH . '.env', true); 43 | 44 | foreach ($env as $key => $val) { 45 | $name = ENV_PREFIX . strtoupper($key); 46 | 47 | if (is_array($val)) { 48 | foreach ($val as $k => $v) { 49 | $item = $name . '_' . strtoupper($k); 50 | putenv("$item=$v"); 51 | } 52 | } else { 53 | putenv("$name=$val"); 54 | } 55 | } 56 | } 57 | 58 | // 注册自动加载 59 | \think\Loader::register(); 60 | 61 | // 注册错误和异常处理机制 62 | \think\Error::register(); 63 | 64 | // 加载惯例配置文件 65 | \think\Config::set(include THINK_PATH . 'convention' . EXT); 66 | -------------------------------------------------------------------------------- /src/thinkphp/codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: header, changes, diff 3 | coverage: 4 | ignore: 5 | - base.php 6 | - helper.php 7 | - convention.php 8 | - lang/zh-cn.php 9 | - start.php 10 | - console.php 11 | status: 12 | patch: false 13 | -------------------------------------------------------------------------------- /src/thinkphp/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "topthink/framework", 3 | "description": "the new thinkphp framework", 4 | "type": "think-framework", 5 | "keywords": [ 6 | "framework", 7 | "thinkphp", 8 | "ORM" 9 | ], 10 | "homepage": "http://thinkphp.cn/", 11 | "license": "Apache-2.0", 12 | "authors": [ 13 | { 14 | "name": "liu21st", 15 | "email": "liu21st@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=5.4.0", 20 | "topthink/think-installer": "~1.0" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "4.8.*", 24 | "johnkary/phpunit-speedtrap": "^1.0", 25 | "mikey179/vfsStream": "~1.6", 26 | "phploc/phploc": "2.*", 27 | "sebastian/phpcpd": "2.*", 28 | "phpdocumentor/reflection-docblock": "^2.0" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "think\\": "library/think" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/thinkphp/console.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think; 13 | 14 | // ThinkPHP 引导文件 15 | // 加载基础文件 16 | require __DIR__ . '/base.php'; 17 | 18 | // 执行应用 19 | App::initCommon(); 20 | Console::init(); 21 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/Env.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think; 13 | 14 | class Env 15 | { 16 | /** 17 | * 获取环境变量值 18 | * @access public 19 | * @param string $name 环境变量名(支持二级 . 号分割) 20 | * @param string $default 默认值 21 | * @return mixed 22 | */ 23 | public static function get($name, $default = null) 24 | { 25 | $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', $name))); 26 | 27 | if (false !== $result) { 28 | if ('false' === $result) { 29 | $result = false; 30 | } elseif ('true' === $result) { 31 | $result = true; 32 | } 33 | 34 | return $result; 35 | } 36 | 37 | return $default; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/Error.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think; 13 | 14 | use think\console\Output as ConsoleOutput; 15 | use think\exception\ErrorException; 16 | use think\exception\Handle; 17 | use think\exception\ThrowableError; 18 | 19 | class Error 20 | { 21 | /** 22 | * 注册异常处理 23 | * @access public 24 | * @return void 25 | */ 26 | public static function register() 27 | { 28 | error_reporting(E_ALL); 29 | set_error_handler([__CLASS__, 'appError']); 30 | set_exception_handler([__CLASS__, 'appException']); 31 | register_shutdown_function([__CLASS__, 'appShutdown']); 32 | } 33 | 34 | /** 35 | * 异常处理 36 | * @access public 37 | * @param \Exception|\Throwable $e 异常 38 | * @return void 39 | */ 40 | public static function appException($e) 41 | { 42 | if (!$e instanceof \Exception) { 43 | $e = new ThrowableError($e); 44 | } 45 | 46 | $handler = self::getExceptionHandler(); 47 | $handler->report($e); 48 | 49 | if (IS_CLI) { 50 | $handler->renderForConsole(new ConsoleOutput, $e); 51 | } else { 52 | $handler->render($e)->send(); 53 | } 54 | } 55 | 56 | /** 57 | * 错误处理 58 | * @access public 59 | * @param integer $errno 错误编号 60 | * @param integer $errstr 详细错误信息 61 | * @param string $errfile 出错的文件 62 | * @param integer $errline 出错行号 63 | * @return void 64 | * @throws ErrorException 65 | */ 66 | public static function appError($errno, $errstr, $errfile = '', $errline = 0) 67 | { 68 | $exception = new ErrorException($errno, $errstr, $errfile, $errline); 69 | 70 | // 符合异常处理的则将错误信息托管至 think\exception\ErrorException 71 | if (error_reporting() & $errno) { 72 | throw $exception; 73 | } 74 | 75 | self::getExceptionHandler()->report($exception); 76 | } 77 | 78 | /** 79 | * 异常中止处理 80 | * @access public 81 | * @return void 82 | */ 83 | public static function appShutdown() 84 | { 85 | // 将错误信息托管至 think\ErrorException 86 | if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) { 87 | self::appException(new ErrorException( 88 | $error['type'], $error['message'], $error['file'], $error['line'] 89 | )); 90 | } 91 | 92 | // 写入日志 93 | Log::save(); 94 | } 95 | 96 | /** 97 | * 确定错误类型是否致命 98 | * @access protected 99 | * @param int $type 错误类型 100 | * @return bool 101 | */ 102 | protected static function isFatal($type) 103 | { 104 | return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]); 105 | } 106 | 107 | /** 108 | * 获取异常处理的实例 109 | * @access public 110 | * @return Handle 111 | */ 112 | public static function getExceptionHandler() 113 | { 114 | static $handle; 115 | 116 | if (!$handle) { 117 | // 异常处理 handle 118 | $class = Config::get('exception_handle'); 119 | 120 | if ($class && is_string($class) && class_exists($class) && 121 | is_subclass_of($class, "\\think\\exception\\Handle") 122 | ) { 123 | $handle = new $class; 124 | } else { 125 | $handle = new Handle; 126 | 127 | if ($class instanceof \Closure) { 128 | $handle->setRender($class); 129 | } 130 | 131 | } 132 | } 133 | 134 | return $handle; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/Exception.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think; 13 | 14 | class Exception extends \Exception 15 | { 16 | /** 17 | * @var array 保存异常页面显示的额外 Debug 数据 18 | */ 19 | protected $data = []; 20 | 21 | /** 22 | * 设置异常额外的 Debug 数据 23 | * 数据将会显示为下面的格式 24 | * 25 | * Exception Data 26 | * -------------------------------------------------- 27 | * Label 1 28 | * key1 value1 29 | * key2 value2 30 | * Label 2 31 | * key1 value1 32 | * key2 value2 33 | * 34 | * @access protected 35 | * @param string $label 数据分类,用于异常页面显示 36 | * @param array $data 需要显示的数据,必须为关联数组 37 | * @return void 38 | */ 39 | final protected function setData($label, array $data) 40 | { 41 | $this->data[$label] = $data; 42 | } 43 | 44 | /** 45 | * 获取异常额外 Debug 数据 46 | * 主要用于输出到异常页面便于调试 47 | * @access public 48 | * @return array 49 | */ 50 | final public function getData() 51 | { 52 | return $this->data; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/config/driver/Ini.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\config\driver; 13 | 14 | class Ini 15 | { 16 | public function parse($config) 17 | { 18 | if (is_file($config)) { 19 | return parse_ini_file($config, true); 20 | } else { 21 | return parse_ini_string($config, true); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/config/driver/Json.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\config\driver; 13 | 14 | class Json 15 | { 16 | public function parse($config) 17 | { 18 | if (is_file($config)) { 19 | $config = file_get_contents($config); 20 | } 21 | $result = json_decode($config, true); 22 | return $result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/config/driver/Xml.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\config\driver; 13 | 14 | class Xml 15 | { 16 | public function parse($config) 17 | { 18 | if (is_file($config)) { 19 | $content = simplexml_load_file($config); 20 | } else { 21 | $content = simplexml_load_string($config); 22 | } 23 | $result = (array) $content; 24 | foreach ($result as $key => $val) { 25 | if (is_object($val)) { 26 | $result[$key] = (array) $val; 27 | } 28 | } 29 | return $result; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2016 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/bin/README.md: -------------------------------------------------------------------------------- 1 | console 工具使用 hiddeninput.exe 在 windows 上隐藏密码输入,该二进制文件由第三方提供,相关源码和其他细节可以在 [Hidden Input](https://github.com/Seldaek/hidden-input) 找到。 2 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/bin/hiddeninput.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2020NCOV/ncov-report-mini-program-server/805360007c4a95feba09ff12a6db4dfdd04a1d4e/src/thinkphp/library/think/console/bin/hiddeninput.exe -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/Build.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\command; 13 | 14 | use think\console\Command; 15 | use think\console\Input; 16 | use think\console\input\Option; 17 | use think\console\Output; 18 | 19 | class Build extends Command 20 | { 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | protected function configure() 26 | { 27 | $this->setName('build') 28 | ->setDefinition([ 29 | new Option('config', null, Option::VALUE_OPTIONAL, "build.php path"), 30 | new Option('module', null, Option::VALUE_OPTIONAL, "module name"), 31 | ]) 32 | ->setDescription('Build Application Dirs'); 33 | } 34 | 35 | protected function execute(Input $input, Output $output) 36 | { 37 | if ($input->hasOption('module')) { 38 | \think\Build::module($input->getOption('module')); 39 | $output->writeln("Successed"); 40 | return; 41 | } 42 | 43 | if ($input->hasOption('config')) { 44 | $build = include $input->getOption('config'); 45 | } else { 46 | $build = include APP_PATH . 'build.php'; 47 | } 48 | if (empty($build)) { 49 | $output->writeln("Build Config Is Empty"); 50 | return; 51 | } 52 | \think\Build::run($build); 53 | $output->writeln("Successed"); 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/Clear.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | namespace think\console\command; 12 | 13 | use think\Cache; 14 | use think\console\Command; 15 | use think\console\Input; 16 | use think\console\input\Argument; 17 | use think\console\input\Option; 18 | use think\console\Output; 19 | 20 | class Clear extends Command 21 | { 22 | protected function configure() 23 | { 24 | // 指令配置 25 | $this 26 | ->setName('clear') 27 | ->addArgument('type', Argument::OPTIONAL, 'type to clear', null) 28 | ->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null) 29 | ->setDescription('Clear runtime file'); 30 | } 31 | 32 | protected function execute(Input $input, Output $output) 33 | { 34 | $path = $input->getOption('path') ?: RUNTIME_PATH; 35 | 36 | $type = $input->getArgument('type'); 37 | 38 | if ($type == 'route') { 39 | Cache::clear('route_check'); 40 | } else { 41 | if (is_dir($path)) { 42 | $this->clearPath($path); 43 | } 44 | } 45 | 46 | $output->writeln("Clear Successed"); 47 | } 48 | 49 | protected function clearPath($path) 50 | { 51 | $path = realpath($path) . DS; 52 | $files = scandir($path); 53 | if ($files) { 54 | foreach ($files as $file) { 55 | if ('.' != $file && '..' != $file && is_dir($path . $file)) { 56 | $this->clearPath($path . $file); 57 | } elseif ('.gitignore' != $file && is_file($path . $file)) { 58 | unlink($path . $file); 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/Help.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\command; 13 | 14 | use think\console\Command; 15 | use think\console\Input; 16 | use think\console\input\Argument as InputArgument; 17 | use think\console\input\Option as InputOption; 18 | use think\console\Output; 19 | 20 | class Help extends Command 21 | { 22 | 23 | private $command; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | protected function configure() 29 | { 30 | $this->ignoreValidationErrors(); 31 | 32 | $this->setName('help')->setDefinition([ 33 | new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), 34 | new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), 35 | ])->setDescription('Displays help for a command')->setHelp(<<%command.name% command displays help for a given command: 37 | 38 | php %command.full_name% list 39 | 40 | To display the list of available commands, please use the list command. 41 | EOF 42 | ); 43 | } 44 | 45 | /** 46 | * Sets the command. 47 | * @param Command $command The command to set 48 | */ 49 | public function setCommand(Command $command) 50 | { 51 | $this->command = $command; 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | protected function execute(Input $input, Output $output) 58 | { 59 | if (null === $this->command) { 60 | $this->command = $this->getConsole()->find($input->getArgument('command_name')); 61 | } 62 | 63 | $output->describe($this->command, [ 64 | 'raw_text' => $input->getOption('raw'), 65 | ]); 66 | 67 | $this->command = null; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/Lists.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\command; 13 | 14 | use think\console\Command; 15 | use think\console\Input; 16 | use think\console\Output; 17 | use think\console\input\Argument as InputArgument; 18 | use think\console\input\Option as InputOption; 19 | use think\console\input\Definition as InputDefinition; 20 | 21 | class Lists extends Command 22 | { 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function configure() 28 | { 29 | $this->setName('list')->setDefinition($this->createDefinition())->setDescription('Lists commands')->setHelp(<<%command.name% command lists all commands: 31 | 32 | php %command.full_name% 33 | 34 | You can also display the commands for a specific namespace: 35 | 36 | php %command.full_name% test 37 | 38 | It's also possible to get raw list of commands (useful for embedding command runner): 39 | 40 | php %command.full_name% --raw 41 | EOF 42 | ); 43 | } 44 | 45 | /** 46 | * {@inheritdoc} 47 | */ 48 | public function getNativeDefinition() 49 | { 50 | return $this->createDefinition(); 51 | } 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | protected function execute(Input $input, Output $output) 57 | { 58 | $output->describe($this->getConsole(), [ 59 | 'raw_text' => $input->getOption('raw'), 60 | 'namespace' => $input->getArgument('namespace'), 61 | ]); 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | */ 67 | private function createDefinition() 68 | { 69 | return new InputDefinition([ 70 | new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), 71 | new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list') 72 | ]); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/Make.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\command; 13 | 14 | use think\App; 15 | use think\Config; 16 | use think\console\Command; 17 | use think\console\Input; 18 | use think\console\input\Argument; 19 | use think\console\Output; 20 | 21 | abstract class Make extends Command 22 | { 23 | 24 | protected $type; 25 | 26 | abstract protected function getStub(); 27 | 28 | protected function configure() 29 | { 30 | $this->addArgument('name', Argument::REQUIRED, "The name of the class"); 31 | } 32 | 33 | protected function execute(Input $input, Output $output) 34 | { 35 | 36 | $name = trim($input->getArgument('name')); 37 | 38 | $classname = $this->getClassName($name); 39 | 40 | $pathname = $this->getPathName($classname); 41 | 42 | if (is_file($pathname)) { 43 | $output->writeln('' . $this->type . ' already exists!'); 44 | return false; 45 | } 46 | 47 | if (!is_dir(dirname($pathname))) { 48 | mkdir(strtolower(dirname($pathname)), 0755, true); 49 | } 50 | 51 | file_put_contents($pathname, $this->buildClass($classname)); 52 | 53 | $output->writeln('' . $this->type . ' created successfully.'); 54 | 55 | } 56 | 57 | protected function buildClass($name) 58 | { 59 | $stub = file_get_contents($this->getStub()); 60 | 61 | $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\'); 62 | 63 | $class = str_replace($namespace . '\\', '', $name); 64 | 65 | return str_replace(['{%className%}', '{%namespace%}', '{%app_namespace%}'], [ 66 | $class, 67 | $namespace, 68 | App::$namespace, 69 | ], $stub); 70 | 71 | } 72 | 73 | protected function getPathName($name) 74 | { 75 | $name = str_replace(App::$namespace . '\\', '', $name); 76 | 77 | return APP_PATH . str_replace('\\', '/', $name) . '.php'; 78 | } 79 | 80 | protected function getClassName($name) 81 | { 82 | $appNamespace = App::$namespace; 83 | 84 | if (strpos($name, $appNamespace . '\\') === 0) { 85 | return $name; 86 | } 87 | 88 | if (Config::get('app_multi_module')) { 89 | if (strpos($name, '/')) { 90 | list($module, $name) = explode('/', $name, 2); 91 | } else { 92 | $module = 'common'; 93 | } 94 | } else { 95 | $module = null; 96 | } 97 | 98 | if (strpos($name, '/') !== false) { 99 | $name = str_replace('/', '\\', $name); 100 | } 101 | 102 | return $this->getNamespace($appNamespace, $module) . '\\' . $name; 103 | } 104 | 105 | protected function getNamespace($appNamespace, $module) 106 | { 107 | return $module ? ($appNamespace . '\\' . $module) : $appNamespace; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/make/Controller.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\command\make; 13 | 14 | use think\Config; 15 | use think\console\command\Make; 16 | use think\console\input\Option; 17 | 18 | class Controller extends Make 19 | { 20 | 21 | protected $type = "Controller"; 22 | 23 | protected function configure() 24 | { 25 | parent::configure(); 26 | $this->setName('make:controller') 27 | ->addOption('plain', null, Option::VALUE_NONE, 'Generate an empty controller class.') 28 | ->setDescription('Create a new resource controller class'); 29 | } 30 | 31 | protected function getStub() 32 | { 33 | if ($this->input->getOption('plain')) { 34 | return __DIR__ . '/stubs/controller.plain.stub'; 35 | } 36 | 37 | return __DIR__ . '/stubs/controller.stub'; 38 | } 39 | 40 | protected function getClassName($name) 41 | { 42 | return parent::getClassName($name) . (Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : ''); 43 | } 44 | 45 | protected function getNamespace($appNamespace, $module) 46 | { 47 | return parent::getNamespace($appNamespace, $module) . '\controller'; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/make/Model.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\command\make; 13 | 14 | use think\console\command\Make; 15 | 16 | class Model extends Make 17 | { 18 | protected $type = "Model"; 19 | 20 | protected function configure() 21 | { 22 | parent::configure(); 23 | $this->setName('make:model') 24 | ->setDescription('Create a new model class'); 25 | } 26 | 27 | protected function getStub() 28 | { 29 | return __DIR__ . '/stubs/model.stub'; 30 | } 31 | 32 | protected function getNamespace($appNamespace, $module) 33 | { 34 | return parent::getNamespace($appNamespace, $module) . '\model'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/make/stubs/controller.plain.stub: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | namespace think\console\command\optimize; 12 | 13 | use think\Config as ThinkConfig; 14 | use think\console\Command; 15 | use think\console\Input; 16 | use think\console\input\Argument; 17 | use think\console\Output; 18 | 19 | class Config extends Command 20 | { 21 | /** @var Output */ 22 | protected $output; 23 | 24 | protected function configure() 25 | { 26 | $this->setName('optimize:config') 27 | ->addArgument('module', Argument::OPTIONAL, 'Build module config cache .') 28 | ->setDescription('Build config and common file cache.'); 29 | } 30 | 31 | protected function execute(Input $input, Output $output) 32 | { 33 | if ($input->getArgument('module')) { 34 | $module = $input->getArgument('module') . DS; 35 | } else { 36 | $module = ''; 37 | } 38 | 39 | $content = 'buildCacheContent($module); 40 | 41 | if (!is_dir(RUNTIME_PATH . $module)) { 42 | @mkdir(RUNTIME_PATH . $module, 0755, true); 43 | } 44 | 45 | file_put_contents(RUNTIME_PATH . $module . 'init' . EXT, $content); 46 | 47 | $output->writeln('Succeed!'); 48 | } 49 | 50 | protected function buildCacheContent($module) 51 | { 52 | $content = ''; 53 | $path = realpath(APP_PATH . $module) . DS; 54 | 55 | if ($module) { 56 | // 加载模块配置 57 | $config = ThinkConfig::load(CONF_PATH . $module . 'config' . CONF_EXT); 58 | 59 | // 读取数据库配置文件 60 | $filename = CONF_PATH . $module . 'database' . CONF_EXT; 61 | ThinkConfig::load($filename, 'database'); 62 | 63 | // 加载应用状态配置 64 | if ($config['app_status']) { 65 | $config = ThinkConfig::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); 66 | } 67 | // 读取扩展配置文件 68 | if (is_dir(CONF_PATH . $module . 'extra')) { 69 | $dir = CONF_PATH . $module . 'extra'; 70 | $files = scandir($dir); 71 | foreach ($files as $file) { 72 | if (strpos($file, CONF_EXT)) { 73 | $filename = $dir . DS . $file; 74 | ThinkConfig::load($filename, pathinfo($file, PATHINFO_FILENAME)); 75 | } 76 | } 77 | } 78 | } 79 | 80 | // 加载行为扩展文件 81 | if (is_file(CONF_PATH . $module . 'tags' . EXT)) { 82 | $content .= '\think\Hook::import(' . (var_export(include CONF_PATH . $module . 'tags' . EXT, true)) . ');' . PHP_EOL; 83 | } 84 | 85 | // 加载公共文件 86 | if (is_file($path . 'common' . EXT)) { 87 | $content .= substr(php_strip_whitespace($path . 'common' . EXT), 5) . PHP_EOL; 88 | } 89 | 90 | $content .= '\think\Config::set(' . var_export(ThinkConfig::get(), true) . ');'; 91 | return $content; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/command/optimize/Route.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | namespace think\console\command\optimize; 12 | 13 | use think\console\Command; 14 | use think\console\Input; 15 | use think\console\Output; 16 | 17 | class Route extends Command 18 | { 19 | /** @var Output */ 20 | protected $output; 21 | 22 | protected function configure() 23 | { 24 | $this->setName('optimize:route') 25 | ->setDescription('Build route cache.'); 26 | } 27 | 28 | protected function execute(Input $input, Output $output) 29 | { 30 | 31 | if (!is_dir(RUNTIME_PATH)) { 32 | @mkdir(RUNTIME_PATH, 0755, true); 33 | } 34 | 35 | file_put_contents(RUNTIME_PATH . 'route.php', $this->buildRouteCache()); 36 | $output->writeln('Succeed!'); 37 | } 38 | 39 | protected function buildRouteCache() 40 | { 41 | $files = \think\Config::get('route_config_file'); 42 | foreach ($files as $file) { 43 | if (is_file(CONF_PATH . $file . CONF_EXT)) { 44 | $config = include CONF_PATH . $file . CONF_EXT; 45 | if (is_array($config)) { 46 | \think\Route::import($config); 47 | } 48 | } 49 | } 50 | $rules = \think\Route::rules(true); 51 | array_walk_recursive($rules, [$this, 'buildClosure']); 52 | $content = 'getStartLine(); 63 | $endLine = $reflection->getEndLine(); 64 | $file = $reflection->getFileName(); 65 | $item = file($file); 66 | $content = ''; 67 | for ($i = $startLine - 1; $i <= $endLine - 1; $i++) { 68 | $content .= $item[$i]; 69 | } 70 | $start = strpos($content, 'function'); 71 | $end = strrpos($content, '}'); 72 | $value = '[__start__' . substr($content, $start, $end - $start + 1) . '__end__]'; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/input/Argument.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\input; 13 | 14 | class Argument 15 | { 16 | 17 | const REQUIRED = 1; 18 | const OPTIONAL = 2; 19 | const IS_ARRAY = 4; 20 | 21 | private $name; 22 | private $mode; 23 | private $default; 24 | private $description; 25 | 26 | /** 27 | * 构造方法 28 | * @param string $name 参数名 29 | * @param int $mode 参数类型: self::REQUIRED 或者 self::OPTIONAL 30 | * @param string $description 描述 31 | * @param mixed $default 默认值 (仅 self::OPTIONAL 类型有效) 32 | * @throws \InvalidArgumentException 33 | */ 34 | public function __construct($name, $mode = null, $description = '', $default = null) 35 | { 36 | if (null === $mode) { 37 | $mode = self::OPTIONAL; 38 | } elseif (!is_int($mode) || $mode > 7 || $mode < 1) { 39 | throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode)); 40 | } 41 | 42 | $this->name = $name; 43 | $this->mode = $mode; 44 | $this->description = $description; 45 | 46 | $this->setDefault($default); 47 | } 48 | 49 | /** 50 | * 获取参数名 51 | * @return string 52 | */ 53 | public function getName() 54 | { 55 | return $this->name; 56 | } 57 | 58 | /** 59 | * 是否必须 60 | * @return bool 61 | */ 62 | public function isRequired() 63 | { 64 | return self::REQUIRED === (self::REQUIRED & $this->mode); 65 | } 66 | 67 | /** 68 | * 该参数是否接受数组 69 | * @return bool 70 | */ 71 | public function isArray() 72 | { 73 | return self::IS_ARRAY === (self::IS_ARRAY & $this->mode); 74 | } 75 | 76 | /** 77 | * 设置默认值 78 | * @param mixed $default 默认值 79 | * @throws \LogicException 80 | */ 81 | public function setDefault($default = null) 82 | { 83 | if (self::REQUIRED === $this->mode && null !== $default) { 84 | throw new \LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); 85 | } 86 | 87 | if ($this->isArray()) { 88 | if (null === $default) { 89 | $default = []; 90 | } elseif (!is_array($default)) { 91 | throw new \LogicException('A default value for an array argument must be an array.'); 92 | } 93 | } 94 | 95 | $this->default = $default; 96 | } 97 | 98 | /** 99 | * 获取默认值 100 | * @return mixed 101 | */ 102 | public function getDefault() 103 | { 104 | return $this->default; 105 | } 106 | 107 | /** 108 | * 获取描述 109 | * @return string 110 | */ 111 | public function getDescription() 112 | { 113 | return $this->description; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/output/descriptor/Console.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\output\descriptor; 13 | 14 | use think\Console as ThinkConsole; 15 | use think\console\Command; 16 | 17 | class Console 18 | { 19 | 20 | const GLOBAL_NAMESPACE = '_global'; 21 | 22 | /** 23 | * @var ThinkConsole 24 | */ 25 | private $console; 26 | 27 | /** 28 | * @var null|string 29 | */ 30 | private $namespace; 31 | 32 | /** 33 | * @var array 34 | */ 35 | private $namespaces; 36 | 37 | /** 38 | * @var Command[] 39 | */ 40 | private $commands; 41 | 42 | /** 43 | * @var Command[] 44 | */ 45 | private $aliases; 46 | 47 | /** 48 | * 构造方法 49 | * @param ThinkConsole $console 50 | * @param string|null $namespace 51 | */ 52 | public function __construct(ThinkConsole $console, $namespace = null) 53 | { 54 | $this->console = $console; 55 | $this->namespace = $namespace; 56 | } 57 | 58 | /** 59 | * @return array 60 | */ 61 | public function getNamespaces() 62 | { 63 | if (null === $this->namespaces) { 64 | $this->inspectConsole(); 65 | } 66 | 67 | return $this->namespaces; 68 | } 69 | 70 | /** 71 | * @return Command[] 72 | */ 73 | public function getCommands() 74 | { 75 | if (null === $this->commands) { 76 | $this->inspectConsole(); 77 | } 78 | 79 | return $this->commands; 80 | } 81 | 82 | /** 83 | * @param string $name 84 | * @return Command 85 | * @throws \InvalidArgumentException 86 | */ 87 | public function getCommand($name) 88 | { 89 | if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) { 90 | throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name)); 91 | } 92 | 93 | return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name]; 94 | } 95 | 96 | private function inspectConsole() 97 | { 98 | $this->commands = []; 99 | $this->namespaces = []; 100 | 101 | $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null); 102 | foreach ($this->sortCommands($all) as $namespace => $commands) { 103 | $names = []; 104 | 105 | /** @var Command $command */ 106 | foreach ($commands as $name => $command) { 107 | if (!$command->getName()) { 108 | continue; 109 | } 110 | 111 | if ($command->getName() === $name) { 112 | $this->commands[$name] = $command; 113 | } else { 114 | $this->aliases[$name] = $command; 115 | } 116 | 117 | $names[] = $name; 118 | } 119 | 120 | $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names]; 121 | } 122 | } 123 | 124 | /** 125 | * @param array $commands 126 | * @return array 127 | */ 128 | private function sortCommands(array $commands) 129 | { 130 | $namespacedCommands = []; 131 | foreach ($commands as $name => $command) { 132 | $key = $this->console->extractNamespace($name, 1); 133 | if (!$key) { 134 | $key = self::GLOBAL_NAMESPACE; 135 | } 136 | 137 | $namespacedCommands[$key][$name] = $command; 138 | } 139 | ksort($namespacedCommands); 140 | 141 | foreach ($namespacedCommands as &$commandsSet) { 142 | ksort($commandsSet); 143 | } 144 | // unset reference to keep scope clear 145 | unset($commandsSet); 146 | 147 | return $namespacedCommands; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/output/driver/Buffer.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\output\driver; 13 | 14 | use think\console\Output; 15 | 16 | class Buffer 17 | { 18 | /** 19 | * @var string 20 | */ 21 | private $buffer = ''; 22 | 23 | public function __construct(Output $output) 24 | { 25 | // do nothing 26 | } 27 | 28 | public function fetch() 29 | { 30 | $content = $this->buffer; 31 | $this->buffer = ''; 32 | return $content; 33 | } 34 | 35 | public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL) 36 | { 37 | $messages = (array) $messages; 38 | 39 | foreach ($messages as $message) { 40 | $this->buffer .= $message; 41 | } 42 | if ($newline) { 43 | $this->buffer .= "\n"; 44 | } 45 | } 46 | 47 | public function renderException(\Exception $e) 48 | { 49 | // do nothing 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/output/driver/Nothing.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\output\driver; 13 | 14 | use think\console\Output; 15 | 16 | class Nothing 17 | { 18 | 19 | public function __construct(Output $output) 20 | { 21 | // do nothing 22 | } 23 | 24 | public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL) 25 | { 26 | // do nothing 27 | } 28 | 29 | public function renderException(\Exception $e) 30 | { 31 | // do nothing 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/output/formatter/Stack.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\output\formatter; 13 | 14 | class Stack 15 | { 16 | 17 | /** 18 | * @var Style[] 19 | */ 20 | private $styles; 21 | 22 | /** 23 | * @var Style 24 | */ 25 | private $emptyStyle; 26 | 27 | /** 28 | * 构造方法 29 | * @param Style|null $emptyStyle 30 | */ 31 | public function __construct(Style $emptyStyle = null) 32 | { 33 | $this->emptyStyle = $emptyStyle ?: new Style(); 34 | $this->reset(); 35 | } 36 | 37 | /** 38 | * 重置堆栈 39 | */ 40 | public function reset() 41 | { 42 | $this->styles = []; 43 | } 44 | 45 | /** 46 | * 推一个样式进入堆栈 47 | * @param Style $style 48 | */ 49 | public function push(Style $style) 50 | { 51 | $this->styles[] = $style; 52 | } 53 | 54 | /** 55 | * 从堆栈中弹出一个样式 56 | * @param Style|null $style 57 | * @return Style 58 | * @throws \InvalidArgumentException 59 | */ 60 | public function pop(Style $style = null) 61 | { 62 | if (empty($this->styles)) { 63 | return $this->emptyStyle; 64 | } 65 | 66 | if (null === $style) { 67 | return array_pop($this->styles); 68 | } 69 | 70 | /** 71 | * @var int $index 72 | * @var Style $stackedStyle 73 | */ 74 | foreach (array_reverse($this->styles, true) as $index => $stackedStyle) { 75 | if ($style->apply('') === $stackedStyle->apply('')) { 76 | $this->styles = array_slice($this->styles, 0, $index); 77 | 78 | return $stackedStyle; 79 | } 80 | } 81 | 82 | throw new \InvalidArgumentException('Incorrectly nested style tag found.'); 83 | } 84 | 85 | /** 86 | * 计算堆栈的当前样式。 87 | * @return Style 88 | */ 89 | public function getCurrent() 90 | { 91 | if (empty($this->styles)) { 92 | return $this->emptyStyle; 93 | } 94 | 95 | return $this->styles[count($this->styles) - 1]; 96 | } 97 | 98 | /** 99 | * @param Style $emptyStyle 100 | * @return Stack 101 | */ 102 | public function setEmptyStyle(Style $emptyStyle) 103 | { 104 | $this->emptyStyle = $emptyStyle; 105 | 106 | return $this; 107 | } 108 | 109 | /** 110 | * @return Style 111 | */ 112 | public function getEmptyStyle() 113 | { 114 | return $this->emptyStyle; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/console/output/question/Confirmation.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\console\output\question; 13 | 14 | use think\console\output\Question; 15 | 16 | class Confirmation extends Question 17 | { 18 | 19 | private $trueAnswerRegex; 20 | 21 | /** 22 | * 构造方法 23 | * @param string $question 问题 24 | * @param bool $default 默认答案 25 | * @param string $trueAnswerRegex 验证正则 26 | */ 27 | public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i') 28 | { 29 | parent::__construct($question, (bool) $default); 30 | 31 | $this->trueAnswerRegex = $trueAnswerRegex; 32 | $this->setNormalizer($this->getDefaultNormalizer()); 33 | } 34 | 35 | /** 36 | * 获取默认的答案回调 37 | * @return callable 38 | */ 39 | private function getDefaultNormalizer() 40 | { 41 | $default = $this->getDefault(); 42 | $regex = $this->trueAnswerRegex; 43 | 44 | return function ($answer) use ($default, $regex) { 45 | if (is_bool($answer)) { 46 | return $answer; 47 | } 48 | 49 | $answerIsTrue = (bool) preg_match($regex, $answer); 50 | if (false === $default) { 51 | return $answer && $answerIsTrue; 52 | } 53 | 54 | return !$answer || $answerIsTrue; 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/controller/Rest.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\controller; 13 | 14 | use think\App; 15 | use think\Request; 16 | use think\Response; 17 | 18 | abstract class Rest 19 | { 20 | 21 | protected $method; // 当前请求类型 22 | protected $type; // 当前资源类型 23 | // 输出类型 24 | protected $restMethodList = 'get|post|put|delete'; 25 | protected $restDefaultMethod = 'get'; 26 | protected $restTypeList = 'html|xml|json|rss'; 27 | protected $restDefaultType = 'html'; 28 | protected $restOutputType = [ // REST允许输出的资源类型列表 29 | 'xml' => 'application/xml', 30 | 'json' => 'application/json', 31 | 'html' => 'text/html', 32 | ]; 33 | 34 | /** 35 | * 构造函数 取得模板对象实例 36 | * @access public 37 | */ 38 | public function __construct() 39 | { 40 | // 资源类型检测 41 | $request = Request::instance(); 42 | $ext = $request->ext(); 43 | if ('' == $ext) { 44 | // 自动检测资源类型 45 | $this->type = $request->type(); 46 | } elseif (!preg_match('/(' . $this->restTypeList . ')$/i', $ext)) { 47 | // 资源类型非法 则用默认资源类型访问 48 | $this->type = $this->restDefaultType; 49 | } else { 50 | $this->type = $ext; 51 | } 52 | // 请求方式检测 53 | $method = strtolower($request->method()); 54 | if (!preg_match('/(' . $this->restMethodList . ')$/i', $method)) { 55 | // 请求方式非法 则用默认请求方法 56 | $method = $this->restDefaultMethod; 57 | } 58 | $this->method = $method; 59 | } 60 | 61 | /** 62 | * REST 调用 63 | * @access public 64 | * @param string $method 方法名 65 | * @return mixed 66 | * @throws \Exception 67 | */ 68 | public function _empty($method) 69 | { 70 | if (method_exists($this, $method . '_' . $this->method . '_' . $this->type)) { 71 | // RESTFul方法支持 72 | $fun = $method . '_' . $this->method . '_' . $this->type; 73 | } elseif ($this->method == $this->restDefaultMethod && method_exists($this, $method . '_' . $this->type)) { 74 | $fun = $method . '_' . $this->type; 75 | } elseif ($this->type == $this->restDefaultType && method_exists($this, $method . '_' . $this->method)) { 76 | $fun = $method . '_' . $this->method; 77 | } 78 | if (isset($fun)) { 79 | return App::invokeMethod([$this, $fun]); 80 | } else { 81 | // 抛出异常 82 | throw new \Exception('error action :' . $method); 83 | } 84 | } 85 | 86 | /** 87 | * 输出返回数据 88 | * @access protected 89 | * @param mixed $data 要返回的数据 90 | * @param String $type 返回类型 JSON XML 91 | * @param integer $code HTTP状态码 92 | * @return Response 93 | */ 94 | protected function response($data, $type = 'json', $code = 200) 95 | { 96 | return Response::create($data, $type)->code($code); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/controller/Yar.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\controller; 13 | 14 | /** 15 | * ThinkPHP Yar控制器类 16 | */ 17 | abstract class Yar 18 | { 19 | 20 | /** 21 | * 构造函数 22 | * @access public 23 | */ 24 | public function __construct() 25 | { 26 | //控制器初始化 27 | if (method_exists($this, '_initialize')) { 28 | $this->_initialize(); 29 | } 30 | 31 | //判断扩展是否存在 32 | if (!extension_loaded('yar')) { 33 | throw new \Exception('not support yar'); 34 | } 35 | 36 | //实例化Yar_Server 37 | $server = new \Yar_Server($this); 38 | // 启动server 39 | $server->handle(); 40 | } 41 | 42 | /** 43 | * 魔术方法 有不存在的操作的时候执行 44 | * @access public 45 | * @param string $method 方法名 46 | * @param array $args 参数 47 | * @return mixed 48 | */ 49 | public function __call($method, $args) 50 | {} 51 | } 52 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/Expression.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db; 13 | 14 | class Expression 15 | { 16 | /** 17 | * 查询表达式 18 | * 19 | * @var string 20 | */ 21 | protected $value; 22 | 23 | /** 24 | * 创建一个查询表达式 25 | * 26 | * @param string $value 27 | * @return void 28 | */ 29 | public function __construct($value) 30 | { 31 | $this->value = $value; 32 | } 33 | 34 | /** 35 | * 获取表达式 36 | * 37 | * @return string 38 | */ 39 | public function getValue() 40 | { 41 | return $this->value; 42 | } 43 | 44 | public function __toString() 45 | { 46 | return (string) $this->value; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/builder/Pgsql.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\builder; 13 | 14 | use think\db\Builder; 15 | 16 | /** 17 | * Pgsql数据库驱动 18 | */ 19 | class Pgsql extends Builder 20 | { 21 | protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; 22 | protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; 23 | 24 | /** 25 | * limit分析 26 | * @access protected 27 | * @param mixed $limit 28 | * @return string 29 | */ 30 | public function parseLimit($limit) 31 | { 32 | $limitStr = ''; 33 | if (!empty($limit)) { 34 | $limit = explode(',', $limit); 35 | if (count($limit) > 1) { 36 | $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; 37 | } else { 38 | $limitStr .= ' LIMIT ' . $limit[0] . ' '; 39 | } 40 | } 41 | return $limitStr; 42 | } 43 | 44 | /** 45 | * 字段和表名处理 46 | * @access protected 47 | * @param mixed $key 48 | * @param array $options 49 | * @return string 50 | */ 51 | protected function parseKey($key, $options = [], $strict = false) 52 | { 53 | if (is_numeric($key)) { 54 | return $key; 55 | } elseif ($key instanceof Expression) { 56 | return $key->getValue(); 57 | } 58 | 59 | $key = trim($key); 60 | if (strpos($key, '$.') && false === strpos($key, '(')) { 61 | // JSON字段支持 62 | list($field, $name) = explode('$.', $key); 63 | $key = $field . '->>\'' . $name . '\''; 64 | } elseif (strpos($key, '.')) { 65 | list($table, $key) = explode('.', $key, 2); 66 | if ('__TABLE__' == $table) { 67 | $table = $this->query->getTable(); 68 | } 69 | if (isset($options['alias'][$table])) { 70 | $table = $options['alias'][$table]; 71 | } 72 | } 73 | if (isset($table)) { 74 | $key = $table . '.' . $key; 75 | } 76 | return $key; 77 | } 78 | 79 | /** 80 | * 随机排序 81 | * @access protected 82 | * @return string 83 | */ 84 | protected function parseRand() 85 | { 86 | return 'RANDOM()'; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/builder/Sqlite.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\builder; 13 | 14 | use think\db\Builder; 15 | 16 | /** 17 | * Sqlite数据库驱动 18 | */ 19 | class Sqlite extends Builder 20 | { 21 | 22 | /** 23 | * limit 24 | * @access public 25 | * @param string $limit 26 | * @return string 27 | */ 28 | public function parseLimit($limit) 29 | { 30 | $limitStr = ''; 31 | if (!empty($limit)) { 32 | $limit = explode(',', $limit); 33 | if (count($limit) > 1) { 34 | $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; 35 | } else { 36 | $limitStr .= ' LIMIT ' . $limit[0] . ' '; 37 | } 38 | } 39 | return $limitStr; 40 | } 41 | 42 | /** 43 | * 随机排序 44 | * @access protected 45 | * @return string 46 | */ 47 | protected function parseRand() 48 | { 49 | return 'RANDOM()'; 50 | } 51 | 52 | /** 53 | * 字段和表名处理 54 | * @access protected 55 | * @param mixed $key 56 | * @param array $options 57 | * @return string 58 | */ 59 | protected function parseKey($key, $options = [], $strict = false) 60 | { 61 | if (is_numeric($key)) { 62 | return $key; 63 | } elseif ($key instanceof Expression) { 64 | return $key->getValue(); 65 | } 66 | 67 | $key = trim($key); 68 | if (strpos($key, '.')) { 69 | list($table, $key) = explode('.', $key, 2); 70 | if ('__TABLE__' == $table) { 71 | $table = $this->query->getTable(); 72 | } 73 | if (isset($options['alias'][$table])) { 74 | $table = $options['alias'][$table]; 75 | } 76 | } 77 | if (isset($table)) { 78 | $key = $table . '.' . $key; 79 | } 80 | return $key; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/connector/Mysql.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\connector; 13 | 14 | use PDO; 15 | use think\db\Connection; 16 | use think\Log; 17 | 18 | /** 19 | * mysql数据库驱动 20 | */ 21 | class Mysql extends Connection 22 | { 23 | 24 | protected $builder = '\\think\\db\\builder\\Mysql'; 25 | 26 | /** 27 | * 解析pdo连接的dsn信息 28 | * @access protected 29 | * @param array $config 连接信息 30 | * @return string 31 | */ 32 | protected function parseDsn($config) 33 | { 34 | if (!empty($config['socket'])) { 35 | $dsn = 'mysql:unix_socket=' . $config['socket']; 36 | } elseif (!empty($config['hostport'])) { 37 | $dsn = 'mysql:host=' . $config['hostname'] . ';port=' . $config['hostport']; 38 | } else { 39 | $dsn = 'mysql:host=' . $config['hostname']; 40 | } 41 | $dsn .= ';dbname=' . $config['database']; 42 | 43 | if (!empty($config['charset'])) { 44 | $dsn .= ';charset=' . $config['charset']; 45 | } 46 | return $dsn; 47 | } 48 | 49 | /** 50 | * 取得数据表的字段信息 51 | * @access public 52 | * @param string $tableName 53 | * @return array 54 | */ 55 | public function getFields($tableName) 56 | { 57 | list($tableName) = explode(' ', $tableName); 58 | if (false === strpos($tableName, '`')) { 59 | if (strpos($tableName, '.')) { 60 | $tableName = str_replace('.', '`.`', $tableName); 61 | } 62 | $tableName = '`' . $tableName . '`'; 63 | } 64 | $sql = 'SHOW COLUMNS FROM ' . $tableName; 65 | $pdo = $this->query($sql, [], false, true); 66 | $result = $pdo->fetchAll(PDO::FETCH_ASSOC); 67 | $info = []; 68 | if ($result) { 69 | foreach ($result as $key => $val) { 70 | $val = array_change_key_case($val); 71 | $info[$val['field']] = [ 72 | 'name' => $val['field'], 73 | 'type' => $val['type'], 74 | 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes 75 | 'default' => $val['default'], 76 | 'primary' => (strtolower($val['key']) == 'pri'), 77 | 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), 78 | ]; 79 | } 80 | } 81 | return $this->fieldCase($info); 82 | } 83 | 84 | /** 85 | * 取得数据库的表信息 86 | * @access public 87 | * @param string $dbName 88 | * @return array 89 | */ 90 | public function getTables($dbName = '') 91 | { 92 | $sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES '; 93 | $pdo = $this->query($sql, [], false, true); 94 | $result = $pdo->fetchAll(PDO::FETCH_ASSOC); 95 | $info = []; 96 | foreach ($result as $key => $val) { 97 | $info[$key] = current($val); 98 | } 99 | return $info; 100 | } 101 | 102 | /** 103 | * SQL性能分析 104 | * @access protected 105 | * @param string $sql 106 | * @return array 107 | */ 108 | protected function getExplain($sql) 109 | { 110 | $pdo = $this->linkID->query("EXPLAIN " . $sql); 111 | $result = $pdo->fetch(PDO::FETCH_ASSOC); 112 | $result = array_change_key_case($result); 113 | if (isset($result['extra'])) { 114 | if (strpos($result['extra'], 'filesort') || strpos($result['extra'], 'temporary')) { 115 | Log::record('SQL:' . $this->queryStr . '[' . $result['extra'] . ']', 'warn'); 116 | } 117 | } 118 | return $result; 119 | } 120 | 121 | protected function supportSavepoint() 122 | { 123 | return true; 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/connector/Pgsql.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\connector; 13 | 14 | use PDO; 15 | use think\db\Connection; 16 | 17 | /** 18 | * Pgsql数据库驱动 19 | */ 20 | class Pgsql extends Connection 21 | { 22 | protected $builder = '\\think\\db\\builder\\Pgsql'; 23 | 24 | /** 25 | * 解析pdo连接的dsn信息 26 | * @access protected 27 | * @param array $config 连接信息 28 | * @return string 29 | */ 30 | protected function parseDsn($config) 31 | { 32 | $dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname']; 33 | if (!empty($config['hostport'])) { 34 | $dsn .= ';port=' . $config['hostport']; 35 | } 36 | return $dsn; 37 | } 38 | 39 | /** 40 | * 取得数据表的字段信息 41 | * @access public 42 | * @param string $tableName 43 | * @return array 44 | */ 45 | public function getFields($tableName) 46 | { 47 | 48 | list($tableName) = explode(' ', $tableName); 49 | $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 . '\');'; 50 | 51 | $pdo = $this->query($sql, [], false, true); 52 | $result = $pdo->fetchAll(PDO::FETCH_ASSOC); 53 | $info = []; 54 | if ($result) { 55 | foreach ($result as $key => $val) { 56 | $val = array_change_key_case($val); 57 | $info[$val['field']] = [ 58 | 'name' => $val['field'], 59 | 'type' => $val['type'], 60 | 'notnull' => (bool) ('' !== $val['null']), 61 | 'default' => $val['default'], 62 | 'primary' => !empty($val['key']), 63 | 'autoinc' => (0 === strpos($val['extra'], 'nextval(')), 64 | ]; 65 | } 66 | } 67 | return $this->fieldCase($info); 68 | } 69 | 70 | /** 71 | * 取得数据库的表信息 72 | * @access public 73 | * @param string $dbName 74 | * @return array 75 | */ 76 | public function getTables($dbName = '') 77 | { 78 | $sql = "select tablename as Tables_in_test from pg_tables where schemaname ='public'"; 79 | $pdo = $this->query($sql, [], false, true); 80 | $result = $pdo->fetchAll(PDO::FETCH_ASSOC); 81 | $info = []; 82 | foreach ($result as $key => $val) { 83 | $info[$key] = current($val); 84 | } 85 | return $info; 86 | } 87 | 88 | /** 89 | * SQL性能分析 90 | * @access protected 91 | * @param string $sql 92 | * @return array 93 | */ 94 | protected function getExplain($sql) 95 | { 96 | return []; 97 | } 98 | 99 | protected function supportSavepoint() 100 | { 101 | return true; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/connector/Sqlite.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\connector; 13 | 14 | use PDO; 15 | use think\db\Connection; 16 | 17 | /** 18 | * Sqlite数据库驱动 19 | */ 20 | class Sqlite extends Connection 21 | { 22 | 23 | protected $builder = '\\think\\db\\builder\\Sqlite'; 24 | 25 | /** 26 | * 解析pdo连接的dsn信息 27 | * @access protected 28 | * @param array $config 连接信息 29 | * @return string 30 | */ 31 | protected function parseDsn($config) 32 | { 33 | $dsn = 'sqlite:' . $config['database']; 34 | return $dsn; 35 | } 36 | 37 | /** 38 | * 取得数据表的字段信息 39 | * @access public 40 | * @param string $tableName 41 | * @return array 42 | */ 43 | public function getFields($tableName) 44 | { 45 | list($tableName) = explode(' ', $tableName); 46 | $sql = 'PRAGMA table_info( ' . $tableName . ' )'; 47 | 48 | $pdo = $this->query($sql, [], false, true); 49 | $result = $pdo->fetchAll(PDO::FETCH_ASSOC); 50 | $info = []; 51 | if ($result) { 52 | foreach ($result as $key => $val) { 53 | $val = array_change_key_case($val); 54 | $info[$val['name']] = [ 55 | 'name' => $val['name'], 56 | 'type' => $val['type'], 57 | 'notnull' => 1 === $val['notnull'], 58 | 'default' => $val['dflt_value'], 59 | 'primary' => '1' == $val['pk'], 60 | 'autoinc' => '1' == $val['pk'], 61 | ]; 62 | } 63 | } 64 | return $this->fieldCase($info); 65 | } 66 | 67 | /** 68 | * 取得数据库的表信息 69 | * @access public 70 | * @param string $dbName 71 | * @return array 72 | */ 73 | public function getTables($dbName = '') 74 | { 75 | 76 | $sql = "SELECT name FROM sqlite_master WHERE type='table' " 77 | . "UNION ALL SELECT name FROM sqlite_temp_master " 78 | . "WHERE type='table' ORDER BY name"; 79 | 80 | $pdo = $this->query($sql, [], false, true); 81 | $result = $pdo->fetchAll(PDO::FETCH_ASSOC); 82 | $info = []; 83 | foreach ($result as $key => $val) { 84 | $info[$key] = current($val); 85 | } 86 | return $info; 87 | } 88 | 89 | /** 90 | * SQL性能分析 91 | * @access protected 92 | * @param string $sql 93 | * @return array 94 | */ 95 | protected function getExplain($sql) 96 | { 97 | return []; 98 | } 99 | 100 | protected function supportSavepoint() 101 | { 102 | return true; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/connector/pgsql.sql: -------------------------------------------------------------------------------- 1 | CREATE OR REPLACE FUNCTION pgsql_type(a_type varchar) RETURNS varchar AS 2 | $BODY$ 3 | DECLARE 4 | v_type varchar; 5 | BEGIN 6 | IF a_type='int8' THEN 7 | v_type:='bigint'; 8 | ELSIF a_type='int4' THEN 9 | v_type:='integer'; 10 | ELSIF a_type='int2' THEN 11 | v_type:='smallint'; 12 | ELSIF a_type='bpchar' THEN 13 | v_type:='char'; 14 | ELSE 15 | v_type:=a_type; 16 | END IF; 17 | RETURN v_type; 18 | END; 19 | $BODY$ 20 | LANGUAGE PLPGSQL; 21 | 22 | CREATE TYPE "public"."tablestruct" AS ( 23 | "fields_key_name" varchar(100), 24 | "fields_name" VARCHAR(200), 25 | "fields_type" VARCHAR(20), 26 | "fields_length" BIGINT, 27 | "fields_not_null" VARCHAR(10), 28 | "fields_default" VARCHAR(500), 29 | "fields_comment" VARCHAR(1000) 30 | ); 31 | 32 | CREATE OR REPLACE FUNCTION "public"."table_msg" (a_schema_name varchar, a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS 33 | $body$ 34 | DECLARE 35 | v_ret tablestruct; 36 | v_oid oid; 37 | v_sql varchar; 38 | v_rec RECORD; 39 | v_key varchar; 40 | BEGIN 41 | SELECT 42 | pg_class.oid INTO v_oid 43 | FROM 44 | pg_class 45 | INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid AND lower(pg_namespace.nspname) = a_schema_name) 46 | WHERE 47 | pg_class.relname=a_table_name; 48 | IF NOT FOUND THEN 49 | RETURN; 50 | END IF; 51 | 52 | v_sql=' 53 | SELECT 54 | pg_attribute.attname AS fields_name, 55 | pg_attribute.attnum AS fields_index, 56 | pgsql_type(pg_type.typname::varchar) AS fields_type, 57 | pg_attribute.atttypmod-4 as fields_length, 58 | CASE WHEN pg_attribute.attnotnull THEN ''not null'' 59 | ELSE '''' 60 | END AS fields_not_null, 61 | pg_attrdef.adsrc AS fields_default, 62 | pg_description.description AS fields_comment 63 | FROM 64 | pg_attribute 65 | INNER JOIN pg_class ON pg_attribute.attrelid = pg_class.oid 66 | INNER JOIN pg_type ON pg_attribute.atttypid = pg_type.oid 67 | LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid = pg_class.oid AND pg_attrdef.adnum = pg_attribute.attnum 68 | LEFT OUTER JOIN pg_description ON pg_description.objoid = pg_class.oid AND pg_description.objsubid = pg_attribute.attnum 69 | WHERE 70 | pg_attribute.attnum > 0 71 | AND attisdropped <> ''t'' 72 | AND pg_class.oid = ' || v_oid || ' 73 | ORDER BY pg_attribute.attnum' ; 74 | 75 | FOR v_rec IN EXECUTE v_sql LOOP 76 | v_ret.fields_name=v_rec.fields_name; 77 | v_ret.fields_type=v_rec.fields_type; 78 | IF v_rec.fields_length > 0 THEN 79 | v_ret.fields_length:=v_rec.fields_length; 80 | ELSE 81 | v_ret.fields_length:=NULL; 82 | END IF; 83 | v_ret.fields_not_null=v_rec.fields_not_null; 84 | v_ret.fields_default=v_rec.fields_default; 85 | v_ret.fields_comment=v_rec.fields_comment; 86 | 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; 87 | IF FOUND THEN 88 | v_ret.fields_key_name=v_key; 89 | ELSE 90 | v_ret.fields_key_name=''; 91 | END IF; 92 | RETURN NEXT v_ret; 93 | END LOOP; 94 | RETURN ; 95 | END; 96 | $body$ 97 | LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER; 98 | 99 | COMMENT ON FUNCTION "public"."table_msg"(a_schema_name varchar, a_table_name varchar) 100 | IS '获得表信息'; 101 | 102 | ---重载一个函数 103 | CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS 104 | $body$ 105 | DECLARE 106 | v_ret tablestruct; 107 | BEGIN 108 | FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP 109 | RETURN NEXT v_ret; 110 | END LOOP; 111 | RETURN; 112 | END; 113 | $body$ 114 | LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER; 115 | 116 | COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar) 117 | IS '获得表信息'; -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/exception/BindParamException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\exception; 13 | 14 | use think\exception\DbException; 15 | 16 | /** 17 | * PDO参数绑定异常 18 | */ 19 | class BindParamException extends DbException 20 | { 21 | 22 | /** 23 | * BindParamException constructor. 24 | * @param string $message 25 | * @param array $config 26 | * @param string $sql 27 | * @param array $bind 28 | * @param int $code 29 | */ 30 | public function __construct($message, $config, $sql, $bind, $code = 10502) 31 | { 32 | $this->setData('Bind Param', $bind); 33 | parent::__construct($message, $config, $sql, $code); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/exception/DataNotFoundException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\exception; 13 | 14 | use think\exception\DbException; 15 | 16 | class DataNotFoundException extends DbException 17 | { 18 | protected $table; 19 | 20 | /** 21 | * DbException constructor. 22 | * @param string $message 23 | * @param string $table 24 | * @param array $config 25 | */ 26 | public function __construct($message, $table = '', array $config = []) 27 | { 28 | $this->message = $message; 29 | $this->table = $table; 30 | 31 | $this->setData('Database Config', $config); 32 | } 33 | 34 | /** 35 | * 获取数据表名 36 | * @access public 37 | * @return string 38 | */ 39 | public function getTable() 40 | { 41 | return $this->table; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/db/exception/ModelNotFoundException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\db\exception; 13 | 14 | use think\exception\DbException; 15 | 16 | class ModelNotFoundException extends DbException 17 | { 18 | protected $model; 19 | 20 | /** 21 | * 构造方法 22 | * @param string $message 23 | * @param string $model 24 | */ 25 | public function __construct($message, $model = '', array $config = []) 26 | { 27 | $this->message = $message; 28 | $this->model = $model; 29 | 30 | $this->setData('Database Config', $config); 31 | } 32 | 33 | /** 34 | * 获取模型类名 35 | * @access public 36 | * @return string 37 | */ 38 | public function getModel() 39 | { 40 | return $this->model; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/ClassNotFoundException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | class ClassNotFoundException extends \RuntimeException 15 | { 16 | protected $class; 17 | public function __construct($message, $class = '') 18 | { 19 | $this->message = $message; 20 | $this->class = $class; 21 | } 22 | 23 | /** 24 | * 获取类名 25 | * @access public 26 | * @return string 27 | */ 28 | public function getClass() 29 | { 30 | return $this->class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/DbException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | use think\Exception; 15 | 16 | /** 17 | * Database相关异常处理类 18 | */ 19 | class DbException extends Exception 20 | { 21 | /** 22 | * DbException constructor. 23 | * @param string $message 24 | * @param array $config 25 | * @param string $sql 26 | * @param int $code 27 | */ 28 | public function __construct($message, array $config, $sql, $code = 10500) 29 | { 30 | $this->message = $message; 31 | $this->code = $code; 32 | 33 | $this->setData('Database Status', [ 34 | 'Error Code' => $code, 35 | 'Error Message' => $message, 36 | 'Error SQL' => $sql, 37 | ]); 38 | 39 | unset($config['username'], $config['password']); 40 | $this->setData('Database Config', $config); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/ErrorException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | use think\Exception; 15 | 16 | /** 17 | * ThinkPHP错误异常 18 | * 主要用于封装 set_error_handler 和 register_shutdown_function 得到的错误 19 | * 除开从 think\Exception 继承的功能 20 | * 其他和PHP系统\ErrorException功能基本一样 21 | */ 22 | class ErrorException extends Exception 23 | { 24 | /** 25 | * 用于保存错误级别 26 | * @var integer 27 | */ 28 | protected $severity; 29 | 30 | /** 31 | * 错误异常构造函数 32 | * @param integer $severity 错误级别 33 | * @param string $message 错误详细信息 34 | * @param string $file 出错文件路径 35 | * @param integer $line 出错行号 36 | * @param array $context 错误上下文,会包含错误触发处作用域内所有变量的数组 37 | */ 38 | public function __construct($severity, $message, $file, $line, array $context = []) 39 | { 40 | $this->severity = $severity; 41 | $this->message = $message; 42 | $this->file = $file; 43 | $this->line = $line; 44 | $this->code = 0; 45 | 46 | empty($context) || $this->setData('Error Context', $context); 47 | } 48 | 49 | /** 50 | * 获取错误级别 51 | * @return integer 错误级别 52 | */ 53 | final public function getSeverity() 54 | { 55 | return $this->severity; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/HttpException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | class HttpException extends \RuntimeException 15 | { 16 | private $statusCode; 17 | private $headers; 18 | 19 | public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = [], $code = 0) 20 | { 21 | $this->statusCode = $statusCode; 22 | $this->headers = $headers; 23 | 24 | parent::__construct($message, $code, $previous); 25 | } 26 | 27 | public function getStatusCode() 28 | { 29 | return $this->statusCode; 30 | } 31 | 32 | public function getHeaders() 33 | { 34 | return $this->headers; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/HttpResponseException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | use think\Response; 15 | 16 | class HttpResponseException extends \RuntimeException 17 | { 18 | /** 19 | * @var Response 20 | */ 21 | protected $response; 22 | 23 | public function __construct(Response $response) 24 | { 25 | $this->response = $response; 26 | } 27 | 28 | public function getResponse() 29 | { 30 | return $this->response; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/PDOException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | /** 15 | * PDO异常处理类 16 | * 重新封装了系统的\PDOException类 17 | */ 18 | class PDOException extends DbException 19 | { 20 | /** 21 | * PDOException constructor. 22 | * @param \PDOException $exception 23 | * @param array $config 24 | * @param string $sql 25 | * @param int $code 26 | */ 27 | public function __construct(\PDOException $exception, array $config, $sql, $code = 10501) 28 | { 29 | $error = $exception->errorInfo; 30 | 31 | $this->setData('PDO Error Info', [ 32 | 'SQLSTATE' => $error[0], 33 | 'Driver Error Code' => isset($error[1]) ? $error[1] : 0, 34 | 'Driver Error Message' => isset($error[2]) ? $error[2] : '', 35 | ]); 36 | 37 | parent::__construct($exception->getMessage(), $config, $sql, $code); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/RouteNotFoundException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | class RouteNotFoundException extends HttpException 15 | { 16 | 17 | public function __construct() 18 | { 19 | parent::__construct(404, 'Route Not Found'); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/TemplateNotFoundException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | class TemplateNotFoundException extends \RuntimeException 15 | { 16 | protected $template; 17 | 18 | public function __construct($message, $template = '') 19 | { 20 | $this->message = $message; 21 | $this->template = $template; 22 | } 23 | 24 | /** 25 | * 获取模板文件 26 | * @access public 27 | * @return string 28 | */ 29 | public function getTemplate() 30 | { 31 | return $this->template; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/ThrowableError.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | class ThrowableError extends \ErrorException 15 | { 16 | public function __construct(\Throwable $e) 17 | { 18 | 19 | if ($e instanceof \ParseError) { 20 | $message = 'Parse error: ' . $e->getMessage(); 21 | $severity = E_PARSE; 22 | } elseif ($e instanceof \TypeError) { 23 | $message = 'Type error: ' . $e->getMessage(); 24 | $severity = E_RECOVERABLE_ERROR; 25 | } else { 26 | $message = 'Fatal error: ' . $e->getMessage(); 27 | $severity = E_ERROR; 28 | } 29 | 30 | parent::__construct( 31 | $message, 32 | $e->getCode(), 33 | $severity, 34 | $e->getFile(), 35 | $e->getLine() 36 | ); 37 | 38 | $this->setTrace($e->getTrace()); 39 | } 40 | 41 | protected function setTrace($trace) 42 | { 43 | $traceReflector = new \ReflectionProperty('Exception', 'trace'); 44 | $traceReflector->setAccessible(true); 45 | $traceReflector->setValue($this, $trace); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/exception/ValidateException.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\exception; 13 | 14 | class ValidateException extends \RuntimeException 15 | { 16 | protected $error; 17 | 18 | public function __construct($error) 19 | { 20 | $this->error = $error; 21 | $this->message = is_array($error) ? implode("\n\r", $error) : $error; 22 | } 23 | 24 | /** 25 | * 获取验证错误信息 26 | * @access public 27 | * @return array|string 28 | */ 29 | public function getError() 30 | { 31 | return $this->error; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/log/driver/Test.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\log\driver; 13 | 14 | /** 15 | * 模拟测试输出 16 | */ 17 | class Test 18 | { 19 | /** 20 | * 日志写入接口 21 | * @access public 22 | * @param array $log 日志信息 23 | * @return bool 24 | */ 25 | public function save(array $log = []) 26 | { 27 | return true; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/model/Collection.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\model; 13 | 14 | use think\Collection as BaseCollection; 15 | use think\Model; 16 | 17 | class Collection extends BaseCollection 18 | { 19 | /** 20 | * 延迟预载入关联查询 21 | * @access public 22 | * @param mixed $relation 关联 23 | * @return $this 24 | */ 25 | public function load($relation) 26 | { 27 | $item = current($this->items); 28 | $item->eagerlyResultSet($this->items, $relation); 29 | return $this; 30 | } 31 | 32 | /** 33 | * 设置需要隐藏的输出属性 34 | * @access public 35 | * @param array $hidden 属性列表 36 | * @param bool $override 是否覆盖 37 | * @return $this 38 | */ 39 | public function hidden($hidden = [], $override = false) 40 | { 41 | $this->each(function ($model) use ($hidden, $override) { 42 | /** @var Model $model */ 43 | $model->hidden($hidden, $override); 44 | }); 45 | return $this; 46 | } 47 | 48 | /** 49 | * 设置需要输出的属性 50 | * @param array $visible 51 | * @param bool $override 是否覆盖 52 | * @return $this 53 | */ 54 | public function visible($visible = [], $override = false) 55 | { 56 | $this->each(function ($model) use ($visible, $override) { 57 | /** @var Model $model */ 58 | $model->visible($visible, $override); 59 | }); 60 | return $this; 61 | } 62 | 63 | /** 64 | * 设置需要追加的输出属性 65 | * @access public 66 | * @param array $append 属性列表 67 | * @param bool $override 是否覆盖 68 | * @return $this 69 | */ 70 | public function append($append = [], $override = false) 71 | { 72 | $this->each(function ($model) use ($append, $override) { 73 | /** @var Model $model */ 74 | $model && $model->append($append, $override); 75 | }); 76 | return $this; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/model/Pivot.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\model; 13 | 14 | use think\Model; 15 | 16 | class Pivot extends Model 17 | { 18 | 19 | /** @var Model */ 20 | public $parent; 21 | 22 | protected $autoWriteTimestamp = false; 23 | 24 | /** 25 | * 架构函数 26 | * @access public 27 | * @param array|object $data 数据 28 | * @param Model $parent 上级模型 29 | * @param string $table 中间数据表名 30 | */ 31 | public function __construct($data = [], Model $parent = null, $table = '') 32 | { 33 | $this->parent = $parent; 34 | 35 | if (is_null($this->name)) { 36 | $this->name = $table; 37 | } 38 | 39 | parent::__construct($data); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/model/Relation.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\model; 13 | 14 | use think\db\Query; 15 | use think\Exception; 16 | use think\Model; 17 | 18 | /** 19 | * Class Relation 20 | * @package think\model 21 | * 22 | * @mixin Query 23 | */ 24 | abstract class Relation 25 | { 26 | // 父模型对象 27 | protected $parent; 28 | /** @var Model 当前关联的模型类 */ 29 | protected $model; 30 | /** @var Query 关联模型查询对象 */ 31 | protected $query; 32 | // 关联表外键 33 | protected $foreignKey; 34 | // 关联表主键 35 | protected $localKey; 36 | // 基础查询 37 | protected $baseQuery; 38 | // 是否为自关联 39 | protected $selfRelation; 40 | 41 | /** 42 | * 获取关联的所属模型 43 | * @access public 44 | * @return Model 45 | */ 46 | public function getParent() 47 | { 48 | return $this->parent; 49 | } 50 | 51 | /** 52 | * 获取当前的关联模型对象实例 53 | * @access public 54 | * @return Model 55 | */ 56 | public function getModel() 57 | { 58 | return $this->query->getModel(); 59 | } 60 | 61 | /** 62 | * 获取关联的查询对象 63 | * @access public 64 | * @return Query 65 | */ 66 | public function getQuery() 67 | { 68 | return $this->query; 69 | } 70 | 71 | /** 72 | * 设置当前关联为自关联 73 | * @access public 74 | * @param bool $self 是否自关联 75 | * @return $this 76 | */ 77 | public function selfRelation($self = true) 78 | { 79 | $this->selfRelation = $self; 80 | return $this; 81 | } 82 | 83 | /** 84 | * 当前关联是否为自关联 85 | * @access public 86 | * @return bool 87 | */ 88 | public function isSelfRelation() 89 | { 90 | return $this->selfRelation; 91 | } 92 | 93 | /** 94 | * 封装关联数据集 95 | * @access public 96 | * @param array $resultSet 数据集 97 | * @return mixed 98 | */ 99 | protected function resultSetBuild($resultSet) 100 | { 101 | return (new $this->model)->toCollection($resultSet); 102 | } 103 | 104 | protected function getQueryFields($model) 105 | { 106 | $fields = $this->query->getOptions('field'); 107 | return $this->getRelationQueryFields($fields, $model); 108 | } 109 | 110 | protected function getRelationQueryFields($fields, $model) 111 | { 112 | if ($fields) { 113 | 114 | if (is_string($fields)) { 115 | $fields = explode(',', $fields); 116 | } 117 | 118 | foreach ($fields as &$field) { 119 | if (false === strpos($field, '.')) { 120 | $field = $model . '.' . $field; 121 | } 122 | } 123 | } else { 124 | $fields = $model . '.*'; 125 | } 126 | 127 | return $fields; 128 | } 129 | 130 | /** 131 | * 执行基础查询(仅执行一次) 132 | * @access protected 133 | * @return void 134 | */ 135 | protected function baseQuery() 136 | {} 137 | 138 | public function __call($method, $args) 139 | { 140 | if ($this->query) { 141 | // 执行基础查询 142 | $this->baseQuery(); 143 | 144 | $result = call_user_func_array([$this->query, $method], $args); 145 | if ($result instanceof Query) { 146 | return $this; 147 | } else { 148 | $this->baseQuery = false; 149 | return $result; 150 | } 151 | } else { 152 | throw new Exception('method not exists:' . __CLASS__ . '->' . $method); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/process/Utils.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | 10 | namespace think\process; 11 | 12 | class Utils 13 | { 14 | 15 | /** 16 | * 转义字符串 17 | * @param string $argument 18 | * @return string 19 | */ 20 | public static function escapeArgument($argument) 21 | { 22 | 23 | if ('' === $argument) { 24 | return escapeshellarg($argument); 25 | } 26 | $escapedArgument = ''; 27 | $quote = false; 28 | foreach (preg_split('/(")/i', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { 29 | if ('"' === $part) { 30 | $escapedArgument .= '\\"'; 31 | } elseif (self::isSurroundedBy($part, '%')) { 32 | // Avoid environment variable expansion 33 | $escapedArgument .= '^%"' . substr($part, 1, -1) . '"^%'; 34 | } else { 35 | // escape trailing backslash 36 | if ('\\' === substr($part, -1)) { 37 | $part .= '\\'; 38 | } 39 | $quote = true; 40 | $escapedArgument .= $part; 41 | } 42 | } 43 | if ($quote) { 44 | $escapedArgument = '"' . $escapedArgument . '"'; 45 | } 46 | return $escapedArgument; 47 | } 48 | 49 | /** 50 | * 验证并进行规范化Process输入。 51 | * @param string $caller 52 | * @param mixed $input 53 | * @return string 54 | * @throws \InvalidArgumentException 55 | */ 56 | public static function validateInput($caller, $input) 57 | { 58 | if (null !== $input) { 59 | if (is_resource($input)) { 60 | return $input; 61 | } 62 | if (is_scalar($input)) { 63 | return (string) $input; 64 | } 65 | throw new \InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller)); 66 | } 67 | return $input; 68 | } 69 | 70 | private static function isSurroundedBy($arg, $char) 71 | { 72 | return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/process/exception/Failed.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\process\exception; 13 | 14 | use think\Process; 15 | 16 | class Failed extends \RuntimeException 17 | { 18 | 19 | private $process; 20 | 21 | public function __construct(Process $process) 22 | { 23 | if ($process->isSuccessful()) { 24 | throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.'); 25 | } 26 | 27 | $error = sprintf('The command "%s" failed.' . "\nExit Code: %s(%s)", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText()); 28 | 29 | if (!$process->isOutputDisabled()) { 30 | $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", $process->getOutput(), $process->getErrorOutput()); 31 | } 32 | 33 | parent::__construct($error); 34 | 35 | $this->process = $process; 36 | } 37 | 38 | public function getProcess() 39 | { 40 | return $this->process; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/process/exception/Timeout.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\process\exception; 13 | 14 | use think\Process; 15 | 16 | class Timeout extends \RuntimeException 17 | { 18 | 19 | const TYPE_GENERAL = 1; 20 | const TYPE_IDLE = 2; 21 | 22 | private $process; 23 | private $timeoutType; 24 | 25 | public function __construct(Process $process, $timeoutType) 26 | { 27 | $this->process = $process; 28 | $this->timeoutType = $timeoutType; 29 | 30 | parent::__construct(sprintf('The process "%s" exceeded the timeout of %s seconds.', $process->getCommandLine(), $this->getExceededTimeout())); 31 | } 32 | 33 | public function getProcess() 34 | { 35 | return $this->process; 36 | } 37 | 38 | public function isGeneralTimeout() 39 | { 40 | return $this->timeoutType === self::TYPE_GENERAL; 41 | } 42 | 43 | public function isIdleTimeout() 44 | { 45 | return $this->timeoutType === self::TYPE_IDLE; 46 | } 47 | 48 | public function getExceededTimeout() 49 | { 50 | switch ($this->timeoutType) { 51 | case self::TYPE_GENERAL: 52 | return $this->process->getTimeout(); 53 | 54 | case self::TYPE_IDLE: 55 | return $this->process->getIdleTimeout(); 56 | 57 | default: 58 | throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/process/pipes/Pipes.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\process\pipes; 13 | 14 | abstract class Pipes 15 | { 16 | 17 | /** @var array */ 18 | public $pipes = []; 19 | 20 | /** @var string */ 21 | protected $inputBuffer = ''; 22 | /** @var resource|null */ 23 | protected $input; 24 | 25 | /** @var bool */ 26 | private $blocked = true; 27 | 28 | const CHUNK_SIZE = 16384; 29 | 30 | /** 31 | * 返回用于 proc_open 描述符的数组 32 | * @return array 33 | */ 34 | abstract public function getDescriptors(); 35 | 36 | /** 37 | * 返回一个数组的索引由其相关的流,以防这些管道使用的临时文件的文件名。 38 | * @return string[] 39 | */ 40 | abstract public function getFiles(); 41 | 42 | /** 43 | * 文件句柄和管道中读取数据。 44 | * @param bool $blocking 是否使用阻塞调用 45 | * @param bool $close 是否要关闭管道,如果他们已经到达 EOF。 46 | * @return string[] 47 | */ 48 | abstract public function readAndWrite($blocking, $close = false); 49 | 50 | /** 51 | * 返回当前状态如果有打开的文件句柄或管道。 52 | * @return bool 53 | */ 54 | abstract public function areOpen(); 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function close() 60 | { 61 | foreach ($this->pipes as $pipe) { 62 | fclose($pipe); 63 | } 64 | $this->pipes = []; 65 | } 66 | 67 | /** 68 | * 检查系统调用已被中断 69 | * @return bool 70 | */ 71 | protected function hasSystemCallBeenInterrupted() 72 | { 73 | $lastError = error_get_last(); 74 | 75 | return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call'); 76 | } 77 | 78 | protected function unblock() 79 | { 80 | if (!$this->blocked) { 81 | return; 82 | } 83 | 84 | foreach ($this->pipes as $pipe) { 85 | stream_set_blocking($pipe, 0); 86 | } 87 | if (null !== $this->input) { 88 | stream_set_blocking($this->input, 0); 89 | } 90 | 91 | $this->blocked = false; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/response/Json.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\response; 13 | 14 | use think\Response; 15 | 16 | class Json extends Response 17 | { 18 | // 输出参数 19 | protected $options = [ 20 | 'json_encode_param' => JSON_UNESCAPED_UNICODE, 21 | ]; 22 | 23 | protected $contentType = 'application/json'; 24 | 25 | /** 26 | * 处理数据 27 | * @access protected 28 | * @param mixed $data 要处理的数据 29 | * @return mixed 30 | * @throws \Exception 31 | */ 32 | protected function output($data) 33 | { 34 | try { 35 | // 返回JSON数据格式到客户端 包含状态信息 36 | $data = json_encode($data, $this->options['json_encode_param']); 37 | 38 | if ($data === false) { 39 | throw new \InvalidArgumentException(json_last_error_msg()); 40 | } 41 | 42 | return $data; 43 | } catch (\Exception $e) { 44 | if ($e->getPrevious()) { 45 | throw $e->getPrevious(); 46 | } 47 | throw $e; 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/response/Jsonp.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\response; 13 | 14 | use think\Request; 15 | use think\Response; 16 | 17 | class Jsonp extends Response 18 | { 19 | // 输出参数 20 | protected $options = [ 21 | 'var_jsonp_handler' => 'callback', 22 | 'default_jsonp_handler' => 'jsonpReturn', 23 | 'json_encode_param' => JSON_UNESCAPED_UNICODE, 24 | ]; 25 | 26 | protected $contentType = 'application/javascript'; 27 | 28 | /** 29 | * 处理数据 30 | * @access protected 31 | * @param mixed $data 要处理的数据 32 | * @return mixed 33 | * @throws \Exception 34 | */ 35 | protected function output($data) 36 | { 37 | try { 38 | // 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的,故使用Request来获取] 39 | $var_jsonp_handler = Request::instance()->param($this->options['var_jsonp_handler'], ""); 40 | $handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler']; 41 | 42 | $data = json_encode($data, $this->options['json_encode_param']); 43 | 44 | if ($data === false) { 45 | throw new \InvalidArgumentException(json_last_error_msg()); 46 | } 47 | 48 | $data = $handler . '(' . $data . ');'; 49 | return $data; 50 | } catch (\Exception $e) { 51 | if ($e->getPrevious()) { 52 | throw $e->getPrevious(); 53 | } 54 | throw $e; 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/response/Redirect.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\response; 13 | 14 | use think\Request; 15 | use think\Response; 16 | use think\Session; 17 | use think\Url; 18 | 19 | class Redirect extends Response 20 | { 21 | 22 | protected $options = []; 23 | 24 | // URL参数 25 | protected $params = []; 26 | 27 | public function __construct($data = '', $code = 302, array $header = [], array $options = []) 28 | { 29 | parent::__construct($data, $code, $header, $options); 30 | $this->cacheControl('no-cache,must-revalidate'); 31 | } 32 | 33 | /** 34 | * 处理数据 35 | * @access protected 36 | * @param mixed $data 要处理的数据 37 | * @return mixed 38 | */ 39 | protected function output($data) 40 | { 41 | $this->header['Location'] = $this->getTargetUrl(); 42 | return; 43 | } 44 | 45 | /** 46 | * 重定向传值(通过Session) 47 | * @access protected 48 | * @param string|array $name 变量名或者数组 49 | * @param mixed $value 值 50 | * @return $this 51 | */ 52 | public function with($name, $value = null) 53 | { 54 | if (is_array($name)) { 55 | foreach ($name as $key => $val) { 56 | Session::flash($key, $val); 57 | } 58 | } else { 59 | Session::flash($name, $value); 60 | } 61 | return $this; 62 | } 63 | 64 | /** 65 | * 获取跳转地址 66 | * @return string 67 | */ 68 | public function getTargetUrl() 69 | { 70 | if (strpos($this->data, '://') || (0 === strpos($this->data, '/') && empty($this->params))) { 71 | return $this->data; 72 | } else { 73 | return Url::build($this->data, $this->params); 74 | } 75 | } 76 | 77 | public function params($params = []) 78 | { 79 | $this->params = $params; 80 | return $this; 81 | } 82 | 83 | /** 84 | * 记住当前url后跳转 85 | * @return $this 86 | */ 87 | public function remember() 88 | { 89 | Session::set('redirect_url', Request::instance()->url()); 90 | return $this; 91 | } 92 | 93 | /** 94 | * 跳转到上次记住的url 95 | * @return $this 96 | */ 97 | public function restore() 98 | { 99 | if (Session::has('redirect_url')) { 100 | $this->data = Session::get('redirect_url'); 101 | Session::delete('redirect_url'); 102 | } 103 | return $this; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/response/View.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\response; 13 | 14 | use think\Config; 15 | use think\Response; 16 | use think\View as ViewTemplate; 17 | 18 | class View extends Response 19 | { 20 | // 输出参数 21 | protected $options = []; 22 | protected $vars = []; 23 | protected $replace = []; 24 | protected $contentType = 'text/html'; 25 | 26 | /** 27 | * 处理数据 28 | * @access protected 29 | * @param mixed $data 要处理的数据 30 | * @return mixed 31 | */ 32 | protected function output($data) 33 | { 34 | // 渲染模板输出 35 | return ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str')) 36 | ->fetch($data, $this->vars, $this->replace); 37 | } 38 | 39 | /** 40 | * 获取视图变量 41 | * @access public 42 | * @param string $name 模板变量 43 | * @return mixed 44 | */ 45 | public function getVars($name = null) 46 | { 47 | if (is_null($name)) { 48 | return $this->vars; 49 | } else { 50 | return isset($this->vars[$name]) ? $this->vars[$name] : null; 51 | } 52 | } 53 | 54 | /** 55 | * 模板变量赋值 56 | * @access public 57 | * @param mixed $name 变量名 58 | * @param mixed $value 变量值 59 | * @return $this 60 | */ 61 | public function assign($name, $value = '') 62 | { 63 | if (is_array($name)) { 64 | $this->vars = array_merge($this->vars, $name); 65 | return $this; 66 | } else { 67 | $this->vars[$name] = $value; 68 | } 69 | return $this; 70 | } 71 | 72 | /** 73 | * 视图内容替换 74 | * @access public 75 | * @param string|array $content 被替换内容(支持批量替换) 76 | * @param string $replace 替换内容 77 | * @return $this 78 | */ 79 | public function replace($content, $replace = '') 80 | { 81 | if (is_array($content)) { 82 | $this->replace = array_merge($this->replace, $content); 83 | } else { 84 | $this->replace[$content] = $replace; 85 | } 86 | return $this; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/response/Xml.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\response; 13 | 14 | use think\Collection; 15 | use think\Model; 16 | use think\Response; 17 | 18 | class Xml extends Response 19 | { 20 | // 输出参数 21 | protected $options = [ 22 | // 根节点名 23 | 'root_node' => 'think', 24 | // 根节点属性 25 | 'root_attr' => '', 26 | //数字索引的子节点名 27 | 'item_node' => 'item', 28 | // 数字索引子节点key转换的属性名 29 | 'item_key' => 'id', 30 | // 数据编码 31 | 'encoding' => 'utf-8', 32 | ]; 33 | 34 | protected $contentType = 'text/xml'; 35 | 36 | /** 37 | * 处理数据 38 | * @access protected 39 | * @param mixed $data 要处理的数据 40 | * @return mixed 41 | */ 42 | protected function output($data) 43 | { 44 | // XML数据转换 45 | return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']); 46 | } 47 | 48 | /** 49 | * XML编码 50 | * @param mixed $data 数据 51 | * @param string $root 根节点名 52 | * @param string $item 数字索引的子节点名 53 | * @param string $attr 根节点属性 54 | * @param string $id 数字索引子节点key转换的属性名 55 | * @param string $encoding 数据编码 56 | * @return string 57 | */ 58 | protected function xmlEncode($data, $root, $item, $attr, $id, $encoding) 59 | { 60 | if (is_array($attr)) { 61 | $array = []; 62 | foreach ($attr as $key => $value) { 63 | $array[] = "{$key}=\"{$value}\""; 64 | } 65 | $attr = implode(' ', $array); 66 | } 67 | $attr = trim($attr); 68 | $attr = empty($attr) ? '' : " {$attr}"; 69 | $xml = ""; 70 | $xml .= "<{$root}{$attr}>"; 71 | $xml .= $this->dataToXml($data, $item, $id); 72 | $xml .= ""; 73 | return $xml; 74 | } 75 | 76 | /** 77 | * 数据XML编码 78 | * @param mixed $data 数据 79 | * @param string $item 数字索引时的节点名称 80 | * @param string $id 数字索引key转换为的属性名 81 | * @return string 82 | */ 83 | protected function dataToXml($data, $item, $id) 84 | { 85 | $xml = $attr = ''; 86 | 87 | if ($data instanceof Collection || $data instanceof Model) { 88 | $data = $data->toArray(); 89 | } 90 | 91 | foreach ($data as $key => $val) { 92 | if (is_numeric($key)) { 93 | $id && $attr = " {$id}=\"{$key}\""; 94 | $key = $item; 95 | } 96 | $xml .= "<{$key}{$attr}>"; 97 | $xml .= (is_array($val) || is_object($val)) ? $this->dataToXml($val, $item, $id) : $val; 98 | $xml .= ""; 99 | } 100 | return $xml; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/session/driver/Memcache.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\session\driver; 13 | 14 | use SessionHandler; 15 | use think\Exception; 16 | 17 | class Memcache extends SessionHandler 18 | { 19 | protected $handler = null; 20 | protected $config = [ 21 | 'host' => '127.0.0.1', // memcache主机 22 | 'port' => 11211, // memcache端口 23 | 'expire' => 3600, // session有效期 24 | 'timeout' => 0, // 连接超时时间(单位:毫秒) 25 | 'persistent' => true, // 长连接 26 | 'session_name' => '', // memcache key前缀 27 | ]; 28 | 29 | public function __construct($config = []) 30 | { 31 | $this->config = array_merge($this->config, $config); 32 | } 33 | 34 | /** 35 | * 打开Session 36 | * @access public 37 | * @param string $savePath 38 | * @param mixed $sessName 39 | */ 40 | public function open($savePath, $sessName) 41 | { 42 | // 检测php环境 43 | if (!extension_loaded('memcache')) { 44 | throw new Exception('not support:memcache'); 45 | } 46 | $this->handler = new \Memcache; 47 | // 支持集群 48 | $hosts = explode(',', $this->config['host']); 49 | $ports = explode(',', $this->config['port']); 50 | if (empty($ports[0])) { 51 | $ports[0] = 11211; 52 | } 53 | // 建立连接 54 | foreach ((array) $hosts as $i => $host) { 55 | $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; 56 | $this->config['timeout'] > 0 ? 57 | $this->handler->addServer($host, $port, $this->config['persistent'], 1, $this->config['timeout']) : 58 | $this->handler->addServer($host, $port, $this->config['persistent'], 1); 59 | } 60 | return true; 61 | } 62 | 63 | /** 64 | * 关闭Session 65 | * @access public 66 | */ 67 | public function close() 68 | { 69 | $this->gc(ini_get('session.gc_maxlifetime')); 70 | $this->handler->close(); 71 | $this->handler = null; 72 | return true; 73 | } 74 | 75 | /** 76 | * 读取Session 77 | * @access public 78 | * @param string $sessID 79 | */ 80 | public function read($sessID) 81 | { 82 | return (string) $this->handler->get($this->config['session_name'] . $sessID); 83 | } 84 | 85 | /** 86 | * 写入Session 87 | * @access public 88 | * @param string $sessID 89 | * @param String $sessData 90 | * @return bool 91 | */ 92 | public function write($sessID, $sessData) 93 | { 94 | return $this->handler->set($this->config['session_name'] . $sessID, $sessData, 0, $this->config['expire']); 95 | } 96 | 97 | /** 98 | * 删除Session 99 | * @access public 100 | * @param string $sessID 101 | * @return bool 102 | */ 103 | public function destroy($sessID) 104 | { 105 | return $this->handler->delete($this->config['session_name'] . $sessID); 106 | } 107 | 108 | /** 109 | * Session 垃圾回收 110 | * @access public 111 | * @param string $sessMaxLifeTime 112 | * @return true 113 | */ 114 | public function gc($sessMaxLifeTime) 115 | { 116 | return true; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/session/driver/Memcached.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\session\driver; 13 | 14 | use SessionHandler; 15 | use think\Exception; 16 | 17 | class Memcached extends SessionHandler 18 | { 19 | protected $handler = null; 20 | protected $config = [ 21 | 'host' => '127.0.0.1', // memcache主机 22 | 'port' => 11211, // memcache端口 23 | 'expire' => 3600, // session有效期 24 | 'timeout' => 0, // 连接超时时间(单位:毫秒) 25 | 'session_name' => '', // memcache key前缀 26 | 'username' => '', //账号 27 | 'password' => '', //密码 28 | ]; 29 | 30 | public function __construct($config = []) 31 | { 32 | $this->config = array_merge($this->config, $config); 33 | } 34 | 35 | /** 36 | * 打开Session 37 | * @access public 38 | * @param string $savePath 39 | * @param mixed $sessName 40 | */ 41 | public function open($savePath, $sessName) 42 | { 43 | // 检测php环境 44 | if (!extension_loaded('memcached')) { 45 | throw new Exception('not support:memcached'); 46 | } 47 | $this->handler = new \Memcached; 48 | // 设置连接超时时间(单位:毫秒) 49 | if ($this->config['timeout'] > 0) { 50 | $this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->config['timeout']); 51 | } 52 | // 支持集群 53 | $hosts = explode(',', $this->config['host']); 54 | $ports = explode(',', $this->config['port']); 55 | if (empty($ports[0])) { 56 | $ports[0] = 11211; 57 | } 58 | // 建立连接 59 | $servers = []; 60 | foreach ((array) $hosts as $i => $host) { 61 | $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1]; 62 | } 63 | $this->handler->addServers($servers); 64 | if ('' != $this->config['username']) { 65 | $this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); 66 | $this->handler->setSaslAuthData($this->config['username'], $this->config['password']); 67 | } 68 | return true; 69 | } 70 | 71 | /** 72 | * 关闭Session 73 | * @access public 74 | */ 75 | public function close() 76 | { 77 | $this->gc(ini_get('session.gc_maxlifetime')); 78 | $this->handler->quit(); 79 | $this->handler = null; 80 | return true; 81 | } 82 | 83 | /** 84 | * 读取Session 85 | * @access public 86 | * @param string $sessID 87 | */ 88 | public function read($sessID) 89 | { 90 | return (string) $this->handler->get($this->config['session_name'] . $sessID); 91 | } 92 | 93 | /** 94 | * 写入Session 95 | * @access public 96 | * @param string $sessID 97 | * @param String $sessData 98 | * @return bool 99 | */ 100 | public function write($sessID, $sessData) 101 | { 102 | return $this->handler->set($this->config['session_name'] . $sessID, $sessData, $this->config['expire']); 103 | } 104 | 105 | /** 106 | * 删除Session 107 | * @access public 108 | * @param string $sessID 109 | * @return bool 110 | */ 111 | public function destroy($sessID) 112 | { 113 | return $this->handler->delete($this->config['session_name'] . $sessID); 114 | } 115 | 116 | /** 117 | * Session 垃圾回收 118 | * @access public 119 | * @param string $sessMaxLifeTime 120 | * @return true 121 | */ 122 | public function gc($sessMaxLifeTime) 123 | { 124 | return true; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/session/driver/Redis.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\session\driver; 13 | 14 | use SessionHandler; 15 | use think\Exception; 16 | 17 | class Redis extends SessionHandler 18 | { 19 | /** @var \Redis */ 20 | protected $handler = null; 21 | protected $config = [ 22 | 'host' => '127.0.0.1', // redis主机 23 | 'port' => 6379, // redis端口 24 | 'password' => '', // 密码 25 | 'select' => 0, // 操作库 26 | 'expire' => 3600, // 有效期(秒) 27 | 'timeout' => 0, // 超时时间(秒) 28 | 'persistent' => true, // 是否长连接 29 | 'session_name' => '', // sessionkey前缀 30 | ]; 31 | 32 | public function __construct($config = []) 33 | { 34 | $this->config = array_merge($this->config, $config); 35 | } 36 | 37 | /** 38 | * 打开Session 39 | * @access public 40 | * @param string $savePath 41 | * @param mixed $sessName 42 | * @return bool 43 | * @throws Exception 44 | */ 45 | public function open($savePath, $sessName) 46 | { 47 | // 检测php环境 48 | if (!extension_loaded('redis')) { 49 | throw new Exception('not support:redis'); 50 | } 51 | $this->handler = new \Redis; 52 | 53 | // 建立连接 54 | $func = $this->config['persistent'] ? 'pconnect' : 'connect'; 55 | $this->handler->$func($this->config['host'], $this->config['port'], $this->config['timeout']); 56 | 57 | if ('' != $this->config['password']) { 58 | $this->handler->auth($this->config['password']); 59 | } 60 | 61 | if (0 != $this->config['select']) { 62 | $this->handler->select($this->config['select']); 63 | } 64 | 65 | return true; 66 | } 67 | 68 | /** 69 | * 关闭Session 70 | * @access public 71 | */ 72 | public function close() 73 | { 74 | $this->gc(ini_get('session.gc_maxlifetime')); 75 | $this->handler->close(); 76 | $this->handler = null; 77 | return true; 78 | } 79 | 80 | /** 81 | * 读取Session 82 | * @access public 83 | * @param string $sessID 84 | * @return string 85 | */ 86 | public function read($sessID) 87 | { 88 | return (string) $this->handler->get($this->config['session_name'] . $sessID); 89 | } 90 | 91 | /** 92 | * 写入Session 93 | * @access public 94 | * @param string $sessID 95 | * @param String $sessData 96 | * @return bool 97 | */ 98 | public function write($sessID, $sessData) 99 | { 100 | if ($this->config['expire'] > 0) { 101 | return $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData); 102 | } else { 103 | return $this->handler->set($this->config['session_name'] . $sessID, $sessData); 104 | } 105 | } 106 | 107 | /** 108 | * 删除Session 109 | * @access public 110 | * @param string $sessID 111 | * @return bool 112 | */ 113 | public function destroy($sessID) 114 | { 115 | return $this->handler->delete($this->config['session_name'] . $sessID) > 0; 116 | } 117 | 118 | /** 119 | * Session 垃圾回收 120 | * @access public 121 | * @param string $sessMaxLifeTime 122 | * @return bool 123 | */ 124 | public function gc($sessMaxLifeTime) 125 | { 126 | return true; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/thinkphp/library/think/template/driver/File.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think\template\driver; 13 | 14 | use think\Exception; 15 | 16 | class File 17 | { 18 | protected $cacheFile; 19 | 20 | /** 21 | * 写入编译缓存 22 | * @param string $cacheFile 缓存的文件名 23 | * @param string $content 缓存的内容 24 | * @return void|array 25 | */ 26 | public function write($cacheFile, $content) 27 | { 28 | // 检测模板目录 29 | $dir = dirname($cacheFile); 30 | if (!is_dir($dir)) { 31 | mkdir($dir, 0755, true); 32 | } 33 | // 生成模板缓存文件 34 | if (false === file_put_contents($cacheFile, $content)) { 35 | throw new Exception('cache write error:' . $cacheFile, 11602); 36 | } 37 | } 38 | 39 | /** 40 | * 读取编译编译 41 | * @param string $cacheFile 缓存的文件名 42 | * @param array $vars 变量数组 43 | * @return void 44 | */ 45 | public function read($cacheFile, $vars = []) 46 | { 47 | $this->cacheFile = $cacheFile; 48 | if (!empty($vars) && is_array($vars)) { 49 | // 模板阵列变量分解成为独立变量 50 | extract($vars, EXTR_OVERWRITE); 51 | } 52 | //载入模版缓存文件 53 | include $this->cacheFile; 54 | } 55 | 56 | /** 57 | * 检查编译缓存是否有效 58 | * @param string $cacheFile 缓存的文件名 59 | * @param int $cacheTime 缓存时间 60 | * @return boolean 61 | */ 62 | public function check($cacheFile, $cacheTime) 63 | { 64 | // 缓存文件不存在, 直接返回false 65 | if (!file_exists($cacheFile)) { 66 | return false; 67 | } 68 | if (0 != $cacheTime && $_SERVER['REQUEST_TIME'] > filemtime($cacheFile) + $cacheTime) { 69 | // 缓存是否在有效期 70 | return false; 71 | } 72 | return true; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/thinkphp/library/traits/think/Instance.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace traits\think; 13 | 14 | use think\Exception; 15 | 16 | trait Instance 17 | { 18 | /** 19 | * @var null|static 实例对象 20 | */ 21 | protected static $instance = null; 22 | 23 | /** 24 | * 获取示例 25 | * @param array $options 实例配置 26 | * @return static 27 | */ 28 | public static function instance($options = []) 29 | { 30 | if (is_null(self::$instance)) self::$instance = new self($options); 31 | 32 | return self::$instance; 33 | } 34 | 35 | /** 36 | * 静态调用 37 | * @param string $method 调用方法 38 | * @param array $params 调用参数 39 | * @return mixed 40 | * @throws Exception 41 | */ 42 | public static function __callStatic($method, array $params) 43 | { 44 | if (is_null(self::$instance)) self::$instance = new self(); 45 | 46 | $call = substr($method, 1); 47 | 48 | if (0 !== strpos($method, '_') || !is_callable([self::$instance, $call])) { 49 | throw new Exception("method not exists:" . $method); 50 | } 51 | 52 | return call_user_func_array([self::$instance, $call], $params); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/thinkphp/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2020NCOV/ncov-report-mini-program-server/805360007c4a95feba09ff12a6db4dfdd04a1d4e/src/thinkphp/logo.png -------------------------------------------------------------------------------- /src/thinkphp/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/thinkphp/ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ./ 23 | 24 | tests 25 | vendor 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/thinkphp/start.php: -------------------------------------------------------------------------------- 1 | 10 | // +---------------------------------------------------------------------- 11 | 12 | namespace think; 13 | 14 | // ThinkPHP 引导文件 15 | // 1. 加载基础文件 16 | require __DIR__ . '/base.php'; 17 | 18 | // 2. 执行应用 19 | App::run()->send(); 20 | -------------------------------------------------------------------------------- /src/thinkphp/tpl/default_index.tpl: -------------------------------------------------------------------------------- 1 | *{ 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 版本由 七牛云 独家赞助发布 ]
'; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/thinkphp/tpl/dispatch_jump.tpl: -------------------------------------------------------------------------------- 1 | {__NOLAYOUT__} 2 | 3 | 4 | 5 | 6 | 跳转提示 7 | 17 | 18 | 19 |
20 | 21 | 22 |

:)

23 |

24 | 25 | 26 |

:(

27 |

28 | 29 | 30 |

31 |

32 | 页面自动 跳转 等待时间: 33 |

34 |
35 | 48 | 49 | 50 | --------------------------------------------------------------------------------