Can someone explain maps in an easy to understand way


#1

So the docs say this

Route groups
To help organize routes into logical groups, the \Slim\App also provides a group() method. Each group’s route pattern is prepended to the routes or groups contained within it, and any placeholder arguments in the group pattern are ultimately made available to the nested routes:

$app = new \Slim\App();
$app->group(’/users/{id:[0-9]+}’, function () {
$this->map([‘GET’, ‘DELETE’, ‘PATCH’, ‘PUT’], ‘’, function ($request, $response, $args) {
// Find, delete, patch or replace user identified by $args[‘id’]
})->setName(‘user’);
$this->get(’/reset-password’, function ($request, $response, $args) {
// Route for /users/{id:[0-9]+}/reset-password
// Reset the password for user identified by $args[‘id’]
})->setName(‘user-password-reset’);
});
Note inside the group closure, $this is used instead of $app. Slim binds the closure to the application instance for you, just like it is the case with route callback binds with container instance.

inside group closure, $this is bound to the instance of Slim\App
inside route closure, $this is bound to the instance of Slim\Container

However what I am finding more and more of, is that the documentation which is meant to help us NOOBS makes us confussed, why can’t the developers take the time to clearly show examples of just how the above works.

This is how the above left me.

  1. Where do I link the map too? does the [‘GET’, ‘DELETE’, ‘PATCH’, ‘PUT’] have the same code? or do they do different things?

    • What I mean by this if I want to delete say the users account is that code inside the map code

      $this->map([‘GET’, ‘DELETE’, ‘PATCH’, ‘PUT’], ‘’, function ($request, $response, $args) {
      // Find, delete, patch or replace user identified by $args[‘id’]

    DO I PUT THE CODE HERE AND HOW DO I SAY THIS CODE FOR DELETE THIS CODE FOR GET ETC.
    })->setName(‘user’);


#2

Most of the methods that you use to create route callables respond to a single HTTP method.

i.e.

$app->post('/user/{id}), function($request, $response) { /* code here */});

will only respond to a POST request. If you want to respond to a PUT request, then you have to write another method:

$app->put('/user/{id}), function($request, $response) { /* code here */});

The map method allows you to write a route callable that responds to more than one HTTP method.

e.g. To respond to both POST and PUT requests:

$app->map(['post', 'put']), '/user/{id}), function($request, $response) { /* code here */});

#3

Follow up requestion.
So lets say that I want to let a user update their contact information. I could then in theory do the following.

$app->post('/update/user/{id}/contacts), function($request, $response) { print_r($_REQUEST); //This should still print out all information that the user has sent in the $_POST? or do I just use $request? });


#4

You should use the methods in the $request variable in a route action as that way you pick up any changes that middleware may have made.

For POSTed data, use $request->getParsedBody() as you get automatic decoding of various content-types to an array that way.


#5

I am getting this error\

Fatal error: Call to undefined method Slim\Http\Response::getParsedBody() in /home/apipetfindr/public_html/index.php on line 14

Code

<?php

require 'vendor/autoload.php';

$app = new Slim\App();

$app->get('/hello/{name}', function ($request, $response, $args) {
    return $response->write("Hello, " . $args['name']);
    return $request->getParsedBody();
});

$app->get('/update/user/{id}/contacts', function($request, $response) {

  $headers = $response->getParsedBody();
  foreach ($headers as $name => $values) {
      echo $name . ": " . implode(", ", $values);
  }
});

$app->run();
?>

#6

Try $request->getParsedBody() instead of $response->getParsedBody().

You can find an example in the tutorial on handling POST data.