nette API – error: Declaration of ..Presenter::run(Request $request) must be compatible

Petr64
Člen | 22
+
0
-

Ahoj,
jsem věčný začátečník. Po letech se snažím udělat v nette aplikaci API rozhraní. Na seznámení jsem si na foru jednoduchý příklad.

"Jan Tvrdík :HelloWorldApi ":https://forum.nette.org/…tte-aplikaci

Okopíroval jsem presenter:

namespace App\Presenters;

/**
 * Description of HelloWorldApi
 */
class HelloWorldApiPresenter implements  Nette\Application\IPresenter
{
        public function run(Request $request) : IResponse
        {
		$name = $request->getParameter('name');
		return new JsonResponse(['message' => "Hello $name"]);
	}
}

přidal jsem routu: $router->addRoute(‚/Api[/<name>]‘, ‚HelloWorldApi:default‘);

declare(strict_types=1);

namespace App\Router;

use Nette;
use Nette\Application\Routers\RouteList;


final class RouterFactory
{
	use Nette\StaticClass;

	public static function createRouter(): RouteList
	{
		$router = new RouteList;
		$router->addRoute('/Api[/<name>]', 'HelloWorldApi:default');
        $router->addRoute('<presenter>/<action>[/<id>]', 'Homepage:default');
		return $router;
	}
}

Těšil jsem se jak je to jednoduché, až spustím http://api.local/api/Petr a objeví se mi nápis „Hello Petr“

Testuji pomocí postman a dostávám v odpovědi:

500Internal Server Error

Fatal error: Declaration of HelloWorldApiPresenter::run(Request $request) must be compatible with
Nette\Application\IPresenter::run(Nette\Application\Request $request): Nette\Application\IResponse in
C:\WWW\Apache24\htdocs\rest73\app\Presenters\HelloWorldApiPresenter.php on line 11
<!DOCTYPE html><!-- "' --></textarea></script>
...

Mohl by mi někdo poradit co ta chyba znamená a jak to opravit?

Editoval Petr64 (4. 2. 2020 16:28)

David Matějka
Moderator | 6445
+
+2
-

u run metody na IPresenter interface je nyni return type, tak stejny return type pridej i k HelloWorldApiPresenter

Petr64
Člen | 22
+
0
-

David Matějka napsal(a):

u run metody na IPresenter interface je nyni return type, tak stejny return type pridej i k HelloWorldApiPresenter

koukal jsem do dokumentace k IPresenter a doplnil jsem toto:

public function run(Request $request) : IResponse

Hlásí to stejnou chybu.

David Matějka
Moderator | 6445
+
0
-

a mas tam tam spravny use?

Petr64
Člen | 22
+
0
-

David Matějka napsal(a):

a mas tam tam spravny use?

Celý presenter HelloWorldApi jsem doplnil do dotazu. use tam nemám žádné. A nevím jaké by tam mělo být.
Strukturu jsem nechal tak jak jsem mi nastavil composer. Zatím jsem moduly nepřidával.

David Matějka
Moderator | 6445
+
+2
-

kdyz se kouknes do te chybove hlasky, tak vidis, ze ten return type je Nette\Application\IResponse. kdyz tam uvedes jen IResponse, tak to php vyresolvuje na App\Presenters\IResponse. musis tedy pridat use Nette\Application\IResponse

vice o tom, jak funguji namespace, najdes v dokumentaci php

Petr64
Člen | 22
+
0
-

David Matějka napsal(a):

kdyz se kouknes do te chybove hlasky, tak vidis, ze ten return type je Nette\Application\IResponse. kdyz tam uvedes jen IResponse, tak to php vyresolvuje na App\Presenters\IResponse. musis tedy pridat use Nette\Application\IResponse

vice o tom, jak funguji namespace, najdes v dokumentaci php

Pročetl jsem odkaz. Snad maličko chápu a upravil jsem HelloWorldApiPresenter takto

přidal jsem:

use Nette\Application\IResponse;`

upravil jsem na absolutní odkaz :

implements \Nette\Application\IPresenter
namespace App\Presenters;

use Nette\Application\IResponse;
/**
 * Description of HelloWorldApi
 */
class HelloWorldApiPresenter implements \Nette\Application\IPresenter
{
        public function run(Request $request) : IResponse
        {
		$name = $request->getParameter('name');
		return new JsonResponse(['message' => "Hello $name"]);
	}
}

Teď snad to resolvuje se správně, ale chyba nezmizela:

Fatal error: Declaration of App\Presenters\HelloWorldApiPresenter::run(App\Presenters\Request $request):
Nette\Application\IResponse must be compatible with Nette\Application\IPresenter::run(Nette\Application\Request
$request): Nette\Application\IResponse in C:\WWW\Apache24\htdocs\rest73\app\Presenters\HelloWorldApiPresenter.php on
line 9

Editoval Petr64 (4. 2. 2020 19:29)

Marek Bartoš
Nette Blogger | 1166
+
+2
-

Pořád to nemáš stejné, podívej se pořádně na chybu. Ještě potřebuješ buď use statement nebo absolutní namespace pro Request.
run(App\Presenters\Request $request): Nette\Application\IResponse
run(Nette\Application\Request $request): Nette\Application\IResponse

Používáš nějaké IDE? Mělo by ti chybu zvýraznit. phpstorm, netbeans, …

Editoval Mabar (4. 2. 2020 20:37)

Petr64
Člen | 22
+
0
-

Mabar napsal(a):

Pořád to nemáš stejné, podívej se pořádně na chybu. Ještě potřebuješ buď use statement nebo absolutní namespace pro Request.
run(App\Presenters\Request $request): Nette\Application\IResponse
run(Nette\Application\Request $request): Nette\Application\IResponse

Používáš nějaké IDE? Mělo by ti chybu zvýraznit. phpstorm, netbeans, …

Ahoj, používám netbeans ale nic mi to nezdůraznilo.
Už to chybu neháže, dopsal do jsem Request i nakonec do JsonResponse absolutní odkaz.
Jde to nějak jinak?

Jinak už to chodí. Díky moc tobě i Davidovi, za trpělivost.

namespace App\Presenters;

use Nette\Application\IResponse;

/**
 * Description of HelloWorldApi
 */

class HelloWorldApiPresenter implements \Nette\Application\IPresenter
{
        public function run(\Nette\Application\Request $request) : IResponse
        {
		$name = $request->getParameter('name');
		return new \Nette\Application\Responses\JsonResponse(['message' => "Hello $name"]);
	}
}

Editoval Petr64 (4. 2. 2020 21:56)

Marek Bartoš
Nette Blogger | 1166
+
0
-

Můžeš používat use statements, tak jak jsi to měl u IResponse. Pak můžeš používat ty krátké názvy.

Netbeans jsem zmínil jen, aby jeden nejmenovaný uživatel nepřišel s tím, že tu propaguju placený software :)

V phpstormu bys takovou třídu měl podtrženou vlnovkou a pomocí klávesové zkratky alt+enter by ti to i nabídlo import třídy ze správného namespace.
Když kód nebudeš kopírovat, ale psát, tak se ti nabídnutá třída po zvolení přidá mezi use statements automaticky.

Editoval Mabar (5. 2. 2020 4:50)