Re: [PHP-DEV] Undefined variables and the array append operator

2022-03-30 Thread Rowan Tommins

On 30/03/2022 15:32, Guilliam Xavier wrote:
On the other hand, I agree that `$undefined[] = $x` looks like a 
bug... are both cases the exact same opcode?



Some very good points raised in this thread about how many different 
closely-related cases there are here. I shall have to think clearly 
about which cases we want to change, and look at the implementation to 
see how easily those can be separated out from the others.


It sounds like there are at least some cases that might pass an RFC vote 
to change, though.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Undefined variables and the array append operator

2022-03-30 Thread Peter Bowyer
On Wed, 30 Mar 2022 at 15:33, Guilliam Xavier 
wrote:

> Not really a "compelling reason why we should keep this inconsistency", but
> I have occasionally relied on array autovivification *for sub-dimensions*,
>

I rely on this often when remapping data for analysis. These scripts are
run a handful of times and discarded. Autovivication keeps the code short.
Here's a snippet I wrote yesterday:

$out = [];
while ($row = $res->fetchAssociative()) {
// ...
$docId = $row['document_id'];
if (!isset($out[$docId])) {
$out[$docId] = [
'application_id' => $row['application_id'],
'document_id' => $docId,
'filename' => $row['filename'],
];
}
$out[$docId]['labels'][$row['document_rejection_reason_id']] =
true;
}

Naturally I would prefer to keep this behaviour for arrays.

Peter


Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Guilliam Xavier
> Ah yes, I hadn't considered expanding this RFC to namespaced and global
> constants. Let me mull over implementation syntax for those and include
> them in the RFC. My initial reaction is to not include those in this RFC,
> keeping the scope to just class constants. If there is value in typing
> namespaced and global constants, then another RFC could add those.
>

Yes, it could be simply a mention in a "Future scope" (or even "Unaffected
functionality") section
(and the syntax could indeed be a problem, like for typed local/global
variables...)


> Once I have all these new issues figured out and the RFC updated, I'll
> start that new thread.
>

Looking forward to it =)


Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Mark Niebergall
Guilliam,

On Wed, Mar 30, 2022 at 7:50 AM Guilliam Xavier 
wrote:

> Hi Mark,
>
> I have updated the RFC https://wiki.php.net/rfc/typed_class_constants with
 more details and examples from this thread, and updated the RFC status
 to
 Under Discussion. Hopefully the updated RFC helps answer questions and
 clarifies what the proposal includes.

>>>
> Thanks (I assume that you talked with the original author) -- not sure if
> you should have started a new thread with the "[RFC]" tag in the subject?
>

I will address the issues from you and Alex in the RFC page, then start a
new thread with "[RFC]" since you are correct this has moved past
initial testing-the-waters and is now into the discussion phase about the
RFC. I reached out multiple times to the original author but have not
received a response. I did leave Benas as an author to give him credit for
the work he did.


>
>
>> I think you should also update the "Supported types" section.
>>> Starting with enums, constants can also be objects. Once a good
>>> technical solution is found, any object would be supported probably
>>> https://wiki.php.net/rfc/new_in_initializers#future_scope
>>> I think that only void, never and callable types should not be
>>> supported, just like on properties.
>>>
>>
>> I have updated the "Supported types" to list out all types that are
>> supported and which types are not supported.
>>
>
> A few comments, by subsection:
>
>   - **Supported types**: This corresponds to the types currently allowed
> for const values (as well as unions thereof) except it [still] doesn't
> mention enums (which internally are classes implementing the `UnitEnum`
> interface, and whose values are ultimately of `object` type) although
> currently allowed. It also doesn't mention `mixed` (used later in examples).
>   - **Strict and coercive typing modes**: I didn't understand it on first
> read; I had to read the later "Constant values" section and compare both
> with
> https://wiki.php.net/rfc/typed_properties_v2#strict_and_coercive_typing_modes
> and https://wiki.php.net/rfc/typed_properties_v2#default_values
>   - **Inheritance and variance**: Several occurrences of "Class constants"
> should probably be "*Typed* class constants". Also, I still think that
> `protected bool $isExtinct` is *not* a good parallel to `public const bool
> CAN_FLY` (see my previous message).
>   - **Constant values**: You should probably remove the `iterable` example
> now [and maybe add an `enum` one].
>

Thanks for the input, I'll work on addressing those.


>
>
>> Constants cannot be objects since objects are mutable, so typed constants
>> will not be allowed to be an enum (which is technically an object). A typed
>> constant _may_ be an enum value though, so the following example will be
>> valid:
>>
>> ```
>> enum Fruit
>> {
>> case Apple;
>> case Banana;
>> }
>>
>> class Colors
>> {
>> protected const string RED = Fruit::Apple;
>> protected const string YELLOW = Fruit::Banana;
>> }
>> ```
>>
>
> This is incorrect, `Fruit::Apple` is of type `Fruit` (ultimately
> `object`), not `string`. But it is *not* mutable, and *is* allowed as a
> const value currently.
>

Yes, Alex also identified this issue in my examples, I will correct that
and include enum examples in an updated RFC. I will do that before starting
an "[RFC]" thread.


>
> Besides, I realized that the RFC is [only] for *class* constants; what
> about *namespaced (and global)* constants?
>

Ah yes, I hadn't considered expanding this RFC to namespaced and global
constants. Let me mull over implementation syntax for those and include
them in the RFC. My initial reaction is to not include those in this RFC,
keeping the scope to just class constants. If there is value in typing
namespaced and global constants, then another RFC could add those.

Once I have all these new issues figured out and the RFC updated, I'll
start that new thread.


>
> Regards,
>
> --
> Guilliam Xavier
>


Re: [PHP-DEV] Undefined variables and the array append operator

2022-03-30 Thread Guilliam Xavier
Hi Rowan,

Not really a "compelling reason why we should keep this inconsistency", but
I have occasionally relied on array autovivification *for sub-dimensions*,
e.g.:

```
function f(iterable $xs) {
$map = []; // initialization!
foreach ($xs as $x) {
// $map[foo($x)] ??= []; not needed
$map[foo($x)][] = bar($x); // autovivification
}

// Then e.g.:
foreach ($map as $foo => $bars) {
foreach ($bars as $bar) {
/* ... */
}
}
}
```

(adapted from my https://externals.io/message/114595#114611 message in the
"Disable autovivification on false" thread).

On the other hand, I agree that `$undefined[] = $x` looks like a bug... are
both cases the exact same opcode? (if yes, I wouldn't really mind updating
my code, especially for consistency with other "append" operators like .=
or +=, and that could even be an opportunity to rewrite it in a more
"functional" style...)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Undefined variables and the array append operator

2022-03-30 Thread Larry Garfield
On Wed, Mar 30, 2022, at 9:11 AM, Claude Pache wrote:
>> Le 29 mars 2022 à 21:44, Rowan Tommins  a écrit :
>> 
>> Hi all,
>> 
>> If $foo is not defined, statements such as $foo += 1 and $foo .= 'blah' 
>> raise "undefined variable" Warnings in PHP 8, and will throw Errors in PHP 
>> 9. However, the very similar looking $foo[] = 1 succeeds silently.
>> 
>> This seems odd to me, as "append to string" and "append to array" seem like 
>> very similar operations, with most of the same use cases and possible bugs.
>> 
>> 
>
>
> Hi,
>
> There are various subcases to consider:
>
> (1) $x[] = 42; and $x['y'] = 42; where $x is undefined
>
> (2) $x[] = 42; and  $x['y'] = 42; where $x is null
>
> (3) $x['y'][] = 42;  and  $x['y']['w'] = 42; where $x is an array, and 
> $x['y'] is undefined.
>
> Of course, I agree that (1) should be an error.
>
> The case (3) is similar to (1), but I think it is more controversial to 
> change. I bet that they are various places in my code that take 
> advantage of that feature, although personally I don’t mind to write 
> $x['y'] ??= [ ]; when needed.

We should probably also consider if there are other places where we're 
comfortable with ??= working correctly.  I'm not sure off hand if it should be 
acceptable in 1 or 2, but it's a question we should think through and document 
decisions on.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Mark Niebergall
Alex,

On Wed, Mar 30, 2022 at 7:47 AM Alexandru Pătrănescu 
wrote:

