PHP Internals News: Episode 65: Null safe operator – Derick Rethans

PHP Internals News: Episode 65: Null safe operator

In this episode of “PHP Internals News” I chat with Dan Ackroyd (Twitter, GitHub) about the Null Safe Operator RFC.

The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode’s MP3 file, and it’s available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news

Transcript

Derick Rethans 0:18

Hi, I’m Derick, and this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language. This is Episode 65. Today I’m talking with Dan Ackroyd about an RFC that he’s been working on together with Ilija Tovilo. Hello, Dan, would you please introduce yourself?

Dan Ackroyd 0:37

Hi Derick, my name is Daniel, I’m the maintainer of the imagick extension, and I occasionally help other people with RFCs.

Derick Rethans 0:45

And in this case, you helped out Ilija with the null safe operator RFC.

Dan Ackroyd 0:50

It’s an idea that’s been raised on internals before but has never had a very strong RFC written for it. Ilija did the technical implementation, and I helped him write the words for the RFC to persuade other people that it was a good idea.

Derick Rethans 1:04

Ilija declined to be talking to me.

Dan Ackroyd 1:06

He sounds very wise.

Derick Rethans 1:08

Let’s have a chat about this RFC. What is the null safe operator?

Dan Ackroyd 1:13

Imagine you’ve got a variable that’s either going to be an object or it could be null. The variable is an object, you’re going to want to call a method on it, which obviously if it’s null, then you can’t call a method on it, because it gives an error. Instead, what the null safe operator allows you to do is to handle those two different cases in a single line, rather than having to wrap everything with if statements to handle the possibility that it’s just null. The way it does this is through a thing called short circuiting, so instead of evaluating whole expression. As soon as use the null safe operator, and when the left hand side of the operator is null, everything can get short circuited, or just evaluates to null instead.

Derick Rethans 1:53

So it is a way of being able to call a methods. A null variable that can also represent an object and then not crash out with a fatal error

Dan Ackroyd 2:02

That’s what you want is, if the variable is null, it does nothing. If a variable was the object, it calls method. This one of the cases where there’s only two sensible things to do, having to write code to handle the two individual cases all the time just gets a bit tedious to write the same code all the time.

Derick Rethans 2:20

Especially when you have lots of nested calls I suppose.

Dan Ackroyd 2:25

That’s right. It doesn’t happen too often with code, but sometimes when you’re using somebody else’s API, where you’re getting structured data back like in an in a tree, it’s quite possible that you have the first object that might be null, it’s not null, it’s going to point to another object, and the object could be null so and so so down the tree of the structure of the data. It gets quite tedious, just wrapping each of those possible null variables with a if not null.

Derick Rethans 2:55

The RFC as an interesting ex

Truncated by Planet PHP, read more at the original (another 22729 bytes)

Byte-sized functional programming: Filter first – larry@garfieldtech.com

Byte-sized functional programming: Filter first

Often when working with a list, we only want to work with a subset of a list that meets some criteria. All non-zero values, for example, or all users that have a given role. The procedural way to do that is to stick an if statement inside a foreach loop:

<?php
foreach ($list as $value) {
    If (!
meets_criteria($value)) {
        continue;
    }
   
// ...
}
?>

That mixes up the filtering with the iteration, though. It also doesn’t work if we’re using `array_map()`.

Instead, we can make stripping down the list a separate operation called “filter.” PHP offers the array_filter() function for that purpose.

<?php
$criteria
= fn(User $user): bool => $user->hasRole('moderator');

$filtered = array_filter($users, $criteria);
?>

Now we can work with the `$filtered` list, which has only the values we want. That could be a simple foreach loop, or, better, it's now ideally suited for use with array_map().


Want to know more about functional programming and PHP? Read the whole book on the topic: Thinking Functionally in PHP.

Thinking Functionally in PHP

Larry
3 August 2020 - 1:47pm

PHP Internals News: Episode 64: More About Attributes – Derick Rethans

PHP Internals News: Episode 64: More About Attributes

In this episode of “PHP Internals News” I chat with Benjamin Eberlei (Twitter, GitHub, Website) about a few RFCs related to Attributes.

The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode’s MP3 file, and it’s available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news

Transcript

Derick Rethans 0:17

Hi, I’m Derick, and this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language. This is Episode 64. Today I’m talking with Benjamin Eberlei, about a bunch of RFCs related to Attributes. Hello Benjamin, how are you this morning?

Benjamin Eberlei 0:36

I’m fine. I’m very well actually yeah. The weather’s great.

Derick Rethans 0:39

I can see that behind you. Of course, if you listen to this podcast, you can’t see the bright sun behind Benjamin, or behind me, by the way. In any case, we don’t want to talk about the weather today, we want to talk about a bunch of RFCs related to attributes. We’ll start with one of the RFCs that Benjamin proposed or actually, one of them that he has proposed and one of them that he’s put into discussion. The first one is called attribute amendments.

Benjamin Eberlei 1:05

Yes.

Derick Rethans 1:06

What is attribute amendments about?

Benjamin Eberlei 1:08

