hyperf踩坑笔记

环境配置

  • 虚拟机1:centos7 1h2g

参考官网文档:传送门 使用docker架设。
docker在Linux中的安装可以参考这篇文章:Linux环境安装、卸载Docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 下载并运行 hyperf/hyperf 镜像,并将镜像内的项目目录绑定到宿主机的 /tmp/skeleton 目录
docker run -v /tmp/skeleton:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:7.2-alpine-cli

# 镜像容器运行后,在容器内安装 Composer
wget https://github.com/composer/composer/releases/download/1.8.6/composer.phar
chmod u+x composer.phar
mv composer.phar /usr/local/bin/composer
# 将 Composer 镜像设置为阿里云镜像,加速国内下载速度
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer

# 通过 Composer 安装 hyperf/hyperf-skeleton 项目
composer create-project hyperf/hyperf-skeleton

# 进入安装好的 Hyperf 项目目录
cd hyperf-skeleton
# 启动 Hyperf
php bin/hyperf.php start
  • 虚拟机2 centos7 1h2g

使用宝塔面板编译安装mysql(v5.5.62)+redis(v5.0.8)。

进行以下配置操作:

  1. 在面板左侧的『安全』中开放3306和6379端口(生产环境绝不推荐开放这俩的外网端口
  2. 在面板左侧的『数据库』中创建一个名为hyperF的数据库,访问权限为:所有人
  3. 在面板左侧的『软件商店』找到redis,设置requirepass和bind(外网访问时设置为0.0.0.0)

IDE相关 2020.10.13更新

今天把phpstorm升级到了2020.2版本,拉取了hyperf 2.0框架。

编写代码的时候遇到了一个提示 multiple definitions exist for class

multiple definitions exist for class

如图所示,搜索Undefined class,找到右侧这个选项打勾即可。(Don’t report multiple class declaration potential problems)

通过curl在Terminal窗口测试请求接口时,返回结果乱码

10.19更新最新答案

解决方法:

  1. Terminal

通过 File->Settings->Tools->Terminal 修改 Shell Path 为 cmd.exe /k chcp 65001 & cls

  1. SSH Terminal

通过 File->Settings->Tools->SSH Terminal 修改 Default encoding为 UTF-8

  1. HTTP Client

这个还没有找到办法,目前只能这样看了

hyperf这个注释单词会在PhpStorm中提示Typo: In word ‘hyperf’

在提示的行右键,选择More Action

再选择Save xxx to dictionary

之后这个提示就不会出现了。

如果后续需要把某个单词移除,可以在File - Settings - Editor - Proofreading - Spelling中进行管理

redis相关

使用redis-server时报错:-bash: redis-server: command not found

宝塔的redis-server位置在:/www/server/redis/src/redis-server

使用这行命令创建软连接:

ln -s /www/server/redis/src/redis-server /usr/bin/redis-server

之后再运行redis-server即正常。

使用redis-cli登录时,如果输入redis密码

1
2
3
4
5
[root@localhost ~]# redis-cli
127.0.0.1:6379> auth 123456 # redis使用 auth <password> 指令登录
OK
127.0.0.1:6379>
[root@localhost ~]#

redis的远程连接

将bind从127.0.0.1设置成0.0.0.0后重启redis即可

安装拓展时提示 Do not run Composer as root/super user!

这个问题我之前找不到解决方法,都是通过重装环境搞得。

后来发现可能是每次docker停止之后我通过docker run而不是docker start启动容器,导致的出错。

服务器重启之后,docker ps找不到容器怎么办?

可以通过docker ps -a查询,对于status为exit的容器,可以使用 docker start 启动。

docker安装redis,使用redis.conf后启动失败。

把redis.conf中的daemonize设置为no或者注释掉,再次run即可。

框架

软删除的功能没有代码提示

可以参考我新写的文章:hyperf 模型的软删除功能在IDE内没有代码提示的问题与解决

数据库迁移功能 如何在创建表时添加备注

方法来自 Hyperf\Database\Schema\ColumnDefinition

1
2
3
4
5
6
7
8
9
10
11
12

public function up(): void
{
Schema::create('users', function (Blueprint $table) {
// 设置之后调用comment(String $text)设置备注
$table->bigIncrements('id')->comment('主键id');
// 备注方法必须在最后调用,否则该字段将不会被创建
// 调用change()方法后会导致该字段不会被创建,原因未知
$table->smallInteger('role_id')->unsigned()->comment('角色id');
});
}

json-prc 传递PHP对象报错,报错Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException:Cannot create an instance of from serialized data because its constructor requires parameter to be present.

看了下 vendor\symfony\serializer\Normailzer\AbstractNormalizer.php 的 instantiateObject方法,通**过__construct传递的参数,必须要有同名的public级别的类属性。**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

<?php

declare(strict_types=1);

namespace App\JsonRpc;

class DemoItem {

// 如果这个属性未定义,则会报MissingConstructorArgumentsException
public $data;

// 此处传递了一个$data变量,此时在DemoItem类中,必须定义一个data属性
public function __construct($data)
{
$this->data = $data;
}
}

某些第三方组件的model没有phpDoc属性,导致使用Model->property时会报Property accessed via magic method

因为是vendor里的包,所以不可能去修改这个包里的内容;也无法通过@var或者@property来定义。

在stackoverflow上找到一个回答:可以用/** @noinspection PhpUndefinedFieldInspection */来解决。

代码如下:

1
2
3
$foo = Foo::findById(1);
/** @noinspection PhpUndefinedFieldInspection */
$bar = $foo->id;

consul (服务中心)

更新于2020/10/22:

开发环境:docker方式开发,在同一台虚拟机中创建了三个容器。
容器A gateway 开放80端口
容器B provide 开放9501端口(jsonrpc)
容器C consul 开放8300、8400、8500、8600端口

启动provide报错,Cannot register service, connection of service center failed…

这问题困扰了我好久,docker删除重装了多次consul都不行。后来想到是不是docker下的环境隔离了导致通过127.0.0.1:port无法访问consul服务,然后换成了通过ifconfig给出的172.17.xxx.xxx地址启动consul。

1
2
3
4
5
6
7
8
9
10
11
12
# 容器C中把-client换成通过ifconfig得到的内网IP
consul> ./consul agent -server -bootstrap-expect 1 -data-dir=/tmp/consul -node=n1 -client=172.17.xxx.xxx -ui

# 容器B中修改 config/autoload/consul.php
<?php

return [
'uri' => 'http://172.17.xxx.xxx:8500',
];

# 重启容器B
provide> php bin/hyperf.php start

这时候服务成功被注册到服务中心了。

参考

  1. multiple definitions exist for class
  2. 解决–docker run -d指定本地redis.conf文件启动失败
  3. PhpStorm Field accessed via magic method

评论区