Fixed code standards. (#1844)

This commit is contained in:
李铭昕 2020-06-01 14:01:52 +08:00 committed by GitHub
parent 73d859eaf2
commit 07f3d8d2e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 252 additions and 401 deletions

View File

@ -35,37 +35,6 @@ before_script:
- composer config -g process-timeout 900 && composer update
script:
- |
composer analyse \
src/amqp \
src/async-queue \
src/cache \
src/command \
src/config \
src/config-aliyun-acm \
src/config-apollo \
src/config-etcd \
src/constants \
src/consul \
src/db \
src/db-connection \
src/devtool \
src/di \
src/dispatcher \
src/elasticsearch \
src/etcd \
src/event \
src/exception-handler \
src/filesystem \
src/framework \
src/grpc-client \
src/guzzle \
src/http-message \
src/http-server \
src/json-rpc \
src/load-balancer \
src/logger \
src/memory \
src/metric
- composer analyse src
- composer test -- --exclude-group NonCoroutine
- vendor/bin/phpunit --group NonCoroutine

View File

@ -34,6 +34,15 @@
- Removed `Hyperf\Di\Aop\AstCollector`;
- Removed `Hyperf\Di\Aop\ProxyClassNameVisitor`;
- Removed `Hyperf\Di\Listener\LazyLoaderBootApplicationListener`
- Removed method `dispatch(...$params)` from `Hyperf\Dispatcher\AbstractDispatcher`
## Tip
- SymfonyNormalizer(^5.0) `$serializer->denormalize('1', 'int')` will throw `NotNormalizableValueException: Data expected to be of type "int" ("string" given).`
## Added
- [#1844](https://github.com/hyperf/hyperf/pull/1844) Support type `\DateInterval` for `ttl` in `model-cache`.
## Fixed

View File

@ -68,14 +68,15 @@
"php-di/phpdoc-reader": "^2.0.1",
"phpstan/phpstan": "^0.12.18",
"phpunit/phpunit": "^7.0.0",
"predis/predis": "^1.1",
"roave/better-reflection": "^4.0",
"smarty/smarty": "^3.1",
"squizlabs/php_codesniffer": "^3.4",
"start-point/etcd-php": "^1.1",
"swoole/ide-helper": "dev-master",
"sy-records/think-template": "^2.0",
"symfony/event-dispatcher": "^5.0",
"symfony/console": "^5.0",
"symfony/event-dispatcher": "^5.0",
"symfony/finder": "^5.0",
"symfony/property-access": "^5.0",
"symfony/serializer": "^5.0",

View File

@ -11,6 +11,17 @@ parameters:
- %currentWorkingDirectory%/src/*/tests/*
- %currentWorkingDirectory%/src/*/publish/*
- %currentWorkingDirectory%/src/di/src/Resolver/FactoryResolver.php
- %currentWorkingDirectory%/src/circuit-breaker/*
- %currentWorkingDirectory%/src/config-zookeeper/*
- %currentWorkingDirectory%/src/contract/*
- %currentWorkingDirectory%/src/crontab/*
- %currentWorkingDirectory%/src/database/*
- %currentWorkingDirectory%/src/graphql/*
- %currentWorkingDirectory%/src/grpc/*
- %currentWorkingDirectory%/src/grpc-server/*
- %currentWorkingDirectory%/src/swagger/*
- %currentWorkingDirectory%/src/validation/*
- %currentWorkingDirectory%/src/view/*
ignoreErrors:
- '#side of && is always#'
- '#method Redis::zRevRangeByScore\(\) expects int, string given#'
@ -23,3 +34,7 @@ parameters:
- '#Unsafe usage of new static#'
- '#Method Hyperf\\Contract\\Sendable::send#'
- '#Variable .* in PHPDoc tag @var does not exist#'
- '#Call to an undefined method Hyperf\\DbConnection\\Model\\Model::hydrate#'
- '#PHPDoc tag @param has invalid value#'
- '#Static call to instance method Hyperf\\RpcServer\\Router\\Router::#'
- '#Method Hyperf\\Utils\\Serializer\\ScalarNormalizer::denormalize\(\) should return array\|object but returns#'

View File

@ -161,6 +161,7 @@ abstract class Command extends SymfonyCommand
/**
* Give the user a multiple choice from an array of answers.
* @param null|mixed $default
*/
public function choiceMultiple(
string $question,
@ -178,14 +179,13 @@ abstract class Command extends SymfonyCommand
/**
* Give the user a single choice from an array of answers.
*
* @param null|bool $multiple Deprecated: use choiceMultiple method instead.
* @param null|mixed $default
*/
public function choice(
string $question,
array $choices,
$default = null,
$attempts = null,
$multiple = null
?int $attempts = null
): string {
return $this->choiceMultiple($question, $choices, $default, $attempts)[0];
}

View File

@ -15,7 +15,6 @@ use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\TransferException;
use Hyperf\Consul\Exception\ClientException;
use Hyperf\Consul\Exception\ServerException;
use Hyperf\Contract\StdoutLoggerInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

View File

@ -26,7 +26,7 @@ interface NormalizerInterface
*
* @param mixed $data Data to restore
* @param string $class The expected class to instantiate
* @return object
* @return mixed|object
*/
public function denormalize($data, $class);
}

View File

@ -34,7 +34,7 @@ class Config
/**
* The lifetime of model cache.
* @var int
* @var \DateInterval|int
*/
protected $ttl = 3600;
@ -126,12 +126,18 @@ class Config
return $this;
}
public function getTtl(): int
/**
* @return \DateInterval|int
*/
public function getTtl()
{
return $this->ttl;
}
public function setTtl(int $ttl): Config
/**
* @param \DateInterval|int $ttl
*/
public function setTtl($ttl): Config
{
$this->ttl = $ttl;
return $this;

View File

@ -18,18 +18,20 @@ use Hyperf\ModelCache\Redis\HashIncr;
use Hyperf\ModelCache\Redis\LuaManager;
use Hyperf\Redis\RedisProxy;
use Hyperf\Utils\Contracts\Arrayable;
use Hyperf\Utils\InteractsWithTime;
use Psr\Container\ContainerInterface;
use Redis;
class RedisHandler implements HandlerInterface
{
use InteractsWithTime;
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var Redis
* @var RedisProxy
*/
protected $redis;
@ -87,8 +89,11 @@ class RedisHandler implements HandlerInterface
$data = array_merge($data, [$this->defaultKey => $this->defaultValue]);
$res = $this->redis->hMSet($key, $data);
if ($ttl && $ttl > 0) {
$this->redis->expire($key, $ttl);
if ($ttl) {
$seconds = $this->secondsUntil($ttl);
if ($seconds > 0) {
$this->redis->expire($key, $seconds);
}
}
return $res;

View File

@ -16,18 +16,21 @@ use Hyperf\ModelCache\Config;
use Hyperf\ModelCache\Exception\CacheException;
use Hyperf\Redis\RedisProxy;
use Hyperf\Utils\Contracts\Arrayable;
use Hyperf\Utils\InteractsWithTime;
use Hyperf\Utils\Packer\PhpSerializerPacker;
use Psr\Container\ContainerInterface;
class RedisStringHandler implements HandlerInterface
{
use InteractsWithTime;
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var Redis
* @var RedisProxy
*/
protected $redis;
@ -74,13 +77,13 @@ class RedisStringHandler implements HandlerInterface
}
$serialized = $this->packer->pack($data);
if ($ttl && $ttl > 0) {
$res = $this->redis->set($key, $serialized, ['EX' => $ttl]);
} else {
$res = $this->redis->set($key, $serialized);
if ($ttl) {
$seconds = $this->secondsUntil($ttl);
if ($seconds > 0) {
return $this->redis->set($key, $serialized, ['EX' => $seconds]);
}
}
return $res;
return $this->redis->set($key, $serialized);
}
public function delete($key)

View File

@ -217,7 +217,7 @@ class Manager
}
/**
* @param $id
* @param int|string $id
*/
protected function getCacheKey($id, Model $model, Config $config): string
{

View File

@ -14,6 +14,8 @@ namespace HyperfTest\ModelCache\Handler;
use Hyperf\ModelCache\Config;
use Hyperf\ModelCache\Handler\HandlerInterface;
use Hyperf\ModelCache\Handler\RedisHandler;
use Hyperf\Redis\RedisProxy;
use Hyperf\Utils\ApplicationContext;
use HyperfTest\ModelCache\Stub\ContainerStub;
use Mockery;
use PHPUnit\Framework\TestCase;
@ -40,6 +42,23 @@ class RedisHandlerTest extends TestCase
$this->assertSame(['id' => $id], $data);
}
public function testSetTtl()
{
$handler = $this->mockHandler();
$key = 'test:model-cache:' . $this->handler . ':1';
$handler->set($key, ['id' => $id = uniqid()], 10);
$data = $handler->get($key);
$this->assertSame(['id' => $id], $data);
$redis = ApplicationContext::getContainer()->make(RedisProxy::class, ['pool' => 'default']);
$this->assertSame(10, $redis->ttl($key));
$handler->set($key, ['id' => $id = uniqid()], new \DateInterval('PT12S'));
$this->assertSame(12, $redis->ttl($key));
$handler->set($key, ['id' => $id = uniqid()], new \DateInterval('P1DT12S'));
$this->assertSame(86400 + 12, $redis->ttl($key));
}
public function testDelete()
{
$handler = $this->mockHandler();

View File

@ -193,6 +193,34 @@ class ModelCacheTest extends TestCase
$this->assertEquals(array_keys($model->getAttributes()), array_keys($model3->getAttributes()));
}
public function testModelCacheExpireTime()
{
$container = ContainerStub::mockContainer();
/** @var UserExtModel $model */
$model = UserExtModel::query()->find(1);
$model->deleteCache();
/** @var \Redis $redis */
$redis = $container->make(RedisProxy::class, ['pool' => 'default']);
UserExtModel::findFromCache(1);
$this->assertSame(86400, $redis->ttl('{mc:default:m:user_ext}:id:1'));
}
public function testModelCacheExpireTimeWithDateInterval()
{
$container = ContainerStub::mockContainer(new \DateInterval('P1DT10S'));
/** @var UserExtModel $model */
$model = UserExtModel::query()->find(1);
$model->deleteCache();
/** @var \Redis $redis */
$redis = $container->make(RedisProxy::class, ['pool' => 'default']);
UserExtModel::findFromCache(1);
$this->assertSame(86410, $redis->ttl('{mc:default:m:user_ext}:id:1'));
}
public function testModelCacheWithHidden()
{
ContainerStub::mockContainer();

View File

@ -42,7 +42,7 @@ use Psr\Log\LogLevel;
class ContainerStub
{
public static function mockContainer()
public static function mockContainer($ttl = 86400)
{
$container = Mockery::mock(Container::class);
$container->shouldReceive('get')->with(TableCollector::class)->andReturn(new TableCollector());
@ -81,7 +81,7 @@ class ContainerStub
'cache_key' => '{mc:%s:m:%s}:%s:%s',
'prefix' => 'default',
'pool' => 'default',
'ttl' => 3600 * 24,
'ttl' => $ttl, // new \DateInterval('P1D'),
'empty_model_ttl' => 3600,
'load_script' => true,
'use_default_value' => true,

View File

@ -534,7 +534,7 @@ class Connection
*
* @param int $len number of bytes to receive
*
* @return string
* @return bool|string
*/
private function receive(int $len = 0)
{

View File

@ -422,7 +422,7 @@ class ConnectionOptions
/**
* Initialize the parameters.
*
* @param array|Traversable $options the connection options
* @param array|mixed|Traversable $options the connection options
*
* @throws Exception when $options are an invalid type
*/

View File

@ -40,7 +40,7 @@ class ConsumerManager
{
$classes = AnnotationCollector::getClassByAnnotation(ConsumerAnnotation::class);
/**
* @var string
* @var string $class
* @var ConsumerAnnotation $annotation
*/
foreach ($classes as $class => $annotation) {

View File

@ -80,6 +80,6 @@ class EncodedConnection extends Connection
$message->setBody($this->encoder->decode($message->getBody()));
$callback($message);
};
parent::queueSubscribe($subject, $queue, $c);
return parent::queueSubscribe($subject, $queue, $c);
}
}

View File

@ -40,7 +40,7 @@ class ConsumerManager
{
$classes = AnnotationCollector::getClassByAnnotation(ConsumerAnnotation::class);
/**
* @var string
* @var string $class
* @var ConsumerAnnotation $annotation
*/
foreach ($classes as $class => $annotation) {

View File

@ -166,6 +166,7 @@ class MessageBuilder
$command = "IDENTIFY\n";
$version = PrettyVersions::getVersion('hyperf/nsq') ?? '1.0';
$hostname = value(function () {
/** @var mixed|string $ip */
$ip = gethostbyname(gethostname());
if (is_string($ip)) {
return $ip;

View File

@ -77,6 +77,9 @@ class NsqConnection extends KeepaliveConnection
return $socket;
}
/**
* @param Socket $connection
*/
protected function sendClose($connection): void
{
try {

View File

@ -96,6 +96,6 @@ class Subscriber
private function isMatchResponse($response): bool
{
return ! is_null($this->getPayload()) && (int) $this->type === self::TYPE_RESPONSE && $response === $this->getPayload();
return (int) $this->type === self::TYPE_RESPONSE && $response === $this->getPayload();
}
}

View File

@ -171,9 +171,8 @@ abstract class AbstractPaginator implements PaginatorInterface
* Add a set of query string values to the paginator.
*
* @param null|array|string $key
* @return $this
*/
public function appends($key, ?string $value = null)
public function appends($key, ?string $value = null): self
{
if (is_null($key)) {
return $this;
@ -191,7 +190,10 @@ abstract class AbstractPaginator implements PaginatorInterface
*/
public function loadMorph(string $relation, array $relations): self
{
$this->getCollection()->loadMorph($relation, $relations);
$collection = $this->getCollection();
if (method_exists($collection, 'loadMorph')) {
$collection->loadMorph($relation, $relations);
}
return $this;
}

View File

@ -18,7 +18,7 @@ class UrlWindow
/**
* The paginator implementation.
*
* @var LengthAwarePaginatorInterface
* @var AbstractPaginator|LengthAwarePaginatorInterface
*/
protected $paginator;

View File

@ -38,4 +38,11 @@ class LengthAwarePaginatorTest extends TestCase
$this->assertSame(3, $paginator->firstItem());
$this->assertSame(4, $paginator->lastItem());
}
public function testAppends()
{
$paginator = new LengthAwarePaginator([1, 2], 10, 2, 2);
$paginator = $paginator->appends('keyword', 'Hyperf');
$this->assertSame('/?keyword=Hyperf&page=1', $paginator->url(1));
}
}

View File

@ -11,6 +11,7 @@ declare(strict_types=1);
*/
namespace Hyperf\Pool;
use Hyperf\Contract\ConnectionInterface;
use Hyperf\Utils\Coroutine;
use Swoole\Coroutine\Channel as CoChannel;
@ -35,6 +36,9 @@ class Channel
$this->queue = new \SplQueue();
}
/**
* @return ConnectionInterface
*/
public function pop(float $timeout)
{
if ($this->isCoroutine()) {
@ -43,12 +47,17 @@ class Channel
return $this->queue->shift();
}
/**
* @param ConnectionInterface $data
* @return bool
*/
public function push($data)
{
if ($this->isCoroutine()) {
return $this->channel->push($data);
}
return $this->queue->push($data);
$this->queue->push($data);
return true;
}
public function length(): int

View File

@ -224,7 +224,7 @@ abstract class KeepaliveConnection implements ConnectionInterface
/**
* Send close protocol.
* @param $connection
* @param mixed $connection
*/
protected function sendClose($connection): void
{

View File

@ -35,7 +35,7 @@ class RateLimit extends AbstractAnnotation
public $capacity;
/**
* @var callable
* @var null|callable
*/
public $limitCallback;

View File

@ -109,6 +109,7 @@ class RateLimitAnnotationAspect implements AroundInterface
public function getWeightingAnnotation(array $annotations): RateLimit
{
$property = array_merge($this->annotationProperty, $this->config);
/** @var null|RateLimit $annotation */
foreach ($annotations as $annotation) {
if (! $annotation) {
continue;

View File

@ -60,7 +60,7 @@ class RedisStorage implements Storage, GlobalScope
public function isBootstrapped()
{
try {
return $this->redis->exists($this->key);
return (bool) $this->redis->exists($this->key);
} catch (InvalidArgumentException $e) {
throw new StorageException('Failed to check for key existence', 0, $e);
}

View File

@ -202,7 +202,6 @@ abstract class AbstractServiceClient
break;
default:
throw new InvalidArgumentException(sprintf('Invalid protocol of registry %s', $registryProtocol));
break;
}
return [$nodes, $refreshCallback];
}

View File

@ -18,12 +18,12 @@ use InvalidArgumentException;
class Client
{
/**
* @var PackerInterface
* @var null|PackerInterface
*/
private $packer;
/**
* @var TransporterInterface
* @var null|TransporterInterface
*/
private $transporter;

View File

@ -1,47 +0,0 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\RpcClient\Pool;
use Hyperf\Di\Container;
use Psr\Container\ContainerInterface;
class PoolFactory
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var RpcClientPool[]
*/
protected $pools = [];
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getPool(string $name): RpcClientPool
{
if (isset($this->pools[$name])) {
return $this->pools[$name];
}
if ($this->container instanceof Container) {
$pool = $this->container->make(RpcClientPool::class, ['name' => $name]);
} else {
$pool = new RpcClientPool($this->container, $name);
}
return $this->pools[$name] = $pool;
}
}

View File

@ -1,67 +0,0 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\RpcClient\Pool;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Contract\ConnectionInterface;
use Hyperf\Pool\Pool;
use Hyperf\Rpc\Contract\PackerInterface;
use Hyperf\RpcClient\Client;
use Hyperf\Utils\Arr;
use Psr\Container\ContainerInterface;
class RpcClientPool extends Pool
{
/**
* @var string
*/
protected $name;
/**
* @var array
*/
protected $config;
public function __construct(ContainerInterface $container, string $name)
{
$this->name = $name;
$config = $container->get(ConfigInterface::class);
$key = sprintf('services.consumers.%s', $this->name);
if (! $config->has($key)) {
throw new \InvalidArgumentException(sprintf('config[%s] is not exist!', $key));
}
$this->config = $config->get($key);
$options = Arr::get($this->config, 'pool', []);
parent::__construct($container, $options);
}
public function getName(): string
{
return $this->name;
}
protected function createConnection(): ConnectionInterface
{
$packer = $this->container->get(PackerInterface::class);
$config = [
'host' => '0.0.0.0',
'port' => 9502,
'options' => [
'open_eof_split' => true,
'package_eof' => "\r\n",
],
];
return new Client($config, $packer);
}
}

View File

@ -39,6 +39,7 @@ class ProxyCallVisitor extends NodeVisitorAbstract
if ($node instanceof Node\Stmt\Namespace_) {
$this->namespace = $node->name->toCodeString();
}
return null;
}
public function leaveNode(Node $node)
@ -53,6 +54,7 @@ class ProxyCallVisitor extends NodeVisitorAbstract
],
]);
}
return null;
}
public function generateStmts(Interface_ $node): array
@ -66,15 +68,18 @@ class ProxyCallVisitor extends NodeVisitorAbstract
return $stmts;
}
protected function overrideMethod(Node\Stmt\ClassMethod $stmt): Node\Stmt\ClassMethod
protected function overrideMethod(Node\FunctionLike $stmt): Node\Stmt\ClassMethod
{
if (! $stmt instanceof Node\Stmt\ClassMethod) {
throw new \InvalidArgumentException('stmt must instanceof Node\Stmt\ClassMethod');
}
$stmt->stmts = value(function () use ($stmt) {
$methodCall = new Node\Expr\MethodCall(
new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), new Node\Identifier('client')),
new Node\Identifier('__call'),
[
new Node\Scalar\MagicConst\Function_(),
new Node\Expr\FuncCall(new Node\Name('func_get_args')),
new Node\Arg(new Node\Scalar\MagicConst\Function_()),
new Node\Arg(new Node\Expr\FuncCall(new Node\Name('func_get_args'))),
]
);
if ($this->shouldReturn($stmt)) {

View File

@ -16,6 +16,7 @@ use Hyperf\Dispatcher\HttpRequestHandler;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
class RequestDispatcher extends HttpDispatcher
{
@ -33,7 +34,7 @@ class RequestDispatcher extends HttpDispatcher
{
/** @var ServerRequestInterface $request */
/** @var array $middlewares */
/** @var string $coreHandler */
/** @var MiddlewareInterface $coreHandler */
[$request, $middlewares, $coreHandler] = $params;
$requestHandler = new HttpRequestHandler($middlewares, $coreHandler, $this->container);
return $requestHandler->handle($request);

View File

@ -53,7 +53,6 @@ class RouteCollector
*
* The syntax used in the $route string depends on the used route parser.
*
* @param string|string[] $httpMethod
* @param mixed $handler
*/
public function addRoute(string $route, $handler, array $options = [])

View File

@ -12,7 +12,6 @@ declare(strict_types=1);
namespace Hyperf\Server;
use Hyperf\Contract\MiddlewareInitializerInterface;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Framework\Bootstrap;
use Hyperf\Framework\Event\BeforeMainServerStart;
use Hyperf\Framework\Event\BeforeServerStart;
@ -47,7 +46,7 @@ class Server implements ServerInterface
protected $onRequestCallbacks = [];
/**
* @var StdoutLoggerInterface
* @var LoggerInterface
*/
protected $logger;
@ -109,7 +108,7 @@ class Server implements ServerInterface
$this->eventDispatcher->dispatch(new BeforeMainServerStart($this->server, $config->toArray()));
}
} else {
/** @var \Swoole\Server\Port $slaveServer */
/** @var bool|\Swoole\Server\Port $slaveServer */
$slaveServer = $this->server->addlistener($host, $port, $sockType);
if (! $slaveServer) {
throw new \RuntimeException("Failed to listen server port [{$host}:{$port}]");

View File

@ -25,12 +25,12 @@ class ServerFactory
protected $container;
/**
* @var LoggerInterface
* @var null|LoggerInterface
*/
protected $logger;
/**
* @var EventDispatcherInterface
* @var null|EventDispatcherInterface
*/
protected $eventDispatcher;

View File

@ -63,7 +63,7 @@ class InitProcessTitleListenerTest extends TestCase
$listener->process(new BeforeProcessHandle($process, 1));
if (!$listener->isSupportedOS()) {
if (! $listener->isSupportedOS()) {
$this->assertSame(null, Context::get('test.server.process.title'));
} else {
$this->assertSame('test.demo.1', Context::get('test.server.process.title'));
@ -85,7 +85,7 @@ class InitProcessTitleListenerTest extends TestCase
$listener->process(new BeforeProcessHandle($process, 0));
if (!$listener->isSupportedOS()) {
if (! $listener->isSupportedOS()) {
$this->assertSame(null, Context::get('test.server.process.title'));
} else {
$this->assertSame($name . '.test.demo.0', Context::get('test.server.process.title'));
@ -107,7 +107,7 @@ class InitProcessTitleListenerTest extends TestCase
$listener->process(new BeforeProcessHandle($process, 0));
if (!$listener->isSupportedOS()) {
if (! $listener->isSupportedOS()) {
$this->assertSame(null, Context::get('test.server.process.title'));
} else {
$this->assertSame($name . '#test.demo#0', Context::get('test.server.process.title'));

View File

@ -247,9 +247,10 @@ class RegisterServiceListener implements ListenerInterface
protected function getInternalIp(): string
{
$ips = swoole_get_local_ip();
if (is_array($ips)) {
if (is_array($ips) && ! empty($ips)) {
return current($ips);
}
/** @var mixed|string $ip */
$ip = gethostbyname(gethostname());
if (is_string($ip)) {
return $ip;

View File

@ -51,11 +51,7 @@ class FileHandler implements SessionHandlerInterface
* Close the session.
*
* @see https://php.net/manual/en/sessionhandlerinterface.close.php
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function close()
{
@ -67,11 +63,7 @@ class FileHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.destroy.php
* @param string $session_id the session ID being destroyed
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function destroy($session_id)
{
@ -83,15 +75,8 @@ class FileHandler implements SessionHandlerInterface
* Cleanup old sessions.
*
* @see https://php.net/manual/en/sessionhandlerinterface.gc.php
* @param int $maxlifetime <p>
* Sessions that have not updated for
* the last maxlifetime seconds will be removed.
* </p>
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @param int $maxlifetime
* @return bool
*/
public function gc($maxlifetime)
{
@ -114,11 +99,7 @@ class FileHandler implements SessionHandlerInterface
* @see https://php.net/manual/en/sessionhandlerinterface.open.php
* @param string $save_path the path where to store/retrieve the session
* @param string $name the session name
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function open($save_path, $name)
{
@ -130,12 +111,7 @@ class FileHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.read.php
* @param string $session_id the session id to read data for
* @return string <p>
* Returns an encoded string of the read data.
* If nothing was read, it must return an empty string.
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return string
*/
public function read($session_id)
{
@ -153,18 +129,8 @@ class FileHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.write.php
* @param string $session_id the session id
* @param string $session_data <p>
* The encoded session data. This data is the
* result of the PHP internally encoding
* the $_SESSION superglobal to a serialized
* string and passing it as this parameter.
* Please note sessions use an alternative serialization method.
* </p>
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @param string $session_data
* @return bool
*/
public function write($session_id, $session_data)
{

View File

@ -19,11 +19,7 @@ class NullHandler implements SessionHandlerInterface
* Close the session.
*
* @see https://php.net/manual/en/sessionhandlerinterface.close.php
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function close()
{
@ -35,11 +31,7 @@ class NullHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.destroy.php
* @param string $session_id the session ID being destroyed
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function destroy($session_id)
{
@ -50,15 +42,8 @@ class NullHandler implements SessionHandlerInterface
* Cleanup old sessions.
*
* @see https://php.net/manual/en/sessionhandlerinterface.gc.php
* @param int $maxlifetime <p>
* Sessions that have not updated for
* the last maxlifetime seconds will be removed.
* </p>
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @param int $maxlifetime
* @return bool
*/
public function gc($maxlifetime)
{
@ -71,11 +56,7 @@ class NullHandler implements SessionHandlerInterface
* @see https://php.net/manual/en/sessionhandlerinterface.open.php
* @param string $save_path the path where to store/retrieve the session
* @param string $name the session name
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function open($save_path, $name)
{
@ -87,12 +68,7 @@ class NullHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.read.php
* @param string $session_id the session id to read data for
* @return string <p>
* Returns an encoded string of the read data.
* If nothing was read, it must return an empty string.
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return string
*/
public function read($session_id)
{
@ -104,18 +80,8 @@ class NullHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.write.php
* @param string $session_id the session id
* @param string $session_data <p>
* The encoded session data. This data is the
* result of the PHP internally encoding
* the $_SESSION superglobal to a serialized
* string and passing it as this parameter.
* Please note sessions use an alternative serialization method.
* </p>
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @param string $session_data
* @return bool
*/
public function write($session_id, $session_data)
{

View File

@ -40,11 +40,7 @@ class RedisHandler implements SessionHandlerInterface
* Close the session.
*
* @see https://php.net/manual/en/sessionhandlerinterface.close.php
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function close()
{
@ -56,11 +52,7 @@ class RedisHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.destroy.php
* @param string $session_id the session ID being destroyed
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function destroy($session_id)
{
@ -72,15 +64,8 @@ class RedisHandler implements SessionHandlerInterface
* Cleanup old sessions.
*
* @see https://php.net/manual/en/sessionhandlerinterface.gc.php
* @param int $maxlifetime <p>
* Sessions that have not updated for
* the last maxlifetime seconds will be removed.
* </p>
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @param int $maxlifetime
* @return bool
*/
public function gc($maxlifetime)
{
@ -93,11 +78,7 @@ class RedisHandler implements SessionHandlerInterface
* @see https://php.net/manual/en/sessionhandlerinterface.open.php
* @param string $save_path the path where to store/retrieve the session
* @param string $name the session name
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return bool
*/
public function open($save_path, $name)
{
@ -109,12 +90,7 @@ class RedisHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.read.php
* @param string $session_id the session id to read data for
* @return string <p>
* Returns an encoded string of the read data.
* If nothing was read, it must return an empty string.
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @return string
*/
public function read($session_id)
{
@ -126,18 +102,8 @@ class RedisHandler implements SessionHandlerInterface
*
* @see https://php.net/manual/en/sessionhandlerinterface.write.php
* @param string $session_id the session id
* @param string $session_data <p>
* The encoded session data. This data is the
* result of the PHP internally encoding
* the $_SESSION superglobal to a serialized
* string and passing it as this parameter.
* Please note sessions use an alternative serialization method.
* </p>
* @return bool <p>
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @since 5.4.0
* @param string $session_data
* @return bool
*/
public function write($session_id, $session_data)
{

View File

@ -76,7 +76,7 @@ class SessionMiddleware implements MiddlewareInterface
*/
private function url(RequestInterface $request): string
{
return rtrim(preg_replace('/\?.*/', '', $request->getUri()));
return rtrim(preg_replace('/\?.*/', '', (string) $request->getUri()));
}
/**

View File

@ -280,15 +280,7 @@ class RedisAdapter implements AdapterInterface
private function formatThrowable(\Throwable $throwable): string
{
sprintf(
"%s:%s(%s) in %s:%s\nStack trace:\n%s",
get_class($throwable),
$throwable->getMessage(),
$throwable->getCode(),
$throwable->getFile(),
$throwable->getLine(),
$throwable->getTraceAsString()
);
return (string) $throwable;
}
private function phpRedisSubscribe()
@ -309,9 +301,6 @@ class RedisAdapter implements AdapterInterface
{
$sub->subscribe($this->getChannelKey());
$chan = $sub->channel();
if (! $chan) {
return;
}
Coroutine::create(function () use ($sub) {
CoordinatorManager::get(Constants::ON_WORKER_EXIT)->yield();
$sub->close();

View File

@ -12,13 +12,13 @@ declare(strict_types=1);
namespace Hyperf\SuperGlobals;
use ArrayAccess;
use Hyperf\Contract\ContainerInterface;
use Hyperf\SuperGlobals\Exception\ContainerNotFoundException;
use Hyperf\SuperGlobals\Exception\RequestNotFoundException;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Context;
use Hyperf\Utils\Contracts\Arrayable;
use JsonSerializable;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;
abstract class Proxy implements Arrayable, ArrayAccess, JsonSerializable

View File

@ -63,7 +63,11 @@ class TaskExecutor
if ($result instanceof Exception) {
$exception = $this->normalizer->denormalize($result->attributes, $result->class);
throw $exception;
if ($exception instanceof \Throwable) {
throw $exception;
}
throw new TaskExecuteException(get_class($exception) . ' is not instance of Throwable.');
}
return $result;

View File

@ -408,6 +408,8 @@ class Translator implements TranslatorInterface
return $line;
}
return null;
}
/**

View File

@ -255,7 +255,7 @@ class Arr
* Check if an item or items exist in an array using "dot" notation.
*
* @param array|\ArrayAccess $array
* @param array|string $keys
* @param null|array|string $keys
*/
public static function has($array, $keys): bool
{
@ -390,7 +390,6 @@ class Arr
* Set an array item to a given value using "dot" notation.
* If no key is given to the method, the entire array will be replaced.
*
* @param array|\ArrayAccess $array
* @param null|int|string $key
* @param mixed $value
*/

View File

@ -55,7 +55,7 @@ class ClearStatCache
return self::$interval;
}
public static function setInterval(int $interval): self
public static function setInterval(int $interval)
{
self::$interval = $interval;
}

View File

@ -226,7 +226,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
public function mode($key = null)
{
if ($this->count() == 0) {
return;
return null;
}
$collection = isset($key) ? $this->pluck($key) : $this;
$counts = new self();
@ -1111,7 +1111,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
return new static();
}
$groups = new static();
$groupSize = floor($this->count() / $numberOfGroups);
$groupSize = (int) floor($this->count() / $numberOfGroups);
$remain = $this->count() % $numberOfGroups;
$start = 0;
for ($i = 0; $i < $numberOfGroups; ++$i) {
@ -1347,7 +1347,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
return $value->jsonSerialize();
}
if ($value instanceof Jsonable) {
return json_decode($value->toJson(), true);
return json_decode($value->__toString(), true);
}
if ($value instanceof Arrayable) {
return $value->toArray();
@ -1534,7 +1534,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
return $items->toArray();
}
if ($items instanceof Jsonable) {
return json_decode($items->toJson(), true);
return json_decode($items->__toString(), true);
}
if ($items instanceof JsonSerializable) {
return $items->jsonSerialize();

View File

@ -16,12 +16,12 @@ use Composer\Autoload\ClassLoader;
class Composer
{
/**
* @var Collection
* @var null|Collection
*/
private static $content;
/**
* @var Collection
* @var null|Collection
*/
private static $json;
@ -41,7 +41,7 @@ class Composer
private static $versions = [];
/**
* @var ClassLoaders
* @var null|ClassLoader
*/
private static $classLoader;

View File

@ -64,11 +64,9 @@ class Context
*/
public static function copy(int $fromCoroutineId, array $keys = []): void
{
/**
* @var \ArrayObject
* @var \ArrayObject $current
*/
/** @var \ArrayObject $from */
$from = SwCoroutine::getContext($fromCoroutineId);
/** @var \ArrayObject $current */
$current = SwCoroutine::getContext();
$current->exchangeArray($keys ? Arr::only($from->getArrayCopy(), $keys) : $from->getArrayCopy());
}

View File

@ -11,8 +11,6 @@ declare(strict_types=1);
*/
namespace Hyperf\Utils\Contracts;
use Hyperf\Validation\Contracts\Support\MessageProvider;
interface MessageBag
{
/**

View File

@ -115,7 +115,7 @@ class Filesystem
public function put(string $path, $contents, bool $lock = false)
{
if ($lock) {
return $this->atomic($path, function ($path) use ($contents, $lock) {
return $this->atomic($path, function ($path) use ($contents) {
$handle = fopen($path, 'w+');
if ($handle) {
$wouldBlock = false;

View File

@ -66,7 +66,7 @@ if (! function_exists('retry')) {
/**
* Retry an operation a given number of times.
*
* @param int|float $times
* @param float|int $times
* @param int $sleep millisecond
* @throws \Throwable
*/
@ -126,7 +126,7 @@ if (! function_exists('data_get')) {
/**
* Get an item from an array or object using "dot" notation.
*
* @param array|int|string $key
* @param null|array|int|string $key
* @param null|mixed $default
* @param mixed $target
*/
@ -207,6 +207,7 @@ if (! function_exists('data_set')) {
} else {
$target = [];
if ($segments) {
$target[$segment] = [];
data_set($target[$segment], $segments, $value, $overwrite);
} elseif ($overwrite) {
$target[$segment] = $value;
@ -447,7 +448,8 @@ if (! function_exists('swoole_hook_flags')) {
}
if (! function_exists('timepoint')) {
function timepoint(?string $key = null) {
function timepoint(?string $key = null)
{
if (! isset($GLOBALS['__timepoint_beginTime__'])) {
$GLOBALS['__timepoint_beginTime__'] = microtime(true);
return;

View File

@ -94,7 +94,7 @@ class MessageBag implements Arrayable, Countable, Jsonable, JsonSerializable, Me
/**
* Determine if messages exist for all of the given keys.
*
* @param array|string $key
* @param null|array|string $key
*/
public function has($key): bool
{

View File

@ -20,14 +20,11 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class ExceptionNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface
{
/**
* @var Instantiator
* @var null|Instantiator
*/
protected $instantiator;
/**
* {@inheritdoc}
*/
public function denormalize($data, $class, $format = null, array $context = [])
public function denormalize($data, string $class, string $format = null, array $context = [])
{
if (is_string($data)) {
$ex = unserialize($data);
@ -67,18 +64,12 @@ class ExceptionNormalizer implements NormalizerInterface, DenormalizerInterface,
return new \RuntimeException('Bad data data: ' . json_encode($data));
}
/**
* {@inheritdoc}
*/
public function supportsDenormalization($data, $type, $format = null)
{
return class_exists($type) && is_a($type, \Throwable::class, true);
}
/**
* {@inheritdoc}
*/
public function normalize($object, $format = null, array $context = [])
public function normalize($object, string $format = null, array $context = [])
{
if ($object instanceof \Serializable) {
return serialize($object);
@ -92,17 +83,11 @@ class ExceptionNormalizer implements NormalizerInterface, DenormalizerInterface,
];
}
/**
* {@inheritdoc}
*/
public function supportsNormalization($data, $format = null)
public function supportsNormalization($data, string $format = null)
{
return $data instanceof \Throwable;
}
/**
* {@inheritdoc}
*/
public function hasCacheableSupportsMethod(): bool
{
return \get_class($this) === __CLASS__;

View File

@ -24,7 +24,7 @@ class ScalarNormalizer implements NormalizerInterface, DenormalizerInterface, Ca
return get_class($this) === __CLASS__;
}
public function denormalize($data, $class, $format = null, array $context = [])
public function denormalize($data, string $class, string $format = null, array $context = [])
{
switch ($class) {
case 'int':
@ -40,7 +40,7 @@ class ScalarNormalizer implements NormalizerInterface, DenormalizerInterface, Ca
}
}
public function supportsDenormalization($data, $type, $format = null)
public function supportsDenormalization($data, $type, string $format = null)
{
return in_array($type, [
'int',
@ -52,12 +52,12 @@ class ScalarNormalizer implements NormalizerInterface, DenormalizerInterface, Ca
]);
}
public function normalize($object, $format = null, array $context = [])
public function normalize($object, string $format = null, array $context = [])
{
return $object;
}
public function supportsNormalization($data, $format = null)
public function supportsNormalization($data, string $format = null)
{
return is_scalar($data);
}

View File

@ -15,6 +15,7 @@ use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\SymfonyNormalizer;
use HyperfTest\Utils\Stub\Foo;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
/**
* @internal
@ -47,12 +48,6 @@ class SymfonySerializerTest extends TestCase
$this->assertInstanceOf(Foo::class, $ret[0]);
$this->assertEquals(10, $ret[0]->int);
$ret = $serializer->denormalize('1', 'int');
$this->assertSame(1, $ret);
$ret = $serializer->denormalize(['1', 2, '03'], 'int[]');
$this->assertSame([1, 2, 3], $ret);
$ret = $serializer->denormalize('1', 'mixed');
$this->assertSame('1', $ret);
@ -60,6 +55,19 @@ class SymfonySerializerTest extends TestCase
$this->assertSame(['1', 2, '03'], $ret);
}
public function testDenormalizeWithWrongType()
{
$this->expectException(NotNormalizableValueException::class);
$this->expectExceptionMessageRegExp('/Data expected to be of type/');
$serializer = $this->createSerializer();
$ret = $serializer->denormalize('1', 'int');
$this->assertSame(1, $ret);
$ret = $serializer->denormalize(['1', 2, '03'], 'int[]');
$this->assertSame([1, 2, 3], $ret);
}
public function testException()
{
$serializer = $this->createSerializer();

View File

@ -32,9 +32,9 @@ class Frame
public function __construct(SwFrame $frame)
{
foreach ($frame as $key => $val) {
$this->{$key} = $val;
}
$this->finish = $frame->finish;
$this->opcode = $frame->opcode;
$this->data = $frame->data;
}
public function __toString()

View File

@ -11,10 +11,10 @@ declare(strict_types=1);
*/
namespace Hyperf\WebSocketServer;
use Hyperf\HttpMessage\Base\Response;
use Hyperf\HttpServer\CoreMiddleware as HttpCoreMiddleware;
use Hyperf\HttpServer\Router\Dispatched;
use Hyperf\Utils\Context;
use Hyperf\Utils\Contracts\Arrayable;
use Hyperf\WebSocketServer\Exception\WebSocketHandeShakeException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@ -23,8 +23,6 @@ class CoreMiddleware extends HttpCoreMiddleware
{
/**
* Handle the response when found.
*
* @return array|Arrayable|mixed|ResponseInterface|string
*/
protected function handleFound(Dispatched $dispatched, ServerRequestInterface $request): ResponseInterface
{
@ -33,7 +31,7 @@ class CoreMiddleware extends HttpCoreMiddleware
throw new WebSocketHandeShakeException('Router not exist.');
}
/** @var ResponseInterface $response */
/** @var Response $response */
$response = Context::get(ResponseInterface::class);
$security = $this->container->get(Security::class);

View File

@ -55,7 +55,9 @@ class Sender
$result = $this->check($fd);
if ($result) {
$this->getServer()->push(...$arguments);
/** @var \Swoole\WebSocket\Server $server */
$server = $this->getServer();
$server->push(...$arguments);
$this->logger->debug("[WebSocket] Worker.{$this->workerId} send to #{$fd}");
}

View File

@ -20,6 +20,7 @@ use Hyperf\Contract\OnOpenInterface;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Dispatcher\HttpDispatcher;
use Hyperf\ExceptionHandler\ExceptionHandlerDispatcher;
use Hyperf\HttpMessage\Base\Response;
use Hyperf\HttpMessage\Server\Request as Psr7Request;
use Hyperf\HttpMessage\Server\Response as Psr7Response;
use Hyperf\HttpServer\Contract\CoreMiddlewareInterface;
@ -33,7 +34,6 @@ use Hyperf\WebSocketServer\Context as WsContext;
use Hyperf\WebSocketServer\Exception\Handler\WebSocketExceptionHandler;
use Hyperf\WebSocketServer\Exception\WebSocketHandeShakeException;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Swoole\Http\Request as SwooleRequest;
@ -139,6 +139,7 @@ class Server implements MiddlewareInitializerInterface, OnHandShakeInterface, On
$middlewares = array_merge($middlewares, $registedMiddlewares);
}
/** @var Response $psr7Response */
$psr7Response = $this->dispatcher->dispatch($psr7Request, $middlewares, $this->coreMiddleware);
$class = $psr7Response->getAttribute('class');
@ -207,7 +208,7 @@ class Server implements MiddlewareInitializerInterface, OnHandShakeInterface, On
/**
* Initialize PSR-7 Request.
*/
protected function initRequest(SwooleRequest $request): RequestInterface
protected function initRequest(SwooleRequest $request): ServerRequestInterface
{
Context::set(ServerRequestInterface::class, $psr7Request = Psr7Request::loadFromSwooleRequest($request));
WsContext::set(ServerRequestInterface::class, $psr7Request);