Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Negotiator::getBest() return type hint? #89

Open
mindplay-dk opened this issue Dec 23, 2016 · 7 comments · May be fixed by #117
Open

Negotiator::getBest() return type hint? #89

mindplay-dk opened this issue Dec 23, 2016 · 7 comments · May be fixed by #117

Comments

@mindplay-dk
Copy link

To get offline source inspection (phan, Php Storm, etc.) currently I have to manually type-hint the return-type of getBest() inline - for example:

            $negotiator = new Negotiator();

            /** @var Accept $result */
            $result = $negotiator->getBest(
                $request->getHeaderLine("Accept"),
                ["application/json", "text/html"]
            );

            if ($result->getValue() === "application/json") {
                // ...
            }

Without the @var annotation, the if-statement will fail inspection, because the return-type of getBest() was declared as AcceptHeader rather than Accept, which appears to be the actual return-type.

What's the purpose of the empty AcceptHeader interface?

@azjezz azjezz mentioned this issue Apr 8, 2018
@willemstuursma
Copy link

Maybe just change the @return hint in \Negotiation\AbstractNegotiator::getBest to AcceptHeader|BaseAccept?

@teohhanhui
Copy link

What's the purpose of the empty AcceptHeader interface?

Just came across this with phpstan as well. This is puzzling.

@g105b
Copy link

g105b commented Jun 2, 2021

I'm pasting the example from the readme into my editor.

Here's how 3.0.0 looks in PhpStorm:

image

@willdurand
Copy link
Owner

I am not quite sure what you're talking about to be honest (phpstan wasn't a thing when I was writing PHP..) but I'd be happy to see these issues fixed.

@g105b
Copy link

g105b commented Jan 31, 2022

This issue occurs because of the following:

  • Negotiator extends AbstractNegotiator
  • AbstractNegotiator::getBest() is documented to return AcceptHeader|null
  • AcceptHeader is a completely empty interface, so IDEs or static analysis don't understand that the type returned by getBest() should have the getValue() method.

I think this can be solved by refactoring the inheritance of the project. I'll take a look into it when I've got a bit of time.

Edit: in fact, this can be fixed really easily by providing a more accurate return type in the doc blocks, but I think the project would benefit from some simple OO refactoring.

g105b added a commit to g105b/Negotiation that referenced this issue Feb 15, 2022
This is for willdurand#89 - to ensure correct type hints are provided
to developers who use IDEs.
g105b added a commit to g105b/Negotiation that referenced this issue Feb 15, 2022
Fixes willdurand#89 - IDEs and PHPStan are happy with this implementation
@g105b g105b linked a pull request Feb 15, 2022 that will close this issue
g105b added a commit to g105b/Negotiation that referenced this issue Feb 15, 2022
* Depend on PHPUnit for development

In order to run the unit tests, PHPUnit is a hard dev
dependency, so I've included it in this commit, and now
I can run the unit tests as part of this PR.

* Depend on PHPStan for development

This is for willdurand#89 - to ensure correct type hints are provided
to developers who use IDEs.

* Fix object model of AcceptHeader interface

Fixes willdurand#89 - IDEs and PHPStan are happy with this implementation

* Correct return type

* Correct nonexistent Priority class to AcceptHeader

* Improve typehint - allow looser type to be returned

* Improve typehint - more accurate types as parameters

* Improve typehint - more accurate generics as parameters

* Expose script property - was only ever written

* Properly typehint associative array

* Typehint nullable string

* Match typehints of parent method

* Add PHPStan to CI

* Configure PHPUnit versions for different PHP runtimes

* Use real phpunit
g105b added a commit to g105b/Negotiation that referenced this issue Feb 15, 2022
* Depend on PHPUnit for development

In order to run the unit tests, PHPUnit is a hard dev
dependency, so I've included it in this commit, and now
I can run the unit tests as part of this PR.

* Depend on PHPStan for development

This is for willdurand#89 - to ensure correct type hints are provided
to developers who use IDEs.

* Fix object model of AcceptHeader interface

Fixes willdurand#89 - IDEs and PHPStan are happy with this implementation

* Correct return type

* Correct nonexistent Priority class to AcceptHeader

* Improve typehint - allow looser type to be returned

* Improve typehint - more accurate types as parameters

* Improve typehint - more accurate generics as parameters

* Expose script property - was only ever written

* Properly typehint associative array

* Typehint nullable string

* Match typehints of parent method

* Add PHPStan to CI

* Configure PHPUnit versions for different PHP runtimes

* Use real phpunit
@nreynis
Copy link

nreynis commented Mar 14, 2022

An easy fix would be to just add every public method of BaseAccept into the AcceptHeader interface.

It would solve the issue without introducing any BC.

@josefsabl
Copy link

josefsabl commented Sep 18, 2023

I am not quite sure what you're talking about to be honest (phpstan wasn't a thing when I was writing PHP..) but I'd be happy to see these issues fixed.

The AbstractNegotiator::getBest method returns AcceptHeader interface, that doesn't prescribe any methods so you (as a user of the library) don't know what to call next and you have to rely on looking into implementation details or documentation to know that you can call getType on that.

I.e. this isn't about static analysis or phpstan but rather the flawed interface of the library and it hurts its usage even when no static analysis tools are involved. I indeed was puzzled when using the lib on Friday and was like: AcceptHeader interface and now what.

You should pull the methods shapes to the interface or maybe type-hint the getBest method to be returning a BaseAccept class instead of the interface.

What is the interface for anyway?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants