init
This commit is contained in:
commit
6c5a7eb472
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
|
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.buildpath
|
||||||
|
.settings/
|
||||||
|
.project
|
||||||
|
*.patch
|
||||||
|
.idea/
|
||||||
|
.git/
|
||||||
|
runtime/
|
||||||
|
vendor/
|
||||||
|
.phpintel/
|
||||||
|
.env
|
||||||
|
.DS_Store
|
||||||
|
.phpunit*
|
||||||
|
*.cache
|
||||||
|
.vscode/
|
||||||
|
/phpstan.neon
|
||||||
|
/phpunit.xml
|
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));
|
||||||
|
}
|
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.
|
63
README.md
Normal file
63
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.
|
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}.",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
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
|
||||||
|
{
|
||||||
|
}
|
31
bin/hyperf.php
Normal file
31
bin/hyperf.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* 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');
|
||||||
|
ini_set('memory_limit', '1G');
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
! 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();
|
||||||
|
})();
|
76
composer.json
Normal file
76
composer.json
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"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.1",
|
||||||
|
"hyperf/cache": "~3.1.0",
|
||||||
|
"hyperf/command": "~3.1.0",
|
||||||
|
"hyperf/config": "~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/process": "~3.1.0"
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
9005
composer.lock
generated
Normal file
9005
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
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 [
|
||||||
|
];
|
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'],
|
||||||
|
],
|
||||||
|
];
|
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>
|
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);
|
Loading…
Reference in New Issue
Block a user