Derick RethansXdebug Update: October 2024 (5.11.2024, 10:10 UTC)

Xdebug Update: October 2024

In this monthly update I explain what happened with Xdebug development

GitHub and Pro/Business supporters will get it earlier, around the first of each month.

On GitHub sponsors, I am currently 31% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug. This is again less than last month.

If you are leading a team or company, then it is also possible to support Xdebug through a subscription.

In the last month, I spend around 10 hours on Xdebug, with 19 hours funded. I also spent 16 hours on the Native Path Mapping project.

PHP 8.4

I made the first beta release of Xdebug 3.4 that is compatible with PHP 8.4, which is due to be released on November 21st. I hope to have a GA release of Xdebug 3.4.0 out around that date too.

Beyond making that beta release, I have also looked into many bug reports, and fixed a few bugs.

As side-project to the new PIE installer, which is expected to replace PECL in the near future, a new Windows extension build action for GitHub actions has been created. I have been evaluating that, and provided some feedback. This is not quite ready for prime time, and I am not sure yet whether I will be able to use that for the 3.4 releases.

Native Xdebug Path Mapping

I also continued with the Native Xdebug Path Mapping project.

This is a separately funded project, I don't classify the hours that I worked on this in "Xdebug Hours". I also publish a separate report on the project page.

In short, I have finished the parser, and also made some performance improvements in the way I store data internally. I dive into the depths of that in its dedicated report.

I am now working on integrating it into Xdebug, and realised that there is one thing that I had forgotten to add, and that is a reverse mapping. The algorithms can only map remote a file/line to a local file/line, but in order to be able for an IDE to set a breakpoint on a local file line (which is how you would edit it), it also needs to have a reverse map.

By the end of this month I hope to have a working version to try out, but it will likely not be in the Xdebug 3.4 release, as that has to be released near when PHP 8.4 is released.

Xdebug Videos

I have created no new videos since last month, but you can see all the previous ones on my channel.

If you have any suggestions, feel free to reach out to me on Mastodon or via email.

Business Supporter Scheme and Funding

In the last month, no new business supporters signed up.

Besides business support, I also maintain a Patreon page, a profile on GitHub sponsors, as well as an OpenCollective organisation.

If you want to contribute to specific projects, you can find those on the Projects page.

Xdebug Cloud

Xdebug Cloud is the Proxy As A Service platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.

Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.

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.

Become a Patron!
Link
PHP: Hypertext PreprocessorPHP 8.4.0 RC3 available for testing (24.10.2024, 00:00 UTC)
The PHP team is pleased to announce the release of PHP 8.4.0, RC3. This is the third release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the PHP Wiki. For source downloads of PHP 8.4.0, RC3 please visit the download page. Please carefully test this version and report any issues found in the bug reporting system. Please DO NOT use this version in production, it is an early test version. For more information on the new features and other changes, you can read the NEWS file or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release will be RC 4, planned for 07 November 2024. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
Link
Larry GarfieldProperty hooks in practice (23.10.2024, 04:32 UTC)
Property hooks in practice

Two of the biggest features in the upcoming PHP 8.4 are property hooks and asymmetric visibility (or "aviz" for short). Ilija Tovilo and I worked on them over the course of two years, and they're finally almost here!

OK, so now what?

Rather than just reiterate what's in their respective RFCs (there are many blog posts that do that already), today I want to walk through a real-world application I'm working on as a side project, where I just converted a portion of it to use hooks and aviz. Hopefully that will give a better understanding of the practical benefits of these tools, and where there may be a rough edge or two still left.

One of the primary use cases for hooks is to not use them: They're there in case you need them, so you don't need to make boilerplate getter/setter methods "just in case." However, that's not their only use. They're also really nice when combined with interface properties, and delegation. Let's have a look.

Larry 22 October 2024 - 11:32pm
Link
Evert PotIn the future using top-level await might be cause a backwards compatibility break in Node (18.10.2024, 01:13 UTC)

Node 23 was released this week, and the hot ticket item probably is the fact that you can now require() files that use ESM (import/export).

This is helpful because ESM and CommonJS (require/module.exports) are kind of different worlds and before this change if you wanted to use a “module” from your CommonJS file, you would need to do something like:

const theThing = await import('some/module/file.mjs');

This is called a dynamic import and it’s extra annoying, because you can’t just put this at the top of your file. It returns a Promise, so you can only import these modules ‘asynchronously’ or in functions. The reason is that you can only await inside functions in CommonJS files. So this syntax prevents importing a “module” and immediately using it. To use a module in CommonJS, you’ll need some kind of initialization logic.

Many Javascript packages resort to shipping both a ‘CommonJS’ and a ‘ESM’ version of their code to reduce this kind of annoyance, but not everyone does.

The Node 23 change

Node 23 makes it possible to load ESM modules transparently via require(). This means that the above example can be rewritten to:

const theThing = require('some/module/file.mjs');

The important part here is not the usage of require, but the absense of await. This allows ESM modules to be loaded without this kind of initialization logic.

But there’s a big caveat:

This only works if the module you loaded in is not using top-level await. “Top level await” means awaiting things outside of (async) functions, which is possible in modules (but not CommonJS).

If a top-level await was used, a ERR_REQUIRE_ASYNC_MODULE error will be thrown. But the important thing to note is that this doesn’t just apply to the file you are directly importing/requiring. It also applies to any files loaded by that file, at any level in either your project or any dependency or sub-dependencies.

Using top-level await is now a BC break

Typically when we think of backwards compatibility breaks that require a major new version in semver, you might think of functions changing, or removing or arguments no longer being supported.

Before this change in Node, if your project was fully switched to ESM you might not think of placing a top-level await anywhere in your code as a backwards compatibility break, but if it’s the first await you might now inadvertently break Node.js users, if they used require() to bring in your module.

This means that the first top-level await in your project (or any of your dependencies) might now constitute a new major version if you follow semver.

If you don’t want to do this, here are some other things you could do:

1. Tell your users you don’t support require()

You could effectively tell them if they use require() they’re on their own. Chances are that your users won’t read this and do it anyway, but arguably

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

Link
Evert PotDiscovering features using HTTP OPTIONS (16.10.2024, 13:44 UTC)

Say you have an API, and you want to communicate what sort of things a user can do on a specific endpoint. You can use external description formats like OpenAPI or JSON Schema, but sometimes it’s nice to also dynamically communicate this on the API itself.

OPTIONS is the method used for that. You may know this HTTP method from CORS, but it’s general purpose is for clients to passively find out ‘What can I do here?’.

All HTTP clients typically support making OPTIONS request. For example with fetch():

const response = await fetch(
  'https://example.org',
  {method: 'OPTIONS'}
);

A basic OPTIONS response might might look like this:

HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 02:57:38 GMT
Server: KKachel/1.2
Allow: GET, PUT, POST, DELETE, OPTIONS

Based on the Allow header you can quickly tell which HTTP methods are available at a given endpoint. Many web frameworks emit this automatically and generate the list of methods dynamically per route, so chances are that you get this one for free.

To find out if your server does, try running the command below (with your URL!):

curl -X OPTIONS http://localhost:3000/some/endpoint/

One nice thing you could do with the Allow header, is that you could also communicate access-control information on a very basic level. For example, you could only include DELETE and PUT if a user has write access to a resource.

Accept and Accept-Encoding

There’s server other standard headers for discovery. Here’s an example showing a few at once:

HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 02:57:38 GMT
Server: KKachel/1.2
Allow: GET, PUT, POST, DELETE, OPTIONS
Accept: application/vnd.my-company-api+json, application/json, text/html
Accept-Encoding: gzip,brotli,identity

You may already be familiar with Accept and Accept-Encoding from HTTP requests, but they can also appear in responses. Accept in a response lets you tell the client which kind of mimetypes are available at an endpoint. I like adding text/html to every JSON api endpoint and making sure that API urls

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

Link
PHP: Hypertext PreprocessorPHP 8.4.0 RC2 available for testing (10.10.2024, 00:00 UTC)
The PHP team is pleased to announce the release of PHP 8.4.0, RC2. This is the second release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the PHP Wiki. For source downloads of PHP 8.4.0, RC2 please visit the download page. Please carefully test this version and report any issues found in the bug reporting system. Please DO NOT use this version in production, it is an early test version. For more information on the new features and other changes, you can read the NEWS file or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release will be RC 3, planned for 24 October 2024. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
Link
Brian MoonVarnish Workspace Error (7.10.2024, 17:21 UTC)

We had been having an issue with losing cookies in Varnish. Because of how Varnish works, the way to work around cookies is to store them in headers inbetween states of the request process. We were finally able to get some data out of varnishlog that looked like this.

      - ReqHeader DN-Varnish-Offer-Group: 
- LostHeader DN-Varnish-Offer-Sort: price
- Error out of workspace (req)
- LostHeader DN-Varnish-Sbtab-Sorts:
- Error out of workspace (req)
- LostHeader DN-Varnish-Use-View:
- Error out of workspace (req)
- LostHeader DN-Varnish-Ux-Variant: classic_site
- Error out of workspace (req)

When you first read these errors, you will likely find the settings workspace_client and workspace_backend. Those seem like very logical settings to tweak. However, no matter how big we set them nothing helped. We graph stats coming out of Varnish using the prometheus exporter. We found the metric varnish_main_ws_backend_overflow. That made us believe even more that this was a workspace_backend limit we were hitting. It turns out, there is more to the workspace settings than just this. I read through an old issue on Github and found some folks trying to set other settings related to header size and header limits. In the end, that was our issue. We increased these settings and our overflows disappeared. 

http_req_hdr_len = 64k (default is 8k)
http_req_size = 128k (default is 32k)
http_max_hdr=256 (default is 64)

Hopefully this will help someone else that runs up against this.

Link
Evert PotNew Structured Fields RFC out, and so is my Javascript package (3.10.2024, 15:56 UTC)

A new RFC was released for Structured Fields: RFC9651.

What is it?

HTTP headers have been a bit of a free-for all in terms of how complex values are encoded, with many headers requiring their own mini-parser.

A while back an effort was started to fix this for headers going forward, named ‘Structured Fields’. They’re called Fields and not ‘Headers’ because HTTP has both Headers and Trailers!

Structured fields let you encode things like lists, dictionaries, strings, numbers, booleans and binary data. The original RFC from 2021 is pretty successful and although many existing headers can’t be retrofitted to this format, a lot of new standards are taking advantage.

Some examples:

# Parsed an ASCII string
Header: "foo"

# A simple string, called a 'Token' in the spec
Header: foo

# Parsed as number
Header: 5
Header: -10
Header: 5.01415

# Parsed into boolean
Header: ?1
Header: ?0

# Binaries are base64 encoded
Header: :RE0gbWUgZm9yIGEgZnJlZSBjb29raWU=:

# Items can have parameters
Header: "Hello world"; a="5"

# A simple list
Header: 5, "foo", bar, ?1

# Each element can have parameters
Header: sometoken; param1; param2=hi, 42

# A list can also contain lists itself. These are called 'inner lists' and
# use parenthesis
Header: sometoken, (innerlistitem1 innerlistitem2), (anotherlist)

# A simple dictionary
Header: fn="evert", ln="pot", coffee=?1

# Each item may have parameters too
Header: foo=123; q=1, bar=123, q=0.5

# A dictionary value may be an inner list again
Header: foo=(1 2 3)

The new RFC published last week adds 2 new data types: Dates and ‘Display strings’, which is a Unicode serialization that fits in the HTTP header (and trailer) format.

# Parsed into a Date object
Header: @1686634251

# A Unicode string, called a 'Display String' in the spec. They use
# percent encoding, but encode a different set of characters than
# URLs.
Header %"Frysl%C3%A2n"

Why should you care?

If you encounter these headers in the wild, it’s a really good idea to use a standard parser. One of the reasons is that with using structured-fields, there’s a built-in extension mechanism. You’ll want to make sure that when a new parameter appears your application doesn’t suddenly break.

You may also want to define and use your own HTTP headers. The structured fields format is a very good ‘default choice’ that removes decisions such as ‘How should I encode a key value object’ or ‘how do I encode a UTF-8 string’.

With parsers popping up for every language, you don’t have to worry about writing your own one-off formats.

Javascript package

I’m the maintainer of a Javascript library for Structured Fields, called “structured headers”, which I’ve also updated for this new RFC. I wish I picked the name “structured-fields”, but I picked the name before the original standard changed it’s name.

I’ve just released v2 of this library supporting these new types, and also added ES Modules support.

Comments?

Reply to one of these:

Link
Evert PotHello World, meet Kian (2.10.2024, 15:08 UTC)

One week ago on September 24th my son Kian was born, after a 5 year fertility journey with my wife Roxy. Roxy and Kian are well and I’m really excited for everything that comes next!

Link
PHP: Hypertext PreprocessorPHP 8.4.0 RC 1 now available for testing (26.9.2024, 00:00 UTC)
The PHP team is pleased to announce the release of PHP 8.4.0, RC 1. This is the first release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the PHP Wiki. For source downloads of PHP 8.4.0, RC 1 please visit the download page. Please carefully test this version and report any issues found in the bug reporting system. Please DO NOT use this version in production, it is an early test version. For more information on the new features and other changes, you can read the NEWS file or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release will be RC 2, planned for 10 October 2024. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP