405 Method Not Allowed

Hello Guys, how are you? Guys, here’s the thing, I used Slim3 and now I decided to migrate to Slim4, but for 3 days I have a very annoying problem and so far I haven’t been able to solve it. When I try to change a record via form, using the PUT method, slim returns the following error:

405 Method Not Allowed
The application could not run because of the following error:

Details
Type: Slim\Exception\HttpMethodNotAllowedException
Code: 405
Message: Method not allowed. Must be one of: GET
File: E:\GIT\WEB\IsaquelSilva\dashboard\vendor\slim\slim\Slim\Middleware\RoutingMiddleware.php
Line: 96

My Code
form.php
< form action=“./bancas/33” id=“formulario” method=“POST”>

    <input type="hidden" name="_METHOD" value="PUT"> 
    <button id="btn-confirm" type="submit" class="btn btn-primary">Confirm</button>                     
</form> 

routes.php
$app->group(’/bancas’, function(RouteCollectorProxy $group) {
$group->get(’[/{page:[0-9]+}]’, ‘\App\Controller\ControllerBancas:getAll’)->setName(‘bancas’);
$group->get(’/inserir’, ‘\App\Controller\ControllerBancas:openForm’);
$group->get(’/{id:[0-9]+}-{titulo}’, ‘\App\Controller\ControllerBancas:getById’);
$group->post(’’, ‘\App\Controller\ControllerBancas:createData’);
//$group->put(’/{id}’, ‘\App\Controller\ControllerBancas:updateData’);
$group->delete(’/{id:[0-9]+}’, ‘\App\Controller\ControllerBancas:delete’);
});

I don’t know what else to do :'(. Thank’s

1 Like

I am also having an issue but with delete request. Is your delete request working?

$app->group('/album', function (RouteCollectorProxy $group) {
    $group->get('', AlbumController::class . ':index')->setName('web.album');

    $group->get('/create[/{id}]', AlbumController::class . ':create')->setName('web.album.create');
    $group->post('/create[/{id}]', AlbumController::class . ':create');
    $group->patch('/create[/{id}]', AlbumController::class . ':create');

    $group->get('/delete[/{id}]', AlbumController::class . ':delete');
    $group->delete('/delete[/{id}]', AlbumController::class . ':delete')->setName('web.album.delete');

});

Hi!

The first route (not the method) that matches will be used a matching route. One of your group route matches before your desired route matches. Try to remove all other routes and then add more and more routes step by step. Start with this and then add more routes:

$app->group('/bancas', function(RouteCollectorProxy $group) {
    $group->post('', '\App\Controller\ControllerBancas:createData');
});

Then add more routes like this and so on…

$group->put('/{id:[0-9]+}', '\App\Controller\ControllerBancas:updateData');

Your form method is using the POST method: method=“POST”
Using this <input type="hidden" name="_METHOD" value="PUT"> will not change the browsers behavior. Press F12 (Developer Toolbar) and then check out the request your browser sends to the server.

Hello FvsJson, I’m also having problems with the delete, only GET and POST works.

Hello friend odan, how are you? Thank you very much for the reply, as soon as I am on the laptop I will try what you said. Yes, earlier today I realized that _Method = PUT is sending a POST to the browser, but in Slim3 it was not like that, do you know how to get around this? Thanks again.

I think browsers form method only supports POST and GET. If you need PUT, you have to send the form data via Ajax (e.g. with Axios or jQuery) and then handle the proper PUT request on server-side.

If you still have to use the hidden _METHOD for PUT/PATCH/DELETE methods, you may need special middleware (PSR-15) to convert the request before the actual routing is performed.

I understand @odan, thank you very much for your help. Very enlightening.

I used the _METHOD delete and still got an issue… :frowning:

Me too, @FvsJson, but by the comment of @odan we could understand the setting. As soon as I’m at my house, I’ll check it out.

@niloblack did you git working?

Hello @FvsJson, forgive me for the delay, unfortunately it took me a long time to get back to work on this project, but i already did and i will post what i did.

Regarding the PUT method, I solved creating a new post route by adding “/ {id”:

$group->post(’’, ‘\App\Controller\ControllerX:createData’);
$group->post(’/{id:[0-9]+}’, ‘\App\Controller\ControllerX:updateData’);

The DELETE method, I created an AJAX request:

Router
$group->delete(’/{id:[0-9]+}’, ‘\App\Controller\ControllerX:delete’);

Controller
public function delete($request, $response, $args) {
try{
$id = (int) $args[‘id’];

        // Model Delete($id)

        $response->getBody()->write(json_encode(['success' => true]));
        return $response
                    ->withHeader('Content-type', 'application/json')
                    ->withStatus(200);
    } catch (\Exception $e){
        $response->getBody()->write(json_encode(['success' => false, 'msg'=> $e->getMessage()]));
        return $response
                    ->withHeader('Content-type', 'application/json')
                    ->withStatus($e->getCode());
    }
}

Form
< button class=“btn btn-success” id=“btn-delete”>Delete</ button>

("#btn-delete").click(function(){ ("#loader").html(’ Aguarde…’);

  // AJAX request
  $.ajax({
    url: '{my_router}/{my_id}',
    type: 'DELETE',
    success: function(response){
      window.location.href = 'my_page';
    },
    error: function(response){
      console.log(response);
      $('#loader').html('<span class="font-weight-bold text-danger"><i class="far fa-times-circle"></i> A error ocorred</span>');
    }
  });
});

@niloblack Hi thanks for the feedback, I created a new route too and changed my to post for the delete action. However the point is we used be aboe to use the _Method and delete / put should work.

Im going to create an issue on the slim project and see what they say.

@niloblack I logged it if you want to follow. Github issue

Have you read this?

Method Overriding Middleware (Slim v4)

Have you added that Middleware and do you see it in your call stack?

1 Like

Great @FvsJson, thanks, I go follow. :wink:

Not, I go verify. Thanks.

@tflight, this is unbelievable, my brother kkkk I researched so much, so much, so much and the solution was so easy, it seems like a lie. My brother, thank you very much, problem solved.

https://www.slimframework.com/docs/v4/middleware/method-overriding.html

I have yes added the middleware yes

<?php

use App\Middleware\FlashMessageMiddleware;
use Slim\Middleware\MethodOverrideMiddleware;
use Slim\Views\TwigMiddleware;
use Zeuxisoo\Whoops\Slim\WhoopsMiddleware;

$app->add($session);

// Register Middleware To Be Executed On All Routes
$app->add('csrf');

//$app->add(new \App\Middleware\TestMiddleware($app));
$app->add(new FlashMessageMiddleware($container));

// Add Twig-View Middleware
$app->add(TwigMiddleware::createFromContainer($app));

// Add MethodOverride middleware
$app->add(new MethodOverrideMiddleware());

// The RoutingMiddleware should be added after our CORS middleware so routing is performed first
$app->addRoutingMiddleware();

/*SHOULD BE LAST MIDDLEWARE*/
//$app->addErrorMiddleware(getenv('APP_DEBUG') === 'true', true, true);
$app->add(new WhoopsMiddleware([
    'enable' => getenv('APP_DEBUG') === 'true'
]));

@FvsJson, Did it work?

@niloblack Ive always had it. Ill have to created my delete section and see but last time I tested it wasnt working.

Just fyi I wasnt using Ajax to do my delete. I used a normal form for my put and that works 100% but my delete with a normal from nothing.