Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: getPost() still returns empty strings despite updating the $_POST superglobal via a filter #9456

Closed
campio97 opened this issue Feb 20, 2025 · 4 comments

Comments

@campio97
Copy link

PHP Version

8.3

CodeIgniter4 Version

4.5.7

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

macOS

Which server did you use?

fpm-fcgi

Database

No response

What happened?

I am implementing a filter in CodeIgniter 4 to recursively convert empty strings in POST data to null. However, even though I update the $_POST superglobal and use the method setGlobal('post', $data) within the filter, subsequent calls to $this->request->getPost() continue to return the original values (with empty strings), ignoring the conversion.

Steps to Reproduce

Create a filter (for example, EmptyStringToNullFilter) that:
Retrieves POST data using $request->getPost().
Recursively converts empty strings to null.
Directly updates $_POST and calls $request->setGlobal('post', $data).

In the filter (or in the controller), perform a var_dump($this->request->getPost()) to verify the data.

Observe that the field that should be null (instead of an empty string) is not updated and remains an empty string.


namespace App\Filters;

use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;

class EmptyStringToNullFilter implements FilterInterface
{
    public function before(RequestInterface $request, $arguments = null)
    {
        // Otteniamo i dati POST
        $post = $request->getPost();
        if (!empty($post)) {
            // Convertiamo ricorsivamente le stringhe vuote in null
            $post = $this->convertEmptyToNull($post);
            // Impostiamo nuovamente i dati globali per POST
            var_dump($post);
            // Aggiorniamo direttamente la superglobale $_POST
            $_POST = $post;
            $request->setGlobal('post', $post);
            var_dump($request->getPost());
            die();
        }
    }

    /**
     * Funzione ricorsiva per convertire le stringhe vuote in null.
     *
     * @param mixed $data
     * @return mixed
     */
    private function convertEmptyToNull($data)
    {
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                $data[$key] = $this->convertEmptyToNull($value);
            }
            return $data;
        }
        return ($data === '') ? null : $data;
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        // Non è necessario operare nulla dopo l'esecuzione
    }
}

Expected Output

The changes made to $_POST via the filter (specifically, the conversion of empty strings to null) should be reflected in subsequent calls to $this->request->getPost(), including updating the internal cache of the request.

Anything else?

No response

@campio97 campio97 added the bug Verified issues on the current code behavior or pull requests that will fix them label Feb 20, 2025
@michalsn
Copy link
Member

  1. Modifying superglobals is a bad practice
  2. You can't send a null value via a normal POST request
  3. We use filter_var(), to fetch data from superglobals, so naturally, you will not receive a null value.
  4. We could make some modifications to make it work, but I don't believe it's a good idea. The null value is reserved to indicate that the value is not set/doesn't exist.

@michalsn michalsn removed the bug Verified issues on the current code behavior or pull requests that will fix them label Feb 20, 2025
@campio97
Copy link
Author

Hello,
Thank you for your response. I understand that modifying superglobals is not recommended and that filter_var() returns an empty string for fields that exist but have no value rather than null.

However, I'm facing a challenge with input handling in my application. Some inputs might actually arrive as null, and if I automatically convert these null values to empty strings, it could lead to issues such as:

  • Validation Failures: Converting null values to empty strings might cause validation to fail when a different type or a proper null value is expected.
  • Database Insertions: With permit_empty in use, converting null to an empty string might result in a 0 being inserted into the database, even though the intended value should remain null.

Could you please advise on the best approach to handle these cases? Specifically, I would like guidance on:

  • Input Processing: How to properly recognize and process inputs that are null during validation so that converting to an empty string (or vice versa) doesn’t cause errors.
  • Database Management: How to ensure that null values are preserved when necessary, particularly when using permit_empty.

Also, is the recommended solution to handle these cases individually for each field, or use casts to automatically manage the conversion?

Thanks for your help,

@michalsn
Copy link
Member

Some inputs might actually arrive as null...

Not in the context of a normal POST request. You may send JSON, but that is a different case.

The permit_empty rule is indeed a bit wide, but that's because it should handle broad use cases.

If you are really determined to convert all empty strings to null values, you can simply convert the values from the POST array just before adding them to the validation method. You can also extend the IncomingRequest class and override getPost() method to do so automatically.

When it comes to inserting values into the database I would use casting, either on the model side (preferably) or in the entity.

It all depends on the particular problem you're dealing with. Please feel free to post on our Forum, as we don't answer support questions here.

@campio97
Copy link
Author

Ok thank you for the support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants