From 43505a54db5b14de8c96965167b08aa61d4481df Mon Sep 17 00:00:00 2001 From: Anna Damm Date: Thu, 5 Jun 2025 15:04:58 +0200 Subject: [PATCH 1/7] [php84-compatibility] fix deprecation error in php 8.4 --- src/Connection/TcpSocketException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Connection/TcpSocketException.php b/src/Connection/TcpSocketException.php index 79ce50f..4820bae 100644 --- a/src/Connection/TcpSocketException.php +++ b/src/Connection/TcpSocketException.php @@ -6,7 +6,7 @@ class TcpSocketException extends \RuntimeException { - public function __construct(string $host, int $port, string $message, \Exception $previous = null) + public function __construct(string $host, int $port, string $message, ?\Exception $previous = null) { parent::__construct( sprintf('Couldn\'t connect to host "%s:%d": %s', $host, $port, $message), From 5aef40ea55374206337a86ad38fadeaa40cf502c Mon Sep 17 00:00:00 2001 From: Anna Damm Date: Thu, 5 Jun 2025 15:05:17 +0200 Subject: [PATCH 2/7] [php84-compatibility] add 8.4 to ci matrix --- .github/workflows/php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 0355c33..eb5a346 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: operating-system: [ubuntu-latest] - php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3'] + php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout From 2e1ae587c20599b66945e1afb2840eab3be34b50 Mon Sep 17 00:00:00 2001 From: Anna Damm Date: Thu, 5 Jun 2025 15:07:58 +0200 Subject: [PATCH 3/7] [php84-compatibility] add php cs ignore env because php cs fixer is not fully 8.4 compliant --- .github/workflows/php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index eb5a346..a04cd6f 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -25,7 +25,7 @@ jobs: run: composer install --prefer-dist --no-progress --no-suggest --no-interaction - name: phpcs - run: vendor/bin/php-cs-fixer fix --diff --dry-run -v + run: PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix --diff --dry-run -v - name: psalm run: vendor/bin/psalm --show-info=false From bf82614816bf47dd38542cfd5c8467a4daf48daa Mon Sep 17 00:00:00 2001 From: Anna Damm Date: Thu, 5 Jun 2025 15:22:57 +0200 Subject: [PATCH 4/7] [php84-compatibility] update dev requirements, increase php version requirement to php 8.1 --- .gitignore | 1 + composer.json | 8 ++-- phpunit.xml.dist | 33 ++++++++++------ tests/unit/ClientTest.php | 60 +++++++++++------------------- tests/unit/Connection/FileTest.php | 5 ++- 5 files changed, 51 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index 6e26b63..6561bc0 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ stats.log # php-cs-fixer .php-cs-fixer.cache +/.phpunit.cache/test-results diff --git a/composer.json b/composer.json index 5f1b5e7..dcc2572 100644 --- a/composer.json +++ b/composer.json @@ -18,12 +18,12 @@ } ], "require": { - "php": ">= 7.3 || ^8" + "php": "^8.1" }, "require-dev": { - "phpunit/phpunit": "^9", - "vimeo/psalm": "^4.6", - "friendsofphp/php-cs-fixer": "^3.0" + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^6.12", + "friendsofphp/php-cs-fixer": "^3.75" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d42bd40..db9cc38 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,24 @@ - - - - ./src - - - - - tests/unit - - + + + + tests/unit + + + + + ./src + + diff --git a/tests/unit/ClientTest.php b/tests/unit/ClientTest.php index 7dbe98c..83678de 100644 --- a/tests/unit/ClientTest.php +++ b/tests/unit/ClientTest.php @@ -5,6 +5,8 @@ namespace Domnikl\Test\Statsd; use Domnikl\Statsd\Client as Client; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; class ClientTest extends TestCase @@ -58,7 +60,7 @@ public function testCountWithFloatValue() ); } - public function sampleRateData() + public static function sampleRateData() { return [ [0.9, 1, '0.9'], @@ -66,10 +68,8 @@ public function sampleRateData() ]; } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testCountWithSamplingRate(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -82,10 +82,8 @@ public function testCountWithSamplingRate(float $globalSampleRate, float $sample ); } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testCountWithSamplingRateAndTags(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -107,10 +105,8 @@ public function testIncrement() ); } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testIncrementWithSamplingRate(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -123,10 +119,8 @@ public function testIncrementWithSamplingRate(float $globalSampleRate, float $sa ); } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testIncrementWithSamplingRateAndTags(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -148,10 +142,8 @@ public function testDecrement() ); } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testDecrementWithSamplingRate(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -164,10 +156,8 @@ public function testDecrementWithSamplingRate(float $globalSampleRate, float $sa ); } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testDecrementWithSamplingRateAndTags(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -190,10 +180,8 @@ public function testCanMeasureTimingWithClosure() } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testTimingWithSamplingRate(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -232,10 +220,8 @@ public function testEndTimingReturnsTiming() $this->assertGreaterThanOrEqual($sleep / 1000, $this->client->endTiming($key)); } - /** - * @dataProvider sampleRateData - * @group sampling - */ + #[DataProvider('sampleRateData')] + #[Group('sampling')] public function testStartEndTimingWithSamplingRate(float $globalSampleRate, float $sampleRate, string $expectedSampleRate) { $client = new Client($this->connection, 'test', $globalSampleRate); @@ -265,9 +251,7 @@ public function testTimeClosure() ); } - /** - * @group memory - */ + #[Group('memory')] public function testMemory() { $this->client->memory('foo.bar'); @@ -277,9 +261,7 @@ public function testMemory() ); } - /** - * @group memory - */ + #[Group('memory')] public function testMemoryProfile() { $this->client->startMemoryProfile('foo.bar'); diff --git a/tests/unit/Connection/FileTest.php b/tests/unit/Connection/FileTest.php index a58513e..22cee85 100644 --- a/tests/unit/Connection/FileTest.php +++ b/tests/unit/Connection/FileTest.php @@ -5,6 +5,7 @@ namespace Domnikl\Test\Statsd\Connection; use Domnikl\Statsd\Connection\File; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class FileTest extends TestCase @@ -22,8 +23,8 @@ public function testSend() /** * @param string $metric - * @dataProvider dataForSendWrongData */ + #[DataProvider('dataForSendWrongData')] public function testSendWrongData(string $metric) { $connection = new File('php://memory'); @@ -34,7 +35,7 @@ public function testSendWrongData(string $metric) /** * @return string[] */ - public function dataForSendWrongData() + public static function dataForSendWrongData() { return [ [''], From d8b3193990023f6071e11d06d21081a0a9d4b836 Mon Sep 17 00:00:00 2001 From: Anna Damm Date: Thu, 5 Jun 2025 15:38:18 +0200 Subject: [PATCH 5/7] [php84-compatibility] fix psalm errors and make some silent --- psalm.xml | 5 +++++ src/Client.php | 8 ++++---- src/Connection/File.php | 2 +- src/Connection/InMemory.php | 2 +- src/Connection/InetSocket.php | 30 +++++++++++++++--------------- src/Connection/UdpSocket.php | 4 ++-- src/StatsdAwareTrait.php | 5 +---- 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/psalm.xml b/psalm.xml index 622e23e..e3032bf 100644 --- a/psalm.xml +++ b/psalm.xml @@ -51,5 +51,10 @@ + + + + + diff --git a/src/Client.php b/src/Client.php index a8be5d8..d50aada 100644 --- a/src/Client.php +++ b/src/Client.php @@ -129,7 +129,7 @@ public function timing(string $key, float $value, float $sampleRate = 1.0, array */ public function startTiming(string $key, array $tags = []): void { - $timingKey = $key . md5(json_encode($tags)); + $timingKey = $key . md5((string)json_encode($tags)); $this->timings[$timingKey] = gettimeofday(true); } @@ -145,7 +145,7 @@ public function startTiming(string $key, array $tags = []): void public function endTiming(string $key, float $sampleRate = 1.0, array $tags = []): ?float { $end = gettimeofday(true); - $timingKey = $key . md5(json_encode($tags)); + $timingKey = $key . md5((string)json_encode($tags)); if (isset($this->timings[$timingKey])) { $timing = ($end - $this->timings[$timingKey]) * 1000; @@ -266,10 +266,10 @@ private function send(string $key, $value, string $type, float $sampleRate, arra $key = $this->namespace . '.' . $key; } - $message = $key . ':' . $value . '|' . $type; + $message = $key . ':' . ((string)$value) . '|' . $type; if ($sampleRate < 1) { - $sampledData = $message . '|@' . $sampleRate; + $sampledData = $message . '|@' . ((string)$sampleRate); } else { $sampledData = $message; } diff --git a/src/Connection/File.php b/src/Connection/File.php index 70d67d3..ab7aff2 100644 --- a/src/Connection/File.php +++ b/src/Connection/File.php @@ -32,7 +32,7 @@ public function __construct(string $filePath, string $mode = "a+") private function open(): void { - $this->handle = @fopen($this->filePath, $this->mode); + $this->handle = @fopen($this->filePath, $this->mode) ?: null; } public function send(string $message): void diff --git a/src/Connection/InMemory.php b/src/Connection/InMemory.php index 4a9f9f8..9d276fb 100644 --- a/src/Connection/InMemory.php +++ b/src/Connection/InMemory.php @@ -15,7 +15,7 @@ class InMemory implements Connection /** * @var string[] */ - private $messages = []; + private array $messages = []; public function send(string $message): void { diff --git a/src/Connection/InetSocket.php b/src/Connection/InetSocket.php index e2a7946..bd83ef6 100644 --- a/src/Connection/InetSocket.php +++ b/src/Connection/InetSocket.php @@ -14,36 +14,28 @@ abstract class InetSocket implements Connection /** * host name - * - * @var string */ - protected $host; + protected string $host; /** * port number - * - * @var int */ - protected $port; + protected int $port; /** * Socket timeout - * - * @var int */ - private $timeout; + private int $timeout; /** * Persistent connection - * - * @var bool */ - private $persistent = false; + private bool $persistent; /** - * @var int + * @var int<1, max> */ - private $maxPayloadSize; + private int $maxPayloadSize; /** * instantiates the Connection object and a real connection to statsd @@ -64,11 +56,19 @@ public function __construct( $this->host = $host; $this->port = $port; $this->persistent = $persistent; - $this->maxPayloadSize = $mtu - + $maxPayloadSize = $mtu - self::IP_HEADER_SIZE - $this->getProtocolHeaderSize() - strlen(self::LINE_DELIMITER); + if ($maxPayloadSize <= 0) { + throw new \InvalidArgumentException( + 'The maximum payload size must be greater than 0. Please check the MTU value.' + ); + } + + $this->maxPayloadSize = $maxPayloadSize; + if ($timeout === null) { $this->timeout = (int) ini_get('default_socket_timeout'); } else { diff --git a/src/Connection/UdpSocket.php b/src/Connection/UdpSocket.php index 827a9b3..870559a 100644 --- a/src/Connection/UdpSocket.php +++ b/src/Connection/UdpSocket.php @@ -69,9 +69,9 @@ protected function connect(string $host, int $port, int $timeout, bool $persiste $url = 'udp://' . $host; if ($persistent) { - $this->socket = @pfsockopen($url, $port, $errorNumber, $errorMessage, $timeout); + $this->socket = @pfsockopen($url, $port, $errorNumber, $errorMessage, $timeout) ?: null; } else { - $this->socket = @fsockopen($url, $port, $errorNumber, $errorMessage, $timeout); + $this->socket = @fsockopen($url, $port, $errorNumber, $errorMessage, $timeout) ?: null; } } diff --git a/src/StatsdAwareTrait.php b/src/StatsdAwareTrait.php index aece9ce..e5dee24 100644 --- a/src/StatsdAwareTrait.php +++ b/src/StatsdAwareTrait.php @@ -7,10 +7,7 @@ */ trait StatsdAwareTrait { - /** - * @var Client - */ - protected $statsd; + protected Client $statsd; /** * Sets the StatsD client. From 4554dbf2d1b7f30f8bf9157af2412dd5f859ee4b Mon Sep 17 00:00:00 2001 From: Anna Damm Date: Thu, 5 Jun 2025 15:39:09 +0200 Subject: [PATCH 6/7] [php84-compatibility] remove php 7.4 and 8.0 from test matrix --- .github/workflows/php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index a04cd6f..14ce69a 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: operating-system: [ubuntu-latest] - php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + php-versions: ['8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout From 5b7b269efe43e1834f79062e0887d728cd9da20a Mon Sep 17 00:00:00 2001 From: Anna Damm Date: Thu, 19 Jun 2025 11:56:40 +0200 Subject: [PATCH 7/7] [php84-compatibility] remove breaking changes --- src/Connection/InetSocket.php | 24 ++++++++++++++++-------- src/StatsdAwareTrait.php | 5 ++++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/Connection/InetSocket.php b/src/Connection/InetSocket.php index bd83ef6..aa0e335 100644 --- a/src/Connection/InetSocket.php +++ b/src/Connection/InetSocket.php @@ -6,6 +6,8 @@ use Domnikl\Statsd\Connection; +use function ini_get; + abstract class InetSocket implements Connection { private const LINE_DELIMITER = "\n"; @@ -14,35 +16,39 @@ abstract class InetSocket implements Connection /** * host name + * @var string */ - protected string $host; + protected $host; /** * port number + * @var int<1, 65535> */ - protected int $port; + protected $port; /** * Socket timeout + * @var int<0, max> */ - private int $timeout; + private $timeout; /** * Persistent connection + * @var bool */ - private bool $persistent; + private $persistent; /** * @var int<1, max> */ - private int $maxPayloadSize; + private $maxPayloadSize; /** * instantiates the Connection object and a real connection to statsd * * @param string $host Statsd hostname - * @param int $port Statsd port - * @param ?int $timeout Connection timeout + * @param int<1, 65535> $port Statsd port + * @param ?int<0, max> $timeout Connection timeout * @param bool $persistent (default FALSE) Use persistent connection or not * @param int $mtu Maximum Transmission Unit (default: 1500) */ @@ -70,7 +76,9 @@ public function __construct( $this->maxPayloadSize = $maxPayloadSize; if ($timeout === null) { - $this->timeout = (int) ini_get('default_socket_timeout'); + /** @var int<0, max> $timeout */ + $timeout = (int) ini_get('default_socket_timeout'); + $this->timeout = $timeout; } else { $this->timeout = $timeout; } diff --git a/src/StatsdAwareTrait.php b/src/StatsdAwareTrait.php index e5dee24..aece9ce 100644 --- a/src/StatsdAwareTrait.php +++ b/src/StatsdAwareTrait.php @@ -7,7 +7,10 @@ */ trait StatsdAwareTrait { - protected Client $statsd; + /** + * @var Client + */ + protected $statsd; /** * Sets the StatsD client.