diff --git a/src/Message.php b/src/Message.php index 5561a513..39a13e10 100644 --- a/src/Message.php +++ b/src/Message.php @@ -67,6 +67,25 @@ public static function bodySummary(MessageInterface $message, int $truncateAt = return null; } + do { + $body->rewind(); + $body->seek($truncateAt); + $char = $body->read(1); + $bin = str_pad(base_convert(strval(ord($char)), 10, 2), 8, '0', STR_PAD_LEFT); + // detect the character binary conversion + // stoped at 0x00000000 - 0x0000007F or the first byte of the utf8 code points + // @see https://man7.org/linux/man-pages/man7/utf-8.7.html + if (!$bin[0] || ($bin[0] && $bin[1])) { + $body->rewind(); + break; + } + $truncateAt -= 1; + } while ($bin[0]); + // fast return while won't need reading the stream + if ($truncateAt === 0) { + return null; + } + $body->rewind(); $summary = $body->read($truncateAt); $body->rewind(); diff --git a/tests/MessageTest.php b/tests/MessageTest.php index 1a43152d..2c4cf683 100644 --- a/tests/MessageTest.php +++ b/tests/MessageTest.php @@ -271,6 +271,16 @@ public function testMessageBodySummaryWithSpecialUTF8Characters(): void self::assertSame('’é€௵ဪ‱', Psr7\Message::bodySummary($message)); } + public function testMessageBodySummaryWithComfortableUTF8Characters(): void + { + $message = new Psr7\Response(200, [], '必填性规则校验失败,此字段为必填项'); + $wellformed = '必填性规则校验失 (truncated...)'; + // One chinese character is three bytes in the utf8 character range. + self::assertSame($wellformed, Psr7\Message::bodySummary($message, 24)); + self::assertSame($wellformed, Psr7\Message::bodySummary($message, 25)); + self::assertSame($wellformed, Psr7\Message::bodySummary($message, 26)); + } + public function testMessageBodySummaryWithSpecialUTF8CharactersAndLargeBody(): void { $message = new Psr7\Response(200, [], '🤦🏾‍♀️');