-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
feat: Improve Superglobals
service
#9482
base: 4.7
Are you sure you want to change the base?
Conversation
a972fdf
to
e1da19c
Compare
Can someone sync the v4.7 branch? |
Synced |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's still a draft, but I have left initial comments on the design. No review yet on the implementation.
* | ||
* @see \CodeIgniter\HTTP\Parameters\ParametersTest | ||
*/ | ||
class Parameters implements ParametersInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this class should be abstract by itself, unless there's a superglobal that is being represented by this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will not be a global object. It might be worth making it abstract. Let's wait for the other participants.
But I wrote general tests for it.
e1da19c
to
c3d096b
Compare
I applied some suggestions.
|
c3d096b
to
dee9d30
Compare
* @param TKey $key | ||
* @param TValue $default | ||
* | ||
* @return TValue|null | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand now the issue. You need to specify another template for this default. Like:
* @param TKey $key | |
* @param TValue $default | |
* | |
* @return TValue|null | |
*/ | |
* @template TDefault | |
* | |
* @param TKey $key | |
* @param TDefault $default | |
* | |
* @return TValue|TDefault|null | |
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the problem.
I didn't plan on null
in scalar data. $_GET['a'] = null
from the request will never exist. Yes, this is acceptable in other places.
Are there any examples for null
tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the tinkering I made to allow strict default value and not allowing null
for InputParameters.
diff --git a/system/HTTP/Parameters/InputParameters.php b/system/HTTP/Parameters/InputParameters.php
index 8aa0508075..a45f7b22bd 100644
--- a/system/HTTP/Parameters/InputParameters.php
+++ b/system/HTTP/Parameters/InputParameters.php
@@ -19,8 +19,9 @@ use CodeIgniter\Exceptions\RuntimeException;
/**
* @template TKey of string
* @template TValue of scalar|array<(int|string), mixed>
+ * @template TDefault of scalar|array<(int|string), mixed>
*
- * @extends Parameters<TKey, TValue>
+ * @extends Parameters<TKey, TValue, TDefault>
*
* @see \CodeIgniter\HTTP\Parameters\InputParametersTest
*/
@@ -35,7 +36,7 @@ class InputParameters extends Parameters
}
}
- public function get(string $key, mixed $default = null): mixed
+ public function get(string $key, mixed $default = ''): mixed
{
if ($default !== null && ! is_scalar($default)) {
throw new InvalidArgumentException(sprintf('The default value for the InputParameters must be a scalar type, "%s" given.', gettype($defau
lt)));
diff --git a/system/HTTP/Parameters/Parameters.php b/system/HTTP/Parameters/Parameters.php
index 20f9b7d66c..8629f750d2 100644
--- a/system/HTTP/Parameters/Parameters.php
+++ b/system/HTTP/Parameters/Parameters.php
@@ -19,8 +19,9 @@ use CodeIgniter\Exceptions\RuntimeException;
/**
* @template TKey of string
* @template TValue
+ * @template TDefault
*
- * @implements ParametersInterface<TKey, TValue>
+ * @implements ParametersInterface<TKey, TValue, TDefault>
*
* @see \CodeIgniter\HTTP\Parameters\ParametersTest
*/
diff --git a/system/HTTP/Parameters/ParametersInterface.php b/system/HTTP/Parameters/ParametersInterface.php
index 6873e78f78..21ccd09744 100644
--- a/system/HTTP/Parameters/ParametersInterface.php
+++ b/system/HTTP/Parameters/ParametersInterface.php
@@ -19,6 +19,7 @@ use IteratorAggregate;
/**
* @template TKey of string
* @template TValue
+ * @template TDefault
*
* @extends IteratorAggregate<TKey, TValue>
*/
@@ -41,9 +42,9 @@ interface ParametersInterface extends IteratorAggregate, Countable
/**
* @param TKey $key
- * @param TValue $default
+ * @param TDefault $default
*
- * @return TValue|null
+ * @return TValue|TDefault|null
*/
public function get(string $key, mixed $default = null): mixed;
diff --git a/system/HTTP/Parameters/ServerParameters.php b/system/HTTP/Parameters/ServerParameters.php
index c6e87d49ae..0bbf8f2b07 100644
--- a/system/HTTP/Parameters/ServerParameters.php
+++ b/system/HTTP/Parameters/ServerParameters.php
@@ -16,8 +16,9 @@ namespace CodeIgniter\HTTP\Parameters;
/**
* @template TKey of string
* @template TValue
+ * @template TDefault
*
- * @extends Parameters<TKey, TValue>
+ * @extends Parameters<TKey, TValue, TDefault>
*/
class ServerParameters extends Parameters
{
I think yes. For queries like |
No. array (size=6)
'num' => string '123' (length=3)
'flag' => string 'true' (length=4)
'nullable' => string 'null' (length=4)
'float' => string '10.13' (length=5)
'int' => string '2024' (length=4)
'null' => string '' (length=0) |
Isn't it default for |
Probably. I'm not a cool architect) Therefore, it is necessary to discuss. $_GET = ['int' => '1000'];
$p = new InputParameters($_GET);
$_GET = $p->all(); // or back set
$p->all(); // ['int' => 1000] I think it's bad Symfony has additional methods for this, but I wouldn't want to go that far now. |
Ok. Let's leave this for discussion. |
@michalsn @samsonasik @MGatner @lonnieezell do you have an opinion on the feature? We have few people to discuss this with, I hope we will come to a result. |
What was the general idea behind For this reason, I feel that the proposed solution is somewhat overengineering. In my opinion, only string values should be returned, as the server does not typically handle other types in a normal scenario. We risk breaking existing applications if we suddenly start casting values to specific types. Moreover, |
The reason for replacing global variables is the possibility of abstraction and, in general, their use is not recommended. Plus, kenjis offered the job, which means he accepted the situation. Regarding typing, I also suggest a string type for GET POST, but the SERVER can have scalar types. |
At the moment, we don’t directly use superglobals in most places - instead, we use an additional layer to access them. The use of superglobals is discouraged mainly because of the lack of sanitization - which we are already handling. Scalar types in PHP are well-defined, and typically, But again - currently everything from I'm not suggesting that The question is, what real problem are we trying to solve by implementing the |
It's not that much of a problem. This is a natural movement forward. Similar to using PSR. But testing based on _POST _FILES doesn't seem like a good example. |
Description
Fixes #7866
Fixes #9392
We need to discuss further actions.
I suggest an option for working with global variables: hide
$_SERVER, $_POST
, ... inParameters
objects.It is necessary to decide which types of data to allow. Globally,
Parameters
can store anything.InputParameters
only have compatible values for$_POST, $_GET
,... (string, int, float, bool).ServerParameters
for$_SERVER
(it is possible to allow storage of objects?).As soon as you say that you agree to such changes, you need to decide on the initialization location:
Should I replace it in Request, Superglobals, or only in Superlglobals?
Next, we'll update the methods for Superglobals:
The userguide update can wait for now.
Ask questions.
P.S. I've looked at the Symfony code, and I think it can be adapted to our needs.
Checklist: