Dear PHP internals community,
I hope this email finds you all well. I'd like to propose an idea that I
believe could enhance PHP's flexibility and consistency, especially when
working with string literals. I'm looking forward to hearing your thoughts
and feedback on this proposal.
Introduction
I'm suggesting two enhancements to PHP that I think could make our lives as
developers a bit easier:
Support for String Literals as Object Properties
Support for String Literals as Named Parameters in Function Calls
The main goal here is to reduce our reliance on arrays and provide more
intuitive ways to define and access data, particularly in scenarios like
working with HTTP headers where we often deal with non-standard characters
and strings.
- String Literals as Object Properties
Current Situation
As we all know, we typically define and access object properties using
standard identifiers:
class Foo {
public string $contentType = "application/json";
}
$obj = new Foo();
$obj->contentType = "text/html";
But when we're dealing with data that includes non-standard characters or
strings (think HTTP headers), we often end up using associative arrays:
$headers = [
"Content-Type" => "application/json",
"X-Custom-Header" => "value"
];
I think we can all agree that this reliance on arrays can make our code
less intuitive, especially when we're managing complex data structures.
Proposed Enhancement
What if we could use string literals as object property names? Here's what
I'm thinking:
class MyHeaders {
public function __construct(
public string "Content-Type" = "application/json",
public string "Cache-Control" = "no-cache, no-store,
must-revalidate",
public string "Pragma" = "no-cache",
public string "Expires" = "0",
public string "X-Frame-Options" = "SAMEORIGIN",
public string "X-XSS-Protection" = "1; mode=block",
public string "X-Content-Type-Options" = "nosniff",
public string "Referrer-Policy" = "strict-origin-when-cross-origin",
public string "Access-Control-Allow-Origin" = "*",
public string "X-Custom-Header" = "value",
) {}
public static function create(string ...$headers): self {
return new self(...$headers); // Throws an error if an unknown
named parameter is passed
}
public function dispatch(): void {
foreach ((array) $this as $name => $value) {
header("$name: $value");
}
}
}
$headers = new MyHeaders("Content-Type": "application/json",
"X-Custom-Header": "value");
// or
$headers = MyHeaders::create("Content-Type": "text/html; charset=utf-8",
"X-Custom-Header": "value");
$headers->dispatch();
This would allow us to include characters in property names that aren't
typically allowed in PHP identifiers, like hyphens or spaces. I think this
could make our code more readable and aligned with natural data
representation.
Benefits
Greater Flexibility: We could create more natural and direct
representations of data within objects.
Enhanced Consistency: This aligns with the proposed support for string
literals as named parameters, creating a more uniform language experience.
Simplification: It could reduce our need for associative arrays, which can
be more error-prone and less intuitive.
- String Literals as Named Parameters in Function Calls
If we're going to use string literals as object properties, it makes sense
to also use them as named parameters, especially in constructors with
promoted properties. And why stop at constructors? This leads to the second
part of my proposal.
Current Situation
We can use named parameters in function calls, but only with standard
identifiers:
function myHeaders(...$args) {
foreach ($args as $key => $value) header("$key: $value");
}
To use string literals with special characters, we have to use associative
arrays:
myHeaders(...["Content-Type" => "application/json"]);
This can be a bit cumbersome and less readable, especially for complex data
structures.
Proposed Enhancement
What if we could use string literals as named parameters? It might look
something like this:
foo("Content-Type": "application/json");
I think this syntax could offer several advantages:
Improved Readability: Our code could become clearer and more aligned with
natural data representation.
Automatic Parameter Mapping: We could map string literals to corresponding
parameters without requiring manual intervention.
Simplified Constructor Usage: This could be especially beneficial for
constructors where we need to pass complex data structures directly.
Implementation Considerations
Of course, implementing these changes would require some work:
The PHP engine would need to accommodate string literals as valid property
names and named parameters, both at runtime and in class/function
definitions.
We'd need to carefully manage compatibility with existing code to ensure
traditional property access remains unaffected.
We'd need to decide whether to allow string literals as parameters in
function/method declarations or only in function calls (to be retrieved by
func_get_args()
or variadic functions), with exceptions for constructors
with promoted properties.
I'm really interested to hear what you all think about this proposal. Do
you see potential benefits or challenges that I might have overlooked? How
do you think this could impact your day-to-day coding?
Looking forward to a great discussion!
Best regards,
Hammed
Dear PHP internals community,
I hope this email finds you all well. I'd like to propose an idea that I believe could enhance PHP's flexibility and consistency, especially when working with string literals. I'm looking forward to hearing your thoughts and feedback on this proposal.
Introduction
I'm suggesting two enhancements to PHP that I think could make our lives as developers a bit easier:Support for String Literals as Object Properties
Support for String Literals as Named Parameters in Function CallsThe main goal here is to reduce our reliance on arrays and provide more intuitive ways to define and access data, particularly in scenarios like working with HTTP headers where we often deal with non-standard characters and strings.
- String Literals as Object Properties
Current Situation
As we all know, we typically define and access object properties using standard identifiers:class Foo { public string $contentType = "application/json"; } $obj = new Foo(); $obj->contentType = "text/html";
But when we're dealing with data that includes non-standard characters or strings (think HTTP headers), we often end up using associative arrays:
$headers = [ "Content-Type" => "application/json", "X-Custom-Header" => "value" ];
I think we can all agree that this reliance on arrays can make our code less intuitive, especially when we're managing complex data structures.
Proposed Enhancement
What if we could use string literals as object property names? Here's what I'm thinking:class MyHeaders { public function __construct( public string "Content-Type" = "application/json", public string "Cache-Control" = "no-cache, no-store, must-revalidate", public string "Pragma" = "no-cache", public string "Expires" = "0", public string "X-Frame-Options" = "SAMEORIGIN", public string "X-XSS-Protection" = "1; mode=block", public string "X-Content-Type-Options" = "nosniff", public string "Referrer-Policy" = "strict-origin-when-cross-origin", public string "Access-Control-Allow-Origin" = "*", public string "X-Custom-Header" = "value", ) {} public static function create(string ...$headers): self { return new self(...$headers); // Throws an error if an unknown named parameter is passed } public function dispatch(): void { foreach ((array) $this as $name => $value) { header("$name: $value"); } } } $headers = new MyHeaders("Content-Type": "application/json", "X-Custom-Header": "value"); // or $headers = MyHeaders::create("Content-Type": "text/html; charset=utf-8", "X-Custom-Header": "value"); $headers->dispatch();
This would allow us to include characters in property names that aren't typically allowed in PHP identifiers, like hyphens or spaces. I think this could make our code more readable and aligned with natural data representation.
BenefitsGreater Flexibility: We could create more natural and direct representations of data within objects.
Enhanced Consistency: This aligns with the proposed support for string literals as named parameters, creating a more uniform language experience.
Simplification: It could reduce our need for associative arrays, which can be more error-prone and less intuitive.
- String Literals as Named Parameters in Function Calls
If we're going to use string literals as object properties, it makes sense to also use them as named parameters, especially in constructors with promoted properties. And why stop at constructors? This leads to the second part of my proposal.
Current Situation
We can use named parameters in function calls, but only with standard identifiers:function myHeaders(...$args) { foreach ($args as $key => $value) header("$key: $value"); }
To use string literals with special characters, we have to use associative arrays:
myHeaders(...["Content-Type" => "application/json"]);
This can be a bit cumbersome and less readable, especially for complex data structures.
Proposed Enhancement
What if we could use string literals as named parameters? It might look something like this:foo("Content-Type": "application/json");
I think this syntax could offer several advantages:
Improved Readability: Our code could become clearer and more aligned with natural data representation.
Automatic Parameter Mapping: We could map string literals to corresponding parameters without requiring manual intervention.
Simplified Constructor Usage: This could be especially beneficial for constructors where we need to pass complex data structures directly.Implementation Considerations
Of course, implementing these changes would require some work:The PHP engine would need to accommodate string literals as valid property names and named parameters, both at runtime and in class/function definitions.
We'd need to carefully manage compatibility with existing code to ensure traditional property access remains unaffected.
We'd need to decide whether to allow string literals as parameters in function/method declarations or only in function calls (to be retrieved byfunc_get_args()
or variadic functions), with exceptions for constructors with promoted properties.I'm really interested to hear what you all think about this proposal. Do you see potential benefits or challenges that I might have overlooked? How do you think this could impact your day-to-day coding?
Looking forward to a great discussion!
I know if it not exactly what you asked for, but have you considered using Enums and Attributes instead?
Here is a working single file example of what I am suggesting:
https://gist.github.com/mikeschinkel/b71beb8b7ee626ba9e6ea4afaba11e22
I know it is more boilerplate, but does it address the same issues you were trying to address, or not? If not, in what ways does not not address your use-cases?
I know it uses arrays which you seem to want to avoid, but it only uses they are the result of operations on an enum which are not arrays that you need to maintain in your code.
Are there other use-cases besides working with HTTP header where Enums and Attributes would not address the issues you were trying to address?
Generally I am one who welcomes new feature ideas, but I fear that string literals as object properties would break a valuable assumption that all properties must be a valid identifier. Without that assumption I fear many things that would become more complex.
Also there are chances such a change could break a lot of userland code that makes that same assumption. I know from using MySQL where field names do not need to be valid identifiers that such a "feature" complicates coding, makes certain bugs easier to create, and often makes code less elegant (read "uglier") that it would otherwise be.
So I am sympathetic to the desire to improve the language. However I fear this specific change would create more pain than pleasure. Better IMO to look for less disruptive solutions to achieve the same goals. For example, if the Enum+Attributes approach meets your needs aside from having too much boilerplate, maybe we could enhance PHP to have less of that boilerplate?
-Mike
P.S. I want to (again) thank those who brought us Enums as I think they are one of the best new features PHP has added in the past decade. #fwiw
Generally I am one who welcomes new feature ideas, but I fear that string literals as object properties would break a valuable assumption that all properties must be a valid identifier. Without that assumption I fear many things that would become more complex.
Is that so? See https://3v4l.org/bZTFi.
So I am sympathetic to the desire to improve the language. However I fear this specific change would create more pain than pleasure. Better IMO to look for less disruptive solutions to achieve the same goals. For example, if the Enum+Attributes approach meets your needs aside from having too much boilerplate, maybe we could enhance PHP to have less of that boilerplate?
ACK
Christoph
Generally I am one who welcomes new feature ideas, but I fear that string literals as object properties would break a valuable assumption that all properties must be a valid identifier. Without that assumption I fear many things that would become more complex.
Is that so? See https://3v4l.org/bZTFi.
Consider me corrected.
I seem to now remember once knowing this was possible since you point it out. I think my subconscious must have caused me to repress that memory given the tragedy of it when I read Hammad's proposal. ¯_(ツ)_/¯
So I am sympathetic to the desire to improve the language. However I fear this specific change would create more pain than pleasure. Better IMO to look for less disruptive solutions to achieve the same goals. For example, if the Enum+Attributes approach meets your needs aside from having too much boilerplate, maybe we could enhance PHP to have less of that boilerplate?
ACK
Can you elaborate on what 'ACK' means in this context?
-Mike
So I am sympathetic to the desire to improve the language. However I fear this specific change would create more pain than pleasure. Better IMO to look for less disruptive solutions to achieve the same goals. For example, if the Enum+Attributes approach meets your needs aside from having too much boilerplate, maybe we could enhance PHP to have less of that boilerplate?
ACK
Can you elaborate on what 'ACK' means in this context?
That I fully agree to your statement. (Seems this term might be more
common in German newsgroups. :)
Christoph
Generally I am one who welcomes new feature ideas, but I fear that string literals as object properties would break a valuable assumption that all properties must be a valid identifier. Without that assumption I fear many things that would become more complex.
Is that so? See https://3v4l.org/bZTFi.
And it works with methods too, you just can't define them but can catch
with __call:
<?php
class AAA {
public function __call(string $name, array $arguments)
{
var_dump($name);
}
}
Wrong example, sorry, should be
(new AAA)->{'123AnyChars%%!@#'}();
Still, '123AnyChars%%!@#' is not included in the array returned by get_class_methods()
and/or ReflectionClass::getMethod()
which is evidence of why procedural magic methods are at best a bandaid compared with declarative solutions.
-Mike
Hello Mike,
Thanks for reading and responding. While your enum does technically address
some of the issues I am discussing, it does so in a very verbose and
cumbersome way.
- First you need the DefaultValue attribute
- Then you need to use it on each of your
properties
- You also need to define an identifier for the const which defeats the
purpose of using literal strings - Then you need to use reflection to access the properties
- Then you're left with : MyHeaders::create(MyHeaders::CONTENT_TYPE,
"plain/text", MyHeaders::X_CUSTOM_HEADER,"new_value"); which isn't super
clear that it's mapping every other value to the one before it.
As for the idea that an object property must be a valid identifier, I'm not
sure that's correct. Objects can have integer properties natively i.e
$obj->{1}, and literal string properties are already possible when you cast
an array to an object
Let me show you a few other use cases i've run into
class Sizes {
public function __construct(
private string $sm,
private string $md,
private string $lg,
private string $xl,
private string $2xl, // will throw
private string "10xl", // wouldn't this be nice
) {}
}
function htmlElement(string $tag, string $content, string|bool
...$attr) {}
htmlElement("div", "Hello, world!", class: "greeting", id:
"greeting", "data-foo": "bar");
Cheers,
Hammed.
Dear PHP internals community,
I hope this email finds you all well. I'd like to propose an idea that I
believe could enhance PHP's flexibility and consistency, especially when
working with string literals. I'm looking forward to hearing your thoughts
and feedback on this proposal.
Introduction
I'm suggesting two enhancements to PHP that I think could make our lives
as developers a bit easier:Support for String Literals as Object Properties
Support for String Literals as Named Parameters in Function CallsThe main goal here is to reduce our reliance on arrays and provide more
intuitive ways to define and access data, particularly in scenarios like
working with HTTP headers where we often deal with non-standard characters
and strings.
- String Literals as Object Properties
Current Situation
As we all know, we typically define and access object properties using
standard identifiers:class Foo { public string $contentType = "application/json"; } $obj = new Foo(); $obj->contentType = "text/html";
But when we're dealing with data that includes non-standard characters
or strings (think HTTP headers), we often end up using associative arrays:$headers = [ "Content-Type" => "application/json", "X-Custom-Header" => "value" ];
I think we can all agree that this reliance on arrays can make our code
less intuitive, especially when we're managing complex data structures.
Proposed Enhancement
What if we could use string literals as object property names? Here's
what I'm thinking:class MyHeaders { public function __construct( public string "Content-Type" = "application/json", public string "Cache-Control" = "no-cache, no-store,
must-revalidate",
public string "Pragma" = "no-cache", public string "Expires" = "0", public string "X-Frame-Options" = "SAMEORIGIN", public string "X-XSS-Protection" = "1; mode=block", public string "X-Content-Type-Options" = "nosniff", public string "Referrer-Policy" =
"strict-origin-when-cross-origin",
public string "Access-Control-Allow-Origin" = "*", public string "X-Custom-Header" = "value", ) {} public static function create(string ...$headers): self { return new self(...$headers); // Throws an error if an unknown
named parameter is passed
} public function dispatch(): void { foreach ((array) $this as $name => $value) { header("$name: $value"); } }
}
$headers = new MyHeaders("Content-Type": "application/json",
"X-Custom-Header": "value");
// or
$headers = MyHeaders::create("Content-Type": "text/html; charset=utf-8",
"X-Custom-Header": "value");
$headers->dispatch();This would allow us to include characters in property names that aren't
typically allowed in PHP identifiers, like hyphens or spaces. I think this
could make our code more readable and aligned with natural data
representation.Benefits
Greater Flexibility: We could create more natural and direct
representations of data within objects.
Enhanced Consistency: This aligns with the proposed support for string
literals as named parameters, creating a more uniform language experience.
Simplification: It could reduce our need for associative arrays, which
can be more error-prone and less intuitive.
- String Literals as Named Parameters in Function Calls
If we're going to use string literals as object properties, it makes
sense to also use them as named parameters, especially in constructors with
promoted properties. And why stop at constructors? This leads to the second
part of my proposal.
Current Situation
We can use named parameters in function calls, but only with standard
identifiers:function myHeaders(...$args) { foreach ($args as $key => $value) header("$key: $value"); }
To use string literals with special characters, we have to use
associative arrays:myHeaders(...["Content-Type" => "application/json"]);
This can be a bit cumbersome and less readable, especially for complex
data structures.
Proposed Enhancement
What if we could use string literals as named parameters? It might look
something like this:foo("Content-Type": "application/json");
I think this syntax could offer several advantages:
Improved Readability: Our code could become clearer and more aligned
with natural data representation.
Automatic Parameter Mapping: We could map string literals to
corresponding parameters without requiring manual intervention.
Simplified Constructor Usage: This could be especially beneficial for
constructors where we need to pass complex data structures directly.Implementation Considerations
Of course, implementing these changes would require some work:The PHP engine would need to accommodate string literals as valid
property names and named parameters, both at runtime and in class/function
definitions.
We'd need to carefully manage compatibility with existing code to ensure
traditional property access remains unaffected.
We'd need to decide whether to allow string literals as parameters in
function/method declarations or only in function calls (to be retrieved by
func_get_args()
or variadic functions), with exceptions for constructors
with promoted properties.I'm really interested to hear what you all think about this proposal. Do
you see potential benefits or challenges that I might have overlooked? How
do you think this could impact your day-to-day coding?
Looking forward to a great discussion!I know if it not exactly what you asked for, but have you considered using
Enums and Attributes instead?Here is a working single file example of what I am suggesting:
https://gist.github.com/mikeschinkel/b71beb8b7ee626ba9e6ea4afaba11e22
I know it is more boilerplate, but does it address the same issues you
were trying to address, or not? If not, in what ways does not not address
your use-cases?I know it uses arrays which you seem to want to avoid, but it only uses
they are the result of operations on an enum which are not arrays that you
need to maintain in your code.Are there other use-cases besides working with HTTP header where Enums and
Attributes would not address the issues you were trying to address?Generally I am one who welcomes new feature ideas, but I fear that string
literals as object properties would break a valuable assumption that all
properties must be a valid identifier. Without that assumption I fear many
things that would become more complex.Also there are chances such a change could break a lot of userland code
that makes that same assumption. I know from using MySQL where field names
do not need to be valid identifiers that such a "feature" complicates
coding, makes certain bugs easier to create, and often makes code less
elegant (read "uglier") that it would otherwise be.So I am sympathetic to the desire to improve the language. However I fear
this specific change would create more pain than pleasure. Better IMO to
look for less disruptive solutions to achieve the same goals. For example,
if the Enum+Attributes approach meets your needs aside from having too much
boilerplate, maybe we could enhance PHP to have less of that boilerplate?-Mike
P.S. I want to (again) thank those who brought us Enums as I think they
are one of the best new features PHP has added in the past decade. #fwiw
Hello Mike,
Thanks for reading and responding. While your enum does technically address some of the issues I am discussing, it does so in a very verbose and cumbersome way.
- First you need the DefaultValue attribute
- Then you need to use it on each of your
properties
- You also need to define an identifier for the const which defeats the purpose of using literal strings
- Then you need to use reflection to access the properties
- Then you're left with : MyHeaders::create(MyHeaders::CONTENT_TYPE, "plain/text", MyHeaders::X_CUSTOM_HEADER,"new_value"); which isn't super clear that it's mapping every other value to the one before it.
That is why I wrote that maybe we could consider reducing the verbosity and more cumbersome aspects as I proactively recognized it was painful.
That is why I asked about other use-cases. If the only solid use-case is HTTP headers we write it once and its done.
OTOH, if there are many other use-cases then we could look at adding syntax sugar. Adding syntax sugar to languages when boilerplate patterns emerge has many benefits: fewer bugs, easier coding, making the language more powerful, and etc.
As for the idea that an object property must be a valid identifier, I'm not sure that's correct. Objects can have integer properties natively i.e $obj->{1}, and literal string properties are already possible when you cast an array to an object
Yes, that was pointed out to me.
I was thinking more about the PHP language for language parsers syntax when I wrote that and thinking less about the fact that instances can have dynamically assigned properties. My bad.
Let me show you a few other use cases i've run into
class Sizes { public function __construct( private string $sm, private string $md, private string $lg, private string $xl, private string $2xl, // will throw private string "10xl", // wouldn't this be nice ) {} }
Is that really a class that someone would write, with a different property for each size and a constructor that required setting each size? Or wouldn't they typically have an Enum for the sizes and an array property indexed by the enum?
Maybe your example was just to illustrate your desire for a $2xl
and "10xl"
property? I see what you want here, OTOH I would not be a fan. I'm just as happy to name them $twoXL
and $tenXL
, or $_2xl
and $_10xl
vs. dealing with non-identifiers in declared property names. I get that is not what you want, but realize I am not the decider, I am just representing one person's opinion, and I can't even vote on RFCs, so there is that. ¯_(ツ)_/¯
function htmlElement(string $tag, string $content, string|bool ...$attr) {} htmlElement("div", "Hello, world!", class: "greeting", id: "greeting", "data-foo": "bar");
I did not grasp the use-case you are showing here because the one in your original email included using non-identifiers as parameter names so I conflated your two proposals as being one.
In the case you presenting here —assuming I understand what you are proposing — I would likely be in favor of something like it. That is if it were orthogonal and not requiring of your first proposal i.e. in its own RFC.
Taking what you have I would expect something more like the following but where [HtmlAttribute]
is my placeholder for a syntax that would specify that zero or more named parameters be collected and assigned by property name to the object $attr
of type HtmlAttribute
— bikeshed away on that syntax —, and to assign to arrays you specify the array index in the named argument, e.g. data["foo"]
:
class HtmlAttribute {
public string $_class;
public string $id;
public array $data;
}
function htmlElement(string $tag, string $content, [HtmlAttribute] ...$attr) {}
htmlElement("div", "Hello, world!", class: "greeting", id: "greeting", data["foo"]: "bar");
Alternately if you were not envisioning the mapping to an object a similar feature could just be way to use a function to collect arbitrarily names parameters into an array, e.g.:
function htmlAttributes(string|int ...$attr) {}
htmlAttributes(class: "greeting", id: "greeting", data["foo"]: "bar");
The above would collect the args into an array $attr
shaped like this:
array(
"class" => "greeting",
"id" => "greeting",
"data" => array(
"foo" => "greeting",
),
);
Actually, it would be nice if PHP offered both options.
- Then you're left with : MyHeaders::create(MyHeaders::CONTENT_TYPE, "plain/text", MyHeaders::X_CUSTOM_HEADER,"new_value"); which isn't super clear that it's mapping every other value to the one before it.
BTW: it could currently be written like any of the following:
// 2-element arrays represents name-value pairs
public static function create(string ...$headers): self {...}
MyHeaders::create(
[MyHeaders::CONTENT_TYPE, "plain/text"],
[MyHeaders::X_CUSTOM_HEADER,"new_value"]
)
// 1-element arrays w/key and value represents name-value pairs
public static function create(string ...$headers): self {...}
MyHeaders::create(
[MyHeaders::CONTENT_TYPE => "plain/text"],
[MyHeaders::X_CUSTOM_HEADER =>"new_value"]
)
// 1-element array w/multiple elements represents name-value pairs
public static function create(array $headers): self {...}
MyHeaders::create([
MyHeaders::CONTENT_TYPE => "plain/text",
MyHeaders::X_CUSTOM_HEADER =>"new_value"
])
Alternately imagine some syntax sugar that allows dropping the MyHeaders::
from the enum reference when a parameter is declared to be an instance of that enum:
// Objects represents name-value pairs
Header(MyHeaders $header, string $name):array {...}
public static function create(Header ...$headers): self {...}
MyHeaders::create(
Header(CONTENT_TYPE, "plain/text"),
Header(X_CUSTOM_HEADER, "new_value")
)
Finally imagine adding a feature that allows specifying that a parameter is the result of a function call give brace enclosed parameters where Header(*)
is my placeholder syntax for bikeshedding, e.g.:
// Objects represents name-value pairs
public static function create(Header(*) ...$headers): self {...}
MyHeaders::create(
{ CONTENT_TYPE, "plain/text" },
{ X_CUSTOM_HEADER, "new_value"}
)
#fwiw
-Mike
Dear PHP internals community,
I hope this email finds you all well. I'd like to propose an idea that I believe could enhance PHP's flexibility and consistency, especially when working with string literals. I'm looking forward to hearing your thoughts and feedback on this proposal.
Introduction
I'm suggesting two enhancements to PHP that I think could make our lives as developers a bit easier:Support for String Literals as Object Properties
Support for String Literals as Named Parameters in Function CallsThe main goal here is to reduce our reliance on arrays and provide more intuitive ways to define and access data, particularly in scenarios like working with HTTP headers where we often deal with non-standard characters and strings.
- String Literals as Object Properties
Current Situation
As we all know, we typically define and access object properties using standard identifiers:class Foo { public string $contentType = "application/json"; } $obj = new Foo(); $obj->contentType = "text/html";
But when we're dealing with data that includes non-standard characters or strings (think HTTP headers), we often end up using associative arrays:
$headers = [ "Content-Type" => "application/json", "X-Custom-Header" => "value" ];
I think we can all agree that this reliance on arrays can make our code less intuitive, especially when we're managing complex data structures.
Proposed Enhancement
What if we could use string literals as object property names? Here's what I'm thinking:class MyHeaders { public function __construct( public string "Content-Type" = "application/json", public string "Cache-Control" = "no-cache, no-store, must-revalidate", public string "Pragma" = "no-cache", public string "Expires" = "0", public string "X-Frame-Options" = "SAMEORIGIN", public string "X-XSS-Protection" = "1; mode=block", public string "X-Content-Type-Options" = "nosniff", public string "Referrer-Policy" = "strict-origin-when-cross-origin", public string "Access-Control-Allow-Origin" = "*", public string "X-Custom-Header" = "value", ) {} public static function create(string ...$headers): self { return new self(...$headers); // Throws an error if an unknown named parameter is passed } public function dispatch(): void { foreach ((array) $this as $name => $value) { header("$name: $value"); } } } $headers = new MyHeaders("Content-Type": "application/json", "X-Custom-Header": "value"); // or $headers = MyHeaders::create("Content-Type": "text/html; charset=utf-8", "X-Custom-Header": "value"); $headers->dispatch();
This would allow us to include characters in property names that aren't typically allowed in PHP identifiers, like hyphens or spaces. I think this could make our code more readable and aligned with natural data representation.
BenefitsGreater Flexibility: We could create more natural and direct representations of data within objects.
Enhanced Consistency: This aligns with the proposed support for string literals as named parameters, creating a more uniform language experience.
Simplification: It could reduce our need for associative arrays, which can be more error-prone and less intuitive.
- String Literals as Named Parameters in Function Calls
If we're going to use string literals as object properties, it makes sense to also use them as named parameters, especially in constructors with promoted properties. And why stop at constructors? This leads to the second part of my proposal.
Current Situation
We can use named parameters in function calls, but only with standard identifiers:function myHeaders(...$args) { foreach ($args as $key => $value) header("$key: $value"); }
To use string literals with special characters, we have to use associative arrays:
myHeaders(...["Content-Type" => "application/json"]);
This can be a bit cumbersome and less readable, especially for complex data structures.
Proposed Enhancement
What if we could use string literals as named parameters? It might look something like this:foo("Content-Type": "application/json");
I think this syntax could offer several advantages:
Improved Readability: Our code could become clearer and more aligned with natural data representation.
Automatic Parameter Mapping: We could map string literals to corresponding parameters without requiring manual intervention.
Simplified Constructor Usage: This could be especially beneficial for constructors where we need to pass complex data structures directly.Implementation Considerations
Of course, implementing these changes would require some work:The PHP engine would need to accommodate string literals as valid property names and named parameters, both at runtime and in class/function definitions.
We'd need to carefully manage compatibility with existing code to ensure traditional property access remains unaffected.
We'd need to decide whether to allow string literals as parameters in function/method declarations or only in function calls (to be retrieved byfunc_get_args()
or variadic functions), with exceptions for constructors with promoted properties.I'm really interested to hear what you all think about this proposal. Do you see potential benefits or challenges that I might have overlooked? How do you think this could impact your day-to-day coding?
Looking forward to a great discussion!
Best regards,
Hammed
Hey Hammed,
This gets into the parser and its definition of "LABEL" (below PHP's syntax):
LABEL [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
This means the first letter must be alpha-numeric ascii, or higher. And you can actually just use the latter part and whatever encoding your file is (usually utf8):
For example, this is valid PHP:
class HTML {
public string $Content–Type;
public string $ዐxl;
public string $𝟷0sm;
}
You can also use emojis or look-alikes as much as you want. It's not a direct answer to what you are seeking, but it gets pretty close.
— Rob
Dear PHP internals community,
I hope this email finds you all well. I'd like to propose an idea that I
believe could enhance PHP's flexibility and consistency, especially when
working with string literals. I'm looking forward to hearing your thoughts
and feedback on this proposal.
Introduction
I'm suggesting two enhancements to PHP that I think could make our lives
as developers a bit easier:Support for String Literals as Object Properties
Support for String Literals as Named Parameters in Function CallsThe main goal here is to reduce our reliance on arrays and provide more
intuitive ways to define and access data, particularly in scenarios like
working with HTTP headers where we often deal with non-standard characters
and strings.
- String Literals as Object Properties
Current Situation
As we all know, we typically define and access object properties using
standard identifiers:class Foo { public string $contentType = "application/json"; } $obj = new Foo(); $obj->contentType = "text/html";
But when we're dealing with data that includes non-standard characters or
strings (think HTTP headers), we often end up using associative arrays:$headers = [ "Content-Type" => "application/json", "X-Custom-Header" => "value" ];
I think we can all agree that this reliance on arrays can make our code
less intuitive, especially when we're managing complex data structures.
Proposed Enhancement
What if we could use string literals as object property names? Here's what
I'm thinking:class MyHeaders { public function __construct( public string "Content-Type" = "application/json", public string "Cache-Control" = "no-cache, no-store, must-revalidate", public string "Pragma" = "no-cache", public string "Expires" = "0", public string "X-Frame-Options" = "SAMEORIGIN", public string "X-XSS-Protection" = "1; mode=block", public string "X-Content-Type-Options" = "nosniff", public string "Referrer-Policy" = "strict-origin-when-cross-origin", public string "Access-Control-Allow-Origin" = "*", public string "X-Custom-Header" = "value", ) {} public static function create(string ...$headers): self { return new self(...$headers); // Throws an error if an unknown named parameter is passed } public function dispatch(): void { foreach ((array) $this as $name => $value) { header("$name: $value"); } } } $headers = new MyHeaders("Content-Type": "application/json", "X-Custom-Header": "value"); // or $headers = MyHeaders::create("Content-Type": "text/html; charset=utf-8", "X-Custom-Header": "value"); $headers->dispatch();
This would allow us to include characters in property names that aren't
typically allowed in PHP identifiers, like hyphens or spaces. I think this
could make our code more readable and aligned with natural data
representation.
BenefitsGreater Flexibility: We could create more natural and direct
representations of data within objects.
Enhanced Consistency: This aligns with the proposed support for string
literals as named parameters, creating a more uniform language experience.
Simplification: It could reduce our need for associative arrays, which can
be more error-prone and less intuitive.
- String Literals as Named Parameters in Function Calls
If we're going to use string literals as object properties, it makes sense
to also use them as named parameters, especially in constructors with
promoted properties. And why stop at constructors? This leads to the second
part of my proposal.
Current Situation
We can use named parameters in function calls, but only with standard
identifiers:function myHeaders(...$args) { foreach ($args as $key => $value) header("$key: $value"); }
To use string literals with special characters, we have to use associative
arrays:myHeaders(...["Content-Type" => "application/json"]);
This can be a bit cumbersome and less readable, especially for complex
data structures.
Proposed Enhancement
What if we could use string literals as named parameters? It might look
something like this:foo("Content-Type": "application/json");
I think this syntax could offer several advantages:
Improved Readability: Our code could become clearer and more aligned with
natural data representation.
Automatic Parameter Mapping: We could map string literals to corresponding
parameters without requiring manual intervention.
Simplified Constructor Usage: This could be especially beneficial for
constructors where we need to pass complex data structures directly.Implementation Considerations
Of course, implementing these changes would require some work:The PHP engine would need to accommodate string literals as valid property
names and named parameters, both at runtime and in class/function
definitions.
We'd need to carefully manage compatibility with existing code to ensure
traditional property access remains unaffected.
We'd need to decide whether to allow string literals as parameters in
function/method declarations or only in function calls (to be retrieved by
func_get_args()
or variadic functions), with exceptions for constructors
with promoted properties.I'm really interested to hear what you all think about this proposal. Do
you see potential benefits or challenges that I might have overlooked? How
do you think this could impact your day-to-day coding?
Looking forward to a great discussion!
Best regards,
HammedHey Hammed,
This gets into the parser and its definition of "LABEL" (below PHP's
syntax):LABEL [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
This means the first letter must be alpha-numeric ascii, or higher. And
you can actually just use the latter part and whatever encoding your file
is (usually utf8):For example, this is valid PHP:
class HTML {
public string $Content–Type;
public string $ዐxl;
public string $𝟷0sm;
}You can also use emojis or look-alikes as much as you want. It's not a
direct answer to what you are seeking, but it gets pretty close.— Rob
Hi Rob,
That's actually pretty neat, but it starts to fall apart when you need the
unicode representation e.g. converting to json :https://3v4l.org/VXfDl .
Hammed
__
Dear PHP internals community,
I hope this email finds you all well. I'd like to propose an idea that I believe could enhance PHP's flexibility and consistency, especially when working with string literals. I'm looking forward to hearing your thoughts and feedback on this proposal.
Introduction
I'm suggesting two enhancements to PHP that I think could make our lives as developers a bit easier:Support for String Literals as Object Properties
Support for String Literals as Named Parameters in Function CallsThe main goal here is to reduce our reliance on arrays and provide more intuitive ways to define and access data, particularly in scenarios like working with HTTP headers where we often deal with non-standard characters and strings.
- String Literals as Object Properties
Current Situation
As we all know, we typically define and access object properties using standard identifiers:class Foo { public string $contentType = "application/json"; } $obj = new Foo(); $obj->contentType = "text/html";
But when we're dealing with data that includes non-standard characters or strings (think HTTP headers), we often end up using associative arrays:
$headers = [ "Content-Type" => "application/json", "X-Custom-Header" => "value" ];
I think we can all agree that this reliance on arrays can make our code less intuitive, especially when we're managing complex data structures.
Proposed Enhancement
What if we could use string literals as object property names? Here's what I'm thinking:class MyHeaders { public function __construct( public string "Content-Type" = "application/json", public string "Cache-Control" = "no-cache, no-store, must-revalidate", public string "Pragma" = "no-cache", public string "Expires" = "0", public string "X-Frame-Options" = "SAMEORIGIN", public string "X-XSS-Protection" = "1; mode=block", public string "X-Content-Type-Options" = "nosniff", public string "Referrer-Policy" = "strict-origin-when-cross-origin", public string "Access-Control-Allow-Origin" = "*", public string "X-Custom-Header" = "value", ) {} public static function create(string ...$headers): self { return new self(...$headers); // Throws an error if an unknown named parameter is passed } public function dispatch(): void { foreach ((array) $this as $name => $value) { header("$name: $value"); } } } $headers = new MyHeaders("Content-Type": "application/json", "X-Custom-Header": "value"); // or $headers = MyHeaders::create("Content-Type": "text/html; charset=utf-8", "X-Custom-Header": "value"); $headers->dispatch();
This would allow us to include characters in property names that aren't typically allowed in PHP identifiers, like hyphens or spaces. I think this could make our code more readable and aligned with natural data representation.
BenefitsGreater Flexibility: We could create more natural and direct representations of data within objects.
Enhanced Consistency: This aligns with the proposed support for string literals as named parameters, creating a more uniform language experience.
Simplification: It could reduce our need for associative arrays, which can be more error-prone and less intuitive.
- String Literals as Named Parameters in Function Calls
If we're going to use string literals as object properties, it makes sense to also use them as named parameters, especially in constructors with promoted properties. And why stop at constructors? This leads to the second part of my proposal.
Current Situation
We can use named parameters in function calls, but only with standard identifiers:function myHeaders(...$args) { foreach ($args as $key => $value) header("$key: $value"); }
To use string literals with special characters, we have to use associative arrays:
myHeaders(...["Content-Type" => "application/json"]);
This can be a bit cumbersome and less readable, especially for complex data structures.
Proposed Enhancement
What if we could use string literals as named parameters? It might look something like this:foo("Content-Type": "application/json");
I think this syntax could offer several advantages:
Improved Readability: Our code could become clearer and more aligned with natural data representation.
Automatic Parameter Mapping: We could map string literals to corresponding parameters without requiring manual intervention.
Simplified Constructor Usage: This could be especially beneficial for constructors where we need to pass complex data structures directly.Implementation Considerations
Of course, implementing these changes would require some work:The PHP engine would need to accommodate string literals as valid property names and named parameters, both at runtime and in class/function definitions.
We'd need to carefully manage compatibility with existing code to ensure traditional property access remains unaffected.
We'd need to decide whether to allow string literals as parameters in function/method declarations or only in function calls (to be retrieved byfunc_get_args()
or variadic functions), with exceptions for constructors with promoted properties.I'm really interested to hear what you all think about this proposal. Do you see potential benefits or challenges that I might have overlooked? How do you think this could impact your day-to-day coding?
Looking forward to a great discussion!
Best regards,
HammedHey Hammed,
This gets into the parser and its definition of "LABEL" (below PHP's syntax):
LABEL [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
This means the first letter must be alpha-numeric ascii, or higher. And you can actually just use the latter part and whatever encoding your file is (usually utf8):
For example, this is valid PHP:
class HTML {
public string $Content–Type;
public string $ዐxl;
public string $𝟷0sm;
}You can also use emojis or look-alikes as much as you want. It's not a direct answer to what you are seeking, but it gets pretty close.
— Rob
Hi Rob,That's actually pretty neat, but it starts to fall apart when you need the unicode representation e.g. converting to json :https://3v4l.org/VXfDl .
Hammed
Hey Hammed,
You'll still need to do a conversion of some type; luckily, someone else maintains a list: https://github.com/codebox/homoglyph/blob/master/raw_data/chars.txt
I briefly looked into allowing this last night and allowing properties like this would allow everything to have a full string representation. This would be valid:
$"fancy-thing" = other fancy thing.
The thing is, we kinda already allow it through variable-variables and other means, as this is all valid php: https://3v4l.org/nFBeV
So, if I understand correctly, you are seeking a syntax to allow for defining the properties without using dynamic properties?
Currently, you can access the property like this:
$this->{'my-invalid-prop'}
So, why not embrace what already exists instead of trying to change the syntax drastically? So, like this, maybe?
public string {'my-invalid-prop'};
Allowing this appears to be on the grammar level of the language, meaning it is probably a straightforward change.
— Rob