chyba „$this when not in object context“ v routerfactory pouze na produkčním

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
argosovo
Člen | 54
+
0
-

Ahoj,
vzhledem k tomu, že už se několik hodin hádám se svým serverem o chybu, která nastává pouze na produkčním serveru „Using $this when not in object context“ u routerFactory a vy jste mi vždy dobře poradili, rozhodl jsem se zeptat, zda někdo z vás nemá nápad. Několikrát jsem smazal a překopíroval celou App, smazal temp a problém stále přetrvává, nicméně pouze na produkčním, na localu vše funguje správně.

<?php
class RouterFactory
{

        private $firmy,$inzeraty;
        public function __construct(\Model\AdminModule\Firmy $firmy,\Model\FrontModule\Inzeraty $inzeraty){
            $this->firmy=$firmy;
            $this->inzeraty=$inzeraty;
        }
        /**
	 * @return \Nette\Application\IRouter
	 */
	public function createRouter()
	{
          $bazarRoute=new Route('bazary/<bazar>/',array(
    'module'=>'Front',
    'presenter'=>'Inzeraty',
    'action'=>'bazar',
    'bazar'=>array(
        Route::FILTER_IN => function($bazar){
          if(is_numeric($bazar)){
              return $bazar;
          }
          else{
              $bazar= $this->firmy->getIdBySeo($bazar);
              return $bazar;
          }
        },
        Route::FILTER_OUT =>function($bazar){
            if(!is_numeric($bazar)){
                return $bazar;
            }else{
               return $this->firmy->getSeoById($bazar);
            }
        }
    )
    ));
    $inzeratRoute=new Route('prodam/<id>',array(
    'module'=>'Front',
    'presenter'=>'Bazary',
    'action'=>'inzerat',
    'id'=>array(
        Route::FILTER_IN => function($inzerat){
          if(is_numeric($inzerat)){
              return $inzerat;
          }
          else{
              $inzerat= $this->inzeraty->getIdBySeo($inzerat);
              return $inzerat;
          }
        },
        Route::FILTER_OUT =>function($inzerat){
            if(!is_numeric($inzerat)){
                return $inzerat;
            }else{
               return $this->inzeraty->getSeoById($inzerat);
            }
        }
    )
    ));
		$router = new RouteList;
                $router[]=$bazarRoute;
                $router[]=$inzeratRoute;
		return $router;
	}
}
?>

Jde o ty části (ty končí chybou):
$inzerat= $this->inzeraty->getIdBySeo($inzerat);
$bazar= $this->firmy->getIdBySeo($bazar);

v config.neon je potom třída zavedena jako:

<?php
...
services:
        firmy: Model\AdminModule\Firmy
        inzeraty: Model\FrontModule\Inzeraty
        router: App\RouterFactory(@firmy,@inzeraty)::createRouter
...
?>

Uměl bych si představit, že bude tato chyba na statické metodě – což možná tak je, vzhledem k tomu, že v configu je volána funkce ::createRouter – nicméně nepředpokládám rozdíl mezi testovací a produkční verzí. Nějaké nápady proč to tak je a hlavně jak to dostat do funkčního stavu? Děkuji

CZechBoY
Člen | 3608
+
0
-

V anonymní funkci nemůžeš používat $this na php 5.3.x
Takže to přepiš nějak takhle:

public function createRouter()
    {
		$me = $this;

          $bazarRoute=new Route('bazary/<bazar>/',array(
    'module' => 'Front',
    'presenter' => 'Inzeraty',
    'action' => 'bazar',
    'bazar' => array(
        Route::FILTER_IN => function($bazar) use ($me) {
          if(is_numeric($bazar)){
              return $bazar;
          }
          else{
              $bazar = $me->firmy->getIdBySeo($bazar);
              return $bazar;
          }
        },
        Route::FILTER_OUT =>function($bazar) use ($me) {
            if(!is_numeric($bazar)){
                return $bazar;
            }else{
               return $me->firmy->getSeoById($bazar);
            }
        }
    )
    ));
    $inzeratRoute=new Route('prodam/<id>',array(
    'module'=>'Front',
    'presenter'=>'Bazary',
    'action'=>'inzerat',
    'id'=>array(
        Route::FILTER_IN => function($inzerat) use ($me) {
          if(is_numeric($inzerat)){
              return $inzerat;
          }
          else{
              $inzerat= $me->inzeraty->getIdBySeo($inzerat);
              return $inzerat;
          }
        },
        Route::FILTER_OUT =>function($inzerat) use ($me) {
            if(!is_numeric($inzerat)){
                return $inzerat;
            }else{
               return $me->inzeraty->getSeoById($inzerat);
            }
        }
    )
    ));
        $router = new RouteList;
                $router[]=$bazarRoute;
                $router[]=$inzeratRoute;
        return $router;
    }
}
?>
argosovo
Člen | 54
+
0
-

Děkuji, jednoduché a účinné, pokud člověk ví, jakým směrem se vydat.

David Kudera
Člen | 455
+
0
-

jestli by nebylo ještě účinnější používat aktuální verze PHP ;-)

Dismember
Člen | 50
+
0
-

@CZechBoY já tomu $me = $this nerozumím. Mám stejný problém, co @argosovo … když použiju, to co píšeš, tak mi to hlásí Undefined variable: $this

Jsem na tom triku něco nepochopil?

CZechBoY
Člen | 3608
+
0
-

Trik je v tom, že v php 5.3 nejde používat $this v anonymních funkcích, které @argosovo používá.
Pokud nemáš ani $this tak máš nejspíš php 4 nebo statickou funkci.

Aurielle
Člen | 1281
+
0
-

@Dismember v sandboxu je metoda createRouter() statická, proto v ní $this použít nejde.

Dismember
Člen | 50
+
0
-

@Aurielle aha…stále mi ale asi něco nědochází. Když u metody zruším static, tak mi to pak křičí

Non-static method App\RouterFactory::createRouter() should not be called statically, assuming $this from incompatible context

Jak ten router mám zaregistrovat, aby to fungovalo tak, abych mohl mohl pužít $this?

Díky

Aurielle
Člen | 1281
+
0
-

@Dismember tuším, že musíš dát před volání v configu zavináč:

services:
	router: @App\RouterFactory::createRouter

Editoval Aurielle (6. 4. 2016 21:45)

abc
Člen | 92
+
0
-

@Dismember:
takto:

services:
    router: App\RouterFactory()::createRouter
Dismember
Člen | 50
+
0
-

@Aurielle zavináč nefungoval, ale verze podle @abc je v pořádku.
Díky moc!

Aurielle
Člen | 1281
+
0
-

@Dismember ah, promiň, moje verze funguje v momentě, kdy máš službu v kontejneru zaregistrovanou, ale nepojmenovanou. A od @abc jsem se něco nového přiučil i já :)