> Hey Mark,
>
> On Wed, Mar 30, 2022 at 4:01 PM Mark Niebergall 
> wrote:
>
>> Alex,
>>
>> On Tue, Mar 29, 2022 at 10:35 PM Alexandru Pătrănescu 
>> wrote:
>>
>>> Hey Mark,
>>>
>>>
>>> On Wed, Mar 30, 2022 at 6:03 AM Mark Niebergall 
>>> wrote:
>>>

 I have updated the RFC https://wiki.php.net/rfc/typed_class_constants
 with
 more details and examples from this thread, and updated the RFC status
 to
 Under Discussion. Hopefully the updated RFC helps answer questions and
 clarifies what the proposal includes.

>>>
>>> Thanks for the RFC and the drive here.
>>> I personally see the benefit and I think it would be a nice addition.
>>>
>>> I think you should also update the "Supported types" section.
>>> Starting with enums, constants can also be objects. Once a good
>>> technical solution is found, any object would be supported probably
>>> https://wiki.php.net/rfc/new_in_initializers#future_scope
>>> I think that only void, never and callable types should not be
>>> supported, just like on properties.
>>>
>>>
>> I have updated the "Supported types" to list out all types that are
>> supported and which types are not supported.
>>
>> Constants cannot be objects since objects are mutable, so typed constants
>> will not be allowed to be an enum (which is technically an object). A typed
>> constant _may_ be an enum value though, so the following example will be
>> valid:
>>
>> ```
>> enum Fruit
>> {
>> case Apple;
>> case Banana;
>> }
>>
>> class Colors
>> {
>> protected const string RED = Fruit::Apple;
>> protected const string YELLOW = Fruit::Banana;
>> }
>> ```
>>
>
> Actually, Fruit::Apple is an enum instance and that is an object that is
> of Fruit enum type (Fruit class).
> You can check this as it's already possible in PHP 8.1, even if it's not
> yet possible to have them with type: https://3v4l.org/f4WIC
>
> What you are referring to as enum value is actually a backed value for an
> enum instance.
> If you would define the enum as
> ```
> enum Fruit: string
> {
> case Apple = 'apple';
> case Banana = 'banana';
> }
> ```
> You could obtain the value with Fruit::Apple->value. But I'm not
> referring to this.
>
> So going back to the topic I mentioned, a constant can right now be an
> object.
> It can be only an enum instance for now but I believe that in the near
> future we will be able to have any object there.
>

Ah yes, you are correct, my mistake. I will need to make some more updates
to the RFC page to address that.


>
> Also, self and parent would make sense for valid typed constants, just
> like they do work on properties.
>

I'll add examples and an item about this as well.


>
> Regards,
> Alex
>
>
>>
>>>
 Of note is the "Inheritance and variance" section, which details uses
 with
 abstracts and interfaces, plus the "Constant values" section which
 includes
 details about errors.


 >
 > --
 > Guilliam Xavier
 >

>>>
>>> Thanks,
>>> Alex
>>>
>>


Re: [PHP-DEV] Undefined variables and the array append operator

2022-03-30 Thread Claude Pache



> Le 29 mars 2022 à 21:44, Rowan Tommins  a écrit :
> 
> Hi all,
> 
> If $foo is not defined, statements such as $foo += 1 and $foo .= 'blah' raise 
> "undefined variable" Warnings in PHP 8, and will throw Errors in PHP 9. 
> However, the very similar looking $foo[] = 1 succeeds silently.
> 
> This seems odd to me, as "append to string" and "append to array" seem like 
> very similar operations, with most of the same use cases and possible bugs.
> 
> 


Hi,

There are various subcases to consider:

(1) $x[] = 42; and $x['y'] = 42; where $x is undefined

(2) $x[] = 42; and  $x['y'] = 42; where $x is null

(3) $x['y'][] = 42;  and  $x['y']['w'] = 42; where $x is an array, and $x['y'] 
is undefined.

Of course, I agree that (1) should be an error.

The case (3) is similar to (1), but I think it is more controversial to change. 
I bet that they are various places in my code that take advantage of that 
feature, although personally I don’t mind to write $x['y'] ??= [ ]; when needed.

—Claude

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Guilliam Xavier
Hi Mark,

I have updated the RFC https://wiki.php.net/rfc/typed_class_constants with
>>> more details and examples from this thread, and updated the RFC status to
>>> Under Discussion. Hopefully the updated RFC helps answer questions and
>>> clarifies what the proposal includes.
>>>
>>
Thanks (I assume that you talked with the original author) -- not sure if
you should have started a new thread with the "[RFC]" tag in the subject?


> I think you should also update the "Supported types" section.
>> Starting with enums, constants can also be objects. Once a good technical
>> solution is found, any object would be supported probably
>> https://wiki.php.net/rfc/new_in_initializers#future_scope
>> I think that only void, never and callable types should not be supported,
>> just like on properties.
>>
>
> I have updated the "Supported types" to list out all types that are
> supported and which types are not supported.
>

A few comments, by subsection:

  - **Supported types**: This corresponds to the types currently allowed
for const values (as well as unions thereof) except it [still] doesn't
mention enums (which internally are classes implementing the `UnitEnum`
interface, and whose values are ultimately of `object` type) although
currently allowed. It also doesn't mention `mixed` (used later in examples).
  - **Strict and coercive typing modes**: I didn't understand it on first
read; I had to read the later "Constant values" section and compare both
with
https://wiki.php.net/rfc/typed_properties_v2#strict_and_coercive_typing_modes
and https://wiki.php.net/rfc/typed_properties_v2#default_values
  - **Inheritance and variance**: Several occurrences of "Class constants"
should probably be "*Typed* class constants". Also, I still think that
`protected bool $isExtinct` is *not* a good parallel to `public const bool
CAN_FLY` (see my previous message).
  - **Constant values**: You should probably remove the `iterable` example
now [and maybe add an `enum` one].


> Constants cannot be objects since objects are mutable, so typed constants
> will not be allowed to be an enum (which is technically an object). A typed
> constant _may_ be an enum value though, so the following example will be
> valid:
>
> ```
> enum Fruit
> {
> case Apple;
> case Banana;
> }
>
> class Colors
> {
> protected const string RED = Fruit::Apple;
> protected const string YELLOW = Fruit::Banana;
> }
> ```
>

This is incorrect, `Fruit::Apple` is of type `Fruit` (ultimately `object`),
not `string`. But it is *not* mutable, and *is* allowed as a const value
currently.

Besides, I realized that the RFC is [only] for *class* constants; what
about *namespaced (and global)* constants?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Alexandru Pătrănescu
Hey Mark,

On Wed, Mar 30, 2022 at 4:01 PM Mark Niebergall 
wrote:

> Alex,
>
> On Tue, Mar 29, 2022 at 10:35 PM Alexandru Pătrănescu 
> wrote:
>
>> Hey Mark,
>>
>>
>> On Wed, Mar 30, 2022 at 6:03 AM Mark Niebergall 
>> wrote:
>>
>>>
>>> I have updated the RFC https://wiki.php.net/rfc/typed_class_constants
>>> with
>>> more details and examples from this thread, and updated the RFC status to
>>> Under Discussion. Hopefully the updated RFC helps answer questions and
>>> clarifies what the proposal includes.
>>>
>>
>> Thanks for the RFC and the drive here.
>> I personally see the benefit and I think it would be a nice addition.
>>
>> I think you should also update the "Supported types" section.
>> Starting with enums, constants can also be objects. Once a good technical
>> solution is found, any object would be supported probably
>> https://wiki.php.net/rfc/new_in_initializers#future_scope
>> I think that only void, never and callable types should not be supported,
>> just like on properties.
>>
>>
> I have updated the "Supported types" to list out all types that are
> supported and which types are not supported.
>
> Constants cannot be objects since objects are mutable, so typed constants
> will not be allowed to be an enum (which is technically an object). A typed
> constant _may_ be an enum value though, so the following example will be
> valid:
>
> ```
> enum Fruit
> {
> case Apple;
> case Banana;
> }
>
> class Colors
> {
> protected const string RED = Fruit::Apple;
> protected const string YELLOW = Fruit::Banana;
> }
> ```
>

Actually, Fruit::Apple is an enum instance and that is an object that is of
Fruit enum type (Fruit class).
You can check this as it's already possible in PHP 8.1, even if it's not
yet possible to have them with type: https://3v4l.org/f4WIC

What you are referring to as enum value is actually a backed value for an
enum instance.
If you would define the enum as
```
enum Fruit: string
{
case Apple = 'apple';
case Banana = 'banana';
}
```
You could obtain the value with Fruit::Apple->value. But I'm not
referring to this.

So going back to the topic I mentioned, a constant can right now be an
object.
It can be only an enum instance for now but I believe that in the near
future we will be able to have any object there.

Also, self and parent would make sense for valid typed constants, just like
they do work on properties.

