Standalone laravel or symfony routre

Is it possible laravel or symfony router standalone without any needs to complete framework? If yes, what is the composer command to download only its router library without downloading the complete framework?

http://symfony.com/doc/current/components/routing/introduction.html

Thanks it seems I was looking at a wrong page that I thought it doesn’t come standalone!

$route = new Route('/foo', array('controller' => 'MyController'));
$routes = new RouteCollection();
$routes->add('route_name', $route);

It seems it is just a MVC and not suitable to handle restapi? I don’t use MVC so how can I use something like: /foo/[‘a-zA-Z’]/blah/ to process a RESTApi request? does this component recognize this regexp in this url? ‘MyController’ is class name so how to tell it that which method should be called? (again without a MVC)

It seems Laravel is more suitable for this purpose? http://laravel.com/docs/4.2/routing
or I understood something wrong about this Symfony component?
Does this laravel component come standalone too? if yes, what is the composer.json just for this component without downloading the entire package?

PS.
reading doc again, I think route_name should be the method inside ExampleController class? right?

$collection = new RouteCollection();
$collection->add(
    'route_name',
    new Route('/foo', array('controller' => 'ExampleController'))
);

Then inside route_method I should define whether I got POST or GET request to take appropriate action if accepting both POST/GET for /foo url? If I need to pass an instance to that method, how is that possible?

Nope, it can handle any kind of API you want. The array of parameters passed as the second argument to new Route are completely arbitrary. The example code arbitrarily named a param “controller”, but you can make your own parameters whatever you want.

$routes = new RouteCollection();

$routes->add('blah_create', new Route(
    '/foo/{bar}/blah', // path         
    array('service' => 'foo'), // defaults     
    array('bar' => '[a-zA-Z]+'), // requirements
    null, // options
    null, // host
    null, // schemes
    'POST' // methods
));

$routes->add('blah_retrieve', new Route(
    '/foo/{bar}/blah/{id}',
    array('service' => 'foo'),
    array('bar' => '[a-zA-Z]+'),
    null, null, null,
    'GET'
));

$routes->add('blah_update', new Route(
    '/foo/{bar}/blah/{id}',
    array('service' => 'foo'),
    array('bar' => '[a-zA-Z]+'),
    null, null, null,
    'PUT'
));

$routes->add('blah_delete', new Route(
    '/foo/{bar}/blah/{id}',
    array('service' => 'foo'),
    array('bar' => '[a-zA-Z]+'),
    null, null, null,
    'DELETE'
));

Thanks.
I guess docs is not much well written for people who are not yet familiar with Symfony?

    use Symfony\Component\Routing\Matcher\UrlMatcher;
    use Symfony\Component\Routing\RequestContext;
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    $routes = new RouteCollection();
    $routes->add('blah_create', new Route(
        '/foo/{bar}/blah/{id}', // path         
        array('service' => 'foo'), // defaults     
        array('bar' => '[a-zA-Z]+'. 'id' => '[0-9]'+), // requirements
        null, // options
        null, // host
        null, // schemes
        'POST' // methods
    ));
$context = new RequestContext(Request::createFromGlobals());
  1. Now after posting some data to /foor/something/blah/45 should I get foo::blah_create() called?

  2. if yes, then how to get posted value and query string in that blah_create() method?

  3. below is still valid inside blah_create method to get {bar} and {id} values?

    $context = new RequestContext();
    $context->getQueryString();

  4. How about posted data? should I use $_POST or Symfony has a method?

  5. As a standalone RESTApi handler, does this symphony router has any advantage vs Klein?

  6. I am still wondering if Laravel Router comes standalone via composer?

By code below:

use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$routes = new RouteCollection();
$routes->add('blah_create', new Route(
    '/foo/{bar}/blah/{id}', // path         
    array('service' => 'Foo'), // defaults     
    array('bar' => '[a-zA-Z]+', 'id' => '[0-9]+'), // requirements
    array(), // options
    null, // host
    null, // schemes
    array('GET') // methods
));
$context = new RequestContext($_SERVER['REQUEST_URI']);

I expected blah_create() method of Foo class get called when going to /foo/f/blah/5 URL. but nothing happened. what else do I need to do?

No. The Symfony router doesn’t invoke anything. It returns the parameters associated with the matched route, then it’s up to you to decide what you want to invoke and how you want to invoke it.

Few things:

  1. If you want to get details about the request, you should use the Request class from Symfony’s HttpFoundation component. The RequestContext class doesn’t find details about the current request on its own. It needs to be given those details. You could either manually pass in the http method, host, scheme, path, query string, etc, or you could create a Request object – which will find details about the current request on its own – then instantiate the RequestContext using the Request object.
use Symfony\Component\HttpFoundation\Request;

$request = Request::createFromGlobals();

$context = new RequestContext();
$context->fromRequest($request);

Then later with the request object you can say things like $request->query->get('foo');.

  1. It looks like you’re trying to get {bar} and {id} from the query string, but those values were never part of the query string. They were part of the path. Those values will be in the set of parameters that’s returned by the router match.

  2. Once you’re ready to invoke whatever method it is you want to invoke, then it’s up to you do decide how to make the router match parameters available to that method. One option is to pass them in as arguments.

// ...

$parameters = $matcher->match('/foo');

