Xdebug Update: May 2021 – Derick Rethans

Xdebug Update: May 2021

Another monthly update where I explain what happened with Xdebug development in this past month. These will be published on the first Tuesday after the 5th of each month.

Patreon and GitHub supporters will get it earlier, around the first of each month.

You can become a patron or support me through GitHub Sponsors. I am currently 51% towards my $2,000 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through a subscription.

In May, I worked on Xdebug for about 25 hours, with funding being around 30 hours.

Xdebug 3.1

I’m continuing to track PHP 8.1’s development and have now added support for Fibers in the debugger. I have not spend time adding support for the new Enum yet, but that should happen soon. I suspect that more work to make Xdebug PHP 8.1 compatible is going to be required in the future too.

After meeting with a developer of the PHP Debug Adapter for Visual Studio Code, I’ve started to work on some of the things that he raised. For example, there is now a new protocol feature that makes Xdebug include information about the breakpoint that was hit.

He also raised a bug where Xdebug truncates log messages and with UNC paths. I have fixed the first one, but the second one requires more investigation and a “clever solution”.

Xdebug Videos

I have published another videos on how to use Xdebug on my YouTube channel.

This one deals about Debugging the Symfony Demo App in Docker with VS Code.

I have been working on another animated video where I explain how to activate Xdebug’s features with triggers and settings. This should come out in the next few weeks.

If you would like to see a 5 to 10 minute long video on another specific topic, feel free to email me at derick@xdebug.org.

Xdebug Cloud

Xdebug Cloud is continuing to operate as Beta release, and provides an easy way to debug your PHP applications with Xdebug, without having to deal with complexities with regards to networking.

Packages start at £49/month, and revenue will also be used to further the development of Xdebug.

If you want to be kept up to date with Xdebug Cloud, please sign up to the mailinglist, which I will use to send out an update not more than once a month.

PHP Internals News: Episode 88: Pure Intersection Types – Derick Rethans

PHP Internals News: Episode 88: Pure Intersection Types

In this episode of “PHP Internals News” I talk with George Peter Banyard (Website, Twitter, GitHub, GitLab) about the “Pure Intersection Types” RFC that he has proposed.

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:14

Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is Episode 88. Today I’m talking with George Peter Banyard about pure intersection types. George, could you please introduce yourself?

George Peter Banyard 0:30

Hello, my name is George Peter Banyard. I work on PHP code development in my free time. And on the PHP Docs.

Derick Rethans 0:36

This RFC is about intersection types. What are intersection types?

George Peter Banyard 0:40

I think the easiest way to explain intersection types is to use something which we already have, which are union types. So union types tells you I want X or Y, whereas intersection types tell you that I want X and Y to be true at the same time. The easiest example I can come up with is a traversable that you want to be countable as well. So traversable and countable. Currently, you can do intersection types in very hacky ways. So you can either create a new interface which extends both traversable and countable, but then all the classes that you want to be using this fashion, you need to make them implement the interface, which might not be possible if you using a library or other things like that. The other very hacky way of doing it is using reference and typed properties. You assign two typed properties by reference, one being traversable, one being countable, and then your actual property, you type alias reference it, with both of these properties. And then my PHP will check: does the property respect type A those reference? If yes, move to the next one. It doesn’t respect type B, which basically gives you intersection types.

Derick Rethans 1:44

Yeah, I saw that in the RFC. And I was wondering like, well, people actually do that?

George Peter Banyard 1:49

The only reason I know that is because of Nikita’s slide.

Derick Rethans 1:51

The thing is, if it is possible, people will do it, right. And that’s how that works.

George Peter Banyard 1:56

Yeah, most of the times.

Derick Rethans 1:57

The RFC isn’t actually called intersection types. It’s called pure intersection types. What does the word pure do here?

George Peter Banyard 2:05

So the word pure here is not very semantic. But it’s more that you cannot mix union types and intersection types together. The reasons for it are mostly technical. One reason is how do you mix and match intersection types and union types? One way is to have like union types take precedence over intersection types, but some people don’t like that and want to explicit it grouping all the time. So you need to do parentheses, A intersection B, close parentheses, pipe for the union, and then the other type. But I think the main reason is mostly the variance, like the variance checks for inheritance are already kind of complicated and kind of mind boggling.

Derick Rethans 2:44

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

PHP Internals News: Episode 87: Deprecating Ticks – Derick Rethans