Regards,
Alex


>
>>
>>> Of note is the "Inheritance and variance" section, which details uses
>>> with
>>> abstracts and interfaces, plus the "Constant values" section which
>>> includes
>>> details about errors.
>>>
>>>
>>> >
>>> > --
>>> > Guilliam Xavier
>>> >
>>>
>>
>> Thanks,
>> Alex
>>
>


Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Mark Niebergall
Alex,

On Tue, Mar 29, 2022 at 10:35 PM Alexandru Pătrănescu 
wrote:

> Hey Mark,
>
>
> On Wed, Mar 30, 2022 at 6:03 AM Mark Niebergall 
> wrote:
>
>>
>> I have updated the RFC https://wiki.php.net/rfc/typed_class_constants
>> with
>> more details and examples from this thread, and updated the RFC status to
>> Under Discussion. Hopefully the updated RFC helps answer questions and
>> clarifies what the proposal includes.
>>
>
> Thanks for the RFC and the drive here.
> I personally see the benefit and I think it would be a nice addition.
>
> I think you should also update the "Supported types" section.
> Starting with enums, constants can also be objects. Once a good technical
> solution is found, any object would be supported probably
> https://wiki.php.net/rfc/new_in_initializers#future_scope
> I think that only void, never and callable types should not be supported,
> just like on properties.
>
>
I have updated the "Supported types" to list out all types that are
supported and which types are not supported.

Constants cannot be objects since objects are mutable, so typed constants
will not be allowed to be an enum (which is technically an object). A typed
constant _may_ be an enum value though, so the following example will be
valid:

```
enum Fruit
{
case Apple;
case Banana;
}

class Colors
{
protected const string RED = Fruit::Apple;
protected const string YELLOW = Fruit::Banana;
}
```


>
>> Of note is the "Inheritance and variance" section, which details uses with
>> abstracts and interfaces, plus the "Constant values" section which
>> includes
>> details about errors.
>>
>>
>> >
>> > --
>> > Guilliam Xavier
>> >
>>
>
> Thanks,
> Alex
>


Re: [PHP-DEV] Re: Undefined variables and the array append operator

2022-03-30 Thread Hans Henrik Bergan
> RFC. There are other inconsistencies as well now, depending on how the
undefined variable comes to exist

absolutely, but shouldn't try to do too much in a single rfc, wouldn't want
it to be rejected for the wrong reasons ^^

On Wed, 30 Mar 2022 at 12:17, Björn Larsson via internals <
internals@lists.php.net> wrote:

> Den 2022-03-29 kl. 21:44, skrev Rowan Tommins:
> > Hi all,
> >
> > If $foo is not defined, statements such as $foo += 1 and $foo .= 'blah'
> > raise "undefined variable" Warnings in PHP 8, and will throw Errors in
> > PHP 9. However, the very similar looking $foo[] = 1 succeeds silently.
> >
> > This seems odd to me, as "append to string" and "append to array" seem
> > like very similar operations, with most of the same use cases and
> > possible bugs.
> >
> >
> >  From an *implementation* point of view, this is presumably because they
> > are defined as different Op Codes - ASSIGN_OP for .= and ASSIGN_DIM for
> > []=, I believe. But that doesn't explain *why* ASSIGN_DIM behaves this
> way.
> >
> > A *historical* explanation might relate to Perl's "autovivification"
> > feature. However, PHP does *not* implement the same rules as Perl: for
> > instance, Perl will create array dimensions just by reading them, which
> > PHP does not; and Perl has a completely different type system, with
> > cases like "a scalar becomes a reference to a hash unless already a
> > reference to a list". Note also that I'm *not* talking about
> > multi-dimensional arrays with missing keys here, only undefined local
> > variables, as were the subject of the recent RFC.
> >
> > The *observable behaviour* for most operators in PHP is the same:
> >
> > 1) if the variable is undefined, consider the value to be null
> > 2) coerce the value to the appropriate type; if the value is null, this
> > gives the relevant "empty" value, such as '', 0, or []
> > 3) apply the operator
> >
> > There isn't anything particularly special with $foo[] = 'bar' in this
> > case, except that it's the only operator that doesn't raise a Warning
> > (and planned Error) at step 1. The same goes for all the other uses of
> > the [] syntax I can think of, like $foo['key'] = 'bar', or $ref =&
> $foo[].
> >
> >
> > For example, consider the following simple validation code
> > [https://3v4l.org/pP5CU]:
> >
> > $requiredFields = ['name', 'age', 'hair_colour'];
> >
> > // Note: $errorString is not initialised
> > foreach ( $requiredFields as $field ) {
> >  if ( ! isset($_POST[$field]) ) {
> >  $errorString .= "Missing required field '$field'. ";
> >  }
> > }
> > echo $errorString;
> >
> > This gives an "Undefined variable" Notice / Warning / Error, depending
> > on the version. That's reasonable, as failing to initialise $errorString
> > might cause problems if this code is integrated into a loop or larger
> > function later.
> >
> > However, switch the code from building up a string to building up an
> > array, and the result is identical, but the Notice / Warning / Error
> > goes away [https://3v4l.org/ojZ1O]:
> >
> > // Note: $errorArray is not initialised
> > foreach ( $requiredFields as $field ) {
> >  if ( ! isset($_POST[$field]) ) {
> >  $errorArray[] = "Missing required field '$field'. ";
> >  }
> > }
> > echo implode('', $errorArray);
> >
> >
> > Can anyone give a compelling reason why we should keep this
> > inconsistency, or should I raise an RFC to bring it in line with other
> > undefined variable accesses?
> >
> >
> I think it deserves an RFC. Then we also capture your excellent
> explanation above!
>
> Regards //Björn L
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


[PHP-DEV] Re: Undefined variables and the array append operator

2022-03-30 Thread Björn Larsson via internals

Den 2022-03-29 kl. 21:44, skrev Rowan Tommins:

Hi all,

If $foo is not defined, statements such as $foo += 1 and $foo .= 'blah' 
raise "undefined variable" Warnings in PHP 8, and will throw Errors in 
PHP 9. However, the very similar looking $foo[] = 1 succeeds silently.


This seems odd to me, as "append to string" and "append to array" seem 
like very similar operations, with most of the same use cases and 
possible bugs.



 From an *implementation* point of view, this is presumably because they 
are defined as different Op Codes - ASSIGN_OP for .= and ASSIGN_DIM for 
[]=, I believe. But that doesn't explain *why* ASSIGN_DIM behaves this way.


A *historical* explanation might relate to Perl's "autovivification" 
feature. However, PHP does *not* implement the same rules as Perl: for 
instance, Perl will create array dimensions just by reading them, which 
PHP does not; and Perl has a completely different type system, with 
cases like "a scalar becomes a reference to a hash unless already a 
reference to a list". Note also that I'm *not* talking about 
multi-dimensional arrays with missing keys here, only undefined local 
variables, as were the subject of the recent RFC.


The *observable behaviour* for most operators in PHP is the same:

1) if the variable is undefined, consider the value to be null
2) coerce the value to the appropriate type; if the value is null, this 
gives the relevant "empty" value, such as '', 0, or []

3) apply the operator

There isn't anything particularly special with $foo[] = 'bar' in this 
case, except that it's the only operator that doesn't raise a Warning 
(and planned Error) at step 1. The same goes for all the other uses of 
the [] syntax I can think of, like $foo['key'] = 'bar', or $ref =& $foo[].



