Error 405 - <form method="post"...> fails with SLIM?

Hi!

I’ve been struggling with this problem for couple of days already. What I’d like to accomplish here is:

  1. Fill in the form with value data.
  2. Press “update” button to POST data to router.
  3. POST data from router.php to another .php-file that has a class method called update().
  4. Die() there to see that POST method went through.

If I die() at top of router.php, the post-method from the form seems to arrive there.

But as the code continues to router’s post method (seen above), the error is popped:
405 Method not allowed: must be one of: (GET)

Any idea how to fix this or have a work-around?

Added: My Router GET-requests do work good, as well as .htaccess -file is configured just as Slim recommends. Also if I do a traditional _form _POST method_ to another .php page (without the router), things work fine, however then I don't know how I could use _form action_ to direct the _POSTed values to a specific Class and Method. That’s why I needed the Router to work.

Thank you!

Umelev

Try this method signature.

<?php

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

class CartController
{
   
   public static function update(ServerRequestInterface $request, ResponseInterface $response, $args){

      die("OK, got this slug: " . $args['slug'] );

   }

}

Thank you for reply!

However, this didn’t solve the problem.

Below you can see my CartController as whole:

I’m not sure if that’s your problem, but your controller functions should not be static. Try removing the static function specifier.

Hi,

Yeah, I forgot that on when doing my tests as supposed by marcelbonnet, normally I don’t have them.

It seems to go OK if I POST anything directly from the form, say to Controller, using absolute path at in form action: /test/App/Controllers/CartController.php. The question now is, how do I target the request to a specific function in there if I do it this way?

Okey, here we go:

Everything works fine as long as I don’t have to pass through third parameter via my http request. In this case it’s $slug (=$args kind of thing to identify a product). The slug is needed in my Cart Controller in order to identify product in upcoming SQLs.

So, when I add that $slug -thing to the POST method of my form {slug: item.slug}, and I try to route it forth in my Router: post(‘cart/{slug}’, … I get the Error 405.

Question: What may cause an error with POST methods “$args” -section? (in this case the $slug)

You want to use a route name to generate your form (and link) URLs. For example:

<form class="form form-horizontal" 
      id="page_editor_form" 
      action="{{ path_for('pageEdit') }}" 
      role="form" 
      method="POST" 
      enctype="application/x-www-form-urlencoded">

In your route definition you then resolve/map this name to a function (actually a class method) to be called:

$app->post ("/admin/page_edit", 'App\Controller\AdminFormController:pageEdit')->setName ('pageEdit');

Try this approach, it works without any issues for me.

Thanks for your effort, however I’m still receiving the same 405 Error.

And there’s is also the same issue remaining: How do I pass the $slug -variable within the POST method, because the update2 -method actually requires (Request $request, Response $response, $slug). For sake of clarity I’ve taken it out in the above example cos I cannot get the normal route post work still…

In that case I’m sorry to say that don’t know why you’re getting 405 error. I’m guessing it’s something simple/stupid, but I’m just not seeing it.

For a post form, there’s no reason to pass a slug (since it’s not visible to the user you can just pass an object-id) but you can define a route like this:

$app->get  ("page_edit/{id}", 'App\Controller\AdminController:pageEdit')->setName ('pageEditExisting');

and then do a

{{ path_for('pageEdit', { 'id': page.id }) }}

or

{{ path_for(‘pageEdit’, { ‘id’: page.slug }) }}

in your form action tag. Your controller of course needs to know whether it’ll be receiving an ID or a slug, but the processing logic is the same for both versions.

Alternatively you can just leave the route without the “/{id}” part and pass a hidden form variable containing the objectID/slug (as you prefer) to your form submission handler in your controller.

Hope this helps.

1 Like

Hey, your latest proposal is just my initial setup which initially popped the 405 :slight_smile: So that’s exactly what I’m aiming for.

But anyway, thanks! I let you know when I get this figured out!

-Vellu