官方文档
* https://hyperf.wiki/2.0/#/README

初步搭建
1. 安装项目

composer create-project hyperf/hyperf-skeleton

2. 项目根目录配置为当前目录的安装目录根目录,即不存在public目录

3. 配置Nginx反向代理

# 至少需要一个 Hyperf 节点,多个配置多行
upstream hyperf {
# Hyperf HTTP Server 的 IP 及 端口
server 127.0.0.1:9501;
server 127.0.0.1:9502;
} server {
# 监听端口
listen 80;
# 绑定的域名,填写您的域名
server_name proxy.hyperf.io; location / {
# 将客户端的 Host 和 IP 信息一并转发到对应节点
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 转发Cookie,设置 SameSite
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; # 执行代理访问真实服务器
proxy_pass http://hyperf;
}
}

4. 宝塔Nginx配置为(同LNMP的Nginx配置)

upstream hyperf {
# Hyperf HTTP Server 的 IP 及 端口
server 127.0.0.1:9501;
server 127.0.0.1:9502;
} server
{
listen 80;
server_name hyperf.com.net;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/hyperf-skeleton; #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#SSL-END #ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END #PHP-INFO-START PHP引用配置,可以注释或修改
include enable-php-74.conf;
#PHP-INFO-END location / {
# 将客户端的 Host 和 IP 信息一并转发到对应节点
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 转发Cookie,设置 SameSite
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; # 执行代理访问真实服务器
proxy_pass http://hyperf;
} #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/hyperf.kefu.com.net.conf;
#REWRITE-END #禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
} #一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
} location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log off;
access_log /dev/null;
} location ~ .*\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
access_log /www/wwwlogs/hyperf.kefu.com.net.log;
error_log /www/wwwlogs/hyperf.kefu.com.net.error.log;
}

5.启动http服务命令

php bin/hyperf.php start

或者重写启动文件watch。执行命令为:php watch

#!/usr/bin/env php
<?php /**
* Hyperf Watch Hot Reload Scripts
* From: https://github.com/ha-ni-cc/hyperf-watch
* Author: hanicc@qq.com
* Usage:
* Open the terminal console in the project root directory and enter:php watch
* 在项目根目录下打开终端控制台,输入:php watch
* If you want to clean the /runtime/container cache, enter: php watch -c
* 如果你想要清除/runtime/container缓存,则输入:php watch -c
*/ # PHP Bin File PHP程序所在路径(默认自动获取)
const PHP_BIN_FILE = 'which php';
# Watch Dir 监听目录(默认监听脚本所在的根目录)
const WATCH_DIR = __DIR__ . '/';
# Watch Ext 监听扩展名(多个可用英文逗号隔开)
const WATCH_EXT = 'php,env';
# Exclude Dir 排除目录(不监听的目录,数组形式)
const EXCLUDE_DIR = ['vendor', 'runtime', 'public'];
# Entry Point File 入口文件
const ENTRY_POINT_FILE = __DIR__ . '/bin/hyperf.php';
# Start Command 启动命令
const START_COMMAND = [ENTRY_POINT_FILE, 'start'];
# PID File Path PID文件路径
const PID_FILE_PATH = __DIR__ . '/runtime/hyperf.pid';
# Scan Interval 扫描间隔(毫秒,默认2000)
const SCAN_INTERVAL = 2000; if (!function_exists('exec')) {
echo '[x] 请在php.ini配置中取消禁用exec方法' . PHP_EOL;
exit(1);
} define('PHP', PHP_BIN_FILE == 'which php' ? exec('which php') : PHP_BIN_FILE); if (!file_exists(PHP) || !is_executable(PHP)) {
echo '[x] PHP bin (" ' . PHP . ' ") 路径没有找到或无法执行,请确认路径正确?' . PHP_EOL;
exit(1);
} if (!file_exists(ENTRY_POINT_FILE)) {
echo '[x] 入口文件 ("' . ENTRY_POINT_FILE . '") 没有找到,请确认文件存在?' . PHP_EOL;
exit(1);
} # 加载env
$content = @file_get_contents('.env');
$values = array_filter(preg_split("/(\r\n|\n|\r)/", $content));
foreach ($values as $val) {
if (substr($val, 0, 1) === '#') {
continue;
}
list($name, $value) = explode('=', $val);
$_ENV[$name] = $value;
} use Swoole\Process;
use Swoole\Timer;
use Swoole\Event; swoole_async_set(['enable_coroutine' => false, 'log_level' => SWOOLE_LOG_INFO]);
$hashes = [];
$serve = null;
echo " Start @ " . date('Y-m-d H:i:s') . PHP_EOL;
start();
state();
Timer::tick(SCAN_INTERVAL, 'watch'); function killOldProcess()
{
// pid存在则关闭存在的进程
if (file_exists(PID_FILE_PATH) && $pid = @file_get_contents(PID_FILE_PATH)) {
if (!@posix_kill($pid)) forceKill();
} else forceKill();
} function forceKill($match = '')
{
if (!$match) {
$match = @$_ENV['APP_NAME'] . '.Master';
}
// 适配MacOS
if (PHP_OS == 'Darwin') $match = ENTRY_POINT_FILE;
$command = "ps -ef | grep '$match' | grep -v grep | awk '{print $2}' | xargs kill -9 2>&1";
// 找不到pid,强杀进程
exec($command);
} function start()
{
// 杀旧进程
killOldProcess();
global $serve;
$serve = new Process('serve', true);
$serve->start();
if (false === $serve->pid) {
echo swoole_strerror(swoole_errno()) . PHP_EOL;
exit(1);
}
addEvent($serve);
} function addEvent($serve)
{
Event::add($serve->pipe, function () use (&$serve) {
$message = @$serve->read();
if (!empty($message)) {
echo $message;
}
});
} function watch()
{
global $hashes;
foreach ($hashes as $pathName => $currentHash) {
if (!file_exists($pathName)) {
unset($hashes[$pathName]);
continue;
}
$newHash = fileHash($pathName);
if ($newHash != $currentHash) {
change();
state();
break;
}
}
} function state()
{
global $hashes;
$files = phpFiles(WATCH_DIR);
$hashes = array_combine($files, array_map('fileHash', $files));
$count = count($hashes);
echo " Watching $count files..." . PHP_EOL;
} function change()
{
global $serve;
echo " Restart @ " . date('Y-m-d H:i:s') . PHP_EOL;
Process::kill($serve->pid);
start();
} function serve(Process $serve)
{
$opt = getopt('c');
# if (isset($opt['c'])) echo exec(PHP . ' ' . ENTRY_POINT_FILE . ' di:init-proxy') . '..' . PHP_EOL;
if (isset($opt['c'])) delDir('./runtime/container');
$serve->exec(PHP, START_COMMAND);
} function fileHash(string $pathname): string
{
$contents = @file_get_contents($pathname);
if (false === $contents) {
return 'deleted';
}
return md5($contents);
} function phpFiles(string $dirname): array
{
$directory = new RecursiveDirectoryIterator($dirname);
$filter = new Filter($directory);
$iterator = new RecursiveIteratorIterator($filter);
return array_map(function ($fileInfo) {
return $fileInfo->getPathname();
}, iterator_to_array($iterator));
} function delDir($path)
{
if (is_dir($path)) {
//扫描一个目录内的所有目录和文件并返回数组
$dirs = scandir($path);
foreach ($dirs as $dir) {
//排除目录中的当前目录(.)和上一级目录(..)
if ($dir != '.' && $dir != '..') {
//如果是目录则递归子目录,继续操作
$sonDir = $path . '/' . $dir;
if (is_dir($sonDir)) {
//递归删除
delDir($sonDir);
//目录内的子目录和文件删除后删除空目录
@rmdir($sonDir);
} else {
//如果是文件直接删除
@unlink($sonDir);
}
}
}
@rmdir($path);
}
} class Filter extends RecursiveFilterIterator
{
public function accept()
{
if ($this->current()->isDir()) {
if (preg_match('/^\./', $this->current()->getFilename())) {
return false;
}
return !in_array($this->current()->getFilename(), EXCLUDE_DIR);
}
$list = array_map(function (string $item): string {
return "\.$item";
}, explode(',', WATCH_EXT));
$list = implode('|', $list);
return preg_match("/($list)$/", $this->current()->getFilename());
}
}

6. 启动报错

ERROR Swoole short name have to disable before start server, please set swoole.use_shortname = off into your php.ini. 

php.ini文件最后一行新增 swoole.use_shortname = off 即可

7. 访问当前配置域名返回

hyperf-搭建初始化的更多相关文章

  1. Activiti工作流搭建---初始化数据库

    Activiti介绍 Activiti5是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩展的可执 ...

  2. vue3.0+vite+ts项目搭建--初始化项目(一)

    vite 初始化项目 使用npm npm init vite@latest 使用yarn yarn create vite 使用pnpm pnpx create-vite 根据提示输入项目名称,选择v ...

  3. 图解Hyperf框架:Hyperf 的初始化

  4. vue二、脚手架搭建

    1:安装nodeJs(下载一路回车) https://nodejs.org/zh-cn/ 2:检验nodeJs是否安装成功 (注意nodeJs是否添加到window路径中) 进入cmd -> n ...

  5. finger-guessing game:1场景搭建

    场景搭建 //初始化legend组件 init(50, "div_caiquan", 800, 400, main); //定义游戏层 //游戏背景层,结果显示层,点击层 var ...

  6. TypeScript完全解读(26课时)_1.TypeScript完全解读-开发环境搭建

    1.TypeScript完全解读-开发环境搭建 初始化项目 手动创建文件夹 D:\MyDemos\tsDemo\client-demo 用VSCode打开 npm init:初始化项目 然后我们的项目 ...

  7. 使用VuePress搭建个人博客

    使用VuePress搭建个人博客 VuePress 是一个基于 Vue 的静态网站生成器.其中主要用到:Vue,VueRouter,Webpack. 类似的工具:hexo 基于 Markdown 语法 ...

  8. rollup 开发环境搭建

    rollup 开发环境搭建 初始化项目使用lerna管理项目 使用npm init 初始化项目 npm init -y 安装lerna并初始化项目 npm install lerna --save-d ...

  9. 【迁移】—Entity Framework实例详解 转

    一.Entity Framework 迁移命令(get-help EntityFramework) Enable-Migrations 启用迁移 Add-Migration 为挂起的Model变化添加 ...

  10. Node.js高级编程读书笔记 - 4 构建Web应用程序

    Outline 5 构建Web应用程序 5.1 构建和使用HTTP中间件 5.2 用Express.js创建Web应用程序 5.3 使用Socket.IO创建通用的实时Web应用程序 5 构建Web应 ...

随机推荐

  1. DolphinScheduler 新晋 Committer 成员啦

    Apache DolphinScheduler在2021年的3月18号正式成为 Apache 顶级项目后,就又迎来了好消息,经过Apache DolphinScheduler PMC们的推荐和投票, ...

  2. MyBatis 01 概述

    官网 http://www.mybatis.org/mybatis-3/zh/index.html GitHub https://github.com/mybatis/mybatis-3 简介 MyB ...

  3. 线程重用问题--ThreadLocal数据错乱

    前言 复现Java业务开发常见错误100例--1 项目完整代码:Github地址 知识点回顾: ThreadLocal的定义和使用: ThreadLocal概念以及使用场景 配置文件的读取: 获取配置 ...

  4. day23--Java集合06

    Java集合06 13.Map接口02 13.2Map接口常用方法 put():添加 remove():根据键键删除映射关系 get():根据键获取值 size():获取元素个数 isEnpty(): ...

  5. 如何在CSS中使用变量

    前言 CSS变量(官方称为自定义属性)是用户定义的值,它可以在你的代码库中设置一次并多次使用.它们使管理颜色.字体.大小和动画值变得更加容易,并确保整个web应用的一致性. 举个例子,你可以将品牌颜色 ...

  6. windows系统-不能打印问题:PDF打印软件正常打开PDF文件,点击打印后软件卡死并提示未响应(No response)

    电脑突然出现PDF软件卡死问题,导致无法打印:初步思路记录: 导致问题出现的原因可能为文件问题(文件过大,打印机容量小).打印机问题(打印机未连接.故障等).电脑驱动问题(打印机驱动损坏).电脑补丁问 ...

  7. 搭建eBackup对接NFS服务

    环境准备 两个虚拟机需要是仅主机并且同一网段 先搭建一个eBackup环境虚拟机 搭建步骤可访问:(https://www.cnblogs.com/zhengyan6/p/16220774.html) ...

  8. KingbaseES 绑定变量窥探机制

    概述: 对于数据严重倾斜的,极端如以下例子,不同的传入值,可能执行计划不同,制定执行计划时,就要求知道变量的值.对于绑定变量的情况,我们知道Oracle 有 _optim_peek_user_bind ...

  9. Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):4、Maven项目转换与pom.xml配置

    文章目录: Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):1.JIRA账号注册 Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):2.PGP ...

  10. 凭借SpringBoot整合Neo4j,我理清了《雷神》中错综复杂的人物关系

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. 虽然距离中秋放假还要熬过漫长的两天,不过也有个好消息,今天是<雷神4>上线Disney+流媒体的日子 ...