Re: [PHP-DEV] [RFC] [Discussion] Add openStream() to XML{Reader,Writer}

2024-04-24 Thread Claude Pache


> Le 23 avr. 2024 à 21:23, Niels Dossche  a écrit :
> 
> On 22/04/2024 21:53, Larry Garfield wrote:
>> On Mon, Apr 22, 2024, at 6:41 PM, Niels Dossche wrote:
>>> Hi internals
>>> 
>>> I'm opening the discussion for my RFC "Add openStream() to 
>>> XML{Reader,Writer}".
>>> RFC link: https://wiki.php.net/rfc/xmlreader_writer_streams
>>> 
>>> Kind regards
>>> Niels
>> 
>> This seems quite reasonable to me overall.  My one question is regarding the 
>> writer version.  Why is that not a static method, too?  I would have 
>> expected that to be a "named constructor" just like the reader.
>> 
>> --Larry Garfield
> 
> Hi Larry
> 
> XMLReader already had these static methods that act as named constructors, 
> but XMLWriter has no named constructors at the moment.
> The XMLWriter::openMemory() and XMLWriter::openUri() functions are instance 
> methods that must be called after doing "new XMLWriter".
> If these two existing functions were static methods instead, I would've made 
> XMLWriter::openStream() static too.
> So IOW, for consistency I followed the model of the existing XMLWriter 
> methods.
> 
> While it is possible to do the magic trick that XMLReader uses to have the 
> open methods on XMLWriter both static and non-static, this is quite hacky and 
> was only done to XMLReader for BC reasons.

That’s odd. The inconsistency was introduced (or at least sanctioned) in PHP 
8.0. In PHP 7, XMLReader::open() and XMLReader::XML() already worked when used 
both as static and non-static methods, but triggered a deprecation warning when 
called statically. The deprecation warning was removed in 8.0, regardless of 
the differing semantics when called statically and non-statically, and 
regardless of the the inconsistency with corresponding XMLWriter methods.

Another point: when called statically on a subclass, both `XMLReader::open()` 
and `XMLReader::XML()` return an object of type `XMLReader`, not of the 
subclass: https://3v4l.org/lCOAvJ
For that reason, they are unusable as static methods on a subclass. The new 
`openStream()` method should work on instances, so that it will be usable on 
subclasses. (And for the same reason, I think it was a mistake to undeprecate 
`XMLReader::{open,XML}()` as static methods in 8.0.)

—Claude



Re: [PHP-DEV] [RFC] [Discussion] Deprecate GET/POST sessions

2024-04-04 Thread Claude Pache



> Le 4 avr. 2024 à 01:08, Kamil Tekiela  a écrit :
> 
> If there are no more comments, I would like to put this RFC to vote in
> the next two days.


Hi,

1. In session_start(), it is possible to override ini settings like that:

```php
session_start([ 'use_cookies' => '1', 'use_only_cookies' => '1', 
'referer_check' => '' ]);
```

The relevant options should also be deprecated in that context.

2. A clarification: Suppose that I have  `session.use_only_cookie = 1` in my 
ini file (no deprecation warning), and I call 
`ini_set("session.use_only_cookie", "1")` in my code (no-op). Will the 
`ini_set(...)` invocation trigger a deprecation warning?

—Claude

Re: [PHP-DEV] RFC idea: using the void type to control maximum arity of user-defined functions

2024-04-04 Thread Claude Pache

> Le 4 avr. 2024 à 15:10, Kamil Tekiela  a écrit :
> 
> Why is passing extra arguments a problem at all?

In a parallel perfect and boring world, it is not a problem. In our world, 
disallowing extra arguments have two advantages:

* catching bugs;

* allowing to add new optional parameters to an existing function without 
fearing to break existing code.

—Claude



Re: [PHP-DEV] RFC idea: using the void type to control maximum arity of user-defined functions

2024-04-04 Thread Claude Pache



> Le 4 avr. 2024 à 15:03, Mark Trapp  a écrit :
> 
> On Thu, Apr 4, 2024 at 5:43 AM Pablo Rauzy  wrote:
> 
> I like this concept, but instead of introducing a new syntax, have you
> considered leveraging attributes in the same way that PHP 8.3
> introduced #[Override]?
> 
> #[Nonvariadic]
> function foo () {}
> foo(42); // warning: foo() expects exactly 0 arguments, 1 given
> 
> I think the intent would be clearer and it would avoid introducing a new 
> syntax.
> 

Indeed, except that I think it should be better to have *by default* the same 
behaviour between built-in functions and user-defined functions:

```php
function foo() { }

foo(42);
// in PHP 8.x: Deprecated: foo() expects expects exactly 0 arguments, 1 given
// in PHP 9: Fatal error: foo() expects expects exactly 0 arguments, 1 given
```

and, in case you want a variadic function:

```php
#[Variadic]
function foo() { }
```

Alternatively, we don’t really need to introduce a new attribute, because one 
can just write:

```php
function foo(...$args) { }
```


—Claude


Re: [PHP-DEV] Allow properties to be defined on interface

2024-03-28 Thread Claude Pache



> Le 28 mars 2024 à 16:03, Saki Takamachi  a écrit :
> 
> Therefore, I propose to allow public properties to be defined on the 
> interface (It does not matter whether it is read-only or not).
> 


Hi, 

For information, the question of properties on interfaces is covered by the 
currently discussed RFC “Property hooks”: 
https://wiki.php.net/rfc/property-hooks 

—Claude

Re: [PHP-DEV] [RFC idea introduce] The issue where the __callStatic magic method is not called when statically calling a public method.

2024-03-28 Thread Claude Pache

> Le 28 mars 2024 à 03:29, 하늘아부지  a écrit :
> 
> Hi.
> 
> I would like to register an RFC on the following issue.
> https://github.com/php/php-src/issues/13813
> 
> To summarize briefly, users expect that the `__callStatic` magic method will 
> be called in all cases when a method is not static while using the 
> `__callStatic`. However, in reality, if the method is public, the 
> `__callStatic` magic method is not called, and an error still occurs.
> 
> I would like to hear your opinions.
> I also hope someone can help with the RFC registration.
> 
> 
> 
> 
> ```php
>  class MyClass
> {
> public static function __callStatic($method, $args)
> {
> echo $method . "\n";
> }
> 
> private function privateMethod() {}
> protected function protectedMethod() {}
> public function publicMethod() {}
> }
> 
> MyClass::privateMethod();
> MyClass::protectedMethod();
> MyClass::publicMethod();
> ```
> 
> Resulted in this output:
> ```
> privateMethod
> protectedMethod
> Fatal error: Uncaught Error: Non-static method MyClass::publicMethod() cannot 
> be called statically in ...
> ```
> 
> But I expected this output instead:
> ```
> privateMethod
> protectedMethod
> publicMethod
> ```
> 
> 
> 


Hi,

One of the issue is that it is not possible to determine statically that a 
certain call is static or not. It is possible to determine it at runtime; but 
you must be careful to articulate clearly the rules. Although it is absolutely 
possible to have logical rules, I fear that they couldn’t be sufficiently 
simple in order to avoid confusion.

In the following real-world (but hopefully rare) case (it is taken from my own 
codebase), I am calling a method of a grandparent class. It is *not* a static 
method:

```php

foo = new class(/* ... */) extends Bar {

// ...

function Header() {
$grandparent_class = get_parent_class(parent::class);
$grandparent_class::Header();
   // ... rest of code
}

   // ...
};
```

In the following more general case, I might intend to call to a static method. 
However, as of today, a call to a non-static method will occur if  `A` has a 
non-static accessible method `qux()` *and* `$this` is an instance of `A`:

```php
class Foo {
function baz() {
A::qux();
}
}
```

(In older versions of PHP, a non-static call would occur even when `$this` is 
not an instance of `A`. Hopefully, this is no longer the case since PHP 8.)


—Claude

Re: [PHP-DEV] Proposal: AS assertions

2024-03-22 Thread Claude Pache

> Le 22 mars 2024 à 16:18, Rowan Tommins [IMSoP]  a écrit 
> :
> 
> $optionalExpiryDateTime = $expiry as ?DateTimeInterface else 
> some_other_function($expiry);
> assert($optionalExpiryDateTime is ?DateTimeInterface); // cannot fail, 
> already asserted by the "as"

I think that the `is` operator is all we need; the `as` operator adds syntax 
complexity for little gain. Compare:

$optionalExpiryDateTime = $expiry as ?DateTimeInterface else 
some_other_function($expiry);

vs

$optionalExpiryDateTime = $expiry is ?DateTimeInterface ? $expiry : 
some_other_function($expiry);

—Claude

Re: [PHP-DEV] [Pre-RFC] Convert exit (and die) from language constructs to functions

2024-02-27 Thread Claude Pache

> 
> I hear you, but what about exit; ?!
> Do not worry exit; is still supported!
> It only requires a _tiny_ bit of dark magic to achieve this!
> exit; would just be interpreted as a fetch to a constant,
> so when attempting to access the undefined exit/die case-insensitive constant
> we just need to exit as if we were calling the function!
> 

Hi Gina,

If it is mostly an implementation detail, this is probably ok. However, please 
make sure that `$foo = 'exit'; constant($foo);` (or any other future way to 
interpolate the constant) does not stop the program, but only fetch the value 
of a “real” constant.

Alternatively, it is probably possible to keep the current parsing with T_EXIT, 
but to make it equivalent to invoke a “regular” function named `exit()` — 
somehow the same way that using the backtick operator is equivalent to calling 
`shell_exec()`, up to the point that disabling `shell_exec()` will also disable 
the the backtick operator?

(BTW, it *is* currently possible to define and use a constant named “exit”: 
https://3v4l.org/aBq2R — of course, no need to keep such a “feature”.)

—Claude

Re: [PHP-DEV] RFC Proposal : Allows calling non-static public methods through the __callStatic magic method instead of throwing an error.

2024-02-17 Thread Claude Pache



> Le 17 févr. 2024 à 16:51, Larry Garfield  a écrit :
> 
> On Fri, Feb 16, 2024, at 7:56 PM, 하늘아부지 wrote:
>> Hi.
>> I'd like to propose an RFC, but I don't have the authority.
>> Below is my suggestion.
>> If you think this makes sense, please write an RFC for me.
>> Sincerely.
>> 
>> --
>> 
>> = Introduction =
>> Allows calling non-static public methods through the __callStatic magic 
>> method instead of throwing an error.
>> 
>> = Proposal =
>> 
>> From a conceptual perspective:
>> It goes without saying that calling a non-static method statically will 
>> result in an error.
>> However, a confusing situation occurred when the __callStatic magic 
>> method exists.
>> Non-public methods can be called, but public methods cannot.
>> This is the opposite of the method visibility policy.
>> 
>> From a practical point of view:
>> If you can call Non-static public methods through the __callStatic 
>> magic method, you can write code like Laravel ORM more simply and tidy.
>> 
>> 
>> User::foo()->bar();
>> 
>> 
>>  Before 
>> 
>> 
>> class Foo
>> {
>>protected static ?Foo $instance = null;
>> 
>>public static function __callStatic($method, $args)
>>{
>>$instance = self::$instance ?? self::$instance = new static();
>>return $instance->__call($method, $args);
>>}
>> 
>>public function __call($method, $args)
>>{
>>if (method_exists($this, $method)) {
>>return $instance->$method(...$args);
>>}
>> 
>>return $this;
>>}
>> 
>>protected function bar()
>>{
>>echo __METHOD__ . '';
>> 
>>return $this;
>>}
>> 
>>protected function baz()
>>{
>>echo __METHOD__ . '';
>> 
>>return $this;
>>}
>> }
>> 
>> Foo::bar()->baz();
>> (new Foo())->bar()->baz();
>> 
>> 
>> There is no error, but the concept of method visibility is broken.
>> All Non-public methods can be called at instance scope.
>> 
>>  After 
>> 
>> 
>> class Foo
>> {
>>protected static ?Foo $instance = null;
>> 
>>public static function __callStatic($method, $args)
>>{
>>$instance = self::$instance ?? self::$instance = new static();
>> 
>>if (method_exists($instance, $method)) {
>>return $instance->$method(...$args);
>>}
>> 
>>return $instance;
>>}
>> 
>>public function bar()
>>{
>>echo __METHOD__ . '';
>> 
>>return $this;
>>}
>> 
>>public function baz()
>>{
>>echo __METHOD__ . '';
>> 
>>return $this;
>>}
>> }
>> 
>> Foo::bar()->baz();
>> (new Foo())->bar()->baz();
>> 
>> 
>> This is more tidy.
>> Only public methods are callable at instance scope.
> 
> That calling bar() works at all in this example is rather accidental.  The 
> whole point of a non-static method is that it has an implicit required $this 
> argument to it.  Without a required argument, a method cannot be called, 
> because it is supposed to fail.
> 
> In fact, even your "before" example fails: https://3v4l.org/moH0s

It does work after having corrected the obvious bug in the `bar()` method.

> 
> I don't think what you describe is even possible, nor would it be a good idea.

Why wouldn’t it possible? Couldn’t the engine invoke __callStatic() instead of 
complaining that the targeted method is not static? (I don’t have opinion on 
whether it is a good idea, though)

—Claude


Re: [PHP-DEV] int|float for sleep? sleep(0.1) => sleep 0.1 seconds

2024-02-17 Thread Claude Pache
Hi,

> 
> FWIW Python's `time.sleep` also works like this: 
> https://docs.python.org/3/library/time.html#time.sleep

Python also implements the following:

> If the sleep is interrupted by a signal and no exception is raised by the 
> signal handler, the sleep is restarted with a recomputed timeout.
> 

I think we should also implement that. As a consequence, `sleep(...)` will 
always return `0`.

If we “fix” sleep(), let’s “fix” it completely.

—Claude

Re: [PHP-DEV] Deprecate declare(encoding='...') + zend.multibyte + zend.script_encoding + zend.detect_unicode ?

2023-11-29 Thread Claude Pache


> Le 28 nov. 2023 à 21:47, Hans Henrik Bergan  a écrit :
> 
>> What is the migration path for legacy code that use those directives?
> 
> The migration path is to convert the legacy-encoding PHP files to UTF-8.
> Luckily this can be largely automated, here is my attempt:
> https://github.com/divinity76/php2utf8/blob/main/src/php2utf8.php
> but that code definitely needs some proof-reading and additions - idk
> if the approach used is even a good approach, it was just the first i
> could think of, feel free to write one from scratch

Hi,

Converting the character encoding of php files is by no means sufficient, 
except in the simplest cases.

Strings of text are to be found in various places, such as:

1. in the php files, as literals;
2. inside memory, at runtime;
3. in non-php data files stored on the server;
4. in the database;
5. as presented to the user (e.g. html document) and as received from them 
(e.g. form submission);
6. etc.

If you change the character encoding in (1), you necessarily change the 
encoding in (2), unless you wrap your literals with some function that performs 
the conversion in the other direction at runtime. And if you change the 
encoding in (2), you should be very careful when your text flows from and to 
(3), (4), (5) and (6): you should either change the encoding at those places, 
or make sure that proper conversion is done at the boundaries of those domains.

Also, mechanical conversion is not the whole story. For example, if you change 
the encoding in (5), you should not forget to adapt the  tag 
and/or the content-type http header.

Also, all strings are not text, and only a human can decide whether the literal 
“\xe9” in a random location is meant to encode the raw byte 0xE9 or the 
character “é” in latin-1.

Of course, because we live in an interesting world, there will be situations 
where the encoding is unknown or ambiguous. Yuya mentioned the case of 
Shift-JIS which has various incompatible variants, and I am happy not to have 
encountered such ambiguities (only unknownnesses) when I converted our code 
base from windows-1252 (aka latin-1) to utf-8 a few years ago.

—Claude



Re: [PHP-DEV] Deprecate declare(encoding='...') + zend.multibyte + zend.script_encoding + zend.detect_unicode ?

2023-11-28 Thread Claude Pache



> Le 28 nov. 2023 à 20:56, Kamil Tekiela  a écrit :
> 
>> Convert your PHP source files to UTF-8.
> 
> If the solution is as easy as just converting the encoding of the
> source file, then why did we even need to have this setting at all?
> Why did PHP parser support encodings that demanded the introduction of
> this declare?

It is not necessary as simple: because your code base may contain literal 
strings, and changing the encoding of the source file will effectively change 
the contents of the strings.

—Claude

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



Re: [PHP-DEV] Deprecate declare(encoding='...') + zend.multibyte + zend.script_encoding + zend.detect_unicode ?

2023-11-28 Thread Claude Pache



> Le 28 nov. 2023 à 19:57, Hans Henrik Bergan  a écrit :
> 
> With the dominance of UTF-8 (a fixed-endian encoding), surely no new
> code should utilize any of declare(encoding='...') / zend.multibyte /
> zend.script_encoding / zend.detect_unicode.
> I propose we deprecate all 4.

Hi,

What is the migration path for legacy code that use those directives?

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



Re: [PHP-DEV] Callable arguments cannot have default value

2023-11-28 Thread Claude Pache


> Le 28 nov. 2023 à 00:59, Sergii Shymko  a écrit :
> 
> Hi,
> 
> Wanted to bring up an inconsistent behavior of callable arguments compared to 
> arguments of other types.
> Callable argument cannot have a default value (tested string or array types - 
> both are not permitted).
> The same exact value works perfectly fine when passed dynamically, it just 
> cannot be specified as a default.
> The workaround is to remove the type annotation which is obviously 
> undesirable.
> 
> Here’s an example:
> declare(strict_types=1);
> function test(callable $idGenerator = 'session_create_id') {
>$id = $idGenerator();
>// ...
> }
> 
> The function/method declaration above produces the following error on all PHP 
> versions:
> Fatal error: Cannot use string as default value for parameter $idGenerator of 
> type callable in /tmp/preview on line 4
> 
> Note that the exact same string argument can be passed without any issue:
> function test(callable $idGenerator) {…}
> test('session_create_id’);
> 
> Is there a specific architectural limitation causing this that's 
> hard/impossible to overcome?
> 
> I’m aware that class properties cannot be annotated with callable - another 
> unfortunate limitation.
> Callable is not a real type like other primitive types which causes all these 
> inconsistencies, correct?
> Callable properties (separate topic) may be a challenge, but can at least 
> argument defaults be supported?
> 
> Regards,
> Sergii Shymko


Hi Sergii,

The big problem with the `callable` type, is that it can be check only at 
runtime. For instance:

```php
function foo(callable $x) { }

foo('strlen'); // ok
foo('i_dont_exist'); // throws a TypeError
```

Another complication, is that a value of the form `[ $class, 
$protected_or_private_method ]` may or may not be callable depending on whether 
the method is visible from the current scope.

In other words, contrarily to all other types, `callable` depends both on 
runtime state and on context.

Therefore, an argument of type `callable` cannot have a default value, because 
it is not known in advance whether the default value will be valid when used.

For the case of class properties, see  
https://wiki.php.net/rfc/typed_properties_v2#supported_types

—Claude




Re: [PHP-DEV] [RFC][Discussion] Harmonise "untyped" and "typed" properties

2023-11-23 Thread Claude Pache



> Le 23 nov. 2023 à 08:56, Rowan Tommins  a écrit :
> 
> On 23 November 2023 01:37:06 GMT, Claude Pache  wrote:
>> What you describe in the last sentence is what was initially designed and 
>> implemented by the RFC: https://wiki.php.net/rfc/typed_properties_v2 
>> (section Overloaded Properties).
>> 
>> However, it was later changed to the current semantics (unset() needed in 
>> order to trigger __get()) in https://github.com/php/php-src/pull/4974
> 
> 
> Good find. So not only is it not specified this way in the RFC, it actually 
> made it into a live release, then someone complained and we rushed out a more 
> complicated version "to avoid WTF". That's really unfortunate.
> 
> I'm not at all convinced by the argument in the linked bug report - whether 
> you get an error or an unexpected call to __get, the solution is to assign a 
> valid value to the property. And making the behaviour different after unset() 
> just hides the user's problem, which is that they didn't expect to *ever* 
> have a call to __get for that property.
> 
> But I guess I'm 4 years too late to make that case.
> 

Hi, 

I think that the legitimacy of the current behaviour is not something to be 
convinced by abstract reasoning like we are doing now (otherwise, it wouldn’t 
probably have waited a live release to be implemented in a rush), but something 
that can be understood only by considering the conflicting uses of  __get(), 
which leads to conflicting expectations, and how they managed to live together 
despite a fundamental contradiction:

1. __get() is used to implement virtual properties (as mentioned in the linked 
bug report). For this use case, access to a declared property should not call 
__get() (whose implementation may be hidden away in a superclass).

2. __get() is used to implement lazy properties. For this use case, access to 
an uninitialised (or unset, or undeclared) property should call __get().

The two expectations did live together as long as declared properties were also 
initialised (implicitly, to null). It is true that they are formally 
incompatible; when you say:

> And making the behaviour different after unset() just hides the user's 
> problem, which is that they didn't expect to *ever* have a call to __get for 
> that property.

you are referring to the expectation given by use case 1, which contradicts the 
expectation given by use case 2. However, it is not a problem in practice, 
because users of classes implementing (1) but not (2) do not unset declared 
properties, ever.

The conflict became evident with the advent of typed properties, which cannot 
be implicitly initialised to null in general. As both use cases are firmly 
rooted in practice, both should be taken in account. The current, cumbersome 
and unfortunate behaviour allows to keep sane semantics for those classes using 
bad practices (use case 1), while not invalidating naughty hacks used by other 
classes (use case 2).


—Claude

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



Re: [PHP-DEV] Re: [RFC][Discussion] Harmonise "untyped" and "typed" properties

2023-11-22 Thread Claude Pache


> Le 22 nov. 2023 à 23:17, Rowan Tommins  a écrit :
> 
> I'm probably going to regret asking this, but is there some reason it works 
> that way? Is there any chance of changing it to just:
> 
>> Typed properties start off as uninitialized.
>> 
>> Once you've assigned a value, you can't go back to the original 
>> uninitialized state using unset()
>> 
>> Accessing an uninitialized property will first check for __get, and throw an 
>> error if that isn't defined.

Hi Rowan,

What you describe in the last sentence is what was initially designed and 
implemented by the RFC: https://wiki.php.net/rfc/typed_properties_v2 (section 
Overloaded Properties).

However, it was later changed to the current semantics (unset() needed in order 
to trigger __get()) in https://github.com/php/php-src/pull/4974

—Claude

Re: [PHP-DEV] [RFC][Discussion] Harmonise "untyped" and "typed" properties

2023-11-22 Thread Claude Pache



> Le 21 nov. 2023 à 00:08, Rowan Tommins  a écrit :
> 
> I've revised the RFC; it now proposes to keep the implicit "= null" for 
> untyped properties, although I'm still interested in suggestions for other 
> strategies around that. 

Hi,

If you really want untyped property not being implicitly initialised to “null” 
in the long term, here is my suggestion:

1. In 8.next, deprecate untyped property without initialiser, suggesting to add 
an explicit “= null” (one deprecation notice per class definition containing at 
least one untyped property without initialiser);
2. In 9.0, an untyped property without initialiser becomes a syntax error;
3. Later, reintroduce untyped property without initialiser with the new 
semantics.

—Claude

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



Re: [PHP-DEV] [RFC][Discussion] Harmonise "untyped" and "typed" properties

2023-11-17 Thread Claude Pache



> Le 17 nov. 2023 à 14:53, Rowan Tommins  a écrit :
> 
> On 17 November 2023 13:30:42 GMT, Claude Pache  wrote:
>> 
>> Yes, except that an untyped (respectively `mixed`) property cannot be 
>> redeclared as `mixed` (resp. untyped) in a subclass. A small step in the 
>> right direction is to allow that.
> 
> Huh, I didn't know that. I'll add it to the RFC, at least to consider.
> 
> The RFC to add "mixed" gives an example of removing the type as invariance, 
> but doesn't seem to justify why "untyped" and "mixed" should be considered 
> different, from a type system point of view. 
> https://wiki.php.net/rfc/mixed_type_v2

Note that untyped is different from `mixed` in the case of return values of 
functions: in that context, untyped is equivalent to `mixed|void`. In all other 
contexts, untyped and `mixed` are effectively equivalent, because `void` is 
void of sense.

—Claude

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



Re: [PHP-DEV] [RFC][Discussion] Harmonise "untyped" and "typed" properties

2023-11-17 Thread Claude Pache



> Le 17 nov. 2023 à 11:47, Rowan Tommins  a écrit :
> 
> On 16 November 2023 21:38:48 GMT, Jakub Zelenka  wrote:
>> This sounds like a huge BC break. Probably bigger and a bit harder to fix
>> than disallowing dynamic props.
> 
> More common, maybe; but trivial to fix: add "=null" at the end of all untyped 
> property declarations that don't already have an initializer. It would be 
> trivial to automate with something like Rector.
> 

The fix is trivial, but the number of files to be touched is huge.

> 
>> Maybe it would be better to do this as some sort of opt in behaviour
> 
> We already have the opt-in behaviour: add "mixed" to a property declaration, 
> and it no longer gets initialized to null. [...]
> 

Yes, except that an untyped (respectively `mixed`) property cannot be 
redeclared as `mixed` (resp. untyped) in a subclass. A small step in the right 
direction is to allow that.

—Claude

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



Re: [PHP-DEV] [RFC] [Discussion] Change the edge case of round()

2023-11-05 Thread Claude Pache



> Le 5 nov. 2023 à 08:31, Saki Takamachi  a écrit :
> Hi,
> 
> It's almost been two weeks since I opened this discussion. If there are no 
> other opinions, I am thinking of starting a vote tomorrow or later.
> 
> Regards.
> 
> Saki

Hi Saki,

Reading the RFC, it is unclear for me what are the benefits of the change, and 
whether it is worth the subtle breaking of existing code that implicitly relies 
on the current behaviour. “FP is just FP” looks like an ideal position, and one 
that has a counteragument given in the RFC that introduced the current 
behaviour. 

We could live with any behaviour of round(), and they are arguments on both 
sides. My issue at this point is not exactly what behaviour we have picked, but 
whether changing between the two is sufficiently motivated. 

—Claude 

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



Re: [PHP-DEV] Basic Type Alias

2023-10-27 Thread Claude Pache


> Le 26 oct. 2023 à 21:23, Larry Garfield  a écrit :
> 
> App-wide aliases run into the autoloading problem.  If the engine runs across 
> the add() function above, and "numeric" isn't defined, what can it do?  
> Currently, all it can do is trigger autoloading, which only works for 
> class-ish constructs (class, interface, trait, enum).  Making type aliases a 
> full class-like construct seems... weird, and over-engineered.  But if not, 
> how do we autoload them?  And if they do autoload somehow, does that mean we 
> end up with a bunch of files with a single `type` line in them?  That seems 
> not-good.  You also then have to ask how they interact with namespaces.
> 
> So far no one seems to like my idea of "composer has a files block, PHP has a 
> preloader, they're small, so who the hell cares about autoloading, just 
> greedily load them and move on with life", even though I think that's the 
> best answer. :-)

Hi,

“Autoloading” does not mean (and has never meant) “one file per class-like 
construct”; even if it is the most customary strategy (and the one consecrated 
by PSR), it is by no means the only one.

Proof of concept: With the following autoloader, at the first time the compiler 
needs the definition of some class-like symbol under the FooBits\Acme\Type 
namespace, all symbols under that namespace are loaded together:

```php
spl_autoload_register(function ($class) {
if (str_starts_with($class, 'FooBits\\Acme\\Type\\')) {
// we have conventionally put all types defined by our library under 
this namespace,
// and there are all defined together in the following file:
require 'vendor/foobits/acme/src/types.php';
}
elseif (str_starts_with($class, 'FooBits\\Acme\\')) {
// for other symbols we use the boring psr-4 convention
require 'vendor/foobits/acme/src/' . str_replace('\\', '/', 
substr($class, 13)) . '.php';
}
});
```

I think that treating the type aliases as class-like *names* for the purpose of 
naming and autoloading (without giving my opinion whether they are class-like 
*constructs* for some definition of “are”) is a reasonable approach, and 
autoloading/preloading/whatever-loading-strategy ought to be treated as an 
orthogonal (non-)issue.

—Claude

Re: [PHP-DEV] [RFC] [Discussion] Adding bcround, bcfloor and bcceil to BCMath

2023-10-06 Thread Claude Pache
Hi,


> Le 5 oct. 2023 à 14:26, Saki Takamachi  a écrit :
> 
> In fact, I predict that many use cases will be covered by GMP.
> 
> Still, I think that there may be cases where calculation functions like 
> mainframe BCD are required, such as when calculating money.
> 
> I am unable to decide whether it is correct to deprecate BCMath and only use 
> GMP.
> 
> I'd like to hear other people's opinions as well.
> 

We use bcmath in particular for money calculation indeed, and some other 
things, most of them have in common to work with decimal numbers.

For those purposes, gmp (in its current state) is pointless, because it 
supports only integers. I could multiply my numbers with an appropriate power 
of ten and work with integers; but in that case I could just use native 64-bits 
integers: even if you work on Apple’s accounting, they won’t overflow.



> Le 4 oct. 2023 à 13:39, Saki Takamachi  a écrit :
> 
> 
> After all, I feel that BCMath and GMP have different roles.
> 
> Arbitrary precision mathematics and very high precision mathematics are 
> similar but distinctly different.
> 
> If PHP has already started integrating these things, then of course I'll 
> follow suit, but if not, I'm against these integrations.
> 
> If I missed something important, could you please let me know?
> 


None of the above. As noted, my main use of bcmath is neither arbitrary 
precision, nor very high precision, it is decimal numbers.

Of course, bcmath works equally well for manipulation of big integers, which is 
my second use case of the library. Because I already use bcmath for other 
things and I don’t need Legendre symbols, I have not much incentive to switch 
to gmp for big integers.

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



Re: [PHP-DEV] [RFC] [Discussion] Adding bcround, bcfloor and bcceil to BCMath

2023-10-02 Thread Claude Pache


> Le 1 oct. 2023 à 14:35, Saki Takamachi  a écrit :
> 
> Hi, internals
> 
> I would like to start the discussion for my RFC "Adding bcround, bcfloor and 
> bcceil to BCMath”.
> https://wiki.php.net/rfc/adding_bcround_bcfloor_bcceil_to_bcmath
> 
> Regards.
> 
> Saki
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 


Hi,

Some remarks about the paragraph “Backward Incompatible Changes”

> These are new features and do not break existing functionality.
> 
> If I had to point out my concerns, I would say that code that satisfies the 
> following conditions will cause an error to occur.
> 
> * A situation where the user has defined a function with the same name, such 
> as bcround()

This is a real concern. I have personally defined a `bcround()` global function 
because I needed such a functionality. A quick search on GitHub shows that I am 
not alone: https://github.com/search?q=bcround+language%3Aphp=code 

> 
> * And, the existence of the function is not checked in advance.

If the existence of the function is checked in advance, the BC risk is worst, 
because they cannot have known whether the signature and semantics of the 
function you will introduce will be compatible with the one they have defined. 
In case of mismatch the eventual breakage could be more difficult to notice and 
trace back.

Note in particular this SO question: 
https://stackoverflow.com/questions/231057/how-to-round-ceil-floor-a-bcmath-number-in-php,
 where the second answer has a different rounding mode on halves than the first 
and third answers.

Fortunately, the few examples I have seen don’t foolishly guard the definition 
with `if (!function_exists(...))`, so that there will be a hard break when 
upgrading PHP (static error: function already defined), and they’ll have to 
decide explicitly what to do.

In my case, I’ll wait until this RFC is accepted, then (and only then) I’ll 
decide what to do depending on whether my version of `bcround()` is compatible 
with yours (either rename or `function_exists()` guard).

> 
> However, I do not think it is necessary to consider these matters.

I think that it is necessary to acknowledge that there will be breakage for 
some people, and to decide explicitly whether this breakage is acceptable. (I 
think it is.)

—Claude



Re: [PHP-DEV] Apply strict_types to internal functions

2023-08-29 Thread Claude Pache


> Le 29 août 2023 à 18:40, Hans Henrik Bergan  a écrit :
> 
> * I think most code actually using strict_types=1 is built with the
> assumption that internal functions use strict too, so it's entirely
> possible that the backwards-compatibility issue is so small that we
> can get away with internal functions just inheriting the userland
> strict_types
> 
> On Tue, 29 Aug 2023 at 18:36, Hans Henrik Bergan  wrote:
>> 
>> maybe we could do a
>> declare(internal_strict_types=1);
>> on a per-file basis just like the existing userland strict_types?
>> (name is up for bikeshedding ofc)
>> 
>> On Tue, 29 Aug 2023 at 17:49, Claude Pache  wrote:
>> [...]
> 


Hi Hans Henrik,

The rule of the mailing list is to post your answer below the text you are 
answering to, and to strip the parts of the original message that are not 
relevant to your answer. The aim is to make readers not to guess what you are 
responding to, and not to read backwards, thanks.

Furthermore, I can’t connect your answer to any of the points I made in the 
specific email you replied to, so that you may have replied to the wrong email.

—Claude

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



Re: [PHP-DEV] Apply strict_types to internal functions

2023-08-29 Thread Claude Pache



> Le 29 août 2023 à 15:19, Saki Takamachi  a écrit :
> 
>> Hi,
>> 
>> The larger issue is that higher-order functions do not inherit the 
>> `strict_types` mode from its calling code, and this is not specific to 
>> internal functions.
>> 
>> If you intend to change that for internal functions (with proper deprecation 
>> period, of course), you might consider making such a behaviour also possible 
>> for userland functions (probably using some opt-in); so that future 
>> higher-order internal functions do not become impossible to polyfill.
>> 
>> —Claude
> 
> Hi, thank you for confirming.
> 
> If you simply put the problem you pointed out in the code, would it be 
> something like this?
> https://gist.github.com/SakiTakamachi/8292dbfe92a2029a6c7b506b12296b7d
> 
> Admittedly, I don't think this is intuitive either.

That might not be intuitive to you, but it follows directly from the specified 
semantics: whether a function is called in `strict_types` mode or not, depends 
only on where the function is called. I personally doubt that there is an easy 
way to adjust the rule in order to make it both “intuitive” and simple.

> 
> [...]
> 
> When considering the inheritance of strict_types, I think that it should be 
> an attribute that can be set in “php.ini" instead of being specified for each 
> file.
> 
> What do you think?

Beware that there are many third-party packages that have not opted for 
`strict_types=1`; if you enable that mode globally, you might make those 
packages malfunction.

As I have just checked, among the packages I’ve installed via composer, there 
are more packages that do not use `strict_types=1`, than packages that use it. 
Among those that don’t use `strict_types`, the following ones are fairly common:

google/apiclient
league/oauth2-client
michelf/php-markdown
microsoft/microsoft-graph
phpmailer/phpmailer
phpoffice/phpspreadsheet
phpseclib/phpseclib

—Claude

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



Re: [PHP-DEV] Apply strict_types to internal functions

2023-08-29 Thread Claude Pache



> Le 29 août 2023 à 02:46, Saki Takamachi  a écrit :
> 
> Hello.
> 
> I’m Saki Takamachi.
> 
> Inspired by the issue below, I'm thinking of proposing this RFC.
> https://github.com/php/php-src/issues/12055
> 
> As the documentation below states, PHP's internal functions currently ignore 
> strict_types.
> https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict
> 
> I think the current spec is not intuitive,
> so I propose changing the behavior of the macro ZEND_ARG_USES_STRICT_TYPES() 
> to allow internal functions to accept strict_types.
> 
> I plan to make changes in zend_compile.h and zend_compile.c and do the 
> changes myself, I haven't written any tests yet, but I'm thinking about 
> making changes like this.
> https://github.com/SakiTakamachi/php-src/pull/1
> 
> As per How To Create an RFC, I will first try to gauge response to this 
> proposal on the mailing list.
> 
> Thank you
> 
> Saki Takamachi


Hi,

The larger issue is that higher-order functions do not inherit the 
`strict_types` mode from its calling code, and this is not specific to internal 
functions.

If you intend to change that for internal functions (with proper deprecation 
period, of course), you might consider making such a behaviour also possible 
for userland functions (probably using some opt-in); so that future 
higher-order internal functions do not become impossible to polyfill.

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



Re: [PHP-DEV] [RFC] Deprecate remains of string evaluated code assertions

2023-06-27 Thread Claude Pache


> Le 27 juin 2023 à 10:36, Claude Pache  a écrit :
> 
> 
> 
>> Le 26 juin 2023 à 17:06, G. P. B.  a écrit :
>> 
>> On Wed, 31 May 2023 at 13:08, G. P. B.  wrote:
>> 
>>> Hello internals,
>>> 
>>> I would like to start the discussion about deprecating various remains
>>> from the now removed string code evaluated assertions functionality of
>>> assert().
>>> 
>>> The RFC is located on the wiki at the following address:
>>> https://wiki.php.net/rfc/assert-string-eval-cleanup
>>> 
>>> Initially, this was part of the mass PHP 8.3 deprecation RFC, but only the
>>> assert_options() function was part of it.
>>> 
>> 
>> Head's up, I'm planning on opening the vote on this on Wednesday the 28th
>> of June.
>> 
>> Best regards,
>> 
>> George P. Banyard
> 
> Hi,
> 
> Still some points:
> 
> I don’t see the RFC listed under https://wiki.php.net/rfc#under_discussion.
> 
> The RFC is imprecise in what is meant by “deprecating”. I guess that a 
> deprecation notice (E_DEPRECATED) will be triggered at least under the 
> following conditions:
> 
> * at startup when one of the assert.* setting has not the default value;
> * at runtime when `assert_options(...)` is used;
> * at runtime when `ini_set(...)` is used to set an `assert.*` option to a 
> non-default value?
> 
> It is unclear to me what will happen when:
> 
> * `ini_set(...)` is used to set an `assert.*` option to its default value, 
> either as a no-op or not?
> 
> Moreover, by removing `assert.callback` (and other options), are you 
> effectively removing a feature? (I don’t really know, I have never considered 
> it even in my worst dreams.) If so, it should be noted in a “Backward 
> Incompatible Changes”.
> 
> —Claude
> 

... and, of course, changing the return value of `assert(...)` from `bool` 
(true) to `void` is also a BC break, (and it is unclear to me what is the 
effective advantage of the break).

—Claude





Re: [PHP-DEV] [RFC] Deprecate remains of string evaluated code assertions

2023-06-27 Thread Claude Pache


> Le 26 juin 2023 à 17:06, G. P. B.  a écrit :
> 
> On Wed, 31 May 2023 at 13:08, G. P. B.  wrote:
> 
>> Hello internals,
>> 
>> I would like to start the discussion about deprecating various remains
>> from the now removed string code evaluated assertions functionality of
>> assert().
>> 
>> The RFC is located on the wiki at the following address:
>> https://wiki.php.net/rfc/assert-string-eval-cleanup
>> 
>> Initially, this was part of the mass PHP 8.3 deprecation RFC, but only the
>> assert_options() function was part of it.
>> 
> 
> Head's up, I'm planning on opening the vote on this on Wednesday the 28th
> of June.
> 
> Best regards,
> 
> George P. Banyard

Hi,

Still some points:

I don’t see the RFC listed under https://wiki.php.net/rfc#under_discussion.

The RFC is imprecise in what is meant by “deprecating”. I guess that a 
deprecation notice (E_DEPRECATED) will be triggered at least under the 
following conditions:

* at startup when one of the assert.* setting has not the default value;
* at runtime when `assert_options(...)` is used;
* at runtime when `ini_set(...)` is used to set an `assert.*` option to a 
non-default value?

It is unclear to me what will happen when:

* `ini_set(...)` is used to set an `assert.*` option to its default value, 
either as a no-op or not?

Moreover, by removing `assert.callback` (and other options), are you 
effectively removing a feature? (I don’t really know, I have never considered 
it even in my worst dreams.) If so, it should be noted in a “Backward 
Incompatible Changes”.

—Claude






Re: [PHP-DEV] [RFC] Deprecate remains of string evaluated code assertions

2023-06-27 Thread Claude Pache


> Le 26 juin 2023 à 17:05, G. P. B.  a écrit :
> 
> On Wed, 31 May 2023 at 23:20, Claude Pache  <mailto:claude.pa...@gmail.com>> wrote:
>> Although your RFC says that the `zend.assertions` ini setting has superseded 
>> `assert.active` for a while, the “official” php.ini file still advises to 
>> modify the value of `assert.active` rather than the one of `zend.assertion` 
>> in order to switch behaviour at runtime:
>> 
>> https://github.com/php/php-src/blob/91fd5641cde138b8894a48c921929b6e4abd5c97/php.ini-development#L1604
>> 
>> I bet that many people (myself included) follows the advice given in 
>> `php.ini`.
> 
> This talks about run-time modification, which is something that I don't think 
> should be done in practice, nor is often done.

Although the specific comment in the php.ini file talks about runtime 
switching, it is in fact irrelevant whether it is set at runtime or not. More 
concretely; I use currently the settings:

* `zend.assertion=1` as set in the global php.ini;
* `assert.active = on` or `off` in my per-directory .user.ini or .htaccess 
file, depending on whether I want to enable assertions by default;
* optionally  `ini_set('assert.active', '1')` at runtime when I want to enable 
debug mode temporarily.

I have established the above settings several years ago (at the time of PHP 7), 
after having carefully read the documentation (and having been slightly 
confused by the redundancy between `assert.active` and `zend.assertion`). I 
might have end up to switch between `zend.assertion = 0/1` instead of switching 
between `assert.active = on/off` instead; I can’t say exactly why I chose the 
former option instead of the latter, but I guess that both the comment in the 
`php.ini` file, and the existence of `assert_options(ASSERT_ACTIVE, ...)` as an 
alternative to `ini_set('assert.active', ...)`, have influenced my choice.

Note also that the above settings minus `zend.assertion` was the way to do it 
in PHP 5 (again it is irrelevant whether it is at runtime or not), and many 
people that used assertions in PHP 5 may have continued to use that way without 
modification, as there is currently no strong reason to change (only 
`zend.assertions=-1` is relevant if you are especially concerned about 
micro-optimisation).

Now, of course, people will adapt to the new settings. But given the confusing 
state of the options (both `zend.assertion` and `assert.active` must be 
enabled, and I am not even speaking about `assert.exception`), you ought to be 
super-clear (in the deprecation notice, in the php.ini file, in the docs), what 
is the the expected state: paradoxically leave `assert.active` and 
`assert.exceptions` enabled (the default value) even when you want to disable 
assertions, and playing exclusively with `zend.assertion`.

—Claude



Re: [PHP-DEV] [RFC] Deprecate remains of string evaluated code assertions

2023-05-31 Thread Claude Pache


> Le 1 juin 2023 à 00:20, Claude Pache  a écrit :
> 
> Another point: Your RFC is missing `assert.quiet_eval`...
> 

(In fact, it is probable that the `assert.quiet_eval` ini setting and the 
ASSERT_QUIET_EVAL constant have been removed in PHP 8, but that the 
documentation has not been updated.)

—Claude

Re: [PHP-DEV] [RFC] Deprecate remains of string evaluated code assertions

2023-05-31 Thread Claude Pache


> Le 31 mai 2023 à 14:08, G. P. B.  a écrit :
> 
> Hello internals,
> 
> I would like to start the discussion about deprecating various remains from
> the now removed string code evaluated assertions functionality of assert().
> 
> The RFC is located on the wiki at the following address:
> https://wiki.php.net/rfc/assert-string-eval-cleanup
> 
> Initially, this was part of the mass PHP 8.3 deprecation RFC, but only the
> assert_options() function was part of it.
> 
> Best regards,
> 
> George P. Banyard

Hi,

Although your RFC says that the `zend.assertions` ini setting has superseded 
`assert.active` for a while, the “official” php.ini file still advises to 
modify the value of `assert.active` rather than the one of `zend.assertion` in 
order to switch behaviour at runtime:

https://github.com/php/php-src/blob/91fd5641cde138b8894a48c921929b6e4abd5c97/php.ini-development#L1604

I bet that many people (myself included) follows the advice given in `php.ini`.

Another point: Your RFC is missing `assert.quiet_eval`...
  
—Claude

Re: [PHP-DEV] [RFC] [Discussion] Deprecate functions with overloaded signatures

2023-05-30 Thread Claude Pache
Hi Máté,

> Le 30 mai 2023 à 01:41, Máté Kocsis  a écrit :
> 
> Hi Claude,
> 
>> The replacement methods for IntlCalendar::set() (namely 
>> IntlCalendar::setDate() and IntlCalendar::setDateTime()) must not have a 
>> return type of `void`, but `true`, like the original method, for the two 
>> following reasons:
>> 
>> 1. By changing the returned value, you are introducing an unnecessary hazard 
>> when migrating code.
>> 
>> 2. Per https://www.php.net/IntlCalendar, all modification methods of that 
>> class (clear(), roll(), setTime(), etc.) consistently return `true` on 
>> success and `false` on failure, even when the method is infallible (and thus 
>> would always return `true`). Don’t break consistency.
> 
> 1.  I don't see much risk with this change, since we clearly indicate at the 
> very beginning that the new methods return void, so programmers migrating 
> their code
> should pay attention to the return types. IDEs and static analysers can 
> surely warn them in case of inattention.

The very risk is that the programmer must be aware that the return convention 
has changed. Recall that not everyone run static analysers, especially for such 
a trivial migration, and that not every code is statically analysable (e.g.. 
`$foo->$bar()`).

Of course, the benefice of the change might be worth the risk; but that leads 
to the second point:

> 
> 2. Some of the methods you mentioned have a "true" return type for a few 
> weeks now. The biggest motivation for introducing these was to at least have 
> some chance to
> make them void in the future. Doing so is a risky move indeed, so should be 
> carried out very carefully, if it's possible at all... That's why I consider 
> it beneficial to spare the
> effort and start with a clean slate by adding the new methods in question 
> with their correct return type.

Concretely, if you change the return value (from `true` to `void/null`), you 
will break the following pattern:

setBar(...)) {
// error handling (might be dead code, it doesn’t matter)
}
?>

Any change that introduce a BC break or a migration burden must be justified. 
(There has been enough rant around justified BC breaks, so let’s not introduce 
unjustified ones.)

What is the purpose of changing the return convention of IntlCalendar methods, 
and is it worth?

—Claude



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-29 Thread Claude Pache



> Le 8 mai 2023 à 23:38, Larry Garfield  a écrit :
> 
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's been a while in coming, and we've evolved the design quite a bit just in 
> the last week so if you saw an earlier draft of it in the past few months, I 
> would encourage you to read it over again to make sure we're all on the same 
> page.  I'm actually pretty happy with where it ended up, even if it's not the 
> original design.  This approach eliminates several hard-to-implement edge 
> cases while still providing a lot of functionality in one package.
> 
> https://wiki.php.net/rfc/property-hooks
> 

Hi,

If I understand correctly, given:

 $field;
set => $field = $value;
}

public float $someFloatWithHook {
get => $field;
set => $field = $value;
}

}
?>

we have:

someInt = 42.0); // int(42)
var_dump($obj->someFloat = 42); // float(42)
?>

but:

someIntWithHook = 42.0); // float(42)
var_dump($obj->someFloatWithHook = 42); // int(42)
?>

If I am correct, it means that the “This also implies that adding a set hook to 
a property cannot change the result of the = operator” statement is a bit too 
optimistic.


—Claude

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



Re: [PHP-DEV] RFC [Discussion]: Marking overridden methods (#[\Override])

2023-05-29 Thread Claude Pache



> Le 11 mai 2023 à 18:37, Tim Düsterhus  a écrit :
> 
> Hi
> 
> I'm now opening discussion for the RFC "Marking overridden methods 
> (#[\Override])":
> 
> 
> 
> RFC: Marking overridden methods (#[\Override])
> https://wiki.php.net/rfc/marking_overriden_methods
> 

Hi Tim,

One weakness of the proposal, is that there is no notice when a method without 
#[\Override] annotation accidentally overrides a parent method. This is 
necessary for the sake of BC, of course. Therefore, (inspired by the 
--noImplicitOverride flag of TypeScript), I suggest adding a complementary 
#[\NoImplicitOverride] annotation on the derived class, that makes #[\Override] 
mandatory on overriding methods. The following example would then trigger a 
compilation error since Laravel 5.4:

message = Http::get($this->url);
$this->save();
  }
}

?>

―Claude

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



Re: [PHP-DEV] [RFC] [Discussion] Deprecate functions with overloaded signatures

2023-05-29 Thread Claude Pache


> Le 27 avr. 2023 à 23:28, Máté Kocsis  a écrit :
> 
> Hi Internals,
> 
> As you have possibly already experienced, overloaded signatures cause
> various smaller and bigger issues, while the concept is not natively
> supported by PHP. That's why I drafted an RFC which intends to phase out
> the majority of overloaded function/method signatures and also forbid
> the introduction of such functions in the future:
> https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures
> 
> 

Hi Máté,

The replacement methods for IntlCalendar::set() (namely IntlCalendar::setDate() 
and IntlCalendar::setDateTime()) must not have a return type of `void`, but 
`true`, like the original method, for the two following reasons:

1. By changing the returned value, you are introducing an unnecessary hazard 
when migrating code.

2. Per https://www.php.net/IntlCalendar, all modification methods of that class 
(clear(), roll(), setTime(), etc.) consistently return `true` on success and 
`false` on failure, even when the method is infallible (and thus would always 
return `true`). Don’t break consistency.

—Claude




Re: [PHP-DEV] Proposal: magic constant '::name' for properties and methods etc. like '::class' is for classes/object

2023-05-12 Thread Claude Pache


> Le 12 mai 2023 à 19:29, Lydia de Jongh  a écrit :
> 
> Hi,
> 
> Lately I made a small object initializer/builder with php Attributes.
> 
> 'Directly' accessing properties and methods of the class as a parameter in
> an Attribute is not really possible.
> You can do that for a class with: \path\to\MyClass::class, but for
> properties or methods you have to use strings, without recognition in
> editors.
> 
> It would be so nice if more items in php could be accessed with a magic
> constant as you can do with ::class.
> With magic constant an editor could recognize it and it limits typos etc.
> and it provides the developer with a list of the properties/methods in
> scope.
> 
> At the moment I implemented a kind of workaround by providing simple
> classes with the property names in class constants.
> Or add an extra property to a class with a property name that can be used
> in an attribute.
> 
> I will try to explain with examples of my code.
> 
> abstract class SaveFactoryAbstract {
> use ObjectBuilderTrait;
> 
> #[ResetValue]
> protected bool $isSaved = false;
> 
> #[InitObject] // tells the builder to initialize this property with the
> latest specs provided by (other) attributes
> #[ResetObject]
> protected ?SaveInterface $oSave = null;
> 
> public function __construct(){
> $this->buildMe(); // provided by the trait
> }
> }
> 
> 
> This is straightforward. Until you extend this class and want to set the
> class for $oSave.
> The other developer does not know which properties he can declare with an
> attribute
> 
> #[UseClass('oSave', ImageSave::class)]
> #[ResetValue('isSaved', default: true)]
> class ImageSaveFactory extends SaveFactoryAbstract { }
> 
> 
> As workaround I make classes like:
> 
> class oop { // lower character on purpose, for this is not a normal class
> 
> final public const isSaved = 'isSaved';
> 
> final public const Save = 'oSave';
> final private function __construct() {}
> }
> 
> So the extending class can be:
> This is recognized by the editor and gives the developer some clues.
> #[UseClass(oop::Save, ImageSave::class)]
> #[ResetValue(oop::isSaved, default: true)]
> class ImageSaveFactory extends SaveFactoryAbstract { }
> 
> But this is really annoying.
> 
> 
> It would be much better if we could do something like:
> #[UseClass(static::$oSave::name, ImageSave::class)] // 'static::' can be
> used, since the attribute belong to the scope of this class
> #[ResetValue(static::$isSaved::name, default: true)]
> class ImageSaveFactory extends SaveFactoryAbstract {
> }
> 
> This could also extend possibilities with/for variable variables
> Like:
> $this->myProp::name
> myClass::$staticProp::name
> 
> 
> A potential difficulty is: how to access normal properties/methods
> Maybe just as if they are static?
> Like parent::normalMethod() is working
> A normal property or method cannot have the same name as its static partner
> (sadly) so internally I hope it is not a problem.
> 
> outside scope:
> myClass::$staticProperty::name
> myClass::$normalProperty::name
> myClass::normalMethod::name
> 
> inside scope:
> static::$normalProperty::name
> self::$normalProperty::name // I do not know if 'self::' adds anything for
> this purpose, except for private properties/methods maybe
> 
> inside class/object:
> $this->normalProperty::name
> $this->normalMethod::name
> $this::$staticProperty::name
> I hope you like the idea! Greetz, Lydia


Hi,

That looks like the `nameof` operator proposed a few days ago?

https://externals.io/message/120173
https://externals.io/message/120173


—Claude




Re: [PHP-DEV] Proposal: native decimal scalar type support

2023-04-27 Thread Claude Pache


> Le 27 avr. 2023 à 00:03, Rowan Tommins  a écrit :
> 
>> 
>> In PHP8, passing float values
>> to BCMath may lead to issues due to type mismatch which is a
>> mind-blowing counter-intuitive issue.
> 
> Far from counter-intuitive, that's an essential feature of any decimal 
> implementation - as soon as the value is in a floating point variable, it's 
> *already too late* to make it a fixed-precision decimal.
> 
> The php-decimal homepage at http://php-decimal.io/#basic-usage makes this 
> very clear:
> 
> > Special float values are also supported (NAN, INF and -INF), but float is 
> > otherwise not a valid argument in order to avoid accidentially using a 
> > float. If you absolutely must use a float to construct a decimal you can 
> > cast it to a string first, but doing so if affected by the precision INI 
> > setting.
> >
> > Projects using this extension should avoid float entirely, wherever 
> > possible. An example workflow is to store values as DECIMAL in the 
> > database, query them as string, parse to Decimal, perform calculations, and 
> > finally prepare for the database using toFixed.

This is the the description of the PHP Decimal extension, which does indeed the 
Right Thing. But BCMath (which is not PHP Decimal) does have “mind-blowing 
counter-intuitive” issues (at least in `strict_types=0` mode) with floats. 
Formally, the root of the issue is in PHP type juggling, not in bcmath itself; 
but from a user perspective, it doesn’t matter. Specifically, passing a float 
to the bc*() functions will “work” most of the time; but in rare cases, when 
PHP decides to use the scientific notation while casting it as string, it will 
fail with an “argument is not well-formed” error, which is puzzling for the 
unprepared user.

—Claude

Re: [PHP-DEV] Final anonymous classes

2023-04-25 Thread Claude Pache



> Le 25 avr. 2023 à 15:46, Nicolas Grekas  a 
> écrit :
> 
> 
> Because they conceptually don't create a new type, I wonder if (final)
> anonymous classes could be allowed to extend final classes? In order to not
> allow hacking around and still create a type with class_alias(), we should
> forbid aliasing final anonymous classes IMHO. Then we could have this
> discussion about allowing finally anonymous classes to extend final
> classes. That'd be really useful in many situations where "final" is
> preventing end users from achieving what they want.


That would violate the very definition of `final`, which may be interpreted as 
“final implementation” as much as “final type”?

If your goal is to have a proxy, I wonder whether it would be more appropriate 
to design a proper way to define a proxy around an existing object, rather than 
hacking around class inheritance?


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



Re: [PHP-DEV] Final anonymous classes

2023-04-24 Thread Claude Pache


> Le 24 avr. 2023 à 12:28, Daniil Gentili  a écrit :
> 
> Hi all,
> 
> I've submitted https://github.com/php/php-src/pull/11126 to add support for 
> final anonymous classes, though as noted by iluuu1994, it would probably make 
> more sense to just make all anonymous classes final by default, what do you 
> think?
> 
> Daniil Gentili.
> 

Hi,

Extending an anonymous class is indeed possible (https://3v4l.org/pDFTL), but 
it is a hack as best. If someone wants a non-final class, could they not write 
a non-anonymous one? As a bonus, they wouldn’t need to instantiate the class 
before referencing it.

—Claude



Re: [PHP-DEV] Moving PHP internals to GitHub

2023-04-12 Thread Claude Pache
Hi ,

You made some good points, but please, avoid including statements that are 
plainly false: it lessens your arguments. I am specifically thinking of:

> - having to subscribe to a mailing list to even see the discussions

Have you never heard about externals.io ?

> - having to learn the specific, uncommon rules of replying: bottom posting, 
> ...

Quoting relevant portion of previous messages and posting below them, is also a 
convention I’ve observed on other platforms, including github.

> ... word wrapping, ...

Really? I always thought that email clients are able to automatically wrap text 
in incoming messages. At least, I never manually wrap text when writing emails, 
and I have never received any complain that my emails are unreadable, If you 
have an issue with my reply, please complain.

> Also popular emailing clients don't do any of that automatically, making
> each reply tedious.

Maybe *some* popular emailing clients make it difficult... Those that I have 
used so far (which are decently popular) have never had problems.

Now to the point:

> What are your thoughts?

I prefer the mailing list for various reasons already mentioned by others 
(which I won’t repeat).

—Claude



Re: [PHP-DEV] [RFC] New core autoloading mechanism with support for function autoloading

2023-04-12 Thread Claude Pache


> Le 10 avr. 2023 à 14:17, G. P. B.  a écrit :
> 
> Hello Internals,
> 
> Dan and I would like to propose a new core autoloading mechanism that fixes
> some minor design issues with the current class autoloading mechanism and
> introduce a brand-new function autoloading mechanism:
> https://wiki.php.net/rfc/core-autoloading
> 

Hi,

1. The proposed modification of `function_exists()` will break existing code:



as soon as a `bar()` function is defined in global scope, with no obvious hint 
why it suddenly broke. You should either (from my increasing order of 
preference):

* acknowledge it in the “Backward Incompatible Changes” section;

*  default the $autoload extra parameter to `false`;

* keep the current semantics, that using a namespaced or qualified function 
name, (including a function name given as string, which is implicitly fully 
qualified), doesn’t fall back to the global scope, — even when a previous use 
of the same function name did trigger the fall back, see: 
https://3v4l.org/mnVWO (Independently of any mechanism introduced to avoid to 
repeatedly trigger the function autoloader.)


2. If you add function autoloading, you ought to support constant autoloading 
as well, of course.

—Claude

Re: [PHP-DEV] Steal labelled break and continue from zig?

2023-02-28 Thread Claude Pache



> Le 27 févr. 2023 à 23:36, Karoly Negyesi  a écrit :
> 
> Hello,
> 
> As I was reading https://kristoff.it/blog/zig-multi-sequence-for-loops/ I
> found a very nice trick which in PHP would be:
> 
> foo: while ($i--) {
>  if ($ % 2) break foo;
> }
> 
> What do you think?
> 

Yes, I use sometimes this feature in JavaScript (which allows to “break” any 
labelled block, not just loops).

That said, it is somewhat less needed, since we have `goto` in PHP. But it 
would be nevertheless welcome. (I won’t go as far as deprecating  `break 3;`, 
although I tend to avoid such code.)

> Le 28 févr. 2023 à 08:45, naitsi...@e.mail.de a écrit :
> 
> Unfortunately goto does not have a good image ;-)
> 


The bad reputation of `goto` is  indeed harmful. I heavily use `goto` in PHP 
because I like structured programming. :-)

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



Re: [PHP-DEV] [RFC] [Discussion] Typed class constants

2023-02-26 Thread Claude Pache


> Le 23 févr. 2023 à 16:51, Máté Kocsis  a écrit :
> 
> As the RFC text is now finalized, I intend to start the vote on Monday.
> 
> Regards,
> Máté

Hi Máté,

I’ve just read the new version of the RFC. It seems ok to me. Just a small 
remark:

Although they are not explicitly mentioned, I assume that typed constants are 
also available on traits?

—Claude 



Re: [PHP-DEV] [RFC] [Discussion] Typed class constants

2023-02-17 Thread Claude Pache
Hi Máté,

I think you didn’t understand me, so I’ll restate:

> To be exact, defining class constants with the class itself as value is 
> already impossible: https://3v4l.org/J7C30

No, for some specific sort of class, namely for enum, it is absolutely possible 
to define a constant with an  effective type of `self`: https://3v4l.org/r8Jo3

```php
enum A {
case foo;
const bar = self::foo;
}

var_dump(A::bar instanceof A); // true
```

—Claude 

Re: [PHP-DEV] 'Uninitialized' creates a lot of cluttering

2023-02-13 Thread Claude Pache



> Le 13 févr. 2023 à 13:12, Robert Landers  a écrit :
> 
> I hope we can all agree that `null` is the absence of a value. Now we
> currently have two different meanings of "absence of a value" which is
> super annoying sometimes.
> 

Although `null` is often used with that semantics in mind, from a technical 
point of view, it is definitely not the same thing as “absence of a value”. For 
example:

```php
function dump_answer($answer = 42) {
var_dump($answer);
}

// null
dump_answer(null); // NULL

// absence of value
dump_answer(); // int(42)

```

Or:

```php
$a = [ 'foo' => null ];

// has value `null`
var_dump(array_key_exists('foo', $a)); // true

// is absent
var_dump(array_key_exists('bar', $a)); // false
```

—Claude

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



Re: [PHP-DEV] [RFC] [Discussion] Typed class constants

2023-02-03 Thread Claude Pache


> Le 31 janv. 2023 à 22:01, Máté Kocsis  a écrit :
> 
> 
> Please find the updated RFC here:
> https://wiki.php.net/rfc/typed_class_constants.
> 
> Regards,
> Máté


Hi,

The RFC states that it is technically not possible to have a constant of 
effective type `static` or `self`. While this is probably correct for regular 
classes, this is not true for enums. The following code ostensibly works 
(https://3v4l.org/84W92):

```php
enum qux {
const foo_alias = self::foo;
case foo;
}

var_dump(qux::foo_alias); // enum(qux::foo)
```

I think that `self` should be allowed here, because it is meaningful.

—Claude

Re: [PHP-DEV] [RFC] [Discussion] Readonly class amendments

2023-01-19 Thread Claude Pache


> Le 19 janv. 2023 à 10:12, Claude Pache  a écrit :
> 
> 
> 
>> Le 19 janv. 2023 à 09:01, Máté Kocsis  a écrit :
>> 
>> Hi Everyone,
>> 
>> As discussion apparently stalled, and since we managed to update the RFC
>> with the recently brought up arguments, we would like to start the vote
>> soon, possibly early next week, unless someone finds a new topic to discuss.
>> 
>> Máté
>> 
> 
> Hi,
> 
> One shortcoming around readonly classes that I just figured out, is that it 
> is not possible to use them as anonymous class:
> 
> ```php
> $c = new readonly class { }; // parse error
> ```
> 
> While it does not makes sense to have `abstract` and it is not useful to have 
> `final` in this position, on the other hand, it is perfectly reasonable to 
> have readonly here. (This is especially problematic in case we keep the 
> limitation that only readonly classes may extend readonly classes, because in 
> that case, an anonymous class could not extend a readonly class. However, 
> this is an orthogonal concern.)
> 
> —Claude

As I think that this limitation is most probably a bug and not a deliberate 
decision (the RFC introducing readonly classes did not mention restrictions 
around anonymous classes), I have open a bug report: 
https://github.com/php/php-src/issues/10377

—Claude



Re: [PHP-DEV] [RFC] [Discussion] Readonly class amendments

2023-01-19 Thread Claude Pache



> Le 19 janv. 2023 à 09:01, Máté Kocsis  a écrit :
> 
> Hi Everyone,
> 
> As discussion apparently stalled, and since we managed to update the RFC
> with the recently brought up arguments, we would like to start the vote
> soon, possibly early next week, unless someone finds a new topic to discuss.
> 
> Máté
> 

Hi,

One shortcoming around readonly classes that I just figured out, is that it is 
not possible to use them as anonymous class:

```php
$c = new readonly class { }; // parse error
```

While it does not makes sense to have `abstract` and it is not useful to have 
`final` in this position, on the other hand, it is perfectly reasonable to have 
readonly here. (This is especially problematic in case we keep the limitation 
that only readonly classes may extend readonly classes, because in that case, 
an anonymous class could not extend a readonly class. However, this is an 
orthogonal concern.)

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



Re: [PHP-DEV] [RFC] Path to Saner Increment/Decrement operators

2023-01-18 Thread Claude Pache


> Le 18 janv. 2023 à 19:33, Alex Wells  a écrit :
> 
> Classes and methods is the expected way of implementing standard library in 
> an OO language. New APIs (such as the new Random api) use OO instead of 
> functions and it makes more sense to use OO in this case too: there's likely 
> a place for other methods too, like toBase(int $otherBase) etc. It would also 
> be possible to use overloaded operators if needed.

Fortunately, PHP is not (yet) a language where every problem requires the use 
and manipulation of objects implementing a generalised and unified solution. I 
guess that the OO way of writing:

```php
function next_alpha_id(): string {
static $x = 'zz';
return ++$x;
}

function next_num_id(): int {
static $x = 0;
return ++$x;
}

$my_id = next_alpha_id();
$my_other_id = next_num_id();
```

would resemble to the following, except that `mixed` should be replaced by the 
use of generics. For brevity, I left the mandatory interfaces as exercise to 
the reader.

```php
class IdGenerator {

protected mixed $current;

public function __construct(
protected readonly IdGeneratorType $type
  , protected readonly IdGeneratorDirection $direction
  , mixed $start
) {
$this->current = $start;
}

public function next(): mixed {
// implementation...
}

}

enum IdGeneratorType {
case alphabetic;
case numeric;
}

enum IdGeneratorDirection {
case positive;
case negative;
}



final class StandardGlobalAlphabeticIdGenerator {

private static IdGenerator $id_generator;

public static function get(): IdGenerator {
return self::$id_generator ?? new IdGenerator(
type: IdGeneratorType::alphabetic
  , direction: IdGeneratorDirection::positive
  , start: 'aaa'
);
}

}

final class StandardGlobalNumericIdGenerator {

private static IdGenerator $id_generator;

public static function get(): IdGenerator {
return self::$id_generator ?? new IdGenerator(
type: IdGeneratorType::numeric
  , direction: IdGeneratorDirection::positive
  , start: 1
);
}

}


$my_id = StandardGlobalAlphabeticIdGenerator::get()->next();
$my_other_id = StandardGlobalNumericIdGenerator::get()->next();
```

—Claude



Re: [PHP-DEV] [RFC] Path to Saner Increment/Decrement operators

2023-01-18 Thread Claude Pache


> Le 18 janv. 2023 à 18:27, Kamil Tekiela  a écrit :
> 
> Strings should not be incrementable unless they are numeric strings. The
> current "feature" is more like a bug from xkcd comic. https://xkcd.com/1172/
> 
> But as there is a real need for a similar functionality, for example when
> working with Excel, I would propose to add a class into the language that
> is able to calculate and iterate any bijective base system. It needs to
> have a clear functional spec and should support both increment/decrement
> operators as well as iterators. I see this as the only way out of this
> mess. This RFC needs to pass, but it cannot pass without an alternative for
> people who actually use this "feature".

For those that lack imagination about possible use cases, here is mine: 
generating unique (in the scope of the request) alphabetic ids:

function nextid(): string {
static $id = 'zz';
return ++$id;
}

But no over-engineering please: no class and no decrement equivalent (the 
latter could be added in a separate RFC if it is really deemed useful), just a 
plain function that replicate the current behaviour for strings of the form 
/^[A-Za-z0-9]*$/, minus the bugs around the peculiar notion of “numeric string” 
(e.g., "9E1" equivalent to 90).

—Claude

Re: [PHP-DEV] [RFC] Path to Saner Increment/Decrement operators

2023-01-18 Thread Claude Pache



> Le 17 janv. 2023 à 15:28, G. P. B.  a écrit :
> 
> Hello Internals,
> 
> I would like to start the discussion on the Path to Saner
> Increment/Decrement operators RFC:
> https://wiki.php.net/rfc/saner-inc-dec-operators

Hi,

Adding a `str_increment(...)` function that roughly replicates the current 
behaviour of `++$x` for non-numeric strings, is necessary and sufficient in 
order to have a simple and clear path forward for those that use the feature, 
thanks. (On the other hand, a `str_decrement(...)` equivalent is not useful for 
the scope of this RFC.)

—Claude

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



Re: [PHP-DEV] [RFC] Add SameSite cookie attribute parameter

2023-01-18 Thread Claude Pache


> Le 18 janv. 2023 à 16:20, Derick Rethans  a écrit :
> 
> if (version_compare(phpversion(), "8.4.0", ">")) {
>   setcookie("test", "value", samesite: SameSite::Stricter);
> } else {
>   setcookie("test", "value", samesite: SameSite::Strict);
> }

Or even, replace `version_compare(...)` with `SameSite::tryFrom(...) !== null`:

setcookie("test", "value", samesite: SameSite::tryFrom('Stricter') ?? 
SameSite::Strict);

—Claude

Re: [PHP-DEV] [RFC] Add SameSite cookie attribute parameter

2023-01-15 Thread Claude Pache



> Le 14 janv. 2023 à 16:14, G. P. B.  a écrit :
> 
> Hello Internals,
> 
> I would like to start the discussion about the Add SameSite cookie
> attribute parameter RFC:
> https://wiki.php.net/rfc/same-site-parameter
> 
> This proposes to add an optional same site parameter to the setrawcooki(),
> setcookie() and session_set_cookie_params() that takes a a value a new
> SameSite enum:
> 
> enum SameSite {
>case None;
>case Lax;
>case Strict;}
> 
> 
> Best regards,
> 
> George P. Banyard

Hi,

Some technical remarks:
* The new parameter name should be `$samesite` (all lowercase), in order to 
match with the casing of the corresponding key in `$options`.
* I think that you should add the case `SameSite::Omit` (which is the current 
default). This is not only for BC, but also for FC if, for some reason, 
`SameSite: Lax` is replaced by some attribute that supersedes it. Or if 
`SameSite: Lax` becomes the default, and therefore redundant. — Having 
`SameSite::Omit` instead of `null` would mean that it would be difficult to 
miss it by accident.

That said, I am much more interested in being able to add custom cookie 
attributes. Back when SameSite was introduced (on the web, not in PHP), I 
recall that I had to use some hack in order to include them in my session 
cookie (before upgrading to PHP 7.3). The new cookie attributes mentioned by 
Nicolas in the other mail are probably too experimental in order to support 
them officially, but it could be interesting to be able to include them 
nonetheless, e.g. using some `customAttributes` parameter.

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



Re: [PHP-DEV] Methods which auto-return the class instance

2022-12-23 Thread Claude Pache


> Le 23 déc. 2022 à 13:46, joke2k  a écrit :
> 
> On Fri, 23 Dec 2022, 09:33 Claude Pache,  <mailto:claude.pa...@gmail.com>> wrote:
>> It is very common for fluent class methods to have a verbose `return
>> $this;` ending in their body.
>> But If you have declared `self` as return type into a non-static class
>> method you have only two options to return:
>> 
>> - the $this object
>> - another instance of the same class or subclass
>> 
>> ... in order to avoid a return type error.
> 
> It is still two options, and it is not clear in general which one to pick. 
> You could also say that, if you have `object` as return type, there are two 
> options to avoid a return type error: either return the `$this` object, or 
> return another object.
> 
> Yes but declaring `self` is more strict than `object`. 
> And talking about the word itself... Declaring to return (your-)`self` but 
> you could return someone-else of the same type as you. 
> But it is ok, it refers to the class name not the instance. just semantic.
> 


It is not about being less or more restricted, it is about being plainly 
ambiguous.

```php
class Point {

public function __construct(
protected float $x
  , protected float $y
) { }

public function withY(float $y): static {
$newPoint = clone $this;
$newPoint->y = $y;
// oops, forgot “return $newPoint;”
}
}
```

With implicit behaviours (at least when there is more than one option), such 
sort of bugs become less apparent at runtime. Therefore, implicit behaviour 
ought to be avoided if possible.

—Claude



Re: [PHP-DEV] Methods which auto-return the class instance

2022-12-23 Thread Claude Pache

> Le 23 déc. 2022 à 01:08, joke2k  a écrit :
> 
> Hi folks,
> 
> What do you think about having a method which returns the class instance
> `$this` by default only IF its return type is set as `self`?
> 
> It is very common for fluent class methods to have a verbose `return
> $this;` ending in their body.
> But If you have declared `self` as return type into a non-static class
> method you have only two options to return:
> 
> - the $this object
> - another instance of the same class or subclass
> 
> ... in order to avoid a return type error.

It is still two options, and it is not clear in general which one to pick. You 
could also say that, if you have `object` as return type, there are two options 
to avoid a return type error: either return the `$this` object, or return 
another object.

> 
> My proposal is to set the instruction `return $this;` as optional for
> non-static class methods with `self` declared as return type.


I’d rather have a syntax saying explicitly that you want to return $this, 
rather than letting the interpreter guess what you meant. The obvious one is:

```php
public function hit(): $this { $this->counter++; }
```

Here, there is only one possible return value, and therefore the `return` 
instruction might be reasonably omitted.

The real question is: Is it worth to add special cases for some specific return 
values?

—Claude

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-13 Thread Claude Pache


> Le 13 déc. 2022 à 16:34, Claude Pache  a écrit :
> 
> 
> Hi,
> 
> As of today, the following declarations are rejected as syntax errors:
> 
> ```php
> class C {
> $a;
> int $b;
> }
> ```
> 
> while the following declarations are accepted with implicit `public` 
> visibility:
> 
> ```php
> class C {
> static $c;
> readonly int $d;
> }
> ```
> 
> It would be reasonable to propose to allow to consistently omit the `public` 
> keyword. But allowing to omit it in some cases (including the most 
> controversial one: `protected(set)`) and not in other cases...? Because of 
> this inconsistency, people are incited to always write explicitly `public` 
> anyway.
> 
> —Claude


However, I’m just realising that omitting `public` in declarations like `public 
$a` and `public int $b` is probably not a good idea, because it is incompatible 
with constructor property promotion, as `function __construct(public int $b) { 
}`, and `function __construct(int $b) { }` have different meanings.

—Claude



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-13 Thread Claude Pache


> Le 11 déc. 2022 à 20:18, Larry Garfield  a écrit :
> 
> On Thu, Dec 1, 2022, at 12:31 PM, Tim Düsterhus wrote:
>> Hi
>> 
>> On 11/29/22 21:29, Larry Garfield wrote:
>>> Thank you everyone for the feedback.  Based on this thread, we've made two 
>>> changes to the RFC:
>>> 
>>> 1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
>>> section to Future Scope where we really should sort this out in the future, 
>>> but we'll do that in the future when we can all focus on the various 
>>> nuances of just that piece.
>>> 
>>> 2. I rewrote the section on __set to make it clearer.  That also included 
>>> Ilija and I digging into all the nuances that are already present.  The 
>>> text may still look a bit complex, but that's because the existing logic is 
>>> already complex with readonly.  Long story short, the a-viz RFC does not 
>>> change anything in the way __set works vis a vis asymmetric visibility; it 
>>> just inherits and continues what readonly already started, so it's 
>>> consistent.
>>> 
>>> The PR should be updated in the next week or two with the latest changes.  
>>> Baring any major need for change, we expect to call a vote for it shortly 
>>> after New Years.
>>> 
>> 
>> Okay, then I'd like to officially "request" that the abbreviated form 
>> [1] is dropped:
>> 
>> I believe 'protected(set) string $foo' is easily confused with 
>> 'protected string $foo' at a simple glance.
>> 
>> Also any implicit rules are something developers will need to learn by 
>> heart, whereas an explicit 'public protected(set) string $foo' could 
>> reasonably be understood by someone without any PHP experience and some 
>> basic experience of OO concepts.
>> 
>> Having two separate explicit keywords also makes it much clearer that 
>> asymmetric visibility is involved, because it's also asymmetric in the code.
>> 
>> I believe the only benefit of the abbreviated form is saving 6 
>> keystrokes (+ one hit to the spacebar) and I don't believe it's worth 
>> the lack of clarity for an important property of the defined property.
>> 
>> Best regards
>> Tim Düsterhus
>> 
>> [1] https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form
> 
> 
> Does anyone else have feelings on this point?  IMO, the shorthand makes a lot 
> of sense when used with readonly to avoid lines getting just annoyingly long, 
> but without it I can see the argument for not allowing it; it's about a wash 
> in terms of length with readonly today.  I'm comfortable going with the 
> consensus on this one for now.
> 
> --Larry Garfield

Hi,

As of today, the following declarations are rejected as syntax errors:

``php
class C {
$a;
int $b;
}
```

while the following declarations are accepted with implicit `public` visibility:

``php
class C {
static $c;
readonly int $d;
}
```

It would be reasonable to propose to allow to consistently omit the `public` 
keyword. But allowing to omit it in some cases (including the most 
controversial one: `protected(set)`) and not in other cases...? Because of this 
inconsistency, people are incited to always write explicitly `public` anyway.

—Claude




Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-05 Thread Claude Pache


> Le 3 déc. 2022 à 19:28, Larry Garfield  a écrit :
> 
> I also clarified that static properties are explicitly not supported with 
> a-viz.  

This is a serious issue, not necessarily because it is of great value, but 
because it introduces an unexpected asymmetry between static and non-static 
properties. In other words, from a user point-of-view, it is expected that 
staticness is orthogonal to visibility.

Therefore, I would expect that the RFC has a dedicated section about static 
properties (as it has already one about [un]typed properties), not just a small 
sentence in the intro that could be overlooked.


> and as it's of limited value we're not going to bother.

Whether it’s of limited value or not, depends, I suppose, of coding style. 
Personally, I use static properties for various good and bad reasons, and some 
of them would be happy to take advantage of asymmetric visibility. E.g.:

* I may store settings that concern the whole class (and that I cannot or want 
not register as constants) in static properties;

* My typical implementation of “monostate pattern” is not: 
`Foo::getInstance()->bar()`, `Foo::getInstance()->baz`, but: `Foo::bar()`, 
`Foo::$baz`;

* ...

Of course, I would accept the reason “it is difficult to implement”, but not 
the excuse “it is almost worthless”.


—Claude

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Claude Pache
Hi,

What is the behaviour of the following code?

```php
class Foo {
public private(set) array $bar = [ ];
}

$foo = new Foo;

$foo->bar['x'] = 'y'; // error?

var_dump(isset($foo->bar['x'])); // true?, false?
```

I think that modification of an array should require write access? (That should 
be clarified in the RFC.)

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



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Claude Pache



> Le 30 nov. 2022 à 02:27, Larry Garfield  a écrit :
> 
> On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
> 
>> In the RFC, section Permitted visibility 
>> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
>> <https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility>):
>>> The set visibility, if it differs from the main (get) visibility, MUST be 
>>> strictly lesser than the main visibility. That is, the set visibility may 
>>> only be protected or private. If the main visibility is protected, set 
>>> visibility may only be private. Any violation of this rule will result in a 
>>> compile time error.
>>> 
>> The first sentence does not forbid `public public(set)`, or `protected 
>> protected(set)`, etc. (the `set` visibility does not differ from the 
>> main visibility), but the rest of the paragraph does not allow it. That 
>> should be clarified.
> 
> Er.  That's exactly what it says: "strictly lesser" than the main visibility. 
>  The lines after are just restating it.  "public public(set)" is not allowed.

As I understand the first sentence (what it says, not what you meant):

“The set visibility, **if it differs from the main (get) visibility**, 
{$some_restriction}.”

In `public public(set)`, the set visibility does not differ from the main/get 
visibility, therefore {$some_restriction} does not apply.

My guess is that you wanted to say:

“The set visibility, **if specified explicitly**, {$some_restriction}.”

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



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-29 Thread Claude Pache


> Le 29 nov. 2022 à 21:29, Larry Garfield  a écrit :
> 
> 
> Thank you everyone for the feedback.  Based on this thread, we've made two 
> changes to the RFC:
> 
> 1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
> section to Future Scope where we really should sort this out in the future, 
> but we'll do that in the future when we can all focus on the various nuances 
> of just that piece.
> 
> 2. I rewrote the section on __set to make it clearer.  That also included 
> Ilija and I digging into all the nuances that are already present.  The text 
> may still look a bit complex, but that's because the existing logic is 
> already complex with readonly.  Long story short, the a-viz RFC does not 
> change anything in the way __set works vis a vis asymmetric visibility; it 
> just inherits and continues what readonly already started, so it's consistent.
> 
> The PR should be updated in the next week or two with the latest changes.  
> Baring any major need for change, we expect to call a vote for it shortly 
> after New Years.
> 
> Thanks all.
> 
> --Larry Garfield
> 

Hi,

In the RFC, section Permitted visibility 
(https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
):
> The set visibility, if it differs from the main (get) visibility, MUST be 
> strictly lesser than the main visibility. That is, the set visibility may 
> only be protected or private. If the main visibility is protected, set 
> visibility may only be private. Any violation of this rule will result in a 
> compile time error.
> 
The first sentence does not forbid `public public(set)`, or `protected 
protected(set)`, etc. (the `set` visibility does not differ from the main 
visibility), but the rest of the paragraph does not allow it. That should be 
clarified.

(Because forbidding `public public(set)`, etc., makes it slightly more 
cumbersome to explain the rules, I am slightly in favour not to forbid it.)

> There is one exception, that of a private readonly property. That would 
> technically expand to private private(set) readonly, which is allowed.

That sentence should be deleted, as `readonly` is now forbidden.

—Claude

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Claude Pache



>> 
>> 1. Relax the set-is-tighter restriction.  That would allow `protected 
>> protected(set)` etc. on any property.  It wouldn't be particularly useful 
>> unless readonly is being used, but it would be syntactically legal and 
>> behave as you'd expect.  We could still disallow "set is more permissive" 
>> combinations (eg, `private public(set)`), as those have no apparent use case.
> 
> I think that Option 1 is the most reasonable. The meaning of `public 
> public(set)` and `protected protected(set)` is straightforward; from a user 
> point-of-view, disallowing them seems more like “it is useless” than “it is 
> confusing”. Unless there are good technical reason to restrict it, we can 
> just leave to linting tools the care of reporting it.
> 
> —Claude
> 

To clarify my position:

* The set visibility must be either more restrictive or of the same restriction 
level than the get visibility.

* When the set visibility is absent, it is inferred as following:
 * If `readonly` is present, the set visibility is `private` (as of today);
 * otherwise, the set visibility is the same as the get visibility (again, 
as of today).

* We don’t judge whether it is reasonable to write `protected protected(set) 
string $foo;` when you could just write `protected string $foo` for the same 
effect. Similarly, we don’t judge whether it is reasonable to write `public 
function()` when you could just write `function()` for the same effect. We 
leave it to coding styles and linters to decide whether the short form or the 
long form is preferred.

—Claude

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



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-13 Thread Claude Pache



> 
> public public(set) readonly string $foo
> 
> protected protected(set) readonly string $foo
> 
> These would be the only way to have a non-private-set readonly property.  
> While the first is in practice quite unlikely, the second has valid use 
> cases.  

Both have use cases. Whether they are valid is quite subjective. (I am speaking 
as someone who suffer from the `match()` construct forbidding having both 
`default` and  some other `case` pointing to the same expression. That 
restriction seemed reasonable the time the feature was designed and voted.)

> 
> 1. Relax the set-is-tighter restriction.  That would allow `protected 
> protected(set)` etc. on any property.  It wouldn't be particularly useful 
> unless readonly is being used, but it would be syntactically legal and behave 
> as you'd expect.  We could still disallow "set is more permissive" 
> combinations (eg, `private public(set)`), as those have no apparent use case.

I think that Option 1 is the most reasonable. The meaning of `public 
public(set)` and `protected protected(set)` is straightforward; from a user 
point-of-view, disallowing them seems more like “it is useless” than “it is 
confusing”. Unless there are good technical reason to restrict it, we can just 
leave to linting tools the care of reporting it.

—Claude

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



Re: [PHP-DEV] [RFC][Discussion] Objects can be declared falsifiable

2022-11-03 Thread Claude Pache


> Le 3 nov. 2022 à 02:51, Josh Bruce  a écrit :
> 
> Similar to:
> 
> function x(?SomeType $arg): ?SomeOtherType
> 
> Instead of:
> 
> function x(SomeType|null $arg): SomeType|null
> 
> Both are the same thing under the hood.

The big difference between `?SomeType` shortcut and falsifiable object feature, 
is that using `?SomeType` does not change the semantics of `SomeType|null`, 
while declaring an object falsifiable changes the semantics of `if ($obj)`.

> 
> In that same spirit, totally opt-in - not required to use or you can get 
> there some other way - similar to Marco’s comment around __toString. 



It is opt-in for the implementer of the library, not for the user of it, as 
they are not necessarily the same person.

Today, in a common situation where I know that a variable contains either an 
object of some type or null, I routinely write `if ($a)` to mean `if ($a !== 
null)`. Now, with magic `__toBool()` possibly implemented by  the library’s 
author, I don’t know what `if ($a)` means, unless I have carefully read the 
docs in order to know whether they have opt into that misfeature, and, if so, 
what exactly “falsy” means for them (invalid?, empty?, zero?). Ironically, that 
will incite me to not use anymore the implicit casting to bool for objects, and 
to write systematically `if ($a !== null)`, so that both myself and the reader 
of my code won’t have to look at the docs in order to understand such simple 
code.

—Claude

Re: [PHP-DEV] ReflectionType for iterable / PHP 8.2

2022-11-02 Thread Claude Pache


> Le 2 nov. 2022 à 19:54, Juliette Reinders Folmer 
>  a écrit :
> 
> On 2-11-2022 18:46, Benjamin Morel wrote:
>> Hi internals,
>> 
>> It just came to my attention that there is a change of behaviour between
>> PHP 8.1 and 8.2 in the way iterable is decomposed, or not, into
>> Traversable|array when reflected:
>> 
>> ```
>> function foo(): iterable {}
>> function bar(): stdClass|iterable {}
>> 
>> echo (new ReflectionFunction('foo'))->getReturnType(), PHP_EOL;
>> echo (new ReflectionFunction('bar'))->getReturnType(), PHP_EOL;
>> ```
>> 
>> Output on PHP 8.1:
>> 
>> ```
>> iterable
>> stdClass|iterable
>> ```
>> 
>> Output on PHP 8.2:
>> 
>> ```
>> iterable
>> stdClass|Traversable|array
>> ```
>> 
>> Is this expected behaviour? Or should I file a bug? I'm particularly
>> surprised that it behaves this way on PHP 8.2 only in the presence of union
>> types.
>> 
>> Thank you,
>> Benjamin
>> 
> That's a intentional behaviour change and related to this accepted PHP 8.2 
> RFC: https://wiki.php.net/rfc/iterator_xyz_accept_array
> 
> Smile,
> Juliette

It is rather related the following RFC:

https://wiki.php.net/rfc/dnf_types

The change was discussed in this thread:

https://externals.io/message/117577

—Claude 

Re: [PHP-DEV] [RFC][Discussion] Objects can be declared falsifiable

2022-11-02 Thread Claude Pache


> Le 2 nov. 2022 à 09:12, Michał Marcin Brzuchalski 
>  a écrit :
> 
> P.S. I don't see it feasible to have objects that evaluate false in
> logical expressions.

For better or for worse (IMHO, for worse), `SimpleXMLElement` instances 
representing attributeless empty elements are already falsy, so yes, it is 
absolutely feasible.

—Claude

Re: [PHP-DEV] RFC [Discussion]: Randomizer Additions

2022-10-29 Thread Claude Pache



> Le 28 oct. 2022 à 23:43, Jordan LeDoux  a écrit :
> 
> On Fri, Oct 28, 2022 at 12:30 PM Joshua Rüsweg via internals <
> internals@lists.php.net> wrote:
> 
> Not to try and bikeshed further, but wouldn't `getBytesFromChars` or
> `getBytesFromCharList` be more clear while being nearly as accurate?
> 
> Jordan


In the face of multibyte character sets such as UTF-8, I wouldn’t use “char” to 
mean “byte” (even if, in practice, the most common use will be strings of 
1-byte chars). “Alphabet” or “string” might be ambiguous (is it an alphabet of 
bytes or an alphabet of characters?), but at least they are not contradictory.

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



Re: [PHP-DEV] Compact can't resolve outer scoped variables using short closures

2022-10-20 Thread Claude Pache

> 
> How would you like it to work, if you pass a variable name variable to
> compact then?
> $x = 123;
> $name = 'x';
> (fn () => compact($name))();
> 

Although it is difficult to make it work in general (of course), there is the 
specific case of names given as literal strings, as in the example provided by 
the OP, that does not suffer from the impossibility of static analysis.


> I agree with the idea of deprecating compact() & extract() and in
> long-term variable of variables as well.

However, in `compact('x', 'y')`, the name of the variables are not variable, 
they are constant.

—Claude

Re: [PHP-DEV] Sanitize filters

2022-10-06 Thread Claude Pache


> Le 6 oct. 2022 à 10:19, Rowan Tommins  a écrit :
> 
> You described FILTER_VALIDATE_EMAIL as "notorious for being next to useless"; 
> that gives us two possibilities:
> 
> a) A new function will be just as useless, because it will be based on the 
> same implementation
> b) There is a better implementation out there, which we should start using in 
> ext/filter right now
> 
> My gut feel is that (a) is true, and there is no point considering what a new 
> function would be called, because we don't know how to implement it.

Hi,

While it may be difficult to validate an email according to some IETF’s RFC, 
the HTML standard has pragmatically adopted a pattern (used to validate `` fields) that is both readable and suitable for most practical 
purposes. See:

https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address 


—Claude

Re: [PHP-DEV] Union type casts

2022-10-05 Thread Claude Pache

> Le 5 oct. 2022 à 19:53, Eugene Sidelnyk  a écrit :
> 
> I used to have an awkward feeling when it was necessary to convert the 
> nullable integer into a nullable string. It would be kind of ternary operator 
> anyway. Either `$b = (null !== $a) ? (string)$a : null;` or `$b = (string)$a 
> ?: null;`. 
> 
> A lot easier to read would it be if written this way: `$b = (?string)$a;`. 
> The intentions are clear when doing explicit type-cast.
> 
> Currently, I don't see any other situations when this feature may be useful
> 
> 
> Thank you 

There has been some discussion and interest around nullable casting (which, 
contrarily to union type casting, has only one possible and obvious semantics), 
see https://wiki.php.net/rfc/nullable-casting 
 and the two discussion threads 
linked in the bottom of the page. However, the RFC seems to be inactive for now,

—Claude

Re: [PHP-DEV] Union type casts

2022-10-05 Thread Claude Pache


> Le 5 oct. 2022 à 06:46, Eugene Sidelnyk  a écrit :
> 
> I assume the behavior should be the same as if we called the function
> having respective parameter type-hint (with a remark that strict types are
> disabled):

Hi,

Function parameters are more restrictive than explicit cast in what it accepts. 
In particular, the following inputs are rejected with a TypeError when fed to a 
function that accepts an `int`: `"3 mices"`, `null`, `[ ]`. Most notably, no 
type conversion is performed when the input type is `null` or  `array`, or when 
the target type is `array` or `object`.

For reference, the original conversion rules are here: 
https://wiki.php.net/rfc/union_types_v2#coercive_typing_mode 
 (I don’t know if 
there has been adjustments since then.)

—Claude




Re: [PHP-DEV] Sanitize filters

2022-10-04 Thread Claude Pache
Hi,

> FILTER_SANITIZE_ENCODED
> FILTER_SANITIZE_SPECIAL_CHARS

See https://www.php.net/manual/en/function.filter-input.php 
 Example #1 for an 
example of use. Apparently, “escaping” is considered as part of  “sanitizing”?

If you want to educate your users, you can consider to deprecate them in favor 
of FILTER_DEFAULT followed by `urlencode()`, respectively `htmlspecialchars()`. 
Ditto for various other FILTER_SANITIZE_* filters.

