Repository: PHP-DI/PHP-DI (php)

Issue:
Wildcard definition for class in global namespace matches any namespace
The project I am working on has quite some classes defined in the global namespace. 
When adding a wildcard definition for these classes, not only those classes are matched, but also matching class names in any namespace.
This is quite unexpected, since the documentation states:
> the wildcard does not match across namespaces

For example:

```
return [
    'Job*' => DI\autowire()->method('foo', 'bar'),
];
```
will call `foo('bar')` on class `JobDoSomething`, but also on class `SomeNamespace\JobScheduler`, which is not in the global namespace.

I am unfortunately on version 6.3.5, because PHP 7.2 ... But the code for matching the wildcard (regex) looks to be equal in both 6.4 and master.

Pull request description:
Fix wildcard definition global namespace matching any namespace
Fixes #861

Patch:
diff --git a/src/Definition/Source/DefinitionArray.php b/src/Definition/Source/DefinitionArray.php
index 74a04c14..2652229e 100644
--- a/src/Definition/Source/DefinitionArray.php
+++ b/src/Definition/Source/DefinitionArray.php
@@ -86,7 +86,7 @@ class DefinitionArray implements DefinitionSource, MutableDefinitionSource
         foreach ($this->wildcardDefinitions as $key => $definition) {
             // Turn the pattern into a regex
             $key = preg_quote($key, '#');
-            $key = '#' . str_replace('\\' . self::WILDCARD, self::WILDCARD_PATTERN, $key) . '#';
+            $key = '#^' . str_replace('\\' . self::WILDCARD, self::WILDCARD_PATTERN, $key) . '#';
             if (preg_match($key, $name, $matches) === 1) {
                 array_shift($matches);
 


Test patch:
diff --git a/tests/UnitTest/Definition/Source/DefinitionArrayTest.php b/tests/UnitTest/Definition/Source/DefinitionArrayTest.php
index 45f23b84..fc2edaec 100644
--- a/tests/UnitTest/Definition/Source/DefinitionArrayTest.php
+++ b/tests/UnitTest/Definition/Source/DefinitionArrayTest.php
@@ -180,6 +180,7 @@ class DefinitionArrayTest extends TestCase
             'Namespaced\*Interface'  => \DI\create('Namespaced\*'),
             'Namespaced2\*Interface' => \DI\create('Namespaced2\Foo'),
             'Multiple\*\*\Matches'   => \DI\create('Multiple\*\*\Implementation'),
+            '*Interface'   => \DI\create('GlobalImplementation'),
         ]);
 
         $definition = $source->getDefinition('foo1');
@@ -201,6 +202,11 @@ class DefinitionArrayTest extends TestCase
         $this->assertInstanceOf(ObjectDefinition::class, $definition);
         $this->assertEquals('Multiple\Foo\Bar\Matches', $definition->getName());
         $this->assertEquals('Multiple\Foo\Bar\Implementation', $definition->getClassName());
+
+        $definition = $source->getDefinition('GlobalInterface');
+        $this->assertInstanceOf(ObjectDefinition::class, $definition);
+        $this->assertEquals('GlobalInterface', $definition->getName());
+        $this->assertEquals('GlobalImplementation', $definition->getClassName());
     }
 
     /**
@@ -240,6 +246,17 @@ class DefinitionArrayTest extends TestCase
         $this->assertNull($source->getDefinition('My\Foo\BarInterface'));
     }
 
+    /**
+     * The wildcard for global namespace should not match across namespaces.
+     */
+    public function testGlobalNamespaceWildcardShouldNotMatchAcrossNamespace()
+    {
+        $source = new DefinitionArray([
+            '*Interface' => \DI\create(),
+        ]);
+        $this->assertNull($source->getDefinition('My\FooInterface'));
+    }
+
     /**
      * @see https://github.com/PHP-DI/PHP-DI/issues/379
      */