diff --git a/src/AspectWeaver.php b/src/AspectWeaver.php index d6dc2bd..4515618 100644 --- a/src/AspectWeaver.php +++ b/src/AspectWeaver.php @@ -237,6 +237,7 @@ class AspectWeaver $params = $this->buildParameterList($method); $paramNames = $this->buildParameterCallList($method); + $paramArray = $this->buildParameterArrayList($method); $returnType = $this->buildReturnType($method); @@ -273,7 +274,7 @@ class AspectWeaver $aspectReflection = new ReflectionClass($aspectClass); if ($aspectReflection->hasMethod('before')) { $code .= " \$currentAspect = \\{$aspectClass}::class;\n"; - $code .= " \$aspect{$index}->before({$paramNames});\n"; + $code .= " \$aspect{$index}->before({$paramArray});\n"; } } $code .= " } catch (\\Throwable \$e) {\n"; @@ -391,6 +392,18 @@ class AspectWeaver return implode(', ', $params); } + private function buildParameterArrayList(ReflectionMethod $method): string + { + $params = []; + + foreach ($method->getParameters() as $param) { + $paramName = $param->getName(); + $params[] = "'{$paramName}' => \${$paramName}"; + } + + return '[' . implode(', ', $params) . ']'; + } + private function buildReturnType(ReflectionMethod $method): string { if (!$method->hasReturnType()) { diff --git a/tests/AspectStackingTest.php b/tests/AspectStackingTest.php index 2cb5b22..bb85d67 100644 --- a/tests/AspectStackingTest.php +++ b/tests/AspectStackingTest.php @@ -62,6 +62,6 @@ final class AspectStackingTest extends TestCase $tracker = (object) ['before' => false, 'after' => false]; $this->instance->multipleAspects(15, $tracker); - $this->assertEquals([15, $tracker], LoggingAspect::$logs[0]['args']); + $this->assertEquals(['value' => 15, 'tracker' => $tracker], LoggingAspect::$logs[0]['args']); } } diff --git a/tests/Aspects/BasicAspect.php b/tests/Aspects/BasicAspect.php index 303d476..c141ea5 100644 --- a/tests/Aspects/BasicAspect.php +++ b/tests/Aspects/BasicAspect.php @@ -15,7 +15,7 @@ class BasicAspect ) { } - public function before(mixed ...$args): void + public function before(array $args): void { $this->object = end($args); $this->object->before = true; diff --git a/tests/Aspects/ConfigurableAspect.php b/tests/Aspects/ConfigurableAspect.php index 4774a45..8e07ee3 100644 --- a/tests/Aspects/ConfigurableAspect.php +++ b/tests/Aspects/ConfigurableAspect.php @@ -18,7 +18,7 @@ class ConfigurableAspect ) { } - public function before(mixed ...$args): void + public function before(array $args): void { if ($this->enabled) { self::$executionLog[] = [ diff --git a/tests/Aspects/LoggingAspect.php b/tests/Aspects/LoggingAspect.php index b10c8c9..653921e 100644 --- a/tests/Aspects/LoggingAspect.php +++ b/tests/Aspects/LoggingAspect.php @@ -15,7 +15,7 @@ class LoggingAspect ) { } - public function before(mixed ...$args): void + public function before(array $args): void { self::$logs[] = ['type' => 'logging_before', 'args' => $args]; } diff --git a/tests/Aspects/ParameterKeyAspect.php b/tests/Aspects/ParameterKeyAspect.php new file mode 100644 index 0000000..e09b71d --- /dev/null +++ b/tests/Aspects/ParameterKeyAspect.php @@ -0,0 +1,35 @@ + 'before', 'args' => $args]; } diff --git a/tests/Classes/ParameterKeyTestClass.php b/tests/Classes/ParameterKeyTestClass.php new file mode 100644 index 0000000..e047ea6 --- /dev/null +++ b/tests/Classes/ParameterKeyTestClass.php @@ -0,0 +1,26 @@ +instance = new ParameterKeyTestClass(); + ParameterKeyAspect::reset(); + } + + public function testBeforeReceivesAssociativeArrayWithParameterNames(): void + { + $this->instance->methodWithNamedParams('John', 'Doe', 30); + + // Verify that the keys are parameter names, not numeric indices + $this->assertEquals(['firstName', 'lastName', 'age'], ParameterKeyAspect::$capturedKeys); + + // Verify the values are correctly mapped to parameter names + $this->assertEquals('John', ParameterKeyAspect::$capturedArgs['firstName']); + $this->assertEquals('Doe', ParameterKeyAspect::$capturedArgs['lastName']); + $this->assertEquals(30, ParameterKeyAspect::$capturedArgs['age']); + } + + public function testSingleParameterHasCorrectKey(): void + { + $testData = ['key1' => 'value1', 'key2' => 'value2']; + $this->instance->methodWithSingleParam($testData); + + // Verify the parameter name is used as the key + $this->assertEquals(['data'], ParameterKeyAspect::$capturedKeys); + $this->assertEquals($testData, ParameterKeyAspect::$capturedArgs['data']); + } + + public function testMixedTypesHaveCorrectKeys(): void + { + $metadata = (object) ['info' => 'test']; + $this->instance->methodWithMixedTypes(42, 'TestName', true, $metadata); + + // Verify all parameter names are present as keys + $this->assertEquals(['id', 'name', 'active', 'metadata'], ParameterKeyAspect::$capturedKeys); + + // Verify each parameter value is accessible by its name + $this->assertEquals(42, ParameterKeyAspect::$capturedArgs['id']); + $this->assertEquals('TestName', ParameterKeyAspect::$capturedArgs['name']); + $this->assertTrue(ParameterKeyAspect::$capturedArgs['active']); + $this->assertSame($metadata, ParameterKeyAspect::$capturedArgs['metadata']); + } + + public function testParametersCanBeAccessedByName(): void + { + $this->instance->methodWithNamedParams('Jane', 'Smith', 25); + + // Verify we can access parameters by their name using array key syntax + $this->assertArrayHasKey('firstName', ParameterKeyAspect::$capturedArgs); + $this->assertArrayHasKey('lastName', ParameterKeyAspect::$capturedArgs); + $this->assertArrayHasKey('age', ParameterKeyAspect::$capturedArgs); + + // Verify numeric keys do NOT exist + $this->assertArrayNotHasKey(0, ParameterKeyAspect::$capturedArgs); + $this->assertArrayNotHasKey(1, ParameterKeyAspect::$capturedArgs); + $this->assertArrayNotHasKey(2, ParameterKeyAspect::$capturedArgs); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index cb424f9..d12e14f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,6 +9,7 @@ use Tests\Aspects\TrackingAspect; use Tests\Aspects\ThrowingAspect; use Tests\Aspects\ModifyingAspect; use Tests\Aspects\ConfigurableAspect; +use Tests\Aspects\ParameterKeyAspect; use Tests\Classes\CallsImportedClass; use Tests\Classes\WrappedClass; use Tests\Classes\ParameterTypesClass; @@ -16,12 +17,13 @@ use Tests\Classes\StackedAspectsClass; use Tests\Classes\ThrowingClass; use Tests\Classes\ModifyingClass; use Tests\Classes\ConfigurableClass; +use Tests\Classes\ParameterKeyTestClass; $cacheDir = sys_get_temp_dir() . '/cache/php-aop-cache'; $useCache = false; $weaver = new AspectWeaver( - [BasicAspect::class, LoggingAspect::class, TrackingAspect::class, ThrowingAspect::class, ModifyingAspect::class, ConfigurableAspect::class], + [BasicAspect::class, LoggingAspect::class, TrackingAspect::class, ThrowingAspect::class, ModifyingAspect::class, ConfigurableAspect::class, ParameterKeyAspect::class], $cacheDir, $useCache, new NullLogger(), @@ -36,6 +38,7 @@ $loader = AspectBuilder::begin() ModifyingClass::class, ConfigurableClass::class, CallsImportedClass::class, + ParameterKeyTestClass::class, ]) ->build($weaver) ->register();