fix: ConnectionRegistry robust to numeric-string ids
PHP coerces numeric-string array keys ("1") to int keys, so ids()/each()/clear()
could hand ints to remove(string) and TypeError. Cast to string in those paths.
Surfaced by the laravel-ws integration (connection ids are sequential numbers).
Regression test added. Suite: 20 tests.
rel learn-atc #1055 #1057
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9173a8897b
commit
5eee2f83b8
|
|
@ -67,7 +67,8 @@ final class ConnectionRegistry implements \Countable
|
||||||
/** @return array<int,string> */
|
/** @return array<int,string> */
|
||||||
public function ids(): array
|
public function ids(): array
|
||||||
{
|
{
|
||||||
return array_keys($this->items);
|
// Cast: PHP coerces numeric-string keys (e.g. "1") to int keys internally.
|
||||||
|
return array_map(strval(...), array_keys($this->items));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function count(): int
|
public function count(): int
|
||||||
|
|
@ -82,7 +83,7 @@ final class ConnectionRegistry implements \Countable
|
||||||
public function each(callable $callback): void
|
public function each(callable $callback): void
|
||||||
{
|
{
|
||||||
foreach ($this->items as $id => $connection) {
|
foreach ($this->items as $id => $connection) {
|
||||||
$callback($connection, $id);
|
$callback($connection, (string) $id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +103,7 @@ final class ConnectionRegistry implements \Countable
|
||||||
public function clear(): void
|
public function clear(): void
|
||||||
{
|
{
|
||||||
foreach (array_keys($this->items) as $id) {
|
foreach (array_keys($this->items) as $id) {
|
||||||
$this->remove($id);
|
$this->remove((string) $id); // keys may be int (PHP numeric-string coercion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,26 @@ final class ConnectionRegistryTest extends TestCase
|
||||||
$this->assertSame(['x'], $added);
|
$this->assertSame(['x'], $added);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_numeric_string_ids_survive_ids_each_and_clear(): void
|
||||||
|
{
|
||||||
|
// PHP coerces numeric-string array keys ("1") to int keys internally, which
|
||||||
|
// used to hand ints to remove(string) during clear(). Regression guard.
|
||||||
|
$registry = new ConnectionRegistry;
|
||||||
|
$registry->add('1', new \stdClass);
|
||||||
|
$registry->add('2', new \stdClass);
|
||||||
|
|
||||||
|
$this->assertSame(['1', '2'], $registry->ids());
|
||||||
|
|
||||||
|
$seen = [];
|
||||||
|
$registry->each(function (object $conn, string $id) use (&$seen) {
|
||||||
|
$seen[] = $id; // must receive strings, not ints
|
||||||
|
});
|
||||||
|
$this->assertSame(['1', '2'], $seen);
|
||||||
|
|
||||||
|
$registry->clear(); // must not TypeError
|
||||||
|
$this->assertCount(0, $registry);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_each_visits_every_connection(): void
|
public function test_each_visits_every_connection(): void
|
||||||
{
|
{
|
||||||
$registry = new ConnectionRegistry;
|
$registry = new ConnectionRegistry;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue