first commit
This commit is contained in:
52
.devcontainer/Dockerfile
Normal file
52
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,52 @@
|
||||
# Dev Container Dockerfile
|
||||
#
|
||||
# @link https://www.hyperf.io
|
||||
# @document https://hyperf.wiki
|
||||
# @contact group@hyperf.io
|
||||
# @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
|
||||
FROM hyperf/hyperf:8.3-alpine-v3.19-swoole
|
||||
LABEL maintainer="Hyperf Developers <group@hyperf.io>" version="1.0" license="MIT" app.name="Hyperf"
|
||||
|
||||
##
|
||||
# ---------- env settings ----------
|
||||
##
|
||||
# --build-arg timezone=Asia/Shanghai
|
||||
ARG timezone
|
||||
|
||||
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
|
||||
APP_ENV=dev \
|
||||
SCAN_CACHEABLE=(false)
|
||||
|
||||
# update
|
||||
RUN set -ex \
|
||||
# show php version and extensions
|
||||
&& php -v \
|
||||
&& php -m \
|
||||
&& php --ri swoole \
|
||||
# ---------- some config ----------
|
||||
&& cd /etc/php* \
|
||||
# - config PHP
|
||||
&& { \
|
||||
echo "upload_max_filesize=128M"; \
|
||||
echo "post_max_size=128M"; \
|
||||
echo "memory_limit=1G"; \
|
||||
echo "date.timezone=${TIMEZONE}"; \
|
||||
} | tee conf.d/99_overrides.ini \
|
||||
# - config timezone
|
||||
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
|
||||
&& echo "${TIMEZONE}" > /etc/timezone \
|
||||
# ---------- clear works ----------
|
||||
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
|
||||
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
|
||||
|
||||
WORKDIR /opt/www
|
||||
|
||||
# Composer Cache
|
||||
# COPY ./composer.* /opt/www/
|
||||
# RUN composer install --no-dev --no-scripts
|
||||
|
||||
COPY . /opt/www
|
||||
RUN composer install && php bin/hyperf.php
|
||||
|
||||
EXPOSE 9501
|
||||
7
.devcontainer/devcontainer.json
Normal file
7
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"build": {
|
||||
"context": "..",
|
||||
"dockerfile": "./Dockerfile"
|
||||
},
|
||||
"forwardPorts": [9501]
|
||||
}
|
||||
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
||||
**
|
||||
!app/
|
||||
!bin/
|
||||
!config/
|
||||
!composer.*
|
||||
17
.env.example
Normal file
17
.env.example
Normal file
@@ -0,0 +1,17 @@
|
||||
APP_NAME=skeleton
|
||||
APP_ENV=dev
|
||||
|
||||
DB_DRIVER=mysql
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=hyperf
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_COLLATION=utf8mb4_unicode_ci
|
||||
DB_PREFIX=
|
||||
|
||||
REDIS_HOST=localhost
|
||||
REDIS_AUTH=(null)
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB=0
|
||||
54
.github/workflows/Dockerfile
vendored
Normal file
54
.github/workflows/Dockerfile
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
# Default Dockerfile
|
||||
#
|
||||
# @link https://www.hyperf.io
|
||||
# @document https://hyperf.wiki
|
||||
# @contact group@hyperf.io
|
||||
# @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
|
||||
FROM hyperf/hyperf:8.3-alpine-v3.19-swoole
|
||||
LABEL maintainer="Hyperf Developers <group@hyperf.io>" version="1.0" license="MIT" app.name="Hyperf"
|
||||
|
||||
##
|
||||
# ---------- env settings ----------
|
||||
##
|
||||
# --build-arg timezone=Asia/Shanghai
|
||||
ARG timezone
|
||||
|
||||
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
|
||||
APP_ENV=prod \
|
||||
SCAN_CACHEABLE=(true)
|
||||
|
||||
# update
|
||||
RUN set -ex \
|
||||
# show php version and extensions
|
||||
&& php -v \
|
||||
&& php -m \
|
||||
&& php --ri swoole \
|
||||
# ---------- some config ----------
|
||||
&& cd /etc/php* \
|
||||
# - config PHP
|
||||
&& { \
|
||||
echo "upload_max_filesize=128M"; \
|
||||
echo "post_max_size=128M"; \
|
||||
echo "memory_limit=1G"; \
|
||||
echo "date.timezone=${TIMEZONE}"; \
|
||||
} | tee conf.d/99_overrides.ini \
|
||||
# - config timezone
|
||||
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
|
||||
&& echo "${TIMEZONE}" > /etc/timezone \
|
||||
# ---------- clear works ----------
|
||||
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
|
||||
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
|
||||
|
||||
WORKDIR /opt/www
|
||||
|
||||
# Composer Cache
|
||||
# COPY ./composer.* /opt/www/
|
||||
# RUN composer install --no-dev --no-scripts
|
||||
|
||||
COPY . /opt/www
|
||||
RUN print "\n" | composer install -o && php bin/hyperf.php
|
||||
|
||||
EXPOSE 9501
|
||||
|
||||
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]
|
||||
12
.github/workflows/build.yml
vendored
Normal file
12
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: Build Docker
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: cp -rf .github/workflows/Dockerfile . && docker build -t hyperf .
|
||||
25
.github/workflows/release.yml
vendored
Normal file
25
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
on:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
name: Release
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
.buildpath
|
||||
.settings/
|
||||
.project
|
||||
*.patch
|
||||
.idea/
|
||||
.git/
|
||||
runtime/
|
||||
vendor/
|
||||
.phpintel/
|
||||
.env
|
||||
.DS_Store
|
||||
.phpunit*
|
||||
*.cache
|
||||
.vscode/
|
||||
/phpstan.neon
|
||||
/phpunit.xml
|
||||
/composer.lock
|
||||
57
.gitlab-ci.yml
Normal file
57
.gitlab-ci.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
# usermod -aG docker gitlab-runner
|
||||
|
||||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
PROJECT_NAME: hyperf
|
||||
REGISTRY_URL: registry-docker.org
|
||||
|
||||
build_test_docker:
|
||||
stage: build
|
||||
before_script:
|
||||
# - git submodule sync --recursive
|
||||
# - git submodule update --init --recursive
|
||||
script:
|
||||
- docker build . -t $PROJECT_NAME
|
||||
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:test
|
||||
- docker push $REGISTRY_URL/$PROJECT_NAME:test
|
||||
only:
|
||||
- test
|
||||
tags:
|
||||
- builder
|
||||
|
||||
deploy_test_docker:
|
||||
stage: deploy
|
||||
script:
|
||||
- docker stack deploy -c deploy.test.yml --with-registry-auth $PROJECT_NAME
|
||||
only:
|
||||
- test
|
||||
tags:
|
||||
- test
|
||||
|
||||
build_docker:
|
||||
stage: build
|
||||
before_script:
|
||||
# - git submodule sync --recursive
|
||||
# - git submodule update --init --recursive
|
||||
script:
|
||||
- docker build . -t $PROJECT_NAME
|
||||
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME
|
||||
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:latest
|
||||
- docker push $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME
|
||||
- docker push $REGISTRY_URL/$PROJECT_NAME:latest
|
||||
only:
|
||||
- tags
|
||||
tags:
|
||||
- builder
|
||||
|
||||
deploy_docker:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo SUCCESS
|
||||
only:
|
||||
- tags
|
||||
tags:
|
||||
- builder
|
||||
106
.php-cs-fixer.php
Normal file
106
.php-cs-fixer.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
$header = <<<'EOF'
|
||||
This file is part of Hyperf.
|
||||
|
||||
@link https://www.hyperf.io
|
||||
@document https://hyperf.wiki
|
||||
@contact group@hyperf.io
|
||||
@license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
EOF;
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'@Symfony' => true,
|
||||
'@DoctrineAnnotation' => true,
|
||||
'@PhpCsFixer' => true,
|
||||
'header_comment' => [
|
||||
'comment_type' => 'PHPDoc',
|
||||
'header' => $header,
|
||||
'separate' => 'none',
|
||||
'location' => 'after_declare_strict',
|
||||
],
|
||||
'array_syntax' => [
|
||||
'syntax' => 'short',
|
||||
],
|
||||
'list_syntax' => [
|
||||
'syntax' => 'short',
|
||||
],
|
||||
'concat_space' => [
|
||||
'spacing' => 'one',
|
||||
],
|
||||
'global_namespace_import' => [
|
||||
'import_classes' => true,
|
||||
'import_constants' => true,
|
||||
'import_functions' => null,
|
||||
],
|
||||
'blank_line_before_statement' => [
|
||||
'statements' => [
|
||||
'declare',
|
||||
],
|
||||
],
|
||||
'general_phpdoc_annotation_remove' => [
|
||||
'annotations' => [
|
||||
'author',
|
||||
],
|
||||
],
|
||||
'ordered_imports' => [
|
||||
'imports_order' => [
|
||||
'class', 'function', 'const',
|
||||
],
|
||||
'sort_algorithm' => 'alpha',
|
||||
],
|
||||
'single_line_comment_style' => [
|
||||
'comment_types' => [
|
||||
],
|
||||
],
|
||||
'yoda_style' => [
|
||||
'always_move_variable' => false,
|
||||
'equal' => false,
|
||||
'identical' => false,
|
||||
],
|
||||
'phpdoc_align' => [
|
||||
'align' => 'left',
|
||||
],
|
||||
'multiline_whitespace_before_semicolons' => [
|
||||
'strategy' => 'no_multi_line',
|
||||
],
|
||||
'constant_case' => [
|
||||
'case' => 'lower',
|
||||
],
|
||||
'class_attributes_separation' => true,
|
||||
'combine_consecutive_unsets' => true,
|
||||
'declare_strict_types' => true,
|
||||
'linebreak_after_opening_tag' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_unused_imports' => true,
|
||||
'not_operator_with_successor_space' => true,
|
||||
'not_operator_with_space' => false,
|
||||
'ordered_class_elements' => true,
|
||||
'php_unit_strict' => false,
|
||||
'phpdoc_separation' => false,
|
||||
'single_quote' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'multiline_comment_opening_closing' => true,
|
||||
'single_line_empty_body' => false,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->exclude('public')
|
||||
->exclude('runtime')
|
||||
->exclude('vendor')
|
||||
->in(__DIR__)
|
||||
)
|
||||
->setUsingCache(false);
|
||||
12
.phpstorm.meta.php
Normal file
12
.phpstorm.meta.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace PHPSTORM_META {
|
||||
// Reflect
|
||||
override(\Psr\Container\ContainerInterface::get(0), map(['' => '@']));
|
||||
override(\Hyperf\Context\Context::get(0), map(['' => '@']));
|
||||
override(\make(0), map(['' => '@']));
|
||||
override(\di(0), map(['' => '@']));
|
||||
override(\Hyperf\Support\make(0), map(['' => '@']));
|
||||
override(\Hyperf\Support\optional(0), type(0));
|
||||
override(\Hyperf\Tappable\tap(0), type(0));
|
||||
}
|
||||
63
BLADE.README.md
Normal file
63
BLADE.README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Introduction
|
||||
|
||||
This is a skeleton application using the Hyperf framework. This application is meant to be used as a starting place for those looking to get their feet wet with Hyperf Framework.
|
||||
|
||||
# Requirements
|
||||
|
||||
Hyperf has some requirements for the system environment, it can only run under Linux and Mac environment, but due to the development of Docker virtualization technology, Docker for Windows can also be used as the running environment under Windows.
|
||||
|
||||
The various versions of Dockerfile have been prepared for you in the [hyperf/hyperf-docker](https://github.com/hyperf/hyperf-docker) project, or directly based on the already built [hyperf/hyperf](https://hub.docker.com/r/hyperf/hyperf) Image to run.
|
||||
|
||||
When you don't want to use Docker as the basis for your running environment, you need to make sure that your operating environment meets the following requirements:
|
||||
|
||||
- PHP >= 8.1
|
||||
- Any of the following network engines
|
||||
- Swoole PHP extension >= 5.0,with `swoole.use_shortname` set to `Off` in your `php.ini`
|
||||
- Swow PHP extension >= 1.3
|
||||
- JSON PHP extension
|
||||
- Pcntl PHP extension
|
||||
- OpenSSL PHP extension (If you need to use the HTTPS)
|
||||
- PDO PHP extension (If you need to use the MySQL Client)
|
||||
- Redis PHP extension (If you need to use the Redis Client)
|
||||
- Protobuf PHP extension (If you need to use the gRPC Server or Client)
|
||||
|
||||
# Installation using Composer
|
||||
|
||||
The easiest way to create a new Hyperf project is to use [Composer](https://getcomposer.org/). If you don't have it already installed, then please install as per [the documentation](https://getcomposer.org/download/).
|
||||
|
||||
To create your new Hyperf project:
|
||||
|
||||
```bash
|
||||
composer create-project hyperf/hyperf-skeleton path/to/install
|
||||
```
|
||||
|
||||
If your development environment is based on Docker you can use the official Composer image to create a new Hyperf project:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v $(pwd):/app composer create-project --ignore-platform-reqs hyperf/hyperf-skeleton path/to/install
|
||||
```
|
||||
|
||||
# Getting started
|
||||
|
||||
Once installed, you can run the server immediately using the command below.
|
||||
|
||||
```bash
|
||||
cd path/to/install
|
||||
php bin/hyperf.php start
|
||||
```
|
||||
|
||||
Or if in a Docker based environment you can use the `docker-compose.yml` provided by the template:
|
||||
|
||||
```bash
|
||||
cd path/to/install
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
This will start the cli-server on port `9501`, and bind it to all network interfaces. You can then visit the site at `http://localhost:9501/` which will bring up Hyperf default home page.
|
||||
|
||||
## Hints
|
||||
|
||||
- A nice tip is to rename `hyperf-skeleton` of files like `composer.json` and `docker-compose.yml` to your actual project name.
|
||||
- Take a look at `config/routes.php` and `app/Controller/IndexController.php` to see an example of a HTTP entrypoint.
|
||||
|
||||
**Remember:** you can always replace the contents of this README.md file to something that fits your project description.
|
||||
54
Dockerfile
Normal file
54
Dockerfile
Normal file
@@ -0,0 +1,54 @@
|
||||
# Default Dockerfile
|
||||
#
|
||||
# @link https://www.hyperf.io
|
||||
# @document https://hyperf.wiki
|
||||
# @contact group@hyperf.io
|
||||
# @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
|
||||
FROM hyperf/hyperf:8.3-alpine-v3.19-swoole
|
||||
LABEL maintainer="Hyperf Developers <group@hyperf.io>" version="1.0" license="MIT" app.name="Hyperf"
|
||||
|
||||
##
|
||||
# ---------- env settings ----------
|
||||
##
|
||||
# --build-arg timezone=Asia/Shanghai
|
||||
ARG timezone
|
||||
|
||||
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
|
||||
APP_ENV=prod \
|
||||
SCAN_CACHEABLE=(true)
|
||||
|
||||
# update
|
||||
RUN set -ex \
|
||||
# show php version and extensions
|
||||
&& php -v \
|
||||
&& php -m \
|
||||
&& php --ri swoole \
|
||||
# ---------- some config ----------
|
||||
&& cd /etc/php* \
|
||||
# - config PHP
|
||||
&& { \
|
||||
echo "upload_max_filesize=128M"; \
|
||||
echo "post_max_size=128M"; \
|
||||
echo "memory_limit=1G"; \
|
||||
echo "date.timezone=${TIMEZONE}"; \
|
||||
} | tee conf.d/99_overrides.ini \
|
||||
# - config timezone
|
||||
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
|
||||
&& echo "${TIMEZONE}" > /etc/timezone \
|
||||
# ---------- clear works ----------
|
||||
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
|
||||
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
|
||||
|
||||
WORKDIR /opt/www
|
||||
|
||||
# Composer Cache
|
||||
# COPY ./composer.* /opt/www/
|
||||
# RUN composer install --no-dev --no-scripts
|
||||
|
||||
COPY . /opt/www
|
||||
RUN composer install --no-dev -o && php bin/hyperf.php
|
||||
|
||||
EXPOSE 9501
|
||||
|
||||
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Hyperf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
79
README.md
Normal file
79
README.md
Normal file
@@ -0,0 +1,79 @@
|
||||
## 仓库
|
||||
|
||||
- [hhl_hyperf_service](https://codeup.aliyun.com/67039465d8d1ada68263f984/hhl/rewrite/hyperf_service.git) - git远程仓库地址
|
||||
|
||||
## 特性
|
||||
|
||||
- **最新技术栈**:使用 PHP8.3/hyperf3.1/swoole5.1.4 等后端前沿技术开发
|
||||
|
||||
## 文档
|
||||
|
||||
[文档地址 Github](https://hyperf.wiki/3.1/)
|
||||
|
||||
## 前序准备
|
||||
|
||||
- [php8.3](https://www.php.net/) 和 [git](https://git-scm.com/) - 项目开发环境
|
||||
- [swoole](https://www.swoole.com/) - 熟悉 swoole 特性
|
||||
- [php8.3](https://www.php.net/) - 熟悉 php 基础语法
|
||||
- [hyperf](https://hyperf.wiki/3.1/) - 熟悉 `hyperf` 基本语法
|
||||
|
||||
## 安装和使用
|
||||
|
||||
- 获取代码
|
||||
|
||||
```bash
|
||||
git clone https://codeup.aliyun.com/67039465d8d1ada68263f984/hhl/rewrite/hyperf_service.git
|
||||
```
|
||||
|
||||
- vendor
|
||||
|
||||
```bash
|
||||
composer install
|
||||
```
|
||||
|
||||
- 运行
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
|
||||
vim .env
|
||||
|
||||
php bin/hyperf.php start
|
||||
```
|
||||
|
||||
- command 函数
|
||||
```bash
|
||||
#框架自有
|
||||
php bin/hyperf.php gen:controller LoginController
|
||||
php bin/hyperf.php gen:model UserModel
|
||||
php bin/hyperf.php gen:request LoginRequest
|
||||
php bin/hyperf.php gen:command TestCommand
|
||||
php bin/hyperf.php gen:job TestJob
|
||||
php bin/hyperf.php gen:listener TestListener
|
||||
php bin/hyperf.php gen:middleware AuthMiddleware
|
||||
php bin/hyperf.php gen:amqp-consumer DemoConsumer
|
||||
php bin/hyperf.php gen:amqp-producer DemoProducer
|
||||
|
||||
#新增命令
|
||||
php bin/hyperf.php gen:service LoginService
|
||||
php bin/hyperf.php gen:cron OssTask
|
||||
php bin/hyperf.php gen:event TestEvent
|
||||
```
|
||||
|
||||
## Git 贡献提交规范
|
||||
|
||||
- `feat` 新功能
|
||||
- `fix` 修补 bug
|
||||
- `docs` 文档
|
||||
- `style` 格式、样式(不影响代码运行的变动)
|
||||
- `refactor` 重构(即不是新增功能,也不是修改 BUG 的代码)
|
||||
- `perf` 优化相关,比如提升性能、体验
|
||||
- `test` 添加测试
|
||||
- `build` 编译相关的修改,对项目构建或者依赖的改动
|
||||
- `ci` 持续集成修改
|
||||
- `chore` 构建过程或辅助工具的变动
|
||||
- `revert` 回滚到上一个版本
|
||||
- `workflow` 工作流改进
|
||||
- `mod` 不确定分类的修改
|
||||
- `wip` 开发中
|
||||
- `types` 类型
|
||||
25
app/Constants/ErrorCode.php
Normal file
25
app/Constants/ErrorCode.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Constants;
|
||||
|
||||
use Hyperf\Constants\AbstractConstants;
|
||||
use Hyperf\Constants\Annotation\Constants;
|
||||
|
||||
#[Constants]
|
||||
class ErrorCode extends AbstractConstants
|
||||
{
|
||||
/**
|
||||
* @Message("Server Error!")
|
||||
*/
|
||||
public const SERVER_ERROR = 500;
|
||||
}
|
||||
30
app/Controller/AbstractController.php
Normal file
30
app/Controller/AbstractController.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
use Hyperf\HttpServer\Contract\ResponseInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
abstract class AbstractController
|
||||
{
|
||||
#[Inject]
|
||||
protected ContainerInterface $container;
|
||||
|
||||
#[Inject]
|
||||
protected RequestInterface $request;
|
||||
|
||||
#[Inject]
|
||||
protected ResponseInterface $response;
|
||||
}
|
||||
27
app/Controller/IndexController.php
Normal file
27
app/Controller/IndexController.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
class IndexController extends AbstractController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$user = $this->request->input('user', 'Hyperf');
|
||||
$method = $this->request->getMethod();
|
||||
|
||||
return [
|
||||
'method' => $method,
|
||||
'message' => "Hello {$user}.",
|
||||
];
|
||||
}
|
||||
}
|
||||
29
app/Exception/BusinessException.php
Normal file
29
app/Exception/BusinessException.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Exception;
|
||||
|
||||
use App\Constants\ErrorCode;
|
||||
use Hyperf\Server\Exception\ServerException;
|
||||
use Throwable;
|
||||
|
||||
class BusinessException extends ServerException
|
||||
{
|
||||
public function __construct(int $code = 0, string $message = null, Throwable $previous = null)
|
||||
{
|
||||
if (is_null($message)) {
|
||||
$message = ErrorCode::getMessage($code);
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
38
app/Exception/Handler/AppExceptionHandler.php
Normal file
38
app/Exception/Handler/AppExceptionHandler.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Exception\Handler;
|
||||
|
||||
use Hyperf\Contract\StdoutLoggerInterface;
|
||||
use Hyperf\ExceptionHandler\ExceptionHandler;
|
||||
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Throwable;
|
||||
|
||||
class AppExceptionHandler extends ExceptionHandler
|
||||
{
|
||||
public function __construct(protected StdoutLoggerInterface $logger)
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(Throwable $throwable, ResponseInterface $response)
|
||||
{
|
||||
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
|
||||
$this->logger->error($throwable->getTraceAsString());
|
||||
return $response->withHeader('Server', 'Hyperf')->withStatus(500)->withBody(new SwooleStream('Internal Server Error.'));
|
||||
}
|
||||
|
||||
public function isValid(Throwable $throwable): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
66
app/Listener/DbQueryExecutedListener.php
Normal file
66
app/Listener/DbQueryExecutedListener.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Collection\Arr;
|
||||
use Hyperf\Database\Events\QueryExecuted;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
#[Listener]
|
||||
class DbQueryExecutedListener implements ListenerInterface
|
||||
{
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->logger = $container->get(LoggerFactory::class)->get('sql');
|
||||
}
|
||||
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
QueryExecuted::class,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param QueryExecuted $event
|
||||
*/
|
||||
public function process(object $event): void
|
||||
{
|
||||
if ($event instanceof QueryExecuted) {
|
||||
$sql = $event->sql;
|
||||
if (! Arr::isAssoc($event->bindings)) {
|
||||
$position = 0;
|
||||
foreach ($event->bindings as $value) {
|
||||
$position = strpos($sql, '?', $position);
|
||||
if ($position === false) {
|
||||
break;
|
||||
}
|
||||
$value = "'{$value}'";
|
||||
$sql = substr_replace($sql, $value, $position, 1);
|
||||
$position += strlen($value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info(sprintf('[%s] %s', $event->time, $sql));
|
||||
}
|
||||
}
|
||||
}
|
||||
35
app/Listener/ResumeExitCoordinatorListener.php
Normal file
35
app/Listener/ResumeExitCoordinatorListener.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Command\Event\AfterExecute;
|
||||
use Hyperf\Coordinator\Constants;
|
||||
use Hyperf\Coordinator\CoordinatorManager;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
|
||||
#[Listener]
|
||||
class ResumeExitCoordinatorListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
AfterExecute::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event): void
|
||||
{
|
||||
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
|
||||
}
|
||||
}
|
||||
19
app/Model/Model.php
Normal file
19
app/Model/Model.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model as BaseModel;
|
||||
|
||||
abstract class Model extends BaseModel
|
||||
{
|
||||
}
|
||||
25
bin/hyperf.php
Normal file
25
bin/hyperf.php
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 'on');
|
||||
ini_set('display_startup_errors', 'on');
|
||||
ini_set('memory_limit', '1G');
|
||||
|
||||
error_reporting(E_ALL);
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
|
||||
|
||||
require BASE_PATH . '/vendor/autoload.php';
|
||||
|
||||
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', Hyperf\Engine\DefaultOption::hookFlags());
|
||||
|
||||
// Self-called anonymous function that creates its own scope and keep the global namespace clean.
|
||||
(function () {
|
||||
Hyperf\Di\ClassLoader::init();
|
||||
/** @var Psr\Container\ContainerInterface $container */
|
||||
$container = require BASE_PATH . '/config/container.php';
|
||||
|
||||
$application = $container->get(Hyperf\Contract\ApplicationInterface::class);
|
||||
$application->run();
|
||||
})();
|
||||
83
composer.json
Normal file
83
composer.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"name": "hyperf/hyperf-skeleton",
|
||||
"type": "project",
|
||||
"keywords": [
|
||||
"php",
|
||||
"swoole",
|
||||
"framework",
|
||||
"hyperf",
|
||||
"microservice",
|
||||
"middleware"
|
||||
],
|
||||
"description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.",
|
||||
"license": "Apache-2.0",
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"hyperf/amqp": "~3.1.0",
|
||||
"hyperf/cache": "~3.1.0",
|
||||
"hyperf/command": "~3.1.0",
|
||||
"hyperf/config": "~3.1.0",
|
||||
"hyperf/constants": "~3.1.0",
|
||||
"hyperf/crontab": "^3.1",
|
||||
"hyperf/database": "~3.1.0",
|
||||
"hyperf/db-connection": "~3.1.0",
|
||||
"hyperf/engine": "^2.10",
|
||||
"hyperf/framework": "~3.1.0",
|
||||
"hyperf/guzzle": "~3.1.0",
|
||||
"hyperf/http-server": "~3.1.0",
|
||||
"hyperf/logger": "~3.1.0",
|
||||
"hyperf/memory": "~3.1.0",
|
||||
"hyperf/paginator": "^3.1",
|
||||
"hyperf/process": "~3.1.0",
|
||||
"hyperf/redis": "~3.1.0",
|
||||
"hyperf/validation": "^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.0",
|
||||
"hyperf/devtool": "~3.1.0",
|
||||
"hyperf/testing": "~3.1.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"swoole/ide-helper": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-openssl": "Required to use HTTPS.",
|
||||
"ext-json": "Required to use JSON.",
|
||||
"ext-pdo": "Required to use MySQL Client.",
|
||||
"ext-pdo_mysql": "Required to use MySQL Client.",
|
||||
"ext-redis": "Required to use Redis Client."
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "app/"
|
||||
},
|
||||
"files": []
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"HyperfTest\\": "./test/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": [],
|
||||
"scripts": {
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
"post-autoload-dump": [
|
||||
"rm -rf runtime/container"
|
||||
],
|
||||
"test": "co-phpunit --prepend test/bootstrap.php --colors=always",
|
||||
"cs-fix": "php-cs-fixer fix $1",
|
||||
"analyse": "phpstan analyse --memory-limit 300M",
|
||||
"start": [
|
||||
"Composer\\Config::disableProcessTimeout",
|
||||
"php ./bin/hyperf.php start"
|
||||
]
|
||||
}
|
||||
}
|
||||
42
config/autoload/amqp.php
Normal file
42
config/autoload/amqp.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
use function Hyperf\Support\env;
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'host' => env('AMQP_HOST', 'localhost'),
|
||||
'port' => (int) env('AMQP_PORT', 5672),
|
||||
'user' => env('AMQP_USER', 'guest'),
|
||||
'password' => env('AMQP_PASSWORD', 'guest'),
|
||||
'vhost' => env('AMQP_VHOST', '/'),
|
||||
'concurrent' => [
|
||||
'limit' => 1,
|
||||
],
|
||||
'pool' => [
|
||||
'connections' => 2,
|
||||
],
|
||||
'params' => [
|
||||
'insist' => false,
|
||||
'login_method' => 'AMQPLAIN',
|
||||
'login_response' => null,
|
||||
'locale' => 'en_US',
|
||||
'connection_timeout' => 3,
|
||||
'read_write_timeout' => 6,
|
||||
'context' => null,
|
||||
'keepalive' => true,
|
||||
'heartbeat' => 3,
|
||||
'channel_rpc_timeout' => 0.0,
|
||||
'close_on_destruct' => false,
|
||||
'max_idle_channels' => 10,
|
||||
],
|
||||
],
|
||||
];
|
||||
21
config/autoload/annotations.php
Normal file
21
config/autoload/annotations.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'scan' => [
|
||||
'paths' => [
|
||||
BASE_PATH . '/app',
|
||||
],
|
||||
'ignore_annotations' => [
|
||||
'mixin',
|
||||
],
|
||||
],
|
||||
];
|
||||
13
config/autoload/aspects.php
Normal file
13
config/autoload/aspects.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
];
|
||||
19
config/autoload/cache.php
Normal file
19
config/autoload/cache.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'default' => [
|
||||
'driver' => Hyperf\Cache\Driver\RedisDriver::class,
|
||||
'packer' => Hyperf\Codec\Packer\PhpSerializerPacker::class,
|
||||
'prefix' => 'c:',
|
||||
'skip_cache_results' => [],
|
||||
],
|
||||
];
|
||||
13
config/autoload/commands.php
Normal file
13
config/autoload/commands.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
];
|
||||
41
config/autoload/databases.php
Normal file
41
config/autoload/databases.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
use function Hyperf\Support\env;
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'driver' => env('DB_DRIVER', 'mysql'),
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
'database' => env('DB_DATABASE', 'hyperf'),
|
||||
'port' => env('DB_PORT', 3306),
|
||||
'username' => env('DB_USERNAME', 'root'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => env('DB_CHARSET', 'utf8'),
|
||||
'collation' => env('DB_COLLATION', 'utf8_unicode_ci'),
|
||||
'prefix' => env('DB_PREFIX', ''),
|
||||
'pool' => [
|
||||
'min_connections' => 1,
|
||||
'max_connections' => 10,
|
||||
'connect_timeout' => 10.0,
|
||||
'wait_timeout' => 3.0,
|
||||
'heartbeat' => -1,
|
||||
'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60),
|
||||
],
|
||||
'commands' => [
|
||||
'gen:model' => [
|
||||
'path' => 'app/Model',
|
||||
'force_casts' => true,
|
||||
'inheritance' => 'Model',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
13
config/autoload/dependencies.php
Normal file
13
config/autoload/dependencies.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
];
|
||||
44
config/autoload/devtool.php
Normal file
44
config/autoload/devtool.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'generator' => [
|
||||
'amqp' => [
|
||||
'consumer' => [
|
||||
'namespace' => 'App\\Amqp\\Consumer',
|
||||
],
|
||||
'producer' => [
|
||||
'namespace' => 'App\\Amqp\\Producer',
|
||||
],
|
||||
],
|
||||
'aspect' => [
|
||||
'namespace' => 'App\\Aspect',
|
||||
],
|
||||
'command' => [
|
||||
'namespace' => 'App\\Command',
|
||||
],
|
||||
'controller' => [
|
||||
'namespace' => 'App\\Controller',
|
||||
],
|
||||
'job' => [
|
||||
'namespace' => 'App\\Job',
|
||||
],
|
||||
'listener' => [
|
||||
'namespace' => 'App\\Listener',
|
||||
],
|
||||
'middleware' => [
|
||||
'namespace' => 'App\\Middleware',
|
||||
],
|
||||
'Process' => [
|
||||
'namespace' => 'App\\Processes',
|
||||
],
|
||||
],
|
||||
];
|
||||
19
config/autoload/exceptions.php
Normal file
19
config/autoload/exceptions.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'handler' => [
|
||||
'http' => [
|
||||
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
|
||||
App\Exception\Handler\AppExceptionHandler::class,
|
||||
],
|
||||
],
|
||||
];
|
||||
15
config/autoload/listeners.php
Normal file
15
config/autoload/listeners.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler::class,
|
||||
Hyperf\Command\Listener\FailToHandleListener::class,
|
||||
];
|
||||
30
config/autoload/logger.php
Normal file
30
config/autoload/logger.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'default' => [
|
||||
'handler' => [
|
||||
'class' => Monolog\Handler\StreamHandler::class,
|
||||
'constructor' => [
|
||||
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
|
||||
'level' => Monolog\Logger::DEBUG,
|
||||
],
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => Monolog\Formatter\LineFormatter::class,
|
||||
'constructor' => [
|
||||
'format' => null,
|
||||
'dateFormat' => 'Y-m-d H:i:s',
|
||||
'allowInlineLineBreaks' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
15
config/autoload/middlewares.php
Normal file
15
config/autoload/middlewares.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'http' => [
|
||||
],
|
||||
];
|
||||
13
config/autoload/processes.php
Normal file
13
config/autoload/processes.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
];
|
||||
29
config/autoload/redis.php
Normal file
29
config/autoload/redis.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
use function Hyperf\Support\env;
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'host' => env('REDIS_HOST', 'localhost'),
|
||||
'auth' => env('REDIS_AUTH', null),
|
||||
'port' => (int) env('REDIS_PORT', 6379),
|
||||
'db' => (int) env('REDIS_DB', 0),
|
||||
'pool' => [
|
||||
'min_connections' => 1,
|
||||
'max_connections' => 10,
|
||||
'connect_timeout' => 10.0,
|
||||
'wait_timeout' => 3.0,
|
||||
'heartbeat' => -1,
|
||||
'max_idle_time' => (float) env('REDIS_MAX_IDLE_TIME', 60),
|
||||
],
|
||||
],
|
||||
];
|
||||
50
config/autoload/server.php
Normal file
50
config/autoload/server.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
use Hyperf\Server\Event;
|
||||
use Hyperf\Server\Server;
|
||||
use Swoole\Constant;
|
||||
|
||||
return [
|
||||
'mode' => SWOOLE_PROCESS,
|
||||
'servers' => [
|
||||
[
|
||||
'name' => 'http',
|
||||
'type' => Server::SERVER_HTTP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9501,
|
||||
'sock_type' => SWOOLE_SOCK_TCP,
|
||||
'callbacks' => [
|
||||
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
|
||||
],
|
||||
'options' => [
|
||||
// Whether to enable request lifecycle event
|
||||
'enable_request_lifecycle' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
'settings' => [
|
||||
Constant::OPTION_ENABLE_COROUTINE => true,
|
||||
Constant::OPTION_WORKER_NUM => swoole_cpu_num(),
|
||||
Constant::OPTION_PID_FILE => BASE_PATH . '/runtime/hyperf.pid',
|
||||
Constant::OPTION_OPEN_TCP_NODELAY => true,
|
||||
Constant::OPTION_MAX_COROUTINE => 100000,
|
||||
Constant::OPTION_OPEN_HTTP2_PROTOCOL => true,
|
||||
Constant::OPTION_MAX_REQUEST => 100000,
|
||||
Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024,
|
||||
Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024,
|
||||
],
|
||||
'callbacks' => [
|
||||
Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
|
||||
Event::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
|
||||
Event::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
|
||||
],
|
||||
];
|
||||
16
config/autoload/translation.php
Normal file
16
config/autoload/translation.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'locale' => 'zh_CN',
|
||||
'fallback_locale' => 'en',
|
||||
'path' => BASE_PATH . '/storage/languages',
|
||||
];
|
||||
33
config/config.php
Normal file
33
config/config.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
use Hyperf\Contract\StdoutLoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
use function Hyperf\Support\env;
|
||||
|
||||
return [
|
||||
'app_name' => env('APP_NAME', 'skeleton'),
|
||||
'app_env' => env('APP_ENV', 'dev'),
|
||||
'scan_cacheable' => env('SCAN_CACHEABLE', false),
|
||||
StdoutLoggerInterface::class => [
|
||||
'log_level' => [
|
||||
LogLevel::ALERT,
|
||||
LogLevel::CRITICAL,
|
||||
LogLevel::DEBUG,
|
||||
LogLevel::EMERGENCY,
|
||||
LogLevel::ERROR,
|
||||
LogLevel::INFO,
|
||||
LogLevel::NOTICE,
|
||||
LogLevel::WARNING,
|
||||
],
|
||||
],
|
||||
];
|
||||
21
config/container.php
Normal file
21
config/container.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Initialize a dependency injection container that implemented PSR-11 and return the container.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
use Hyperf\Context\ApplicationContext;
|
||||
use Hyperf\Di\Container;
|
||||
use Hyperf\Di\Definition\DefinitionSourceFactory;
|
||||
|
||||
$container = new Container((new DefinitionSourceFactory())());
|
||||
|
||||
return ApplicationContext::setContainer($container);
|
||||
18
config/routes.php
Normal file
18
config/routes.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
use Hyperf\HttpServer\Router\Router;
|
||||
|
||||
Router::addRoute(['GET', 'POST', 'HEAD'], '/', 'App\Controller\IndexController@index');
|
||||
|
||||
Router::get('/favicon.ico', function () {
|
||||
return '';
|
||||
});
|
||||
30
deploy.test.yml
Normal file
30
deploy.test.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
version: '3.7'
|
||||
services:
|
||||
hyperf:
|
||||
image: $REGISTRY_URL/$PROJECT_NAME:test
|
||||
environment:
|
||||
- "APP_PROJECT=hyperf"
|
||||
- "APP_ENV=testing"
|
||||
ports:
|
||||
- "9501:9501"
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 5
|
||||
update_config:
|
||||
parallelism: 2
|
||||
delay: 5s
|
||||
order: start-first
|
||||
networks:
|
||||
- hyperf_net
|
||||
configs:
|
||||
- source: hyperf_v1.0
|
||||
target: /opt/www/.env
|
||||
configs:
|
||||
hyperf_v1.0:
|
||||
external: true
|
||||
networks:
|
||||
hyperf_net:
|
||||
external: true
|
||||
18
docker-compose.yml
Normal file
18
docker-compose.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
version: '3'
|
||||
services:
|
||||
hyperf-skeleton:
|
||||
container_name: hyperf-skeleton
|
||||
image: hyperf-skeleton
|
||||
build:
|
||||
context: .
|
||||
volumes:
|
||||
- ./:/opt/www
|
||||
ports:
|
||||
- 9501:9501
|
||||
environment:
|
||||
- APP_ENV=dev
|
||||
- SCAN_CACHEABLE=false
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: hyperf-skeleton
|
||||
14
phpstan.neon.dist
Normal file
14
phpstan.neon.dist
Normal file
@@ -0,0 +1,14 @@
|
||||
# Magic behaviour with __get, __set, __call and __callStatic is not exactly static analyser-friendly :)
|
||||
# Fortunately, You can ignore it by the following config.
|
||||
#
|
||||
# vendor/bin/phpstan analyse app --memory-limit 200M -l 0
|
||||
#
|
||||
parameters:
|
||||
level: 0
|
||||
paths:
|
||||
- ./app
|
||||
- ./config
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
ignoreErrors:
|
||||
- '#Static call to instance method Hyperf\\HttpServer\\Router\\Router::[a-zA-Z0-9\\_]+\(\)#'
|
||||
- '#Static call to instance method Hyperf\\DbConnection\\Db::[a-zA-Z0-9\\_]+\(\)#'
|
||||
16
phpunit.xml.dist
Normal file
16
phpunit.xml.dist
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="./test/bootstrap.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
|
||||
<testsuites>
|
||||
<testsuite name="Tests">
|
||||
<directory suffix="Test.php">./test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing" force="true"/>
|
||||
</php>
|
||||
<source>
|
||||
<include>
|
||||
<directory suffix=".php">./app</directory>
|
||||
</include>
|
||||
</source>
|
||||
</phpunit>
|
||||
180
storage/languages/en/validation.php
Normal file
180
storage/languages/en/validation.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => 'The :attribute must be accepted.',
|
||||
'active_url' => 'The :attribute is not a valid URL.',
|
||||
'after' => 'The :attribute must be a date after :date.',
|
||||
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
|
||||
'alpha' => 'The :attribute may only contain letters.',
|
||||
'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.',
|
||||
'alpha_num' => 'The :attribute may only contain letters and numbers.',
|
||||
'array' => 'The :attribute must be an array.',
|
||||
'before' => 'The :attribute must be a date before :date.',
|
||||
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
|
||||
'between' => [
|
||||
'numeric' => 'The :attribute must be between :min and :max.',
|
||||
'file' => 'The :attribute must be between :min and :max kilobytes.',
|
||||
'string' => 'The :attribute must be between :min and :max characters.',
|
||||
'array' => 'The :attribute must have between :min and :max items.',
|
||||
],
|
||||
'boolean' => 'The :attribute field must be true or false.',
|
||||
'confirmed' => 'The :attribute confirmation does not match.',
|
||||
'date' => 'The :attribute is not a valid date.',
|
||||
'date_format' => 'The :attribute does not match the format :format.',
|
||||
'decimal' => 'The :attribute must have :decimal decimal places.',
|
||||
'different' => 'The :attribute and :other must be different.',
|
||||
'digits' => 'The :attribute must be :digits digits.',
|
||||
'digits_between' => 'The :attribute must be between :min and :max digits.',
|
||||
'dimensions' => 'The :attribute has invalid image dimensions.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'email' => 'The :attribute must be a valid email address.',
|
||||
'exists' => 'The selected :attribute is invalid.',
|
||||
'file' => 'The :attribute must be a file.',
|
||||
'filled' => 'The :attribute field is required.',
|
||||
'gt' => [
|
||||
'numeric' => 'The :attribute must be greater than :value',
|
||||
'file' => 'The :attribute must be greater than :value kb',
|
||||
'string' => 'The :attribute must be greater than :value characters',
|
||||
'array' => 'The :attribute must be greater than :value items',
|
||||
],
|
||||
'gte' => [
|
||||
'numeric' => 'The :attribute must be great than or equal to :value',
|
||||
'file' => 'The :attribute must be great than or equal to :value kb',
|
||||
'string' => 'The :attribute must be great than or equal to :value characters',
|
||||
'array' => 'The :attribute must be great than or equal to :value items',
|
||||
],
|
||||
'image' => 'The :attribute must be an image.',
|
||||
'in' => 'The selected :attribute is invalid.',
|
||||
'in_array' => 'The :attribute field does not exist in :other.',
|
||||
'integer' => 'The :attribute must be an integer.',
|
||||
'ip' => 'The :attribute must be a valid IP address.',
|
||||
'ipv4' => 'The :attribute must be a valid IPv4 address.',
|
||||
'ipv6' => 'The :attribute must be a valid IPv6 address.',
|
||||
'json' => 'The :attribute must be a valid JSON string.',
|
||||
'list' => 'The :attribute must be a list.',
|
||||
'lt' => [
|
||||
'numeric' => 'The :attribute must be less than :value',
|
||||
'file' => 'The :attribute must be less than :value kb',
|
||||
'string' => 'The :attribute must be less than :value characters',
|
||||
'array' => 'The :attribute must be less than :value items',
|
||||
],
|
||||
'lte' => [
|
||||
'numeric' => 'The :attribute must be less than or equal to :value',
|
||||
'file' => 'The :attribute must be less than or equal to :value kb',
|
||||
'string' => 'The :attribute must be less than or equal to :value characters',
|
||||
'array' => 'The :attribute must be less than or equal to :value items',
|
||||
],
|
||||
'max' => [
|
||||
'numeric' => 'The :attribute may not be greater than :max.',
|
||||
'file' => 'The :attribute may not be greater than :max kilobytes.',
|
||||
'string' => 'The :attribute may not be greater than :max characters.',
|
||||
'array' => 'The :attribute may not have more than :max items.',
|
||||
],
|
||||
'mimes' => 'The :attribute must be a file of type: :values.',
|
||||
'mimetypes' => 'The :attribute must be a file of type: :values.',
|
||||
'min' => [
|
||||
'numeric' => 'The :attribute must be at least :min.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes.',
|
||||
'string' => 'The :attribute must be at least :min characters.',
|
||||
'array' => 'The :attribute must have at least :min items.',
|
||||
],
|
||||
'not_in' => 'The selected :attribute is invalid.',
|
||||
'not_regex' => 'The :attribute cannot match a given regular rule.',
|
||||
'numeric' => 'The :attribute must be a number.',
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'prohibits' => 'The :attribute field must be present.',
|
||||
'regex' => 'The :attribute format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
||||
'required_unless' => 'The :attribute field is required unless :other is in :values.',
|
||||
'required_with' => 'The :attribute field is required when :values is present.',
|
||||
'required_with_all' => 'The :attribute field is required when :values is present.',
|
||||
'required_without' => 'The :attribute field is required when :values is not present.',
|
||||
'required_without_all' => 'The :attribute field is required when none of :values are present.',
|
||||
'same' => 'The :attribute and :other must match.',
|
||||
'size' => [
|
||||
'numeric' => 'The :attribute must be :size.',
|
||||
'file' => 'The :attribute must be :size kilobytes.',
|
||||
'string' => 'The :attribute must be :size characters.',
|
||||
'array' => 'The :attribute must contain :size items.',
|
||||
],
|
||||
'starts_with' => 'The :attribute must be start with :values ',
|
||||
'string' => 'The :attribute must be a string.',
|
||||
'timezone' => 'The :attribute must be a valid zone.',
|
||||
'unique' => 'The :attribute has already been taken.',
|
||||
'uploaded' => 'The :attribute failed to upload.',
|
||||
'url' => 'The :attribute format is invalid.',
|
||||
'uuid' => 'The :attribute is invalid UUID.',
|
||||
'max_if' => [
|
||||
'numeric' => 'The :attribute may not be greater than :max when :other is :value.',
|
||||
'file' => 'The :attribute may not be greater than :max kilobytes when :other is :value.',
|
||||
'string' => 'The :attribute may not be greater than :max characters when :other is :value.',
|
||||
'array' => 'The :attribute may not have more than :max items when :other is :value.',
|
||||
],
|
||||
'min_if' => [
|
||||
'numeric' => 'The :attribute must be at least :min when :other is :value.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes when :other is :value.',
|
||||
'string' => 'The :attribute must be at least :min characters when :other is :value.',
|
||||
'array' => 'The :attribute must have at least :min items when :other is :value.',
|
||||
],
|
||||
'between_if' => [
|
||||
'numeric' => 'The :attribute must be between :min and :max when :other is :value.',
|
||||
'file' => 'The :attribute must be between :min and :max kilobytes when :other is :value.',
|
||||
'string' => 'The :attribute must be between :min and :max characters when :other is :value.',
|
||||
'array' => 'The :attribute must have between :min and :max items when :other is :value.',
|
||||
],
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
'phone_number' => 'The :attribute must be a valid phone number',
|
||||
'telephone_number' => 'The :attribute must be a valid telephone number',
|
||||
|
||||
'chinese_word' => 'The :attribute must contain valid characters(chinese/english character, number, underscore)',
|
||||
'sequential_array' => 'The :attribute must be sequential array',
|
||||
];
|
||||
180
storage/languages/zh_CN/validation.php
Normal file
180
storage/languages/zh_CN/validation.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => ':attribute 必须接受',
|
||||
'active_url' => ':attribute 必须是一个合法的 URL',
|
||||
'after' => ':attribute 必须是 :date 之后的一个日期',
|
||||
'after_or_equal' => ':attribute 必须是 :date 之后或相同的一个日期',
|
||||
'alpha' => ':attribute 只能包含字母',
|
||||
'alpha_dash' => ':attribute 只能包含字母、数字、中划线或下划线',
|
||||
'alpha_num' => ':attribute 只能包含字母和数字',
|
||||
'array' => ':attribute 必须是一个数组',
|
||||
'before' => ':attribute 必须是 :date 之前的一个日期',
|
||||
'before_or_equal' => ':attribute 必须是 :date 之前或相同的一个日期',
|
||||
'between' => [
|
||||
'numeric' => ':attribute 必须在 :min 到 :max 之间',
|
||||
'file' => ':attribute 必须在 :min 到 :max kb 之间',
|
||||
'string' => ':attribute 必须在 :min 到 :max 个字符之间',
|
||||
'array' => ':attribute 必须在 :min 到 :max 项之间',
|
||||
],
|
||||
'boolean' => ':attribute 字符必须是 true 或 false, 1 或 0',
|
||||
'confirmed' => ':attribute 二次确认不匹配',
|
||||
'date' => ':attribute 必须是一个合法的日期',
|
||||
'date_format' => ':attribute 与给定的格式 :format 不符合',
|
||||
'decimal' => ':attribute 必须有 :decimal 位小数',
|
||||
'different' => ':attribute 必须不同于 :other',
|
||||
'digits' => ':attribute 必须是 :digits 位',
|
||||
'digits_between' => ':attribute 必须在 :min 和 :max 位之间',
|
||||
'dimensions' => ':attribute 具有无效的图片尺寸',
|
||||
'distinct' => ':attribute 字段具有重复值',
|
||||
'email' => ':attribute 必须是一个合法的电子邮件地址',
|
||||
'exists' => '选定的 :attribute 是无效的',
|
||||
'file' => ':attribute 必须是一个文件',
|
||||
'filled' => ':attribute 的字段是必填的',
|
||||
'gt' => [
|
||||
'numeric' => ':attribute 必须大于 :value',
|
||||
'file' => ':attribute 必须大于 :value kb',
|
||||
'string' => ':attribute 必须大于 :value 个字符',
|
||||
'array' => ':attribute 必须大于 :value 项',
|
||||
],
|
||||
'gte' => [
|
||||
'numeric' => ':attribute 必须大于等于 :value',
|
||||
'file' => ':attribute 必须大于等于 :value kb',
|
||||
'string' => ':attribute 必须大于等于 :value 个字符',
|
||||
'array' => ':attribute 必须大于等于 :value 项',
|
||||
],
|
||||
'image' => ':attribute 必须是 jpg, jpeg, png, bmp 或者 gif 格式的图片',
|
||||
'in' => '选定的 :attribute 是无效的',
|
||||
'in_array' => ':attribute 字段不存在于 :other',
|
||||
'integer' => ':attribute 必须是个整数',
|
||||
'ip' => ':attribute 必须是一个合法的 IP 地址',
|
||||
'ipv4' => ':attribute 必须是一个合法的 IPv4 地址',
|
||||
'ipv6' => ':attribute 必须是一个合法的 IPv6 地址',
|
||||
'json' => ':attribute 必须是一个合法的 JSON 字符串',
|
||||
'list' => ':attribute 必须是一个数组列表',
|
||||
'lt' => [
|
||||
'numeric' => ':attribute 必须小于 :value',
|
||||
'file' => ':attribute 必须小于 :value kb',
|
||||
'string' => ':attribute 必须小于 :value 个字符',
|
||||
'array' => ':attribute 必须小于 :value 项',
|
||||
],
|
||||
'lte' => [
|
||||
'numeric' => ':attribute 必须小于等于 :value',
|
||||
'file' => ':attribute 必须小于等于 :value kb',
|
||||
'string' => ':attribute 必须小于等于 :value 个字符',
|
||||
'array' => ':attribute 必须小于等于 :value 项',
|
||||
],
|
||||
'max' => [
|
||||
'numeric' => ':attribute 的最大值为 :max',
|
||||
'file' => ':attribute 的最大为 :max kb',
|
||||
'string' => ':attribute 的最大长度为 :max 字符',
|
||||
'array' => ':attribute 至多有 :max 项',
|
||||
],
|
||||
'mimes' => ':attribute 的文件类型必须是 :values',
|
||||
'mimetypes' => ':attribute 的文件MIME必须是 :values',
|
||||
'min' => [
|
||||
'numeric' => ':attribute 的最小值为 :min',
|
||||
'file' => ':attribute 大小至少为 :min kb',
|
||||
'string' => ':attribute 的最小长度为 :min 字符',
|
||||
'array' => ':attribute 至少有 :min 项',
|
||||
],
|
||||
'not_in' => '选定的 :attribute 是无效的',
|
||||
'not_regex' => ':attribute 不能匹配给定的正则',
|
||||
'numeric' => ':attribute 必须是数字',
|
||||
'present' => ':attribute 字段必须存在',
|
||||
'prohibits' => '必须提供 :attribute 字段',
|
||||
'regex' => ':attribute 格式是无效的',
|
||||
'required' => ':attribute 字段是必须的',
|
||||
'required_if' => ':attribute 字段是必须的当 :other 是 :value',
|
||||
'required_unless' => ':attribute 字段是必须的,除非 :other 是在 :values 中',
|
||||
'required_with' => ':attribute 字段是必须的当 :values 是存在的',
|
||||
'required_with_all' => ':attribute 字段是必须的当 :values 是存在的',
|
||||
'required_without' => ':attribute 字段是必须的当 :values 是不存在的',
|
||||
'required_without_all' => ':attribute 字段是必须的当 没有一个 :values 是存在的',
|
||||
'same' => ':attribute 和 :other 必须匹配',
|
||||
'size' => [
|
||||
'numeric' => ':attribute 必须是 :size',
|
||||
'file' => ':attribute 必须是 :size kb',
|
||||
'string' => ':attribute 必须是 :size 个字符',
|
||||
'array' => ':attribute 必须包括 :size 项',
|
||||
],
|
||||
'starts_with' => ':attribute 必须以 :values 为开头',
|
||||
'string' => ':attribute 必须是一个字符串',
|
||||
'timezone' => ':attribute 必须是个有效的时区',
|
||||
'unique' => ':attribute 已存在',
|
||||
'uploaded' => ':attribute 上传失败',
|
||||
'url' => ':attribute 无效的格式',
|
||||
'uuid' => ':attribute 无效的UUID格式',
|
||||
'max_if' => [
|
||||
'numeric' => '当 :other 为 :value 时 :attribute 不能大于 :max',
|
||||
'file' => '当 :other 为 :value 时 :attribute 不能大于 :max kb',
|
||||
'string' => '当 :other 为 :value 时 :attribute 不能大于 :max 个字符',
|
||||
'array' => '当 :other 为 :value 时 :attribute 最多只有 :max 个单元',
|
||||
],
|
||||
'min_if' => [
|
||||
'numeric' => '当 :other 为 :value 时 :attribute 必须大于等于 :min',
|
||||
'file' => '当 :other 为 :value 时 :attribute 大小不能小于 :min kb',
|
||||
'string' => '当 :other 为 :value 时 :attribute 至少为 :min 个字符',
|
||||
'array' => '当 :other 为 :value 时 :attribute 至少有 :min 个单元',
|
||||
],
|
||||
'between_if' => [
|
||||
'numeric' => '当 :other 为 :value 时 :attribute 必须介于 :min - :max 之间',
|
||||
'file' => '当 :other 为 :value 时 :attribute 必须介于 :min - :max kb 之间',
|
||||
'string' => '当 :other 为 :value 时 :attribute 必须介于 :min - :max 个字符之间',
|
||||
'array' => '当 :other 为 :value 时 :attribute 必须只有 :min - :max 个单元',
|
||||
],
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
'phone_number' => ':attribute 必须为一个有效的电话号码',
|
||||
'telephone_number' => ':attribute 必须为一个有效的手机号码',
|
||||
|
||||
'chinese_word' => ':attribute 必须包含以下有效字符 (中文/英文,数字, 下划线)',
|
||||
'sequential_array' => ':attribute 必须是一个有序数组',
|
||||
];
|
||||
27
test/Cases/ExampleTest.php
Normal file
27
test/Cases/ExampleTest.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Cases;
|
||||
|
||||
use Hyperf\Testing\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
public function testExample()
|
||||
{
|
||||
$this->get('/')->assertOk()->assertSee('Hyperf');
|
||||
}
|
||||
}
|
||||
45
test/HttpTestCase.php
Normal file
45
test/HttpTestCase.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest;
|
||||
|
||||
use Hyperf\Testing\Client;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
/**
|
||||
* Class HttpTestCase.
|
||||
* @method get($uri, $data = [], $headers = [])
|
||||
* @method post($uri, $data = [], $headers = [])
|
||||
* @method json($uri, $data = [], $headers = [])
|
||||
* @method file($uri, $data = [], $headers = [])
|
||||
* @method request($method, $path, $options = [])
|
||||
*/
|
||||
abstract class HttpTestCase extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
public function __construct($name = null, array $data = [], $dataName = '')
|
||||
{
|
||||
parent::__construct($name, $data, $dataName);
|
||||
$this->client = make(Client::class);
|
||||
}
|
||||
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return $this->client->{$name}(...$arguments);
|
||||
}
|
||||
}
|
||||
30
test/bootstrap.php
Normal file
30
test/bootstrap.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
ini_set('display_errors', 'on');
|
||||
ini_set('display_startup_errors', 'on');
|
||||
|
||||
error_reporting(E_ALL);
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
Swoole\Runtime::enableCoroutine(true);
|
||||
|
||||
! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
|
||||
|
||||
require BASE_PATH . '/vendor/autoload.php';
|
||||
|
||||
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', Hyperf\Engine\DefaultOption::hookFlags());
|
||||
|
||||
Hyperf\Di\ClassLoader::init();
|
||||
|
||||
$container = require BASE_PATH . '/config/container.php';
|
||||
|
||||
$container->get(Hyperf\Contract\ApplicationInterface::class);
|
||||
Reference in New Issue
Block a user