Thank you for your answer. Now I will give examples for better
understanding.
Simple examples from Typescript:
let foo = ...
foo!.bar()
foo!.someProperty.baz()
Examples of potentially using in PHP:
Without this operator we writing this code:
$foo = ...
if ($foo === null) {
throw new FooIsNullException();
}
$foo->bar.
With this operator:
$foo!->bar
$foo!->someProperty->method();
$foo!->someProperty->anotherProperty!->method();
I think the postfix operator would be illogical in PHP because my operator
is similar to the existing nullsafe operator in syntax. And it would be
strange if its syntax were different.
Or we can implement both operator syntaxes: prefix for accessing
properties, and postfix for use with variables, as in your example.
Nullsafe:
$foo?->bar;
Not null assertion:
$foo!->bar;
If variable bar would be null - php will throw an exception. But now i dont
know which exception it would be :)
This operator will be useful in cases where a null value in a specific
place will violate the domain logic. Usually we write either assertions or
checks and throw our exceptions for this. But it seems to me that the not
null assertion operator will help avoid writing unnecessary code. The
problem, of course, will be catching errors. It is not clear how to catch
errors by a specific value. I will think about it.
Thank you for your answer. Now I will give examples for better
understanding.Simple examples from Typescript:
let foo = ...
foo!.bar()
foo!.someProperty.baz()Examples of potentially using in PHP:
Without this operator we writing this code:$foo = ...
if ($foo === null) {
throw new FooIsNullException();
}$foo->bar.
With this operator:
$foo!->bar
$foo!->someProperty->method();
$foo!->someProperty->anotherProperty!->method();I think the postfix operator would be illogical in PHP because my operator
is similar to the existing nullsafe operator in syntax. And it would be
strange if its syntax were different.
Or we can implement both operator syntaxes: prefix for accessing
properties, and postfix for use with variables, as in your example.Nullsafe:
$foo?->bar;
Not null assertion:
$foo!->bar;If variable bar would be null - php will throw an exception. But now i
dont know which exception it would be :)This operator will be useful in cases where a null value in a specific
place will violate the domain logic. Usually we write either assertions or
checks and throw our exceptions for this. But it seems to me that the not
null assertion operator will help avoid writing unnecessary code. The
problem, of course, will be catching errors. It is not clear how to catch
errors by a specific value. I will think about it.
Hi,
I don't see the point of this operator, php doesn't allow any operation
over null.
It's throwing warning (mostly for backwards compatibility), I'd rather have
it throw error in next php version.
Static analysis already complain about it, so whats the point of !->
operator?
https://phpstan.org/r/c9d6e7b3-ac66-4e91-81e8-af0cafdc976c
On Friday, 7 Feb 2025 at 10:45, Faizan Akram Dar hello@faizanakram.me
wrote:
Thank you for your answer. Now I will give examples for better
understanding.Simple examples from Typescript:
let foo = ...
foo!.bar()
foo!.someProperty.baz()Examples of potentially using in PHP:
Without this operator we writing this code:$foo = ...
if ($foo === null) {
throw new FooIsNullException();
}$foo->bar.
With this operator:
$foo!->bar
$foo!->someProperty->method();
$foo!->someProperty->anotherProperty!->method();I think the postfix operator would be illogical in PHP because my
operator is similar to the existing nullsafe operator in syntax. And it
would be strange if its syntax were different.
Or we can implement both operator syntaxes: prefix for accessing
properties, and postfix for use with variables, as in your example.Nullsafe:
$foo?->bar;
Not null assertion:
$foo!->bar;If variable bar would be null - php will throw an exception. But now i
dont know which exception it would be :)This operator will be useful in cases where a null value in a specific
place will violate the domain logic. Usually we write either assertions or
checks and throw our exceptions for this. But it seems to me that the not
null assertion operator will help avoid writing unnecessary code. The
problem, of course, will be catching errors. It is not clear how to catch
errors by a specific value. I will think about it.Hi,
I don't see the point of this operator, php doesn't allow any operation
over null.It's throwing warning (mostly for backwards compatibility), I'd rather
have it throw error in next php version.Static analysis already complain about it, so whats the point of !->
operator?
https://phpstan.org/r/c9d6e7b3-ac66-4e91-81e8-af0cafdc976cStatic analysis already complain about it
That's exactly where !
is helpful. If at a certain point I am sure that a
property must not be null and I want to make that explicit (to both
developer and static analyzer), I can use
assert($obj->prop !== null)
. However, that requires an extra line of
code. $obj->prop!->x
would be much prettier.
--
Valentin
Thank you for your answer. Now I will give examples for better understanding.
Simple examples from Typescript:
let foo = ...
foo!.bar()
foo!.someProperty.baz()Examples of potentially using in PHP:
Without this operator we writing this code:$foo = ...
if ($foo === null) {
throw new FooIsNullException();
}$foo->bar.
With this operator:
$foo!->bar
$foo!->someProperty->method();
$foo!->someProperty->anotherProperty!->method();I think the postfix operator would be illogical in PHP because my operator is similar to the existing nullsafe operator in syntax. And it would be strange if its syntax were different.
Or we can implement both operator syntaxes: prefix for accessing properties, and postfix for use with variables, as in your example.Nullsafe:
$foo?->bar;
Not null assertion:
$foo!->bar;If variable bar would be null - php will throw an exception. But now i dont know which exception it would be :)
This operator will be useful in cases where a null value in a specific place will violate the domain logic. Usually we write either assertions or checks and throw our exceptions for this. But it seems to me that the not null assertion operator will help avoid writing unnecessary code. The problem, of course, will be catching errors. It is not clear how to catch errors by a specific value. I will think about it.
Hi,
I don't see the point of this operator, php doesn't allow any operation over null.
It's throwing warning (mostly for backwards compatibility), I'd rather have it throw error in next php version.
Static analysis already complain about it, so whats the point of !-> operator?
https://phpstan.org/r/c9d6e7b3-ac66-4e91-81e8-af0cafdc976cStatic analysis already complain about it
That's exactly where
!
is helpful. If at a certain point I am sure that a property must not be null and I want to make that explicit (to both developer and static analyzer), I can use
assert($obj->prop !== null)
. However, that requires an extra line of code.$obj->prop!->x
would be much prettier.--
Valentin
I don't necessarily agree that it is prettier. It also is kinda pointless to use in parameter type hints because by default, it cannot be nullable unless you explicitly declare it is nullable.
Personally, what I would rather see would be making variables non-null by default. In other words, no variable can store null unless explicitly declared as such. Something like this:
$canBeNull? = null; // ?= means the variable on the left can hold null
$cannotBeNull = null; // TypeError
This gets us closer to typed languages, but still very free-form. You can assign anything you want into either variable, but you can only assign null to $canBeNull.
We already have this, sorta, via parameter types, and it would be nice to extend it to the rest of the language as well.
— Rob
On Tue, 11 Feb 2025, 17:07 Valentin Udaltsov, udaltsov.valentin@gmail.com
wrote:
Static analysis already complain about it
That's exactly where
!
is helpful. If at a certain point I am sure that
a property must not be null and I want to make that explicit (to both
developer and static analyzer), I can use
assert($obj->prop !== null)
. However, that requires an extra line of
code.$obj->prop!->x
would be much prettier.--
Valentin
Hi Valentin,
I still don't see the added value. PHP isn't Java—there are no hidden null
pointer exceptions. Accessing a property on null triggers a runtime
warning, and static analysis already flags it. It’s better if PHP throws an
error in such cases, as it does when calling methods on null.
Since types don’t include null by default, and assigning null to a typed
property already throws an error, I don’t think an additional operator is
necessary.
Best,
Faizan
Examples of potentially using in PHP:
Without this operator we writing this code:$foo = ...
if ($foo === null) {
throw new FooIsNullException();
}$foo->bar.
With this operator:
$foo!->bar
$foo!->someProperty->method();
$foo!->someProperty->anotherProperty!->method();
I see where you're coming from, in my code I had to deal with a lot of
APIs with models which have nullable properties, but they shouldn't be
null if some conditions are met.
So I work with them in this way
if ($response->code === ResponseCode::Success) {
// order and quantity are nullable
return $response->data->order->quantity ?? throw new
UnexpectedResponseException($response);
// With method calls you would need to add nullsafe operators
// order and date are nullable
return $response->data->order?->date?->format('Y-m-d') ?? throw
new UnexpectedResponseException($response);
}
UnexpectedResponseException is just an exception that keeps faulty
response, so I can catch it and act on it, or it just gets logged and
I can show producers of API that they have a problem.
I see a point in !-> operator if it would work just like that. Throws
a specific error that has an object that triggered this error.
Examples of potentially using in PHP:
Without this operator we writing this code:$foo = ...
if ($foo === null) {
throw new FooIsNullException();
}$foo->bar.
With this operator:
$foo!->bar
$foo!->someProperty->method();
$foo!->someProperty->anotherProperty!->method();I see where you're coming from, in my code I had to deal with a lot of
APIs with models which have nullable properties, but they shouldn't be
null if some conditions are met.
So I work with them in this wayif ($response->code === ResponseCode::Success) { // order and quantity are nullable return $response->data->order->quantity ?? throw new UnexpectedResponseException($response); // With method calls you would need to add nullsafe operators // order and date are nullable return $response->data->order?->date?->format('Y-m-d') ?? throw new UnexpectedResponseException($response); }
UnexpectedResponseException is just an exception that keeps faulty
response, so I can catch it and act on it, or it just gets logged and
I can show producers of API that they have a problem.I see a point in !-> operator if it would work just like that. Throws
a specific error that has an object that triggered this error.
Hello,
I feel like that is more of an architecture problem than a programming one though. Instead of constantly checking if the conditions are right, use php's type system instead, so it would read more like:
if ($response instanceof SuccessfulResponse) {
return $response->data->order->quantity;
}
throw new UnexpectedResponseException($response);
I'd argue that having an "undefined" aka "null" quantity in a model at all is rather strange as that doesn't seem to represent any possible reality outside of a computer (unless you are dealing with Schrodinger's cat or other quantum effects).
— Rob
Hello,
I feel like that is more of an architecture problem than a programming one though. Instead of constantly checking if the conditions are right, use php's type system instead, so it would read more like:
if ($response instanceof SuccessfulResponse) {
return $response->data->order->quantity;
}throw new UnexpectedResponseException($response);
I'd argue that having an "undefined" aka "null" quantity in a model at all is rather strange as that doesn't seem to represent any possible reality outside of a computer (unless you are dealing with Schrodinger's cat or other quantum effects).
— Rob
Hi,
The thing is I am just a consumer of the API, before implementing I
did have a thought about having Successful and Error DTOs, but for me
that was more work for the same result. First I need to map JSON to
generic Response, then do some checks and map from generic Response to
another DTO. And it's not just success and error, there are about 20
response codes and several variations of response you could get.
And I absolutely agree about null quantity, some of the objects there
have every property nullable, it's insane.
HI!
I was referring to this particular scenario of using this operator.
Constantly writing checks and nullsafes seems like something superfluous.
If we have an opportunity at the language level to throw a domain exception
or something like that, it will be convenient. Besides, it will also be
useful for static analysis. There will be no null pointers in the code.
пт, 7 февр. 2025 г. в 14:21, MrMeshok ilyaorlov124@gmail.com:
Examples of potentially using in PHP:
Without this operator we writing this code:$foo = ...
if ($foo === null) {
throw new FooIsNullException();
}$foo->bar.
With this operator:
$foo!->bar
$foo!->someProperty->method();
$foo!->someProperty->anotherProperty!->method();I see where you're coming from, in my code I had to deal with a lot of
APIs with models which have nullable properties, but they shouldn't be
null if some conditions are met.
So I work with them in this wayif ($response->code === ResponseCode::Success) { // order and quantity are nullable return $response->data->order->quantity ?? throw new UnexpectedResponseException($response); // With method calls you would need to add nullsafe operators // order and date are nullable return $response->data->order?->date?->format('Y-m-d') ?? throw new UnexpectedResponseException($response); }
UnexpectedResponseException is just an exception that keeps faulty
response, so I can catch it and act on it, or it just gets logged and
I can show producers of API that they have a problem.I see a point in !-> operator if it would work just like that. Throws
a specific error that has an object that triggered this error.