Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why the string to variable conversion doesn't work for the _GET variable from another file?

I have the following code in test.php:

<?php

$request_method = $_SERVER['REQUEST_METHOD']; // contains 'GET', as it should

echo 'json_encode($_GET) = ' . json_encode($_GET); echo "\n"; // works, prints the GET variables
echo "\n";

echo 'json_encode(${\'_\' . \'GET\'}) = ' . json_encode(${'_' . 'GET'}); echo "\n"; // also works, prints the GET variables
echo "\n";

echo '$request_method = ' . $request_method; echo "\n";
echo 'json_encode(${\'_\' . $request_method}) = ' . json_encode(${'_' . $request_method}); echo "\n"; // fails
echo "\n";

$a = 'GET';
echo '$a = ' . $a; echo "\n";
echo 'json_encode(${\'_\' . $a}) = ' . json_encode(${'_' . $a}); echo "\n"; // fails
echo "\n";

$x = '_GET';
echo '$x = ' . $x; echo "\n";
echo 'json_encode(${$x}) = ' . json_encode(${$x}); echo "\n"; // fails

if I do a GET request with the query string ?action=getUsername it results in the following output:

json_encode($_GET) = {"action":"getUsername"}

json_encode(${'_' . 'GET'}) = {"action":"getUsername"}

$request_method = GET
json_encode(${'_' . $request_method}) = {"action":"getUsername"}

$a = GET
json_encode(${'_' . $a}) = {"action":"getUsername"}

$x = _GET
json_encode(${$x}) = {"action":"getUsername"}

which is OK.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But, when I’m using the code in a function from a different .php file, then, I get the following output:

json_encode($_GET) = {"action":"getUsername"}

json_encode(${'_' . 'GET'}) = {"action":"getUsername"}

$request_method = GET
json_encode(${'_' . $request_method}) = null

$a = GET
json_encode(${'_' . $a}) = null

$x = _GET
json_encode(${$x}) = null

and I don’t understand what am I doing wrong.

EDIT:

This is AuthController.php, from where I normally do the request but it fails:

class AuthController extends BaseController
{

    protected function handlePostRequest(): void
    {
        switch ($this->action) {
            case 'login': $this->{'handle_' . $this->action}(); break;
            default: $this->respond_action_not_found();
        }
    }

    protected function handleGetRequest(): void
    {
        switch ($this->action) {
            case 'getUsername': $this->{'handle_' . $this->action}(); break;
            default: $this->respond_action_not_found();
        }
    }

    private function handle_login(): void
    {
        echo 'login';
    }

    private function handle_getUsername(): void {
        echo "getUsername";
    }
}

(new AuthController())->handleRequest();

And this is the BaseController.php:

<?php

use JetBrains\PhpStorm\NoReturn;
require_once '../domain/StatusCode.php';


abstract class BaseController
{
    protected string $request_method;
    protected mixed $request_variables;
    protected string $action;

    public function __construct()
    {
        $request_method = $_SERVER['REQUEST_METHOD']; // contains 'GET', as it should

        echo 'json_encode($_GET) = ' . json_encode($_GET); echo "\n"; // works, prints the GET variables
        echo "\n";

        echo 'json_encode(${\'_\' . \'GET\'}) = ' . json_encode(${'_' . 'GET'}); echo "\n"; // also works, prints the GET variables
        echo "\n";

        echo '$request_method = ' . $request_method; echo "\n";
        echo 'json_encode(${\'_\' . $request_method}) = ' . json_encode(${'_' . $request_method}); echo "\n"; // fails
        echo "\n";

        $a = 'GET';
        echo '$a = ' . $a; echo "\n";
        echo 'json_encode(${\'_\' . $a}) = ' . json_encode(${'_' . $a}); echo "\n"; // fails
        echo "\n";

        $x = '_GET';
        echo '$x = ' . $x; echo "\n";
        echo 'json_encode(${$x}) = ' . json_encode(${$x}); echo "\n"; // fails


        echo ""; echo "\n";

//        echo $this->request_method; // 1
//        echo "\n";
//        echo json_encode($_GET); // 2
//        echo "\n";
//        echo json_encode(${'_' . $this->request_method}); // 3
//        echo "\n";
//        echo json_encode(${'_' . $_SERVER['REQUEST_METHOD']}); // 4
//        echo "\n";
//        echo json_encode(${'_' . 'GET'}); // 5
//        echo "\n";
//        $a = "_" . $this->request_method;
//        echo json_encode($a); // 6
//        echo "\n";
//        error_log($a);
//        error_log($$a);
//        echo json_encode($$a); // 7
//        echo "\n";
//        echo "should work: " . json_encode(${'_GET'});
//        echo "\n";
//        echo "request method: " . $this->request_method;
//        echo "\n";
////        $x = ${'_' . $this->request_method};
//        $x = ${'_' . $_SERVER['REQUEST_METHOD']};
//        echo "should work too : " . json_encode($x);
//        echo "\n";
//        echo "should work too : " . $x;
//        echo "\n";

        $this->request_variables = ${'_' . $this->request_method};
        $this->action = $this->request_variables['action'];
    }

    abstract protected function handlePostRequest(): void;
    abstract protected function handleGetRequest(): void;

    public function handleRequest(): void {
        if (!isset($this->action))
            $this->respond(StatusCode::BAD_REQUEST, "Action is not set");

        switch ($this->request_method) {
            case "POST": {$this->handlePostRequest(); break; }
            case "GET": {$this->handleGetRequest(); break; }
            default:
        }
    }

    #[NoReturn] protected function respond(int $status_code, mixed $content = ""): void {
        http_response_code($status_code);
        echo json_decode($content);
        exit;
    }

    #[NoReturn] protected function respond_success(int $status_code, mixed $content = ""): void {
        $this->respond(StatusCode::OK, $content);
    }

    #[NoReturn] protected function respond_action_not_found(): void {
        $this->respond(StatusCode::BAD_REQUEST, "Action not found");
    }

    #[NoReturn] protected function respond_invalid_parameters(string $additional_message = ""): void {
        $this->respond(StatusCode::BAD_REQUEST, "Invalid parameters. " . $additional_message);
    }
}

EDIT 2: Workaround

From @Kubo2 in Superglobals can't be accessed via variable variables in a function?

$a = "_GET";
echo json_encode($GLOBALS[$a]);

>Solution :

You can’t access the superglobals via variable variables (as you did with expressions like ${'_' . $a}) as stated in the manual Variable variables:

Warning
Please note that variable variables cannot be used with PHP’s Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading