2019-12-12 16:24:04 +08:00
|
|
|
# 常見問題
|
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
## `Inject` 或 `Value` 註解不生效
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
`2.0` 使用了構造函數中注入 `Inject` 和 `Value` 的功能,以下兩種場景,可能會導致注入失效,請注意使用。
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
1. 原類沒有使用 `Inject` 或 `Value`,但父類使用了 `Inject` 或 `Value`,且原類寫了構造函數,同時又沒有調用父類構造函數的情況。
|
2020-01-16 14:33:32 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
這樣就會導致原類不會生成代理類,而實例化的時候又調用了自身的構造函數,故沒辦法執行到父類的構造函數。
|
|
|
|
所以父類代理類中的方法 `__handlePropertyHandler` 就不會執行,那麼 `Inject` 或 `Value` 註解就不會生效。
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
```php
|
|
|
|
class ParentClass {
|
|
|
|
/**
|
|
|
|
* @Inject
|
|
|
|
* @var Service
|
|
|
|
*/
|
|
|
|
protected $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
class Origin extends ParentClass
|
|
|
|
{
|
|
|
|
public function __construct() {}
|
|
|
|
}
|
2019-12-12 16:24:04 +08:00
|
|
|
```
|
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
2. 原類沒有使用 `Inject` 或 `Value`,但 `Trait` 中使用了 `Inject` 或 `Value`。
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
這樣就會導致原類不會生成代理類,故沒辦法執行構造函數裏的 `__handlePropertyHandler`,所以 `Trait` 的 `Inject` 或 `Value` 註解就不會生效。
|
2020-01-16 14:33:32 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
```php
|
|
|
|
trait OriginTrait {
|
|
|
|
/**
|
|
|
|
* @Inject
|
|
|
|
* @var Service
|
|
|
|
*/
|
|
|
|
protected $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
class Origin
|
|
|
|
{
|
|
|
|
use OriginTrait;
|
|
|
|
}
|
2020-01-16 14:33:32 +08:00
|
|
|
```
|
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
基於上述兩種情況,可見 `原類` 是否生成代理類至關重要,所以,如果使用了帶有 `Inject` 或 `Value` 的 `Trait` 和 `父類` 時,給原類添加一個 `Inject`,即可解決上述兩種情況。
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
```php
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
use Hyperf\Contract\StdoutLoggerInterface;
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
trait OriginTrait {
|
|
|
|
/**
|
|
|
|
* @Inject
|
|
|
|
* @var Service
|
|
|
|
*/
|
|
|
|
protected $trait;
|
|
|
|
}
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
class ParentClass {
|
|
|
|
/**
|
|
|
|
* @Inject
|
|
|
|
* @var Service
|
|
|
|
*/
|
|
|
|
protected $value;
|
|
|
|
}
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
class Origin extends ParentClass
|
|
|
|
{
|
|
|
|
use OriginTrait;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @Inject
|
|
|
|
* @var StdoutLoggerInterface
|
|
|
|
*/
|
|
|
|
protected $logger;
|
|
|
|
}
|
2019-12-12 16:24:04 +08:00
|
|
|
```
|
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
## Swoole 短名未關閉
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
```
|
|
|
|
[ERROR] Swoole short name have to disable before start server, please set swoole.use_shortname = 'Off' into your php.ini.
|
2019-12-12 16:24:04 +08:00
|
|
|
```
|
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
您需要在您的 php.ini 配置文件增加 `swoole.use_shortname = 'Off'` 配置項
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
> 注意該配置必須於 php.ini 內配置,無法通過 ini_set() 函數來重寫
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
當然,也可以通過以下的命令來啟動服務,在執行 PHP 命令時關閉掉 Swoole 短名功能
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
```
|
|
|
|
php -d swoole.use_shortname=Off bin/hyperf.php start
|
2019-12-12 16:24:04 +08:00
|
|
|
```
|
|
|
|
|
2020-04-30 17:09:23 +08:00
|
|
|
## 異步隊列消息丟失
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-04-30 17:09:23 +08:00
|
|
|
如果在使用 `async-queue` 組件時,發現 `handle` 中的方法沒有執行,請先檢查以下幾種情況:
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-04-30 17:09:23 +08:00
|
|
|
1. `Redis` 是否與其他人共用,消息被其他人消費走
|
|
|
|
2. 本地進程是否存在殘餘,被其他進程消費掉
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-04-30 17:09:23 +08:00
|
|
|
以下提供萬無一失的解決辦法:
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-04-30 17:09:23 +08:00
|
|
|
1. killall php
|
|
|
|
2. 修改 `async-queue` 配置 `channel`
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
## 使用 AMQP 組件報 `Swoole\Error: API must be called in the coroutine` 錯誤
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-09-07 12:55:20 +08:00
|
|
|
可以在 `config/autoload/amqp.php` 配置文件中將 `params.close_on_destruct` 改為 `false` 即可。
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
## 使用 Swoole 4.5 版本和 view 組件時訪問接口出現 404
|
2019-12-12 16:24:04 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
使用 Swoole 4.5 版本和 view 組件如果出現接口 404 的問題,可以嘗試刪除 `config/autoload/server.php` 文件中的 `static_handler_locations` 配置項。
|
2020-04-04 21:22:06 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
此配置下的路徑都會被認為是靜態文件路由,所以如果配置了`/`,就會導致所有接口都會被認為是文件路徑,導致接口 404。
|
2020-04-04 21:22:06 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
## 代碼不生效
|
2020-04-04 21:22:06 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
當碰到修改後的代碼不生效的問題,請執行以下命令
|
|
|
|
|
|
|
|
```bash
|
|
|
|
composer dump-autoload -o
|
2020-04-30 17:09:23 +08:00
|
|
|
```
|
2020-04-04 21:22:06 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
開發階段,請不要設置 `scan_cacheable` 為 `true`,它會導致 `收集器緩存` 存在時,不會再次掃描文件。另外,官方骨架包中的 `Dockerfile` 是默認開啟這個配置的,`Docker` 環境下開發的同學,請注意這裏。
|
2020-06-16 01:43:41 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
> 當環境變量存在 SCAN_CACHEABLE 時,.env 中無法修改這個配置。
|
2020-04-04 21:22:06 +08:00
|
|
|
|
2020-07-27 15:52:51 +08:00
|
|
|
`2.0.0` 和 `2.0.1` 兩個版本,判斷文件是否修改時,沒有判斷修改時間相等的情況,所以文件修改後,立馬生成緩存的情況(比如使用 `watcher` 組件時), 會導致代碼無法及時生效。
|
2020-08-31 13:40:33 +08:00
|
|
|
|
|
|
|
## 語法錯誤導致服務無法啟動
|
|
|
|
|
|
|
|
當項目啟動時,拋出類似於以下錯誤時
|
|
|
|
|
|
|
|
```
|
|
|
|
Fatal error: Uncaught PhpParser\Error: Syntax error, unexpected T_STRING on line 27 in vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php:315
|
|
|
|
```
|
|
|
|
|
|
|
|
可以執行腳本 `composer analyse`,對項目進行靜態檢測,便可以找到出現問題的代碼段。
|
2020-09-28 10:47:04 +08:00
|
|
|
|
|
|
|
此問題通常是由於 [zircote/swagger](https://github.com/zircote/swagger-php) 的 3.0.5 版本更新導致, 詳情請見 [#834](https://github.com/zircote/swagger-php/issues/834) 。
|
|
|
|
如果安裝了 [hyperf/swagger](https://github.com/hyperf/swagger) 建議將 [zircote/swagger](https://github.com/zircote/swagger-php) 的版本鎖定在 3.0.4
|