0

So basically I'm not sure if this is a PhpStorm issue parsing my code or if its a weird quirk of PHP and interfaces but basically I have the following interface

<?php

namespace App\Contracts;

/**
 * Interface IFileSource
 * @package App\Contracts
 */
interface IFileSource
{
    public function getFilesByPattern(string $filePattern) : array;
}

with the following implementation

<?php

namespace App\Sources;

use App\Contracts\IFileService;
use App\Services\File\FileService;

/**
 * Class FileSource
 * @package App\Sources
 */
class FileSource implements IFileSource
{
    /**
     * @var FileService
     */
    private $fileService;

    public function __construct (IFileService $fileService)
    {
        $this->fileService = $fileService;
    }


    /**
     * @param string $filePattern
     * @return File[]
     * NOTE THIS ASSUMES FILESYSTEM
     */
    public function getFilesByPattern (string $filePattern) : array
    {
        $filesDetails = $this->fileService->getFilesByPattern($filePattern);
        return [];
    }
}

and the usage

<?php

namespace App\Console\Commands;

use App\Contracts\IFileSource;
use App\Sources\FileSource;

class ImportXML extends Command
{

    /**
     * @var FileSource
     */
    protected $fileSource;

    public function __construct (IFileSource $fileSource)
    {
        parent::__construct();
        $this->fileSource = $fileSource;
    }

    public function handle () : void
    {     
            $filePattern = 'APATTERN';
            $files = $this->fileSource->getFilesByPattern($filePattern)
    }
}

My question relates to the usage of this implementation.

So the following is a valid usage:

$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern)

But for some reason the following is also seen as a valid usage?

$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern,filePattern,filePattern,filePattern,filePattern,filePattern,filePattern)

Why does it not care that i am not conforming to my implementation?

11
  • 2
    Always provide a real code sample that can be easily copy pasted and tested locally. In my code it always highlights this as an error. But my code might be different to yours... Commented Sep 5, 2019 at 9:56
  • 1
    Haha, sorry but now I think we should try a Minimal, Complete and Verifiable Example with the emphasis on minimal Commented Sep 5, 2019 at 10:09
  • 1
    PhpStorm will correctly report a warning if you use IFileSource instead of FileSource (well, at least in my test project that has no Laravel code & PHP Language Level was set to 7.2 if that would make any diff). postimg.cc/qzk82jp5. Will also work if I use FileSource in both PHPDoc typehint for the field and constructor parameter (so it's the same in both paces) Commented Sep 5, 2019 at 10:57
  • 1
    Cannot say why exactly it does not report an error when interface and concrete class typehints are used at the same time (IDE sees 2 possible signatures: although they are the same ... there are 2 of them...). Could be a bug or IDE specific restriction -- check/report to youtrack.jetbrains.com/issues/WI Commented Sep 5, 2019 at 11:01
  • 1
    Your code is OK -- no issues there. But if you are using interfaces (as a parameter typehint) ... then use interfaces in other places as well (field typehint via PHPDoc). There is no much point to typehint using specific class if interfaces are in use (no need to mix them). Commented Sep 5, 2019 at 11:37

2 Answers 2

1

Why does it not care that i am not conforming to my implementation

That's the whole point of interfaces - they don't care about implementations. They only care about how the method is defined and if the signature conforms to the interface.

However, I think the real question being asked here is why the PHP interpreter doesn't throw an exception when multiple arguments are passed to the function. The answer is because this is how PHP implements overloading. They allow a variable number of arguments to be passed which you can access with functions such as func_get_args.

You should definitely read https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list and also look into the new(ish) splat operator ....

Similar QAs

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for that! So maybe the true question i should be asking is there a way to disable method overloading for an implementation? i was under the impression that if you needed to have another version of such a function, as in it is an indication that you need to update the design of your implementations/interfaces. so in mycase if i needed getFilesByPattern to also take the file path seperate to the filename i would make a getFilesByPatternAndPath instead of adding complexity to getFilesByPattern to support an overloaded parameter? maybe im thinking too small...
0

So incase someone else stumbles across this,

thanks to LazyOne for the help explaining what i was doing wrong

it was due to the fact i am enforcing the implementation in the PHPdoc rather than relying on the interface to enforce the type hinting (or adding the interface as the type hint instead of the implementation), once i changed this it began complaining as expected.

Why enforce an implementation when the point of the interface is the enforce such things.

Doh

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.