PHP Internals News: Episode 87: Deprecating Ticks

In this episode of “PHP Internals News” I chat with Nikita Popov (Twitter, GitHub, Website) about the “Deprecating Ticks” 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:14

Hi I’m Derick, welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is episode 87. Today I’m talking with Nikita Popov about a much smaller RFC this time: Deprecating Ticks. Nikita, would you please introduce yourself.

Nikita Popov 0:34

Hi Derick, I’m Nikita, and I’m working on PHP core development on behalf of JetBrains.

Derick Rethans 0:40

Let’s jump straight into what this RFC is about, and that’s the word ticks. What are ticks?

Nikita Popov 0:46

Ticks are a declare directive,. You write declare ticks equals one at the top of your file, and then PHP we’ll call a tick function after every statement execution. Or if you write ticks equals two, then as we’ll call it the function after every two statement executions.

Derick Rethans 1:05

Do you have to specify which function that calls?

Nikita Popov 1:08

Of course, so there is also a register tick function and unregister tick function and that’s how you specify the function that should be called rather the functions.

Derick Rethans 1:17

How does this work, historically, because the RFC talks about the change being made in PHP seven?

Nikita Popov 1:22

Technically ticks work by introducing an opcode after every statement that calls the tick function depending on current count. The difference that was introduced in PHP seven is to what the tick declaration applies. The way PHP language semantics are supposed to work, is that declare directives are always local. The same way that strict types, only applies to a single file, ticks should also only apply to a single file. Prior to PHP seven, it didn’t work out way. So if you had declare ticks, somewhere in your file, it would just enable ticks from that point forward. If you included the different file or even if the autoloader was triggered and included a different file that one would also make use of ticks. That was fixed in PHP seven, so now it is actually file local, but that also means that the ticks functionality at that point behaviour became, like, not very useful. Because usually if you want to use tics you actually want them to apply it to your whole codebase. There are ways around that. I’m afraid to say that people have approached me after this RFC and told me that they actually do that. The way around that is to register a stream wrapper. It’s possible in PHP to unregister the file stream wrapper and register your own one, and then it’s possible to intercept all the file includes and rewrite the file contents to include the declare ticks at the top of the file. I do use that general mechanism for real things in other places, but apparently people actually use that to like instrument, a whole application with ticks, and essentially restore the behaviour we had in PHP 5.

Derick Rethans 3:03

What was the intended use case for ticks to begin with?

Nikita Popov 3:07

Well I’m not sure what was the intended use case, but at least it was the main use case, and that’s signal handl

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

Good technical writing is hard – larry@garfieldtech.com

Good technical writing is hard

A few days ago, I randomly tossed this out on Twitter without context:

Technical writing requires assuming the reader is simultaneously highly intelligent and utterly ignorant, without making them feel like you think they’re utterly ignorant.

That shit is hard, yo.

Someone asked for ideas on how to achieve that goal, and it seemed like a topic worthy of discussion so here we are.

Technical writing is not for Dummies

I would expand the statement above a bit, actually. Good technical writing requires:

Larry
31 May 2021 – 8:07pm

Setting emails in Yii1 to not trigger Out of Office responses. – Ken Guest

Christian Weiske recently wrote on how to set emails in Laravel to not trigger Out of Office responses.

This is typically done for emails that are auto-generated – for processes such as “Forgot Password” functionality and the like. There’s an RFC for this. In essence, you add an “Auto-Submitted: auto-generated” header to the email.

As I’ve been adding “Forgot Password” functionality for a legacy project, I thought I would see how this would be done in Yii1:

$yMessage = new YiiMailMessage();

$yMessage->addTo($to);
$yMessage->setFrom($fromEmail, $fromName);

$yMessage->setBody($htmlMessage, "text/html", "UTF-8");

$yMessage->setSubject(Yii::t("Link for resetting your password"));

// Mark the email as auto-generated so "Out of office" responses aren't triggered. (RFC-3834)

// https://cweiske.de/tagebuch/laravel-notification-autosubmit.htm

$yMessage->getHeaders()->addTextHeader("Auto-Submitted", "auto-generated");

Yii::app()->mail->send($yMessage);

This is much simpler in Yii1 than Laravel as no callbacks are required.

Don’t test constructors – Matthias Noback

@ediar asked me on Twitter if I still think a constructor should not be tested. It depends on the type of object you’re working with, so I think it’ll be useful to elaborate here.

Would you test the constructor of a service that just gets some dependencies injected? No. You’ll test the behavior of the service by calling one of its public methods. The injected dependencies are collaborating services and the service as a whole won’t work if anything went wrong in the constructor.

Would you test the constructor of a DTO? No. A DTO is by definition a simple object with no behavior, which allows you to pass data in a structured way. The data will be copied to the DTO and used in some other place, so when something goes wrong with assigning values to properties, you will know it when you test the service that uses the DTO.

Would you test the constructor of an entity? Yes, but in very specific ways, none of which is this one:

public function testConstructor(): void
{ $user = new User('Name', 'M'); self::assertSame('Name', $user->getName()); self::assertSame('M', $user->getGender());
}

(“Why do we need to know the user’s gender?” Great question. We don’t. We’ll get back to it.)

I like to call a test like this: “you can take out what you put in”, or: “it assigns the values to the right properties”. It’s a bad test and I’ll explain why.

Common constructor problems will be caught by your static analyzer

If you want to make sure the provided constructor arguments end up being assigned to the right properties, then just rely on static analyzers like PHPStan or Psalm (or even PhpStorm). They will point out that something is wrong, e.g. when you assign a value of the wrong type, or you rely on it to be non-optional, and so on. You don’t need to test these low-level things about your code.

Exposing state breaks encapsulation

If you still want to verify that a constructor assigns the right values to the right properties, then you either have to use reflection to peek into the private properties of the object, or you have to add public getters to the object. Both options break encapsulation. The object can no longer keep its internal data structures and inner workings to itself.

If you choose reflection, the test becomes fragile: it breaks whenever you change anything about the properties.

If you choose getters, you end up with methods that are initially only introduced for testing purposes, but eventually clients will start using those methods and relying on them, even if they weren’t meant to have access to all those values. These getters are not intention-revealing methods anyway, which causes the entity to have a very confusing API with too many public methods that don’t serve any real use case, except testing.

The test doesn’t explain why you need the property assignments

Even if you would allow breaking encapsulation by exposing too much state, the constructor test is still a bad test. It doesn’t answer why you need those property assignments. Do you need them so the getter can return the assigned value? That would be a circular argument. Take the constructor test away and you don’t need them anymore.

Asking “why” means we have to look at a higher abstraction level. Why do you need that property assignment?

  • Because that property will be mapped to a database column and you need that data to be in your database.

This answer needs some further soul searching. Why do you need this value to be in your database?

  1. Because you want to select the value and show it on some page.
  2. Because a legacy system relies on that particular value to be in that particular column.
  3. Because one of the stakeholders has told you to collect and save that data.

Replace the constructor unit test with some higher-level test

The rather unhelpful unit test that we have for the constructor doesn’t mention any of these reasons. Which is how knowledge about a system gets lost over time. Codifying all the reasons as tests, test descriptions, or possibly just comments in tests, would be a great way to preserve knowledge. It also helps us refrain from testing the implementation details of a class. Instead, we’ll be focussing on the behavior of the system as a whole, as we should. For example, providing a high-level test for reason 1:

Given the user registers themself as "Matthias

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

15 years of blogging – Evert Pot

<script src=”/assets/js/request-simulator.js”>

I’m a few days late, but as of May 25, 2021 I’ve had this blog for 15 years!
I guess it also makes this my longest running project.

The blog went through quite a few iterations and platforms, but the current
Github Pages iteration is about 8 years old already.

This is how it looked between 2006 and 2010:

My blog between 2006 and 2010

This was definitely the most elaborate design, but eventually I got sick of a
hand-written PHP and switched to a more plain Habari-based blog.

Habari Blog from 2011

I’ve had plans for years to move away from Github pages again, and do a custom
build. Github pages is so easy to use, but the lack of a server-side language
stifles my creativity a bit. I want to add a regular-old comment system again
and add websockets for bits of creativity.

Some stats

Habari Blog from ga

  • Since I started measuring in 2010, Google Analytics has reported
    2 million pageviews!
  • I’ve published 426 posts. The number of posts is trending downwards
    year-over-year. I find it harder to just write about a small interesting
    thing I came across, and posts tend to be more long-form now.
  • I wrote articles in 15 countries, in 5 continents!
  • I got 101 email subscribers.
Live map of every post on this blog. (see how I did this)

The most popular post ever is about following redirects in PHP, which
probably has to do more with good search keywords than anything. 144,565
pageviews.

I also wrote 68 posts for every HTTP status code. Combined, they got
202,656 page views as of today.

My proudest post is about HTTP/2, Server Push and compound documents,
because I added a bunch of interactivity that I think a lot of people loved.
I’d like to do more like this, but it was extremely time consuming. It must have
taken at least 100 hours!

Thanks!

Thanks everyone for reading and supporting! It’s all the great responses that
give me the energy and motivation to keep going =)

PHP Internals News: Episode 86: Property Accessors – Derick Rethans

PHP Internals News: Episode 86: Property Accessors

In this episode of “PHP Internals News” I chat with Nikita Popov (Twitter, GitHub, Website) about the “Property Accessors” 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:14

Hi I’m Derick. Welcome to PHP internals news, a podcast dedicated to explain the latest developments in the PHP language. This is episode 86. Today I’m talking with Nikita Popov about his massive property excesses RFC. Nikita, would you please introduce yourself?

Nikita Popov 0:32

Hi Derick, I’m Nikita, and I do work on PHP core development, on behalf of JetBrains.

Derick Rethans 0:39

This is probably the largest RFC I’ve seen in a while. What in one sentence, are you proposing to add to PHP here?

Nikita Popov 0:46

I would say it’s an alternative to magic get and set, just for one specific property instead of all of them. That’s the technical side. Maybe I should say something about the like motivation behind it, which is that since PHP seven four, we have type properties, that at least for me personally with that feature, the need to have this typical pattern of private property for storage, plus a public getter and setter methods, the main motivation for that has kind of gone away, because we can now use types to enforce any contracts on value. And now these getter and setter methods most if you like boilerplate. So the idea with accessors, at least my idea with accessors is that you really shouldn’t use them. You should just have them as a backup option. You declare a public property in your class, and then maybe later, years later, it turns out that okay, that property actually requires additional validation. And right now if you have a public property, then you don’t really have a good way of introducing that. Only way is to either break the API contract by converting the property into getter/setter methods where you can introduce arbitrary code, or by using magic get/set, which is definitely possible and persist the API contract, it’s just fairly ugly.

Derick Rethans 2:09

You changes the public property that people could read into a private one. And because it’s private, the set and get metric methods are being called.

Nikita Popov 2:18

Exactly.

Derick Rethans 2:19

This RFC is titled Property accesses, how do these improve on the situation?

Nikita Popov 2:24

So I think there are really two fairly orthogonal parts to this RFC. The first part is implicit accesses that don’t have any custom behaviour, and just allow controlling the behaviour of properties a bit more precisely. In particular, the most important part is probably the asymmetric visibility, where you have a property that’s publicly readable, but can only be set from within the class. So public read/ private write. I think that’s a, maybe the most common requirement. The second part is where you can actually introduce some custom behaviour. So where you can say that okay, the get behaviour for this property looks like this, and the set behaviour, it looks like this. Which is essentially exactly the same as what magic get/set does, just for a single property.

Derick Rethans 3:10

For example, when you then do set, or you can add additional validation to it.

Nikita Popov 3:14

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

PHP Internals News: Episode 85: Add IntlDatePatternGenerator – Derick Rethans

PHP Internals News: Episode 85: Add IntlDatePatternGenerator

In this episode of “PHP Internals News” I discuss the Add IntlDatePatternGenerator RFC with Mel Dafert (GitHub).

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:14

Hi I’m Derick, welcome to PHP internals news, the podcast, dedicated to explain the latest developments in the PHP language. This is episode 85. Today I’m talking with Mel Dafert about the “Add Intl Date Pattern Generator RFC” that she’s proposing for inclusion into PHP 8.1. Mel would you please introduce yourself?

Mel Dafert 0:35

Hello, I am Mel. I’ve been working professionally with PHP for about three years. Recently I started reading the internals mailing list in my free time, but this is my first time contributing.

Derick Rethans 0:46

What made you think starting to read the PHP internals mailing list?

Mel Dafert 0:50

I generally like reading mailing lists and issue trackers. And since I work with PHP, it was interesting to read what’s, what’s happening.

Derick Rethans 1:02

That’s what I’m trying to read this podcast as well of course; explaining what happens in the PHP development. But let’s get to your RFC. What is the problem that you’re trying to solve for this?

Mel Dafert 1:14

Currently, PHP exposes the ability for locale dependent date formatting with the Intl Date Formatter class. It is basically only three options for the format: long, medium and short. These options are not flexible enough in some cases, however. For example, the most common German format is day dot numerical month, dot long version of the year. However, neither the medium nor the short version provide this, and they use either the long version of the month, or a short version of the year, neither of which were acceptable in my situation.

Derick Rethans 1:47

I realize that you basically ran into a problem that PHP wasn’t doing something you wanted to do it. But what made you actually wanting to contribute this?

Mel Dafert 1:57

I ran into this exact problem at work where I wanted to format dates in this specific way. After some research, I found out that ICU, the library that powers Intl Date Formatter, exposes exactly this functionality already. It would be relatively easy to wire this up into PHP and expose it there as well. I also found in a bug report that other people had this problem as well, so I decided to try my best at hacking at the PHP source and make it available to everyone, using PHP.

Derick Rethans 2:25

Had you ever seen a PHP source code before?

Mel Dafert 2:28

I don’t think so. No.

Derick Rethans 2:29

But you are familiar with C a little bit?

Mel Dafert 2:32

On a very basic level, yes.

Derick Rethans 2:34

As part of this RFC What are you trying to suggest to add to PHP?

Mel Dafert 2:39

ICU exposes a class called date time pattern generator, which you can pass a locale and so called skeleton and it generates the correct formatting pattern for you. Skeleton just includes which part are supposed to include it, to be included in the pattern,

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

Early release of Rector – The power of automated refactoring – Matthias Noback

Book cover

In October 2020 I asked Tomáš Votruba, the mastermind behind Rector, if we could have a little chat about this tool. I wanted to learn more about it and had spent a couple of days experimenting with it. Tomáš answered all my questions, which was tremendously valuable to me personally. When this happens I normally feel the need to share: there should be some kind of artefact that can be published, so others can also learn about Rector and how to extend it based on your own refactoring needs.

I started writing a blog post but never published it, because it was just too much for a post. Creating automated refactorings is a slightly complex topic after all, and it needs a lot of background information for everyone to follow what’s going on. So a post was not enough. An alternative would be hours of video recordings, but in my opinion that would just be a waste of everyone’s time. In short, this situation actually called for a new book.

After another chat with Tomáš we decided to work on a book together. Making this a collaborative project was a great idea. Although my own team hasn’t used Rector extensively, I was able to bring real-world refactoring needs and extensive experience with test-driven development, and rely on Tomáš’ expert knowledge about Rector itself, and automated refactorings in general, to bundle lots of sound advice on this topic. It still took several months to finish the bigger part of this book. And although there are still a few chapters that need to be finished, we’d like to share with you now the current version of the book, which contains about a 148 pages of very useful content for developers who want to learn how Rector works and how to automatically refactor and improve their code bases.

You can get your copy now with 5 USD discount by using this link: https://leanpub.com/rector-the-power-of-automated-refactoring/c/RELEASE_DAY. When you buy it, make sure to sign up for notifications about future updates so you’ll get an email when we release the final chapters.

Book automation

As a little background information: the book itself is a mostly automated software project. We use:

  • PHPStan, to enforce correct types everywhere and learn about potential problems early.
  • Rector itself, to enforce certain programming standards, and to help us upgrade the code samples in the book to newer versions of PHP and Rector.
  • A custom-made output generation tool that runs processes like PHPUnit and Rector on the code samples before including them in the book. The process output like PHPUnit test results and diffs are persisted so we can easily include them in the manuscript.
  • A custom-made manuscript resource generation tool that takes working code samples, crops them, and copies them to the Leanpub’s manuscript folder.
  • EasyCodingStandard, to enforce a single code style, and to ensure (most of) the code samples don’t need line wrapping.

This is a very cool approach, and it’s completely different from my previous experiences in book publishing, both with Leanpub and with traditional publishers. With traditional publishing the problem is that you can’t easily make changes to the manuscript once it’s past a certain stage. With Leanpub you can always publish a new version. But if your book has code samples, you often just copy/paste them into the manuscript files. At that point, the code is no longer under test, so you can’t really trust it to be correct, and it becomes very hard to apply a different code style to all the samples at once.

With this automated approach we can just run any tool, then generate the snippets that are actually needed by the manuscript. This means we’ll learn about any problems with upgraded dependencies, and we’ll find out early if a change in Rector itself causes the examples in this book to break.