> FILTER_UNSAFE_RAW

My wild guess is that “unsafe” means that “it is dangerous to use the result in 
random contexts (i.e., without properly escaping it, because we assume that you 
don’t even know what “escape” means). Use FILTER_SANITIZE_ENCODED, 
FILTER_SANITIZE_SPECIAL_CHARS and/or FILTER_SANITIZE_MAGIC_QUOTES if you want 
to be safe” (for some nonstandard definition of “safe”). Of course, it should 
be renamed, because “safety” may be achieved by alternative means.

—Claude



Re: [PHP-DEV] Error behaviour for max_input_vars

2022-09-15 Thread Claude Pache


> Le 13 sept. 2022 à 19:58, Mel Dafert  a écrit :
> 
> In summary, I believe this can only be solved inside of PHP itself, by 
> allowing to configure a way for `max_input_vars` to abort the request instead 
> of truncating the input.
> The options I see feasible are:
> - A new ini setting `max_input_vars_abort` (default to 0), which, if set to 
> 1, will abort the request if there are more input variables than allowed.
> - A method to reliably detect whether the input vars were truncated (eg. 
> `function has_post_been_truncated(): bool`), so the application can decide 
> whether to abort or not.
> - Deciding that `max_input_vars` is not relevant anymore and should be 
> handled by the likes of Apache and NGINX, thus changing the default to `0` 
> and removing the setting
> over a deprecation period.
> 
> I am leaning towards the first option, but would be open to either outcome.

Hi,

A big issue with `max_input_vars` (and indeed any fallible procedure executed 
at startup) is that errors occur before that the program has a chance to 
install a custom error/exception handler or to open a try/catch block.

For the specific case of $_POST, a possible option would be:

* set the ini setting `enable_post_data_reading` to false, so that $_POST and 
$_FILES are not populated at startup;
* have a function that to enable to populate those variables at runtime:

```php
try {
read_post_data([ 'max_input_vars' => 100_000 ]);
}
catch (\TooManyInputVarsException) {
// custom panic procedure
}
```

A more general solution would be to be able to retrieve all errors (not just 
the last) that has been triggered at startup, e.g.:

```php
set_error_handler('app_specific_error_handler');
replay_error_triggered_at_startup(); // will re-trigger all errors that has 
occurred before the first line of code
```

—Claude



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-31 Thread Claude Pache



> Le 31 août 2022 à 23:27, Tim Düsterhus  a écrit :
> I've read through that explanation three times, but don't understand why the 
> C#-style syntax would require to differentiate between `set` and `raw`. Isn't 
> the difference between "visibility only" and "accessor" not clear [1] by 
> having either '{' or ';' after the 'set'?
> 
> [1] Read: Clear to the engine, not talking about the human reader here.

Even if they manage to make the difference clear for the engine without 
resorting to “raw”, I think that it is important to have a syntactical marker 
for the sake of humans. Otherwise, someone would want to incrementally improve 
their class property, and at some unkwown point in time,  it becomes 
unexpectedly unusable for references and array mutations. 

—Claude 

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



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-07 Thread Claude Pache



> Le 5 août 2022 à 19:08, Larry Garfield  a écrit :
> 
> Ilija Tovilo and I are happy to present the first new RFC for PHP 8.3: 
> Asymmetric Visibility.
> 
> https://wiki.php.net/rfc/asymmetric-visibility
> 
> Details are in the RFC, but it's largely a copy of Swift's support for the 
> same.
> 
> -- 
>  Larry Garfield
>  la...@garfieldtech.com
> 

Hi,

I like the RFC, and in particular allowing property visibility to remain 
orthogonal to property accessors.

There are few missing details in the RFC (which is otherwise good):

1. Are static properties supported?

2. What about properties that are overridden/redeclared in a subclass? Given 
that extending the visibility is generally allowed:

```php
class A { 
protected int $x;
}
class B extends A {
public int $x; // ok
}
```

I expect that the following should be allowed as well:

```php
class A { 
public protected(set) int $x;
}
class B extends A {
public int $x; // ok
}
```

On the other hand, I expect that the two following cases should *not* be 
allowed, because it would break encapsulation of class A:

```php
class A { 
public private(set) int $x;
}
class B extends A {
public int $x; // error: cannot change a private property to public (or 
protected)
}
```

and:

```php
class A { 
public private(set) int $x;
}
class B extends A {
public private(set) int $x; // error: cannot make a private property in 
A as private in B
}
```

—Claude

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



Re: [PHP-DEV] [VOTE] Random Extension Improvement

2022-07-14 Thread Claude Pache



> Le 14 juil. 2022 à 06:32, Guilliam Xavier  a écrit 
> :
> 
> On Thursday, July 14, 2022, Go Kudo  wrote:
> 
>> 2022年7月13日(水) 1:10 Tim Düsterhus :
>> 
>>> Hi
>>> 
>>> On 7/12/22 18:04, Tim Düsterhus wrote:
 I also think that both '$string' and '$binary' are appropriate parameter
 names in this case, so particular preference from my side.
>>> 
>>> Sorry for the follow-up, there's two mistakes in that sentence. It
>>> should read:
>>> 
>>> I also think that both '$string' and **'$bytes'** are appropriate
>>> parameter names in this case, so **no** particular preference from my
>>> side.
>>> 
>>> Best regards
>>> Tim Düsterhus
>>> 
>> 
>> Hi
>> 
>> I agree with you. I will change the parameter name from `$string` to
>> `$bytes` as I don't see any problem.
>> 
>> I will try to explain the changes more rigorously in future proposals.
>> Thank you.
>> 
>> Regards,
>> Go Kudo
>> 
> 
> Hi,
> 
> I was waiting for more opinions but... so here's mine:
> 
> I would prefer to keep "$string", as [that's how I read the RFCs, and] when
> calling e.g. shuffleBytes('foobar') I don't feel like I'm passing "bytes"
> (or "a binary") but a string (to be shuffled byte-wise rather than
> character-wise or codepoint-wise, but that's from the function, not the
> argument)...
> Granted, not compelling, and probably won't matter in practice, but hey ;)
> 
> Regards
> 
> PS: sent from mobile
> 
> 
> -- 
> Guilliam Xavier

I agree with Guilliam: this function is about «shuffling the bytes of the given 
string» (as opposed to, say, «array of ints»)

As precedent, there are `bin2hex($string)` and `md5($string)`, which are 
unambiguously working with bytes from data given in the form of string, where 
«string» is a PHP type, which can hold data that is not necessarily 
UTF-8-encoded or Shift-JIS-encoded text.

—Claude

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



Re: [PHP-DEV] [RFC][Under discussion] Fetch properties in const expressions

2022-06-22 Thread Claude Pache



> Le 17 juin 2022 à 00:46, Ilija Tovilo  a écrit :
> 
> (...)
> 
> Since the primary motivation of this RFC is to allow fetching the name
> and value properties of enums I'm inclined to forbid using -> on
> anything but enums. That would circumvent the issue since enums can't
> contain user-defined properties nor the magic __get method, and
> name/value are readonly.
> 
> I'll take a few days to think about the options, and will update the
> RFC and inform the mailing list about the decision I have made. Let me
> know if you have any more thoughts.
> 

Hi,

I feel that, in any case, allowing unrestricted fetching properties in const 
expression in is semantically incorrect, because properties are fundamentally 
mutable. I am not speaking of creative use of code in order to achieve the 
effect, but of the regular semantics of properties.

For me, it seems reasonable to restrict the feature to readonly properties 
(including those of enums), because those are effectively immutable by design.

—Claude

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



Re: [PHP-DEV] [RFC] [Under Discussion] Constants in traits

2022-06-22 Thread Claude Pache



> Le 21 juin 2022 à 23:33, shinji igarashi  a écrit :
> 
> Hello everyone!
> 
> I'd like to start a discussion on an RFC to allow defining constants in 
> traits.
> https://wiki.php.net/rfc/constants_in_traits
> 
> I'm looking forward to your feedback, including corrections on English 
> wordings.
> 
> Thanks!
> 
> --
> Shinji Igarashi
> 


Hi,

Some time ago, I migrated part of some class implementation into a trait, and I 
was surprised that it resulted in a syntax error, because constants were not 
supported in traits. In my case, I could trivially resolve the issue by 
morphing the (private) constant into a static property (semantically less 
correct, but pragmatically simpler); but I was feeling that it is yet one more 
inconsistency of PHP: Why on earth are static properties supported, but not 
constants?

So, this is a welcome addition (or, rather, a welcome correction of an 
oversight).

—Claude

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



Re: [PHP-DEV] Adding new closing tag =?> for keeping trailing newline

2022-06-08 Thread Claude Pache



> Le 8 juin 2022 à 05:34, Sara Golemon  a écrit :
> 
> 
>  declare(ignore_newline_after_close_tag=false); // defaults to true, i.e
> existing behavior
> 
> This would avoid any new syntax rules, but still provide the ability for
> php-as-template-engine to behave in the user's preferred mode.
> 

No, because the user’s preferred mode is not a global one, it is a local one. 
You do not want to keep newlines in the following situation:

```
* line 1

* line 2
* line 3

* line 4
```

With a global switch, not only you have failed to solve the real problem (doing 
the Right Thing with newlines), but also you have created another one (looking 
at the top of the file in order to understand the code). You have the worst of 
both world.

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



Re: [PHP-DEV] [Discussion] Expand deprecation notice scope for partially supported callables

2022-05-12 Thread Claude Pache


> Le 12 mai 2022 à 23:11, Larry Garfield  a écrit :
> 
> For the `callable` type declaration, I'm not opposed but is it redundant with 
> the existing deprecation?  When would you pass a callable to something and 
> not end up calling it anyway, which would trigger the existing deprecation?  
> (Meaning in practice you'd always get 2 deprecations, which are not 
> necessarily better than one.)


Although such a callable is probably intended to be called at some point, it is 
not necessarily called immediately, and it may be easier to track the source of 
it when you trigger the deprecation earlier. Example:

```php
public function registerErrorHandler(callable $onerror) {
$this->onError[] = $onerror;
}
```

(Of course, this argument also holds for `is_callable()`.)

—Claude

Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throwa deprecation notice ?

2022-04-20 Thread Claude Pache



> Le 20 avr. 2022 à 12:42, Rowan Tommins  a écrit :
> 
> 
> The situation with is_callable is a bit less clear, because it depends on how 
> the function is actually being used. If a false return is eventually 
> equivalent to some kind of error, then the behaviour would ideally match 
> callable parameters. In other examples, though, false is actually a valid 
> state, so it's not clear what a user should change to avoid the deprecation 
> notice.
> 
> You make a very important claim in your bug report:
> 
> > However, in real world, is_callable() is almost never given totally 
> > arbitrary stuff
> 
> My concern is that we have no way of knowing whether this is true, and 
> whether there will always be a clear action for users who see the deprecation 
> notice.

In this case, there is always the possibility for them to use the error 
suppression operator. That remains easy, and looks like a reasonable use case 
of that operator.

If we have to balance between addressing the verified issue of not emitting 
deprecation notice for well-known and fairly frequent code patterns, and 
addressing the potential and non-fatal issue of emitting too much notices for 
totally unknown use cases, the choice should be straightforward.

—Claude

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



Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throwa deprecation notice ?

2022-04-20 Thread Claude Pache


> Le 20 avr. 2022 à 00:22, Claude Pache  a écrit :
> 
> 
> 
>> Le 19 avr. 2022 à 20:20, Andreas Hennings  a écrit :
>> 
>> A deprecation warning on is_callable() would imply that in a future
>> version of PHP that call will be illegal.
> 
> No,  in the case of `is_callable()`, the deprecation warning will imply that, 
> in a future version of PHP, the behaviour will change.  There are precedents 
> of deprecation warning for changing behaviour: https://3v4l.org/Iqo4N 
> <https://3v4l.org/Iqo4N>
> 
> —Claude

Expanding my last message: Although we can technically use deprecation warning 
for anything reasonable (even without precedent), we should nevertheless be 
careful that it remains possible to write forward- and backward-compatible code 
without triggering that deprecation notice (and without resorting to the error 
suppression operator). For example, writing `strpos('x', chr(120))` instead of 
`strpos('x', 120)` will work fine in both 7.4 and 8.0 (in case it is really 
what was meant).

In the case of `is_callable()`, it is true that it should in theory accept 
arbitrary input without notice. However, in practice, the value that 
`is_callable()` receives is almost never totally arbitrary: for instance, when 
it is fed with a string beginning with "static::", that particular prefix is 
almost surely written somewhere verbatim in your code, and you must change your 
code in some way in order to keep the intended behaviour in 9.0.

By contrast, we shouldn’t use any type of notice for `password_verify()`, 
because that function must be prepared to accept *really* arbitrary strings. 

—Claude

Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throwa deprecation notice ?

2022-04-19 Thread Claude Pache


> Le 19 avr. 2022 à 20:20, Andreas Hennings  a écrit :
> A deprecation warning on is_callable() would imply that in a future
> version of PHP that call will be illegal.

No,  in the case of `is_callable()`, the deprecation warning will imply that, 
in a future version of PHP, the behaviour will change.  There are precedents of 
deprecation warning for changing behaviour: https://3v4l.org/Iqo4N

—Claude


Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throwa deprecation notice ?

2022-04-19 Thread Claude Pache


> Le 18 mars 2022 à 18:03, Juliette Reinders Folmer 
>  a écrit :
> 
> On 18-3-2022 14:37, Christoph M. Becker wrote:
>> On 16.03.2022 at 06:52, Juliette Reinders Folmer wrote:
>>> I've just been looking in detail at the Partially Supported Callables
>>> deprecation RFC:
>>> https://wiki.php.net/rfc/deprecate_partially_supported_callables
>>> The RFC explicitly excludes the `is_callable()` function and the
>>> `callable` type from throwing deprecation notices.
 The |is_callable()| function and |callable| type remain side-effect
 free and do not throw a deprecation warning. They will continue to
 accept these callables until support is removed entirely.
>>> While I can fully support this for the `callable` type, I wonder if the
>>> decision to not throw a deprecation on use in `is_callable()` is the
>>> right one (though I understand the desire to keep it side-effect free).
>>> Consider these code samples:
>>>   function foo(callable $callback) {}
>>>   foo('static::method');
>>> This function call not throwing a deprecation is not problematic as in
>>> PHP 9.0 the function will start throwing a TypeError.
>>>   if (is_callable('static::method')) {
>>>   static::method();
>>>   }
>>> The second code sample, however, is problematic, as in PHP 9.0, the
>>> behaviour of this code will be silently reversed for those callbacks
>>> which would previously result in `is_callable()` returning true, which
>>> makes this a potentially dangerous change without deprecation notice.
>>> Would anyone care to enlighten me as to whether this was given due
>>> consideration ?
>> Frankly, I don't know.  Apparently, there was almost no discussion about
>> that RFC.  Part of the reasoning to not raise E_DEPRECATED when calling
>> is_callable() was likely the typical use case
>>   $callable = …;
>>   if (is_callable($callable)) {
>>   call_user_func($callable);
>>   }
>> what would report the deprecation when actually calling the callable.
>> Not sure what to do regarding your given use case(s).
>> --
>> Christoph M. Becker
> 
> Unfortunately, those aren't the only places I see this happening and my 
> example is not a stand-alone case either.
> 
> I came across the above code sample ( is_callable('static::method') / 
> is_callable(['parent', __FUNCTION__]) with variable method calls) in a number 
> of different packages when testing a (PHPCompatibility) sniff I am writing to 
> detect the deprecation, so this code pattern looks to be relatively common.
> 
> Some examples:
> * 
> https://github.com/symfony/service-contracts/blob/bc0a2247c72d29241b5a06fb60dc1c9d9acf2a3a/ServiceSubscriberTrait.php#L39
> * 
> https://github.com/mockery/mockery/blob/c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac/library/Mockery/Mock.php#L960
> * 
> https://github.com/simplepie/simplepie/blob/dacf0ed495d2e8fb306e526ca3f2a846af78a7c9/tests/oldtests/absolutize/RFC3986.5.4/base.php#L13
> 

As I think that it is a serious oversight of the RFC, I have open:

https://github.com/php/php-src/issues/8401 


—Claude




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] [RFC][Under discussion] Arbitrary string interpolation

2022-03-18 Thread Claude Pache



> Le 18 mars 2022 à 18:49, Paul Dragoonis  a écrit :
> 
> I think the original goal of this RFC is to make PHP more expressive, and
> less clunky (look at Jav).  This is a good goal and one much desired by the
> community, but I think the approach here isn't the right fit or way to
> achieve it
> 
> Writing code in strings is a DX nightmare, and static analysis challenge.
> 
> PHP is improving onto a more verbose, typed, but exprsssive language, and
> this change would make that harder.
> 
> I'm also thinking if this could become a LCE/RCE vulnerability in a type of
> eval() situation.  Not a huge point but just an observation.
> 
> Happy to re evaluate a new approach to solve the same problem that doesn't
> involve coding inside strings.

Although I agree that code execution in strings is not a great idea, it should 
be noted that this is already possible today, so that this proposal does not 
add a new capability. Indeed, the proposed syntax:

"{$:/* arbitrary expression here */}";

is equivalent to:

$expr = fn($_) => $_;
"{$expr(/* arbitrary expression here */)}";

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



Re: [PHP-DEV] Proposal for RFC to remove undefined array index warning when used ina ternary

2022-02-27 Thread Claude Pache


> Le 27 févr. 2022 à 18:06, Robert Landers  a écrit :
> 
>> $val = $array[?'a'][?'b'][?'c'] ?? 'default';
>> 
>> Currently, the last example would need to be a rather unwieldy ternary:
>> 
>> $val = (isset($array['a']) && isset($array['a']['b']) &&
>> isset($array['a']['b']['c']) ? $array['a']['b']['c'] : 'default';
>> 
> 
> I've been writing it like this:
> 
> $val = (($array['a'] ?? [])['b'] ?? [])['c'] ?? 'default';
> 
> which is still unwieldy. I don't actually know if it is required to use []
> vs. null, but it makes sense to use an empty array to me.
> 


Hi,

In PHP, you can write `$array['a']['b']['c'] ?? 'default';`. It works when 
either null or inexistant index is encountered at any depth of the expression.

—Claude

Re: [PHP-DEV] SensitiveParameterValue serialization behavior

2022-02-26 Thread Claude Pache


> 
> 1. Disallow both serialization and unserialization.
> 
> This will make the serialization issue very obvious, but will require 
> adjustments to exception handlers that serialize the stack traces.

Hi,

Note that exception handlers that serialise stack traces without taking into 
account that the operation may fail, are already broken as of today, because 
common unserialisable objects, such as Closure instances (anonymous functions), 
may appear in stack traces.

https://3v4l.org/tv1s1 

https://3v4l.org/PGKnl 

Making SensitiveParameterValue fail on serialisation won’t break those 
handlers, but make their existing brokenness apparent in more cases (which is a 
good thing).

—Claude



Re: [PHP-DEV] RFC [Discussion] array_column results grouping

2021-12-06 Thread Claude Pache


> Le 6 déc. 2021 à 09:44, Hassan Ahmed <7sno...@gmail.com> a écrit :
> 
> Hello Folks, Thanks a lot for your feedback, as already mentioned in
> the RFC and as mentioned by Rowan too a new function is an option. I
> think that mostly we will go with the new function option.
> I will try to edit the PR to add a new function, does there any
> suggestions/naming conventions for the new function? a colleague
> suggested being `array_group_by` and Hendra already suggested to be
> `array_column_group` which is good too.
> 
> Regards,
> Hassan
> 


Now that we have named arguments, the issue of long and complicated list of 
arguments is considerably weaken, since you can write:

array_column($foo, column_key: 'name', grouping: true);

in lieu of:

array_column($foo, null, 'name', true)

Also, an alternative to a new function, is reusing the same function with an 
alternative signature, as it was done for setcookie:

https://www.php.net/manual/fr/function.setcookie.php 


I have no opinion about which of the three approaches (new parameter, same 
function with alternative signature, new function) is better; I just mention 
the various alternatives.

—Claude

Re: [PHP-DEV] Re: [RFC] Deprecate dynamic properties

2021-11-16 Thread Claude Pache



> Le 17 nov. 2021 à 00:56, Larry Garfield  a écrit :
> 
> They'll get a deprecation, but... we're shouting from the rooftops that 
> deprecations shouldn't be a big red warning, so if you want a big red warning 
> you can't get that until PHP 9.

Deprecation notices *are* big red warnings. They mean: the feature *will* be 
removed or altered in the next major version. 

The beauty of deprecation notices is that they warn you about future breakage 
without actually breaking anything. There is no need to invent some new 
sophisticated way, but only to learn to use correctly the existing one. 

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



Re: [PHP-DEV] Is there an RFC/discussion for ::class being a specific type?

2021-11-16 Thread Claude Pache


> Le 16 nov. 2021 à 18:34, Kamil Tekiela  a écrit :
> 
> 
> At the moment, ::class is just a preprocessor macro. It is not part of the
> runtime. 

This is not true in general. For example `static::class` is not resolvable at 
compile-time.

(In fact, many years ago, when I played with that new feature, I almost filed a 
bug report saying that `static::class` is not supposed to work, since it is not 
resolvable at compile-time.)

(Additionally, since PHP 8, it is also possible to write `$object::class`, see: 
https://wiki.php.net/rfc/class_name_literal_on_object 
. But `static::class` 
worked since 5.5.)

—Claude

Re: [PHP-DEV] [VOTE] Deprecate dynamic properties

2021-11-13 Thread Claude Pache


> Le 12 nov. 2021 à 17:24, Ben Ramsey  a écrit :
> 
> I like this change, but the deprecation in 8.2 seems too disruptive. I’d
> rather promote our intent to deprecate this with a statement in the
> manual that says something like, “This feature will be deprecated in
> PHP 8.3 and removed in 9.0.” Meanwhile, 8.2 should include the
> AllowDynamicProperties attribute so folks can start preparing.
> 

Kindly recalling that the intended meaning of deprecation warnings is duly 
documented in the manual? I have read the manual when I designed my error 
handler many year ago; as a consequence, this deprecation warning will not at 
all be disruptive for me. 

I strongly doubt that a mere statement of intention in the manual is of much 
utility, given that many people apparently don’t read the manual when they 
design their error handlers... We should rather more heavily promote the true 
meaning of “deprecation”.

—Claude

Re: [PHP-DEV] PHP RFC: Locked Classes

2021-11-05 Thread Claude Pache

> Le 5 nov. 2021 à 11:40, Glash Gnome  a écrit :
> 
> Hi internals,
> 
> I was reading the RFC  https://wiki.php.net/rfc/locked-classes
> 

Note that this RFC is marked as “withdrawn”, and that an alternative approach 
has been proposed in:

https://wiki.php.net/rfc/deprecate_dynamic_properties 


—Claude

Re: [PHP-DEV] Add ReflectionFunctionAbstract::isAnonymous()

2021-10-22 Thread Claude Pache

> Le 21 oct. 2021 à 01:12, Dylan K. Taylor  a écrit :
> 
> Hi all, 
> 
> Given the addition of Closure::fromCallable() and the upcoming first-class 
> callable syntax in 8.1, it seems slightly problematic that there's no simple 
> way to tell by reflection if a Closure refers to an anonymous function or 
> not. ReflectionFunctionAbstract::isClosure() (perhaps somewhat misleadingly) 
> returns whether the closure is literally a \Closure instance, so it's not 
> useful for this purpose. 
> 
> The only way to do this currently (that I know about) is to check if the name 
> of the function contains "{closure}", which is a bit unpleasant and depends 
> on undocumented behaviour. 
> 
> I'm proposing the addition of ReflectionFunctionAbstract::isAnonymous(), 
> which would fill this use case, and may be able to offer an implementation. 
> 
> Thanks, 
> Dylan Taylor. 
> 
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 


Hi,

Per the manual [1], Closure::fromCallable() “creates and returns a new 
anonymous function”. I guess that this might not match your notion of 
“anonymous function”?

Therefore, I am asking for clarification: What practical distinction do you 
make between ”an instance of Closure” and “an anonymous function”, and why does 
this distinction matter?

[1]: https://www.php.net/manual/en/closure.fromcallable.php 


—Claude

Re: [PHP-DEV] [RFC] [VOTE] is_literal

2021-09-08 Thread Claude Pache


> Le 7 sept. 2021 à 11:49, Craig Francis  a écrit :
> 
> 
> Obviously I'd still like libraries to be able to protect everyone from
> introducing Injection Vulnerabilities (as the majority of programmers don't
> use static analysis), but that's for another day.
> 


Hi, 

We all want to protect from injection vulnerability, but I think there are 
better way than is_literal.

One way is to use templates, an area where PHP is ironically lagging behind. I 
suggest looking at JS tagged templates:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
 


For example:


$qb->select('u')
   ->from('User', 'u')
   ->where('u.id = ' . $_GET['id']); // INSECURE
could be written as


exec `
SELECT u
FROM User u
WHERE u.id = %{ $_GET['id'] }
`
?>

where the part between %{ ... } is transformed into an SQL literal string (with 
delimiters "...", not just “escaping”) when it is a string; into the SQL 
expression NULL when it is null; into an SQL subexpression if it is an object 
(provided by the library) that represents a well-formed SQL subexpression, etc.

—Claude



Re: [PHP-DEV] [RFC] Never For Argument Types

2021-08-14 Thread Claude Pache



> 
> On Fri, 13 Aug 2021 at 19:27, Jordan LeDoux  wrote:
> 
>> Hey internals,
>> 
>> I've been working on the draft for my operator overloading RFC, and in
>> doing so I encountered a separate change that I would like to see.
>> 
>> That is, the use of `never` as an argument type for interfaces. Since
>> arguments in PHP are contravariant to preserve Liskov substitution, `never`
>> as the bottom type should indicate that implementing classes can require
>> any type combination they want. This is in fact consistent with type theory
>> and set theory, and is how the bottom type is treated in several other
>> languages.
>> 
>> In this case, the bottom type would be used to indicate covariant parameter
>> polymorphism while not conflicting with LSP.
>> 
>> This would provide a sort of minimal form of generics to PHP without the
>> issues that actual generics present from an implementation perspective. It
>> would not, however, restrict or hinder any future RFC for generics.
>> 
>> This is at the first draft stage, and I currently have the RFC on a github
>> repo to allow for easy contribution and collaboration.
>> 
>> Any feedback is greatly appreciated.
>> 
>> https://github.com/JordanRL/never-argument-type
>> 
>> Jordan
>> 


> Le 14 août 2021 à 18:19, Matthew Brown  a écrit :
> 
> Hey!
> 
> Using the "never" type to require that downstream libs specify a type does
> not make intuitive sense to me, because the same is not true the other way
> (covariantly) for return types.
> 
> The existence of a "never" type on an overriding method does not require
> that upstream libs specify a return type — this is perfectly valid:
> 
> class A {
>  public function foo() {}
> }
> class AChild extends A {
>  public function foo():never { exit; }
> }
> 
> Best wishes,
> 
> Matt


Indeed, I was going to write something similar. Concretely, I assume that one 
would want to update the ArrayAccess internal interface as follows:

```php
interface ArrayAccess {
public function offsetGet(never $x): mixed;
// ...
}
```
If users of that interface would suddenly be *required* to specify a parameter 
type, whereas previously they were *forbidden* to specify one, except a 
meaningless `mixed`... it would be not nice and useless.

Moreover, note that `mixed` was only introduced very recently, in 8.0: so that, 
it would be impossible to implement `ArrayAccess` on code that work both in 7.x 
and a future version with the updated interface. Not only would it be not nice, 
but it would be positively harmful.


—Claude

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



Re: [PHP-DEV] Unwrap reference after foreach

2021-08-14 Thread Claude Pache

> Le 13 août 2021 à 15:28, Nikita Popov  a écrit :
> 
> Hi internals,
> 
> I'd like to address a common footgun when using foreach by reference:
> https://wiki.php.net/rfc/foreach_unwrap_ref
> 
> This addresses the issue described in the big red box at
> https://www.php.net/manual/en/control-structures.foreach.php. While this is
> "not a bug" (as our bug tracker can regularly attest), it's rather
> unexpected, and we could easily avoid it...
> 
> Regards,
> Nikita

A case that should be mentioned in the RFC is destructuring:

```php
foreach ($foo as [ $x, &$y ]) { /*  */ }
```
https://3v4l.org/A5Vi7 

I assume that the reference in `$y` would be unwrapped after the loop?

—Claude

Re: [PHP-DEV] Unwrap reference after foreach

2021-08-13 Thread Claude Pache


> Le 13 août 2021 à 15:28, Nikita Popov  a écrit :
> 
> Hi internals,
> 
> I'd like to address a common footgun when using foreach by reference:
> https://wiki.php.net/rfc/foreach_unwrap_ref
> 
> This addresses the issue described in the big red box at
> https://www.php.net/manual/en/control-structures.foreach.php. While this is
> "not a bug" (as our bug tracker can regularly attest), it's rather
> unexpected, and we could easily avoid it...
> 
> Regards,
> Nikita


Hi,

I don’t like the split of semantics between simple and complex variables. It 
makes the language more inconsistent, therefore more difficult to reason about.

On the other hand, using a complex variable as reference in that context should 
be very rare outside obfuscation code contests.

Therefore, I suggest to deprecate (and later remove) the ability to use of a 
complex variable as reference in that context. That would solve the 
inconsistency issue.

—Claude

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



Re: [PHP-DEV] array_merge() inside looping optimization

2021-07-26 Thread Claude Pache


> Le 26 juil. 2021 à 15:41, Sara Golemon  a écrit :
> 
> A much more direct and maintainable solution would be to introduce a new
> function that intentionally modifies by reference. 

That function already exists, it is `array_push()`:

`$x = array_merge($x, $y);` → `array_push($x, ...$y)`

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



Re: [PHP-DEV] [Proposal] call_user_func_map(): flexible named parameter mapping for call_user_func*

2021-07-01 Thread Claude Pache



> Le 27 juin 2021 à 16:39, Ralph Schindler  a écrit :
> 
> The short proposal:
> 
> 
> Make a variation of this work (notice parameter order and 'b' is goes unused):
> 
>call_user_func_map(
>  fn ($c, $a) => var_dump($a, $c),
>  [
>'a' => 'the a value',
>'b' => 'the b value',
>'c' => 'the c value'
>  ]
>);
> 
>// string(11) "the a value"
>// string(11) "the c value"
> 
> 

Hi,

If you want to ignore arguments in excess, your function may have a rest 
parameter collecting them. The following will run without error:

```php
function foo($c, $a, ...$unused) {
var_dump($a, $c);
}

$args = [
'a' => 'the a value'
  , 'b' => 'the b value'
  , 'c' => 'the c value'
];

foo(...$args);
```

—Claude

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



  1   2   3   >