So the initial attributes RFC, and we talked about this a few months ago was accepted, and there were a few things that we didn’t add because it was already a very large RFC, and the feature itself was already quite big. Seems to be that there’s more sort of an appetite to go step by step and put additional things, in additional RFCs. So we had for, for I think about three or four different topics that we wanted to talk about, and maybe amend to the original RFC. And this was sort of a grouping of all those four things that I wanted to propose and change and Martin my co author of the RFC and I worked on them and proposed them.

Derick Rethans 1:55

What are the four things that your new RFC was proposing?

Benjamin Eberlei 1:59

Yes, so the first one was renaming Attribute class. So, the class that is used to mark an attribute from PHP attributes to just attribute. I guess we go into detail in a few seconds but I just list them. The second one is an alternative syntax to group attributes and you’re safe a little bit on the characters to type and allowed to group them. And the third was a way to validate which declarations, an attribute is allowed to be set on, and the force was a way to configure if an attribute is allowed to be declared once or multiple times on one declaration.

Derick Rethans 2:45

Okay, so let’s start with the first one which is renaming the class to Attribute.

Benjamin Eberlei 2:51

Yeah, so in the initial RFC, there was already a lot of discussion about how should this attribute class be caught. Around that time that PhpToken RFC was also accepted, and so I sort of chose this out of a compromise to use PhpAttribute, because it is guaranteed to be a unique name that nobody would ever have used before. There’s also, there was also a lot of talk about putting an RFC, to vote, about namespacing in PHP, so namespacing internal classes and everything. So I wanted to keep this open at the at the time and not make it a contentious decision. After the Attributes RFC was accepted, then namespace

Truncated by Planet PHP, read more at the original (another 29493 bytes)

Relying on the database to validate your data – Matthias Noback

One of my pet peeves is using the database schema to validate data.

Several ways in which this normally happens:

  • Specifying a column as “required”, e.g. email VARCHAR(255) NOT NULL
  • Adding an index to force column values to be unique (e.g. CREATE UNIQUE INDEX email_idx ON users(email))
  • Adding an index for foreign key integrity, including cascading deletes, etc.

Yes, I want data integrity too.
No, I don’t want to rely on the database for that.

I find it surprising that some years ago we decided that we shouldn’t write application logic in our database (e.g. stored procedures) because:

  • They are not written in the same language as the rest of the project.
  • They are not version-controlled (unless you jump through some extra hoops).
  • They are not testable in isolation; you need an actual database to run them.
  • They are “magic” because they are triggered implicitly.
  • The code is vendor-specific.

Well, anyway, it’s clear that we don’t want them.

Yet, many of these concerns apply to validation at the database-level as well.
Except, with stored procedures we actually delegate some work to the database.
With validation, we usually duplicate the work.
We first validate in the code that a value has been provided and show a form error if it hasn’t.
Then we use an assertion in our model object to verify that a value is not null.
Then we save our object to the database, which again verifies that the value is not null.

Why do we do this?
Maybe because we want symmetry?
The model property is not nullable, so the column it’s mapped to should also not be nullable.
Maybe because we are more confident about the database than about our code?
In the code a validation might be skipped somehow, but we’ll always have that extra validation once the data ends up in the database.

Non-nullability

I think we don’t need the symmetry, nor the safe-guard.
Instead, we should put more trust in our application code and make sure everything is handled there.
No need for the “double bookkeeping” where you try to keep the nullability of your model’s properties in sync with the nullability of the database columns.
In my experience often a model property is nullable, but the database column isn’t, or vice versa.
This leads to the application blowing up for a nullability discrepancy between the code and the database.
We can reduce this risk by stopping the double bookkeeping.
Instead of defining non-nullability on database columns, let’s only define it in the code.
We always have to deal with non-nullability in the code anyway, since we want validation errors instead of SQL errors.
So, let’s just remove NOT NULL everywhere, hooray!

Unique indexes

Another interesting database-level validation technique is ensuring uniqueness, like in the case of the unique email address in the users table.
Apparently, we don’t trust the application here either, and leave the verification of an important rule to the database (we’ll talk later about how important it really is).
Given that the database supports a uniqueness check by means of adding an index we jump in and add it to every column we feel should be unique.
We then realize that we don’t want SQL errors when a user registers with a known email address.
We want form validation errors instead.
Then we introduce some more double bookkeeping so we can be user-friendly and protect our data integrity.

What if we only validate the uniqueness of the email address in the application code and not in the database?
We could end up with two records in the users table that have the same email address.
It’s unlikely that this will happen though, because the application always runs the uniqueness validation itself, by querying the table for an existing record with the provided email address:

if ($this->userRepository->containsUserWithEmailAddress($emailAddress)) { // show form error in the response
} else { // the data is valid $user = new User($emailAddress); $this->userRepository->save($user);
}

The only way we could end up with duplicate records is when two registration requests providing the same email address are being processed at the same time.
In that case, the first containsUserWithEmailAddress() may return false during both of these requests and the call to save() would result in two records with the same email address.
Again, it’s not very likely, but it could happen.
But what if it happens?
We just have to make sure it has no significant impact.

I think the biggest fear when having duplicate email addresses in the database is that someone might b

Truncated by Planet PHP, read more at the original (another 8982 bytes)

Save your Drupal team hours and effort with Source Operations and Activity Scripts – platform.sh

FleetOps—running a large fleet of apps and websites efficiently, securely, and predictably—is a challenge for every organization. One difficulty facing organizations managing multiple Drupal sites is keeping their dependencies current. For instance, each time a crucial security update is released, how many resources end up being spent making sure each site has properly been patched? How many team hours could be saved by automating dependency processes?
On Platform.sh, you can deploy your Drupal projects complete with a set of customized Source Operations that will automatically check for and apply updates using Composer to a development environment.

Byte-sized functional programming: Mapping out your data – larry@garfieldtech.com

Byte-sized functional programming: Mapping out your data

Procedural code tends to think in terms of writing out steps, and so the usual way to work with a list is to iterate it using a `for` or `foreach` loop.

Functional code tends to think in terms of the relationships and transformations between data, where those relationships and transformations are defined as functions. That means the natural way to work with a list is to define a function that is the relationship between one list and another. The most common way of doing that is with a “map,” which in PHP usually means the `array_map()` function.

With `array_map()`, you give it an array and a function. You get back the result of applying that function to every element in the array, individually. Like so:

<?php
$arr
= [1, 2, 3, 4, 5];
$fun = fn($x) => $x * 2;
$result = array_map($fn, $arr);
?>

The advantages of that over a `foreach` loop are:

* The function is a separate operation that can be as complex as you want.
* If it’s more than a line or two, make it its own function or method somewhere and test it in isolation.
* If it’s trivial, you can simply inline it.
* It’s clear, visually, that every element’s transformation is independent of every other’s, because that’s how `array_map()` works. A `foreach` loop may maintain state from one iteration to the next, but `array_map()` does not.


Want to know more about functional programming and PHP? Read the whole book on the topic: Thinking Functionally in PHP.

Thinking Functionally in PHP

Larry
27 July 2020 – 3:42pm

PHP Internals News: Episode 63: Property Write/Set Visibility – Derick Rethans

PHP Internals News: Episode 63: Property Write/Set Visibility

In this episode of “PHP Internals News” I talk with André Rømcke (Twitter, GitHub) about an RFC that he is working on to get asymmetric visibility for properties.

The RSS feed for this podcast is https://derickrethans.nl/feed-phpinternalsnews.xml, you can download this episode’s MP3 file, and it’s available on Spotify and iTunes. There is a dedicated website: https://phpinternals.news

Transcript

Derick Rethans 0:16

Hi, I’m Derick, and this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language. This is Episode 63. Today I’m talking with André Rømcke, about an RFC that he’s proposing titled property write/set visibility. Hello André, would you please introduce yourself?

André Rømcke 0:38

Hi Derick, I’m, where to start, that’s a wide question but I think I’ll focus on the technical side of it. I’m been doing PHP for now 15 plus years. Actually started in, eZ systems, now Ibexa, met with you actually Derick.

Derick Rethans 0:56

Yep that’s a long time ago for me.

André Rømcke 0:58

And well I came from dotnet and front and side of things. Eventually I learned more and more in PHP and you were one of the ones getting me deeper into that, while you were working on eZ components. I was trying to profile and improve eZ publish which what’s left of the comments on that that point. A long time ago, though. A lot of things and I’ve been working in engineering since then I’ve been working now actually working with training and more of that, and the services and consulting. One of the pet peeves I’ve had with PHP has been properties for a long time, so I kind of wanted several, several years ago to look into this topic. Overall, like readonly, immutable. To be frank from our side that the only thing I really need is readonly, but I remember the discussions I was kind of involved for at least on the sideline in 2012/ 2013. Readonly and then there was property accessors. And I remember and there was a lot of people with different needs. So that’s kind of the background of why I proposed this.

Derick Rethans 2:04

We’ll get back to these details in a moment, I’m sure. The title of the RFC is property write/set visibility. Can you give me a short introduction of what visibility actually means in this contract, in this context?

André Rømcke 2:16

Visibility, I just use the word visibility because that’s what doc usually in php.net says, but it’s about access the property, so to say, or it being visible to your code. That’s it on visibility but today we can only set one rule so to say, we can only say: this is either public, private, or protected, and in other languages, there are for good reasons, possibilities to have asynchronous visibility. So, or disconnected or whatever you want to call it, between: Please write and read. And then in, with accessors you’ll also have isset() and unset() but that’s really not the topic here at this point.

Derick Rethans 2:56

PHP sort of supports these kind of things, with it’s magic methods, like with __get() and __set(). And then also isset() and unset(). You can sort of implement something like this, of course, in your own implementation, but that’s, of course, ugly, I mean, ugly or, I mean there was no other way for doing it and I remember, you made have a user that in eZ Components that you mentioned earlier. What is the main problem that you’re wanting to solve with what this RFC proposes?

André Rømcke 3:25

the high level use case is in order to let people, somehow, define that their

Truncated by Planet PHP, read more at the original (another 17389 bytes)