I’ve seen it used in a kirbycast:
$album->image()?->url()
As far as I understand, this will execute url() method only if image is true/truish ? correct ?
where does it come from ? is it documented?
I mean I already love it <3
Thanks
I’ve seen it used in a kirbycast:
$album->image()?->url()
As far as I understand, this will execute url() method only if image is true/truish ? correct ?
where does it come from ? is it documented?
I mean I already love it <3
Thanks
almost. only if the thing before the question mark is !== null
. if it is null then stop execution of following function calls and return null.
its called the nullsafe operator
. a nice introduction can be found here:
Does an empty field always return null ?
If a field does not exist , so if a method does not exist, do we get null ?
Thanks
No. You can easily test what you get yourself by doing
dump($page->doesNotExist());
This will always give you a field object, no matter if the field exists or is empty.
There are methods to check if a field exists or is empty.
Hmmm
So we cannot use null safe op. as a substitute of isNotEmpty() then ?
For example:
$d->duration()?->toDate("H'h' mm'' ss''''")
instead of:
$d->duration()->isNotEmpty() ? $d->duration()->toDate("H'h' mm'' ss''''") : '';
In the case of image() , the method does explicitly return null if no image is found, that is why we can use it, I understand that.
No.
The purpose of the null safe operator is to prevent errors of calling a member method on null. So using it only makes sense if the method you call is supposed to return an object but can return null, and you want to call a member method of this objects’s class.
Now that we are at it, is there any method that allows for empty checking then chain, that is not a ternary etc ?
I always hated the verbosity and repetition of a typical:
<?= $d->elementdescription()->isNotEmpty() ? $d->elementdescription()->inline() : '' ?>
And for a moment thought I could do:
(wrong)
<?= $d->elementdescription()?->inline() ?>
Any equivalents ?
Assuming that echoing an empty field is not considered bad practice for some reason.
Thank you
Well, the problem with particularly the inline
method is, that the strip_tags()
method that is used internally in the inline()
method expects a string instead of null:
'inline' => function (Field $field) {
$field->value = strip_tags($field->value, Html::$inlineList);
return $field;
},
I think that is something that should be fixed in Kirby (`inline` field method throws when empty field value is passed · Issue #5061 · getkirby/kirby · GitHub). Usually, you should just be able to call
<?= $page->emptyOrNotExisting()->inline() ?>
So the issue why you get an error here has nothing to do with calling a member method on null, because emptyOrNotExisting()
does return a field. It is something that happens inside the method.
Oh I see,
I actually meant any usual operation on fields that needs a check on the field containing anything, such as:
<?= $page->startdate()->isNotEmpty() ? $page->startdate()->toDate('MMM d - ') : '' ?>
<?= $artwork->elementdescription()->isNotEmpty() ? $artwork->elementdescription()->kirbytextinline() : '' ?>
etc, which are very common in my code.
Assuming that inline() is the only method with that particular behaviour.
Thanks
As I said, checking if the field is empty in this case is not necessary at all. I don’t know why you are doing it. It makes sense in such a case:
<?php if ($page->startdate()->isNotEmpty()) : ?>
<div class="whatever"><?= $page->startdate()->toDate('MMM d - ') ?></div>
<?php endif ?>
i.e to prevent outputting an empty div.
Ok, I wasn’t aware of that, thank you.
That’s also why there are places where the null-safe operator makes sense and where it doesn’t. For example if I just want to ouput an image url if the image exists:
<?= $page->image()?->url() ?>
But it doesn’t make sense when I want to do the following:
<?php if ($image = $page->image()?>
<figure>
<img src="<?= $image->url() ?>">
<figcaption><?= $image->caption() ?></figcaption>
</figure>
<?php endif ?>
Of course I could do:
<figure>
<img src="<?= $page->image()?->url() ?>">
<figcaption><?= $page->image()?->caption() ?></figcaption>
</figure>
But that would be silly.
Ok
But If I chain methods, and the field is empty, and there is no null-safe, the second method may be called upon null and throw an exception, correct?
$page->field()->method1()->method2()
If that is correct, then it may be I encountered one of these situations and I started checking for isNotEmpty by default, even when not chaining methods, which is not necessary as I see…
The important thing to understand is
$page->field()
always returns a field object, no matter if this field exists or not, otherwise it wouldn’t even be possible to call $page->field()->exists()
, because that then would throw a “calling member method exists
on null”.
Any field method (i.e. what you call on that field, e.g. $page->date()->toDate()
can return something different. Some of these methods return a field object again, for example $page->doesnotexist()->kt()
, so you could call $page->doesnotexist()->kt()->esc()
without issues.
However, some field methods do not return a field object, but a string, integer, boolean, array, or other type of object so you cannot chain another field method onto it, even if the field is not empty, these are for example, toSlug()
, toDate()
, toBool()
, words()
, toPages()
etc…
In most cases, our Reference tells you for every single method what it returns.