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

```php

            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.

On Mon, Sep 2, 2024 at 8:51 AM Mike Schinkel <m...@newclarity.net> wrote:

> > On Sep 1, 2024, at 5:47 PM, Hammed Ajao <hamieg...@gmail.com> 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!
>
> 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
>
>

Reply via email to