44

I call a route via AJAX and pass data to it. In a controller, I want to get $_POST['var'], but it does seem to work on Drupal 8.

How I can get values contained in $_POST from a controller?

2
  • 2
    $_POST still exists, you just shoudn't use it directly. If $_POST is empty, then the request object will also be empty and your error happens earlier. Often, this is for example because mod_rewrite is not enabled/configured correctly and the page is redirect through the not found directive, which drops post data.
    – Berdir
    Commented Jul 14, 2016 at 17:44
  • are these answers still valid? I'm trying to submit / receive a simple form and I don't want to undergo creation of a module and all that stuff ; but after the submission all the global arrays (_POST, _REQUEST ...) are empty (except for REQUEST[session]) and \Drupal::request->request->all() and all other combinations (->query ; ->get($name)) return empty arrays or variables.
    – Max
    Commented May 22 at 13:03

7 Answers 7

94

From the change record:

$name = $_POST['name']; // form param

becomes

$name = \Drupal::request()->request->get('name'); // form param

Incidentally, for GET vars, you would use:

$query = \Drupal::request()->query->get('name');
5
  • 2
    thanks, and do you know how can I get all items? I mean $_POST completely not one item.
    – Yuseferi
    Commented Jul 14, 2016 at 9:59
  • 6
    I haven't checked, but knowing Symfony I'd assume: \Drupal::request()->request->all()
    – Clive
    Commented Jul 14, 2016 at 10:02
  • 3
    Thanks, this is true answer to my question although I didn't get expected result ( maybe there is a problem in another place ,I ask it in another question.
    – Yuseferi
    Commented Jul 14, 2016 at 10:08
  • 2
    I can confirm that you can use \Drupal::request()->query->all() to get all $_GET variables.
    – oknate
    Commented Jul 13, 2017 at 14:26
  • 1
    Request should be like this $name = \Drupal::request()->get('name'); // form param
    – Srikanth
    Commented Jun 1, 2020 at 10:11
44

In a controller get the request with a type-hinted argument Request $request:

<?php

namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Request;

class ExampleController extends ControllerBase {

  /**
   * Controller to return a POST or a GET parameter.
   */
  public function action(Request $request) {

    // get your POST parameter
    $foo = $request->request->get('foo');

    // or get your GET parameter
    $foo = $request->query->get('foo');

    // POST requests are not cached, but for GET you need a cache context
    return [
      '#plain_text' => $foo,
      '#cache' => ['contexts' => ['url.query_args:foo']],
    ];
  }

}

More info https://www.drupal.org/docs/8/api/routing-system/using-parameters-in-routes

Use #plain_text to escape the input data for HTML output. See https://www.drupal.org/node/2559263

23

Inject the RequestStack into your controller.

The current request contains the query attribute that in turn contains the GET parameters. request contains the POST parameters.

<?php

namespace Drupal\example_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * An example controller.
 */
class ExampleController extends ControllerBase {

  /**
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  private $requestStack;

  /**
   * Constructor.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   */
  public function __construct(RequestStack $request_stack) {
    $this->requestStack = $request_stack;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('request_stack')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function action() {
    // Get your GET parameter here.
    $this->requestStack->getCurrentRequest()->query->get('foo');
  }

}
5

If you are using Content-Type: application/json please use :

$post_data = json_decode( $this->request->getContent(),TRUE);
4

You can check the Request object like

\Drupal::request()->getMethod();

it will returns GET or POST or whatever. If you are working inside an object, remember to DI the Request service.

2

None of the other answers worked for me but I found this that did:

$request->getContent();
1
  • doesn't work for me - if by $request you mean \Drupal::request(). Any help would be appreciated.
    – Max
    Commented May 25 at 2:19
1

This is an example for accessing URL parameters and passing them to a template. I am assuming you have already created your module and required files and that /test?fn=admin is the path your module is using.

In Your .module file implement hook_theme() and define variables and template name. (Make sure you replace _ with - when creating the template file.)

function my_module_theme () {   
  return [
    'your_template_name' => [
      'variables' => [
        'first_name'    => NULL,
      ],
    ],
  ];
}

Now create your controller and put the following code in it.

 namespace Drupal\my_module\Controller;
 
 use Drupal\Core\Controller\ControllerBase;
 use Symfony\Component\HttpFoundation\Request;

 class MyModule extends ControllerBase {
 
   public function content(Request $request) {
     return [
       '#theme' => 'my_template',
       '#first_name' => $request->query->get('fn'), //This is because the parameters are in $_GET, if you are accessing from $_POST then use "request" instead "query"
     ];
   }

 }

In template file, which should be my-template.html.twig, you can access this parameter as <h3>First Name: {{ first_name }}</h3>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.