call_user_func_array(
    /* whatever func you want to call here, either a hardcoded value or based on the matched route parameters */,

    // arguments
    array(
        $parameters['bar'],
        $parameters['id']
    )
);

You can use Symfony’s Request class.

Klein calls itself a router, but with a service container, validators, session management, request/response handling, and view/template handling, it’s basically a full blown framework. You should compare it with things like Silex.

Technically it does, but I couldn’t find any documentation on how to use it standalone.

Thanks. Got it.

  1. It seems Silex is more powerful and more sophisticated vs. Klein and Slim? Right? Among these three which one do you go as more professional?
  2. Does Symfony $matcher->match recognuze regexp? If yes how can I use regexp with it?
  3. Does assert() of Silex recognize regexp? ->assert(‘id’, ‘\d+’);
    How to have a regexp for alpha only instead of ‘\d+’? and alphanum?

Unfortunately I don’t have enough experience with all three to answer that for you.

This question doesn’t even make sense to me. Each individual route’s path can be a regex, as in the examples earlier, but the path you ultimately match against is just a path.

It looks like you copy-pasted that snippet from the documentation, and \d+ definitely looks like a regex. Do you really need me to answer this question for you?

Are you not familiar with regexes? [a-zA-Z]+ or [a-zA-Z0-9]+

  1. I meant if I have
    new Route(‘/foo/{id}’,…
    it might be /foo/1, /foo/2,… I don’t think I should have one $matcher->match for each {id}, I think I should just pass REQUEST_URI to this matcher, if that would /foo/bar the router will throw exception anyway? right?
  2. I am familiar with regexp I meant which one below should be correct?
    ->assert(‘id’, ‘\a-z+’);
    or
    ->assert(‘id’, ‘[a-z]+’);
    or what?
  3. If there are several hundred routers, isn’t it better to have separate files, one for /posts/ one for /users/ one for comments/ and let htaccess to manage rewrite rule for these files, for better performance instead of having all routers in just one file?
  4. I see to get an individual POST/GET value with Silex I can use $request->get(‘foo’); but I did not find the method to return POST/GET collections as array or so. how is this possible?

Anyy advice yet please?

You wouldn’t. There’s just one matcher and one call to match.

Yes, that’s the correct approach.

If {id} is restricted to only digits, then /foo/bar would not match, and you’d get a ResourceNotFoundException.

If your intention is to match one or more a-through-z characters, then the second one.

I’m not sure what you’re suggesting here.

$request->request // POST
$request->query // GET

Thanks for help.

  1. As about #4, $request->request(); return an array of $_POST with Silex?
  2. As about #2, just to make sure, I am talking about Silex and NOT symfony router, still the second regexp should be valid in Silex?
  3. As about #3 I meant if I have several tens router for /comments/{id}, /comments/{date} etc. and also several tens router for /user/{id} /user/{username} etc. all of these routers together will be several hundreds. Isn’t it to have separate file comment.php, user.php to group/categorize routers in separate file instead of having all hundreds in one index.php file? Better for performance?

We can’t keep going back and forth over every tiny question. This is something simple and in the documentation. You can also just try it and see what happens to answer your own question.

A regex is a regex. Doesn’t matter if it’s Silex or Symfony router or something else.

I doubt it will make a performance difference, but you can always measure to check.

As about #1 above, I expected to have $_GET as array with $request->query but I got below instead. please advice how to have $_GET as an array?

Symfony\Component\HttpFoundation\ParameterBag Object ( [parameters:protected] => Array ( ) )

$request->query and $request->request will be ParameterBag objects. You can call $paramBag->get('some_key') or $paramBag->set('some_key', 'some_value') or iterate over it for ($paramBag as $key => $value), among others.

Thanks,
How to disable direct access to $_POST, $_GET in a script like phpBB did? Does disabling superglobals and just use HttpFoundation add anything to security?

Hello,

Thanks for your time to help. much appreciated. Please see Create listing/form with crud manager with symfony
I was thinking of this:

use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
$routes = new RouteCollection();
$routes->add($request->query->get('action').'Action', new Route(
    $_SERVER['PHP_SELF'], // path         
    array('controller' => 'User'), // defaults     
    array($request->query->get('id') => '[0-9]+'), // requirements
    array(), // options
    null, // host
    null, // schemes
    array('GET', 'POST') // methods
));
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match($_SERVER['PHP_SELF']);
$controller = new $parameters['controller']($em); // with doctrine EntityManager in constructor
$action = $controller->$parameters['_route'];

I think to have this in each page e.g. product.php, user.php to call User or Product controller. Is it a good practice to have two scripts, one router and one controller for everything e.g. User, Product etc.? If bad practice how about having just one index.php and together with action, also pass another query e.g. ‘controller’ to tell the index router which controller and which action method should call like below:

array('controller' => ucfirst($request->query->get('controller'))), // defaults     

so with the router above with a query ?id=1&action=edit&controller=user
it will call editAction method of User controller? Is it a good practice?
and as we don’t know whether we got post or get for this router how do we know if we should pass $request->query->all() or $request->request->all() as a parameter to action method?

$action = $controller->$parameters['_route'](post or get params);

or better to have two separate router one for post and one for get?
Please advice the best practice for the problem I described in that another thread I gave the link. I appreciate your time.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.