Using Dispatcher in Library or Model?

When I use PHP 5.6.30 + Phalcon 2.0.13 this method works fine everywhere, including my libraries or models classes. But when I started using PHP 7.2.4 + Phalcon 3.0.14 this aproach no longer works. Here is few examples of what I mean.

/project/app/config/bootstrap.php

$di->set('dispatcher', function() {
    $dp = new Dispatcher();
    $dp->setControllerSuffix('');
    $dp->setActionSuffix('');
    $dp->setDefaultNamespace('Project\Controllers');
    return $dp;
}); #dispatcher

/project/app/controllers/Index.php

namespace Project\Controllers;
class Index extends Base {
  function index() {
    $test = $this->dispatcher->getParam('test');
    echo $test;
  } #index
} #class

This above example works with my controller. However when I try using similar in my library or model it doesn't work.

/project/app/libraries/Helper.php

namespace Project\Libraries;
class Helper {
  function test() {
    $test = $this->dispatcher->getParam('test');
    return $test;
  } #test
} #class

Then when I try calling it from my Index controller it doesn't work.

/project/app/controllers/Index.php

namespace Project\Controllers;
use Project\Libraries\Helper;
class Index extends Base {
  function index() {
    echo Helpher::test();
  } #index
} #class

All I see is this following error;

Error: Using $this when not in object context

Is there a way to reuse my dispatcher from bootsrap in libraires or models too? Some examples would be apreceated.

What would you recommend? Thank you!



78.1k
edited Apr '18

i am not expert but i dont like the idea for a page being redirected in the middle of some class. I feel like its controller's job to decide where next request will go. I have never had to use dispatcher in the middle of my classes.

but i ofen do


//in controller
$cls = new WHatever();

if ($cls->getErrors() > 0 ) {
   return $this->dispatcher->redirect(" previous url");
}

at least this is what i think

edited Apr '18

@tzo, I actually need it for pagination function in my library. Here is an example of what I used to use.

/project/app/libraries/Helper.php

function paginator($array, $limit) {
  $page = $this->dispatcher->getParam('page');
  if ($array) {
    $paginator = new NativeArray([
      'data' => $array,
      'page' => $page,
      'limit' => $limit,
  ]); #paginator
  return $paginator->getPaginate();
  } #if/array
} #paginator

Then I called it in any of my controllers like this;

/project/app/controllers/Index.php

use Project\Libraries\Helper;
function index() {
  $array = Helper::paginator($array, 50);
  $this->view->data = $array;
} #index

Alternatively, I can also use something like this below, but I get exactly the same problem like when I use dispatcher in my library.

$page = $this->request->getQuery('page', 'int');

I guess, what I'm asking is how can I use Dispatcher or Request in my librariy classes? Because it seems that I cant access them there.

Thank you so much for any help provided! Love Phalcon and community here, very helpful! Couldn't learned phalcon without great people here ^_^

edited Apr '18

I've tried using Request and Dispatcher in my Model or Library like this and all I see is blank page (no value). Can some one please tell me what I'm doing wrong here? Thank you!

$request = new \Phalcon\Http\Request();
$page = $request->getQuery('page');
exit($page);
$dispatcher = new \Phalcon\Mvc\Dispatcher();
$page = $dispatcher->getParam('page');
exit($page);


78.1k

you can just initialize the class with the current page, as it is done in incubator https://github.com/phalcon/incubator/tree/master/Library/Phalcon/Paginator

this is how i do it in my classes as well



3.1k
Helpher::test();

It's static - using static is a bad idea

class Helper {
    function test() {
        $test = $this->dispatcher->getParam('test');
    }
}

It's OOP - You can't mix static with OOP that way, you should declare static method and use "self" instead "this" - static things belong to class, not to object. PHP allows this due to backward compatibility and it depends on Your error settings.

edited Apr '18

Make your library class inherit from Phalcon\Di\Injectable or `` Phalcon\Mvc\User\Component```.

Check this line in the source: https://github.com/phalcon/cphalcon/blob/master/phalcon/di/injectable.zep#L89

If no DI was set on the class instance explicitly, it will get it from factory default.

$dispatcher = new \Phalcon\Mvc\Dispatcher();
$page = $dispatcher->getParam('page');
exit($page);

This will never work, because your are creating a new dispatcher instance, not tied to the request context in any way.

But, as @Izo advised, it is better to decouple redirection from library components.

Hey everyone, thank you for trying to help. But please note that I'm still learning Phalcon and not Advanced in it. So more example on how to properly do something would be apreceated.

@Izo, Thank you this works for pagination. But I need to also be able to use Request or Dispatcher anywhere in any of my Libraries or Models. I was able to do this easy with PHP5+Phalcon2 but its no longer works with PHP7+Phalcon3.

@Micahl, I prefer static over OOP and I can use them or at least I used to. But as always PHP7 broke there backward functionality. But if there is a way to use self please provide an example so I can try. Thank you.

@Lajos, Please provide your own example instead of copying my above code. Also provided GitHub link to Zephir means nothing to me, I can't even read ZEP code.