On Tue, Sep 3, 2024, at 02:00, Hammed Ajao wrote: > > > On Mon, Sep 2, 2024 at 1:50 PM Rob Landers <rob@bottled.codes> wrote: >> __ >> On Sun, Sep 1, 2024, at 23:47, Hammed Ajao wrote: >>> 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. >>> 1. String Literals as Object Properties >>> Current Situation >>> As we all know, we typically define and access object properties using >>> standard identifiers: >>> ```php >>> 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: >>> ```php >>> $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: >>> ```php >>> 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. >>> >>> 2. 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: >>> ```php >>> function myHeaders(...$args) { >>> foreach ($args as $key => $value) header("$key: $value"); >>> } >>> ``` >>> >>> To use string literals with special characters, we have to use associative >>> arrays: >>> ```php >>> 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: >>> ```php >>> 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 >> >> 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; >> } >> >> https://3v4l.org/KgJKm >> >> 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