codeigniter4 / codeigniter4/CodeIgniter4

Bug: `getVar()` behaves inconsistently with GET parameters

Abierto
#9,872 6 comentarios 2 reacciones 0 asignados Ver en GitHub
bug
Lenguaje dominante
PHP
Estrellas
6k
Forks
2k
Merge medio
1 d 11 h
PR fusionados (30 d)
73

Descripción

### PHP Version

8.4

### CodeIgniter4 Version

4.6.4

### CodeIgniter4 Installation Method

Composer (using `codeigniter4/appstarter`)

### Which operating systems have you tested for this bug?

macOS

### Which server did you use?

cli-server (PHP built-in webserver)

### Environment

development

### Database

-

### What happened?

In some cases, using `$validator->withRequest()` will not work correctly. Let's consider this test:

https://github.com/codeigniter4/CodeIgniter4/blob/11f0130a5ecc447d5a4c21b2ba991ea381433949/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php#L226-L241

As you may notice in the above test, `SiteURIFactory` updates some superglobals, here:

https://github.com/codeigniter4/CodeIgniter4/blob/11f0130a5ecc447d5a4c21b2ba991ea381433949/system/HTTP/SiteURIFactory.php#L162-L175

The problem is that while `$_SERVER['QUERY_STRING']` and `$_GET` are being updated, the `$_REQUEST` isn't. And `$_REQUEST` is needed to make `getVar()` work correctly.

https://github.com/codeigniter4/CodeIgniter4/blob/11f0130a5ecc447d5a4c21b2ba991ea381433949/system/Validation/Validation.php#L505-L527

https://github.com/codeigniter4/CodeIgniter4/blob/11f0130a5ecc447d5a4c21b2ba991ea381433949/system/HTTP/IncomingRequest.php#L496-L506

### Steps to Reproduce

```php
public function testQueryStringWithQueryStringAndRequest(): void
{
// /index.php?/ci/woot?code=good#pos
$_SERVER['REQUEST_URI'] = '/index.php?/ci/woot?code=good';
$_SERVER['QUERY_STRING'] = '/ci/woot?code=good';
$_SERVER['SCRIPT_NAME'] = '/index.php';

// these are always the same at the beginning
$_GET['/ci/woot?code'] = 'good';
$_REQUEST['/ci/woot?code'] = 'good';

$factory = $this->createSiteURIFactory($_SERVER);

$expected = 'ci/woot';
$this->assertSame($expected, $factory->detectRoutePath('QUERY_STRING'));
$this->assertSame('code=good', $_SERVER['QUERY_STRING']);
$this->assertSame(['code' => 'good'], $_GET);
// this will fail
$this->assertSame(['code' => 'good'], $_REQUEST);
}
```

### Expected Output

Validation method `$validator->withRequest()` should work correctly.

The most tempting solution is to add `syncRequestAfterGetChange()` to `Superglobals` and call it from `SiteURIFactory` whenever `$_GET` is modified. This would keep `$_REQUEST` synchronized with current values.

The downside is it introduces "magic" behavior that violates standard PHP semantics where `$_REQUEST` is populated once and never auto-updated. However, since we update `$_GET` as a "standard", behavior, then updating `$_REQUEST` may be acceptable?

I was thinking about something like this:

```php
public function syncRequestAfterGetChange(): void
{
$requestOrder = ini_get('request_order') ?: ini_get('variables_order');

$this->request = [];

foreach (str_split($requestOrder) as $type) {
match ($type) {
'G' => $this->request = array_merge($this->request, $this->get),
'P' => $this->request = array_merge($this->request, $this->post),
'C' => $this->request = array_merge($this->request, $this->cookie),
default => null,
};
}

$_REQUEST = $this->request;
}
```

But I'm unsure if this is the right direction.

### Anything else?

https://forum.codeigniter.com/showthread.php?tid=93652

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza con la prueba referenciada en tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php y las actualizaciones de las superglobales en system/HTTP/SiteURIFactory.php. Lee system/Validation/Validation.php y system/HTTP/IncomingRequest.php para seguir cómo withRequest() usa getVar(). Se considera terminado cuando la aserción de $_REQUEST de la prueba pasa y validator->withRequest() funciona correctamente sin infringir la semántica de solicitudes prevista de PHP.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
php
Área
api, backend
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.