Can't make put route to work [SOLVED]


#1

i am using a repository to integrate slim3 with oauth2, https://github.com/pabloroca/slim3-simple-rest-skeleton im tryng to make an API for a mobile app.

I am able to use the repository correctly, or at least the oauth part which i believe it has nothing to do with what im am expiriencing.

the routes are like this:

$app->group('/books', function () {
$this->get   ('',             _Controller_oAuth2::class.':getAll');
$this->get   ('/{id:[0-9]+}', _Controller_oAuth2::class.':get');
$this->post  ('',             _Controller_oAuth2::class.':add');
$this->put   ('/{id:[0-9]+}', _Controller_oAuth2::class.':update');
$this->delete('/{id:[0-9]+}', _Controller_oAuth2::class.':delete');`

I am able to access the get and also the get via /books/1 for example. and here is where i am having trouble, i can also use the post to make a new row in my table and even the delete. But for some reason i can’t make the put form work. I am using postman for this.

My first question is why if the route is defined as /{id:[0-9]+} why do i have to access /books/1 and not /books/id:1?

This is the controller for a get which is working .

public function get(Request $request, Response $response, $args)
{
$this->logger->info(substr(strrchr(rtrim(CLASS, ‘\’), ‘\’), 1).’: '.FUNCTION);

    $path = explode('/', $request->getUri()->getPath())[1];

    $result = $this->dataaccess->get($path, $args);
    if ($result == null) {
        return $response ->withStatus(404);
    } else {
        return $response->write(json_encode($result));
    }
}

And here is the controller for a put which is not working

public function update(Request $request, Response $response, $args)
{
$this->logger->info(substr(strrchr(rtrim(CLASS, ‘\’), ‘\’), 1).’: '.FUNCTION);

    $path = explode('/', $request->getUri()->getPath())[1];
    $request_data = $request->getParsedBody();

    $isupdated = $this->dataaccess->update($path, $args, $request_data);
    if ($isupdated) {
        return $response ->withStatus(200);
    } else {
        return $response ->withStatus(404);
    }
}

and here is the dataaccess for both:

GET:

public function get($path, $args)
{
$this->logger->info(substr(strrchr(rtrim(CLASS, ‘\’), ‘\’), 1).’: '.FUNCTION);

    $table = $this->maintable != '' ? $this->maintable : $path;

    $sql = "SELECT * FROM ". $table . ' WHERE ' . implode(',', array_flip($args)) . ' = :' . implode(',', array_flip($args));

    $stmt = $this->pdo->prepare($sql);
    // bind the key
    $stmt->bindValue(':' . implode(',', array_flip($args)), implode(',', $args));

    $stmt->execute();
    if ($stmt) {
        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
    } else {
    	$result = null;
    }

    return $result;
}

PUT

public function update($path, $args,$request_data)
{
$this->logger->info(substr(strrchr(rtrim(CLASS, ‘\’), ‘\’), 1).’: '.FUNCTION);

    $table = $this->maintable != '' ? $this->maintable : $path;

    // if no data to update or not key set = return false
    if ($request_data == null || !isset($args[implode(',', array_flip($args))])) {
        return false;
    }

    $sets = 'SET ';
    foreach($request_data as $key => $value){
        $sets = $sets . $key . ' = :' . $key . ', ';
    }
    $sets = rtrim($sets, ", ");

    $sql = "UPDATE ". $table . ' ' . $sets . ' WHERE ' . implode(',', array_flip($args)) . ' = :' . implode(',', array_flip($args));
    
    $stmt = $this->pdo->prepare($sql);

    foreach($request_data as $key => $value){
        $stmt->bindValue(':' . $key,$request_data[$key]);
    }
    
    // bind the key
    $stmt->bindValue(':' . implode(',', array_flip($args)), implode(',', $args));

    $stmt->execute();

  	return ($stmt->rowCount() == 1) ? true : false;
}

From the logger i think that the code is stopping at line

if ($request_data == null || !isset($args[implode(’,’, array_flip($args))])) {
return false;
}

and what the postman returns is just this 404.


#2

It appears that i was making a mistake, the body should have been x-www-form-urlencoded, works fine now