13 KiB
2.0 Upgrade Guide
Version 2.0 has added many powerful functions. If you have already invested in a project for business use and created an application project of version 1.1 based on the officially provided Skeleton project, you can adjust your Skeleton project according to the following points: If you are a new project, follow the documentation to create a new project through the composer create-project hyperf/hyperf-skeleton
command to use the new 2.0 version of the skeleton code, if you are currently using a version lower than 1.1 , then you need to upgrade to 1.1 first and then upgrade to 2.0 according to this upgrade guide.
Upgrade Swoole to 4.5+
Version 2.0 has raised the minimum Swoole version requirement from 4.4+ to 4.5+. There are some differences in usage details between the two versions. Hyperf has adapted to this version difference in earlier versions, so you can ignore it. The difference details, upgrading the Swoole version to 4.5+ is mainly to reduce the long-term impact of the historical baggage on Hyperf. You can check the Swoole version in the current environment by executing php --ri swoole
. You can complete the upgrade of Swoole according to the Swoole documentation .
Entry file adds ClassLoader initialization
2.0 has changed the underlying logic of AOP, so you need to add a line of initialization code in the framework entry file bin/hyperf.php
, you need to add the code Hyperf\Di\ClassLoader:: in the first line of the entry anonymous function init();
, as follows:
<?php
ini_set('display_errors', 'on');
ini_set('display_startup_errors', 'on');
error_reporting(E_ALL);
date_default_timezone_set('Asia/Shanghai');
! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
require BASE_PATH . '/vendor/autoload.php';
// 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();
})();
Meanwhile, the PHPUnit entry file might do the same, located in tests/bootstrap.php
, like this:
<?php
declare(strict_types=1);
error_reporting(E_ALL);
date_default_timezone_set('Asia/Shanghai');
! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
Swoole\Runtime::enableCoroutine(true);
require BASE_PATH . '/vendor/autoload.php';
Hyperf\Di\ClassLoader::init();
$container = require BASE_PATH . '/config/container.php';
$container->get(Hyperf\Contract\ApplicationInterface::class);
Adjust composer.json
Due to the adjustment of the underlying logic of AOP in version 2.0, the init-proxy.sh
script has been removed, so you need to remove the "init-proxy' in
scripts.post-autoload-dumpfrom
composer.json. sh"
to execute the statement, and modify the command in post-autoload-dump
to the rm -rf runtime/container
statement.
{
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-autoload-dump": [
"rm -rf runtime/container"
],
"analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config",
"cs-fix": "php-cs-fixer fix $1",
"start": "php ./bin/hyperf.php start",
"test": "co-phpunit -c phpunit.xml --colors=always"
}
}
Adjust the dependency version of composer.json
Since we want to upgrade to the 2.0 version of the component, and the original skeleton project relies on the 1.1.x version of the component by default, we need to make some adjustments to the constraints of the dependency, and change the dependencies of all the original Hyperf components to ~1.1.0
is modified to ~2.0.0
, and you also need to modify the phpstan/phpstan
version dependency to ^0.12
, after the modification, you need to run composer update
to upgrade the dependencies to version 2.0.
Adjust Dockerfile
During the packaging process of the Docker image, actively executing the php bin/hyperf.php
command will help to create all the proxy classes and annotation scanning caches that need to be generated in advance, so that there is no need to scan again when the production environment is started, which can be extremely Greatly optimized production startup time and memory usage. The following examples do not contain unmodified Dockerfile code.
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
APP_ENV=prod \
SCAN_CACHEABLE=(true)
COPY . /opt/www
RUN composer install --no-dev -o && php bin/hyperf.php
EXPOSE 9501
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]
For users who are not deployed by Docker
, it should be noted that before restarting the service, it is best to execute php bin/hyperf.php
and then restart the service to reduce the time-consuming restart.
Adjust the config/config.php configuration file
You need to add two configuration items app_env
and scan_cacheable
to the config/config.php
configuration. The following code example does not contain other irrelevant configuration content, as shown below:
<?php
return [
// The production environment uses the prod value
'app_env' => env('APP_ENV', 'dev'),
// Whether to scan the cache with annotations
'scan_cacheable' => env('SCAN_CACHEABLE', false),
];
The scan_cacheable
configuration is used to control whether to use annotations to scan the cache when the application starts. There are related modifications in the above Dockerfile
and config/config.php
. When the value of this configuration is true
, when the project starts, it will consider that all classes have been scanned and the corresponding caches and proxies have been correctly generated, and the scanning phase will be skipped to optimize startup time and reduce memory overhead.
Modify config/autoload/logger.php
Because version 2.0 has improved the version that depends on Monolog, in the higher version of Monolog, the default log format has changed. If there are requirements for the log format, such as the need to connect with the log system according to the log format, you can modify config/ The
dateFormat configuration item of the autoload/logger.php
configuration file to keep it consistent with the previous version.
<?php
declare(strict_types=1);
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,
],
],
'processors' => [
],
],
];
Modify config/autoload/exceptions.php
Version 2.0 adjusted the processing logic of HTTP routing exception behaviors such as route not found (404), request method mismatch (405), etc., and changed to throw a sub-exception class of Hyperf\HttpMessage\Exception\HttpException
, and then ExceptionHandler is used to uniformly manage these exceptions and handle corresponding responses, so that users can also get a consistent response return experience by throwing corresponding exceptions, but since ExceptionHandler is a user-managed mechanism, the default in version 1.1 Skeleton configures an App\Exception\Handler\AppExceptionHandler
class to handle the exception and return it to the client with a 500 status code, so you need to use the Hyperf\HttpServer provided by version 2.0 to handle HttpException \Exception\Handler\HttpExceptionHandler
is configured in the config/autoload/exceptions.php
configuration file, and make sure to be in front of the App\Exception\Handler\AppExceptionHandler
configuration, the following configuration example omits extraneous configuration, as shown below :
<?php
return [
'handler' => [
'http' => [
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
],
],
];
After you complete the configuration of ExceptionHandler, you can directly access a route that does not exist. If the response status code is 404
, it can be understood that the modification of this configuration is completed.
Modify the gRPC client
In order to avoid naming conflicts with the actual business of gRPC, version 2.0 has adjusted the naming of the base class functions of the gRPC client.
simpleRequest
->_simpleRequest
clientStreamRequest
->_clientStreamRequest
getGrpcClient
->_getGrpcClient
In addition, some methods that should not be exposed have become private methods. If your gRPC client involves the invocation of the above methods, please adjust the naming.
Remove DI lazy load listener
If your project uses the lazy loading function of DI components, you need to register a Hyperf\Di\Listener\LazyLoaderBootApplicationListener
listener, but in version 2.0, this listener has been removed, you can use it directly This function, so if you have used this function before, you need to remove the registration of the listener in config/autoload/listeners.php
;
Bind the NormalizerInterface relationship
When you use the JSONRPC function and use the symfony/serializer
library to provide serialization functions, since version 2.0 no longer automatically maps the implementation class of Hyperf\Contract\NormalizerInterface
, you need to manually add the mapping relationship, as follows :
use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\Serializer;
return [
Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
Adjust the implementation class of Hyperf\Contract\ProcessInterface
The isEnable
method in Hyperf\Contract\ProcessInterface
adds a $server
parameter, isEnable($server): bool
, all implementation classes of ProcessInterface require you to make some adjustments to this method.
Check the config/autoload/aspects.php file
If you have done some thinning operations on Skeleton before, you need to check whether the config/autoload/aspects.php
file exists, if not, you need to add a file and return an empty array.
This problem will be fixed in 2.0.1, so this check is not required in the future.
Check the collector for custom annotations
If you use custom annotations and use a custom collector Collector
to collect annotation metadata, you need to configure the corresponding Collector
in annotations.scan.collectors
, because in development mode, it will be based on the file The modification time determines whether the file is modified, and then decides whether to re-collect the corresponding annotation metadata. So, when annotations.scan.collectors
is not configured, it will cause the annotations to take effect only when the server
is started for the first time.
As in the application layer, the configuration is located in the config/autoload/annotations.php
file, as follows:
<?php
return [
'scan' => [
'collectors' => [
CustomCollector::class,
],
],
];
For components, the configuration is provided by ConfigProvider, as follows:
<?php
return [
'annotations' => [
'scan' => [
'collectors' => [
CustomCollector::class,
],
],
]
];
Start the service and test the access interface
When using Swoole 4.5 and the view component, if there is a problem with interface 404, you can try to delete the static_handler_locations
configuration item in the config/autoload/server.php
file.
Paths under this configuration will be considered static file routes, so if /
is configured, it will cause all interfaces to be considered file paths, resulting in interface 404.
complete the upgrade
At this point, the upgrade of version 2.0 has been completed, but since each underlying file of Hyperf can be rewritten through DI, if you rewrite some internal files of the framework adjusted in this upgrade, you still need to rewrite it according to your to make some adjustments to the actual situation.
If you encounter any problems during or after the upgrade, please go to Github Issue to submit your issue, explain the problem you have encountered, and we will try to fix it as soon as possible help you out.