For example, consider the following simple validation code 
[https://3v4l.org/pP5CU]:


$requiredFields = ['name', 'age', 'hair_colour'];

// Note: $errorString is not initialised
foreach ( $requiredFields as $field ) {
     if ( ! isset($_POST[$field]) ) {
     $errorString .= "Missing required field '$field'. ";
     }
}
echo $errorString;

This gives an "Undefined variable" Notice / Warning / Error, depending 
on the version. That's reasonable, as failing to initialise $errorString 
might cause problems if this code is integrated into a loop or larger 
function later.


However, switch the code from building up a string to building up an 
array, and the result is identical, but the Notice / Warning / Error 
goes away [https://3v4l.org/ojZ1O]:


// Note: $errorArray is not initialised
foreach ( $requiredFields as $field ) {
     if ( ! isset($_POST[$field]) ) {
     $errorArray[] = "Missing required field '$field'. ";
     }
}
echo implode('', $errorArray);


Can anyone give a compelling reason why we should keep this 
inconsistency, or should I raise an RFC to bring it in line with other 
undefined variable accesses?



I think it deserves an RFC. Then we also capture your excellent 
explanation above!


Regards //Björn L

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



[PHP-DEV] ZEND_VM_HOT is ZEND_COLD?

2022-03-30 Thread Su, Tao
Dear PHP Internals,

I am looking at zend_vm_execute.h file and found some lines of code which I do 
not quite get.
Who can help tell that why we should have ZEND_COLD attribute in ZEND_VM_HOT 
line definition,
or I can simply ignore it as it is trivial? Thanks.

# if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
// # define ZEND_COLD __attribute__((cold))
#  define ZEND_VM_HOT zend_always_inline ZEND_COLD ZEND_OPT_SIZE
#  define ZEND_VM_COLDZEND_COLD ZEND_OPT_SIZE

Here is one use of this macro in function declaration.
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL 
ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)


===
Tony Su (Su, Tao)
make a 'lazy' programmer diligently with efficiency



Re: [PHP-DEV] Undefined variables and the array append operator

2022-03-30 Thread Robert Landers
On Tue, Mar 29, 2022 at 9:44 PM Rowan Tommins  wrote:
>
> Hi all,
>
> If $foo is not defined, statements such as $foo += 1 and $foo .= 'blah'
> raise "undefined variable" Warnings in PHP 8, and will throw Errors in
> PHP 9. However, the very similar looking $foo[] = 1 succeeds silently.
>
> This seems odd to me, as "append to string" and "append to array" seem
> like very similar operations, with most of the same use cases and
> possible bugs.
>
>
>  From an *implementation* point of view, this is presumably because they
> are defined as different Op Codes - ASSIGN_OP for .= and ASSIGN_DIM for
> []=, I believe. But that doesn't explain *why* ASSIGN_DIM behaves this way.
>
> A *historical* explanation might relate to Perl's "autovivification"
> feature. However, PHP does *not* implement the same rules as Perl: for
> instance, Perl will create array dimensions just by reading them, which
> PHP does not; and Perl has a completely different type system, with
> cases like "a scalar becomes a reference to a hash unless already a
> reference to a list". Note also that I'm *not* talking about
> multi-dimensional arrays with missing keys here, only undefined local
> variables, as were the subject of the recent RFC.
>
> The *observable behaviour* for most operators in PHP is the same:
>
> 1) if the variable is undefined, consider the value to be null
> 2) coerce the value to the appropriate type; if the value is null, this
> gives the relevant "empty" value, such as '', 0, or []
> 3) apply the operator
>
> There isn't anything particularly special with $foo[] = 'bar' in this
> case, except that it's the only operator that doesn't raise a Warning
> (and planned Error) at step 1. The same goes for all the other uses of
> the [] syntax I can think of, like $foo['key'] = 'bar', or $ref =& $foo[].
>
>
> For example, consider the following simple validation code
> [https://3v4l.org/pP5CU]:
>
> $requiredFields = ['name', 'age', 'hair_colour'];
>
> // Note: $errorString is not initialised
> foreach ( $requiredFields as $field ) {
>  if ( ! isset($_POST[$field]) ) {
>  $errorString .= "Missing required field '$field'. ";
>  }
> }
> echo $errorString;
>
> This gives an "Undefined variable" Notice / Warning / Error, depending
> on the version. That's reasonable, as failing to initialise $errorString
> might cause problems if this code is integrated into a loop or larger
> function later.
>
> However, switch the code from building up a string to building up an
> array, and the result is identical, but the Notice / Warning / Error
> goes away [https://3v4l.org/ojZ1O]:
>
> // Note: $errorArray is not initialised
> foreach ( $requiredFields as $field ) {
>  if ( ! isset($_POST[$field]) ) {
>  $errorArray[] = "Missing required field '$field'. ";
>  }
> }
> echo implode('', $errorArray);
>
>
> Can anyone give a compelling reason why we should keep this
> inconsistency, or should I raise an RFC to bring it in line with other
> undefined variable accesses?
>
>
> Regards,
>
> --
> Rowan Tommins
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

I think it's worth raising an RFC. There are other inconsistencies as
well now, depending on how the undefined variable comes to exist,
particularly around arrays.

For example:

$x = null;
$a = $x['nope'];
echo $a;

There should be an error here, but $a gets the value null and only a
warning is issued. Yet, this is already an error:

$x = new class { public string|null $nope; };
$a = $x->nope;
echo $a;

So, depending on how you json_decode() you may or may not have issues.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php