<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
  <channel>
    <title>Derick Rethans</title>
    <link>https://derickrethans.nl/archive.html</link>
    <description>This feed shows the latest 100 items</description>
    <language>en-us</language>
    <copyright>All rights reserved - Derick Rethans</copyright>
    <managingEditor>derick@derickrethans.nl (Derick Rethans)</managingEditor>
    <pubDate>Fri, 20 Sep 2024 17:30:02 +0000</pubDate>
    <lastBuildDate>Fri, 20 Sep 2024 17:30:02 +0000</lastBuildDate>
    <generator>eZ Components Feed dev (http://ezcomponents.org/docs/tutorials/Feed)</generator>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <ttl>60</ttl>
    <itunes:author>Derick Rethans</itunes:author>
    <itunes:owner>
      <itunes:email>derick@derickrethans.nl</itunes:email>
      <itunes:name>Derick Rethans</itunes:name>
    </itunes:owner>
    <item>
      <title>Friday Night Dinner: Myrtle</title>
      <link>https://derickrethans.nl/myrtle.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_myrtle"/&gt;Friday Night Dinner: Myrtle&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, September 20th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 1a Langton Street, Chelsea, London SW10 0JL, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.myrtlerestaurant.com/"&gt; https://www.myrtlerestaurant.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Tasting Menu with Wine: &amp;#xA3;375&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;em&gt;From the archive: We visited Myrtle in December 2022&lt;/em&gt;
      &lt;/p&gt;
      &lt;p&gt;We had a wonderful tasting menu with accompanying wine pairing to celebrate my birthday (21 again). Myrtle specialises in using Irish ingredients, and overall the presentation was excellent, without being pretentious, the ingredients and the food in general was definitely the star.&lt;/p&gt;
      &lt;p&gt;I don&amp;#x2019;t think they have a Michelin star yet, but it wouldn't surprise me if they&amp;#x2019;d get one soon. The location was a bit odd, as it was very far away from any sort of public transport or major town centre. It doesn't matter much for us, as we&amp;#x2019;re not the type of people that like our valet parking.&lt;/p&gt;
      &lt;p&gt;The food itself, again, was superb. I particularly liked their additional black pudding starter, made with &lt;em&gt;beef&lt;/em&gt; black pudding, instead of the traditional pork version. All the other dishes were great too. My favourite was possibly the sea bass with potato scales, and tasty sauce.&lt;/p&gt;
      &lt;p&gt;As with a tasting menu, we also went with the wine pairing, putting us back &amp;#xA3;167/person&amp;#x2014;excluding service charge (12.5%).&lt;/p&gt;
      &lt;p&gt;Of course, the reason we ended up here was due to Anna's (the head/executive chef) appearance as a judge on Master Chef.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/myrtle.html</guid>
      <pubDate>Fri, 20 Sep 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Chez Tony</title>
      <link>https://derickrethans.nl/chez-tony.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_chez_tony"/&gt;Friday Night Dinner: Chez Tony&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, September 13th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 34 Rue Bois le Vent, 75016 Paris, France&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.thefork.co.uk/restaurant/chez-tony-r60583/reviews"&gt; https://www.thefork.co.uk/restaurant/chez-tony-r60583/reviews&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Dinner: &amp;#x20AC;18-&amp;#x20AC;25; Wines: ~&amp;#x20AC;18-&amp;#x20AC;50&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We were in Paris for the Paralympics, and on our first night we had time for a real meal. My wife suggested this restaurant as she had been here many times when visiting Paris for work. I had heard a lot about Chez Tony already.&lt;/p&gt;
      &lt;p&gt;When we arrived, we found the place empty inside. Tony came over from the terrace across the street nearly immediately and recommended that we sat outside, as the weather was great, and it was going to be stuffy inside. He was totally right after we (briefly) tried sitting inside first.&lt;/p&gt;
      &lt;p&gt;The menu is a blackboard that gets put on a seat close to you. They don't really do starters, and henceforth their menu is dinner. From snails and foie gras, via a beef tartare and cheese burger, the menu eventually leads to pieces of beef: filet mignon de porc (pork tenderloin), and escalope de veau. There is even fish and chips. My wife usually enjoys the cheese burger on her work trips.&lt;/p&gt;
      &lt;p&gt;The "piece de boucher" (butchers piece of beef) seemed the most appealing to us, and we ordered one each served medium rare. While dinner was being prepared our chosen carafe of a nice C&amp;#xF4;te du Rh&amp;#xF4;ne. I can't remember which one, but it was delicious, went well with our steaks, and it was empty by the time we finished our mains.&lt;/p&gt;
      &lt;p&gt;The steak was cooked perfectly medium rare, and the fries were nice and crispy. The peppercorn sauce had just the right amount of pepper to it.&lt;/p&gt;
      &lt;p&gt;We did find a little space for dessert, and shared a cr&amp;#xE8;me br&amp;#xFB;l&amp;#xE9;e. Tony suggested, after tapping it with a fork, to wait a for minutes before enjoying it, so that the cr&amp;#xE8;me had some time to set. By this time, the restaurant had also filled up, and it was full when we left. Mostly locals too!&lt;/p&gt;
      &lt;p&gt;This is not a fancy restaurant, but one that does what it does well. No fuss, no snobby waiters, but good French cooking; and with a good ambiance.&lt;/p&gt;
      &lt;div id="cafe-pasifico" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/chez-tony-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;The Restaurant&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/chez-tony-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Piece de Boucher&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/chez-tony-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Cr&amp;#xEA;me Br&amp;#xFB;l&amp;#xE9;e&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('cafe-pasifico', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('cafe-pasifico', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/chez-tony.html</guid>
      <pubDate>Fri, 13 Sep 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Cafe Pacifico</title>
      <link>https://derickrethans.nl/cafe-pacifico.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_cafe_pacifico"/&gt;Friday Night Dinner: Cafe Pacifico&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, September 6th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 5 Langley Street, Covent Garden, London WC2H 9JA&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://cafe-pacifico.com/"&gt; https://cafe-pacifico.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Starters: &amp;#xA3;8.50-&amp;#xA3;12.95; Mains: &amp;#xA3;15.95-&amp;#xA3;26; Dessert: &amp;#xA3;4.75-&amp;#xA3;7.50&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We had visited Cafe Pacifico a few times in the past already, but we hadn't been back for a while, nor written up a review.&lt;/p&gt;
      &lt;p&gt;As it was a warm day, having Mexican food seemed like a good idea, and starting with a large margarita an even better one.&lt;/p&gt;
      &lt;p&gt;Cafe Pacifico has fairly standard items on their menu, not nearly as adventurous as Polanco where we dined a few weeks ago. We started our meal to share a couple of Empanadas, with a flavourful filling and a subtle chipotle salsa on the side.&lt;/p&gt;
      &lt;p&gt;By now our margarita was empty, and we ordered another one while waiting for our main, for which my wife picked the Chicken Chimichanga with black beans. A lovely dollop of guacamole and cream was perched on top. I chose the Sea Bass and King Prawn Tacos. These came in "tempura style" (i.e.: battered and fried), and were served with grilled pineapple, some red onions, and a slightly spicy mayonnaise.&lt;/p&gt;
      &lt;p&gt;After our mains, we were eventually given the dessert menu. We were quite eying up the churros, but it took so long for staff to return that by that time we had changed our mind and decided not to have any.&lt;/p&gt;
      &lt;p&gt;In my opinion, there could have been a little more spice and flavour in most of the dishes, and service wasn't the speediest. But it's still a reasonable option for a meal after a hard day of shopping in Covent Garden. We would also have benefitted from ordering a bottle of margaritas, instead of 4 individual large glasses.&lt;/p&gt;
      &lt;div id="cafe-pasifico" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/cafe-pacifico-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Classic Margaritas&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/cafe-pacifico-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Crispy Empenadas&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/cafe-pacifico-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Chicken Chimichanga with Black Beans&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/cafe-pacifico-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Sea Bass and King Prawn Tacos&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('cafe-pasifico', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('cafe-pasifico', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/cafe-pacifico.html</guid>
      <pubDate>Fri, 06 Sep 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: August 2024</title>
      <link>https://derickrethans.nl/xdebug-update-august-2024.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_august_2024"/&gt;Xdebug Update: August 2024&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, September 3rd 2024, 14:35 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; and &lt;a href="https://xdebug.org/support"&gt;Pro/Business supporters&lt;/a&gt; will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;On GitHub sponsors, I am currently 32% towards my $2,500 per month goal, which is set to allow continued &lt;strong&gt;maintenance&lt;/strong&gt; of Xdebug. This is again less than last month.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 8 hours on Xdebug, with 20 hours funded. I also spent 8.5 hours on the Native Path Mapping project.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="php_8_4"/&gt;PHP 8.4&lt;/h2&gt;
        &lt;p&gt;The large change for the &lt;a href="https://wiki.php.net/rfc/exit-as-function"&gt;exit-as-a-function&lt;/a&gt; proposal has been merged into PHP, which means I had to spend some time finishing and tidying up a Pull Request that Tim D&amp;#xFC;sterhus had provided.&lt;/p&gt;
        &lt;p&gt;I also improved Xdebug's &lt;a href="https://xdebug.org/ci"&gt;CI&lt;/a&gt; so that it can run as a separate user.&lt;/p&gt;
        &lt;p&gt;Right now, there don't seem to be any outstanding issues with PHP 8.4 so I will soon create another alpha (or beta) release so that you can try out Xdebug with the latest beta versions of PHP 8.4's.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="native_xdebug_path_mapping"/&gt;Native Xdebug Path Mapping&lt;/h2&gt;
        &lt;p&gt;I continued with the &lt;a href="https://xdebug.org/funding/001-native-path-mapping"&gt;Native Xdebug Path Mapping&lt;/a&gt; project.&lt;/p&gt;
        &lt;p&gt;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 &lt;a href="https://xdebug.org/funding/001-native-path-mapping"&gt;project page&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;Again, I am including it here:&lt;/p&gt;
        &lt;p&gt;I continued with the parser to parse the path mapping files. The parsing is now finished, although I do still need to modify how the parsed information is stored. Right now, the data structures are not optimised to be able to do line mapping as well.&lt;/p&gt;
        &lt;p&gt;Because the parser parsers user input, it is important that the parser is rubust. It should be able to handle correctly formatted files, but also files with errors.&lt;/p&gt;
        &lt;p&gt;It is not always possible to come up with all the failure situations by thinking, and therefore a common technique is to use a fuzzer. For PHP there is &lt;a href="https://infection.github.io/"&gt;Infection PHP&lt;/a&gt; for mutation testing for example. For C, and C++, a commonly used tool is &lt;a href="https://github.com/AFLplusplus/AFLplusplus"&gt;AFL++&lt;/a&gt;. This provides a compiler wrapper and a run-time to fuzz the input to your application. You first provide a template, which it then modifies to try to break your code.&lt;/p&gt;
        &lt;p&gt;The template that I used in this case was a minimal map file:&lt;/p&gt;
        &lt;pre&gt;remote_prefix: /usr/local/www
local_prefix: /home/derick/project
/projects/example.php:5-17 = /example.php:8
/example.php:5-17 = /example.php:8-20
/example.php:17 = /example.php:20
/projects/php-web/ = /php-web/

&lt;/pre&gt;
        &lt;p&gt;In addition to the template you also need to provide a shim &amp;#x2014; the program that in my case takes the argument given to it and then parses that as a file. The AFL++ tool's compiler wrapper adds some magic to it to be able to catch errors.&lt;/p&gt;
        &lt;p&gt;When you then run the fuzzer, such as with:&lt;/p&gt;
        &lt;pre&gt;AFL_SKIP_CPUFREQ=1 afl-fuzz -b 7 -i fuzz-seeds -o fuzz-output -- ./afl-test @@

&lt;/pre&gt;
        &lt;p&gt;It then runs your program with your template files (in fuzz-seeds in my example). And then also with loads of variants.&lt;/p&gt;
        &lt;p&gt;The fuzzer found a few errors in my parser, which ended up crashing it. One such examples that I hadn't thought of is of a line starting with a =:&lt;/p&gt;
        &lt;pre&gt;remote_prefix: /usr/local/www
local_prefix: /home/derick/project
=/example.php:42-5 = /example.php

&lt;/pre&gt;
        &lt;p&gt;You can find the other cases it found in a &lt;a href="https://github.com/derickr/xdebug/blob/001-native-path-mapping/tests/ctest/fuzz-cases.cpp#L93"&gt;dedicated test file&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;In September I hope to finish the parser (by storing things more efficiently internally) as well as creating APIs to do the mapping.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have created no new videos since last month, but you can see all the previous ones on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;If you have any suggestions, feel free to reach out to &lt;a href="https://phpc.social/@derickr"&gt;me on Mastodon&lt;/a&gt; or via &lt;a href="http://derickrethans/who.html"&gt;email&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last month, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;p&gt;If you want to contribute to specific projects, you can find those on the &lt;a href="https://xdebug.org/funding"&gt;Projects&lt;/a&gt; page.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-august-2024.html</guid>
      <pubDate>Tue, 03 Sep 2024 13:35:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Brother Marcus</title>
      <link>https://derickrethans.nl/brother-marcus.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_brother_marcus"/&gt;Friday Night Dinner: Brother Marcus&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, August 30th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 1-3 Pelham Street, South Kensington, London SW7 2ND&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://brothermarcus.co.uk/locations/southkensington/"&gt; https://brothermarcus.co.uk/locations/southkensington/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Snacks: &amp;#xA3;2.80-&amp;#xA3;7.20; Mezze: &amp;#xA3;8.20-&amp;#xA3;18.20; Wines: &amp;#xA3;29-&amp;#xA3;56; Cocktails: &amp;#xA3;12.50&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Brother Marcus has a few different locations. The one we visited is right beside South Kensington station. It's a light filled comfy restaurant, specialising in middle eastern style sharing platters.&lt;/p&gt;
      &lt;p&gt;We like eating on the earlier side, which meant that we could benefit from the "pre-show set menu". This consists of a "rip and dip platter", consisting of three dips, olives, and fluffy pittas; and then a veggie and meat mezze per person.&lt;/p&gt;
      &lt;p&gt;The dips platter arrived swiftly, with our choice of roasted beetroot hummus, baba ghanoush and taramasalata. All the dips were delicious, and the pittas were indeed fluffy. A bottle of Kokotos wine showed up soon after, although I probably should put bottle in double quotes, as it was filled from a tap. That didn't do anything against its tastiness though.&lt;/p&gt;
      &lt;p&gt;As is usual in restaurants like this, everything comes when it's ready, so our table was soon overflowing with dishes. The pan-fried halloumi was sweet and sticky with a watermelon jam. The crispy aubergine skewer, crispy, but not dry and served with a creamy labneh sprinkled with grape molasses. The calamari had a well-seasoned coating, and was served with a green aioli. A little sprinkling of chilli added a little kick. And finally, the moist and well-spiced lamb koftas came on a smooth bed of aubergine begendi (b&amp;#xE9;chamel sauce).&lt;/p&gt;
      &lt;p&gt;Close to many of London's top museums, the pre-show menu was excellent value at &amp;#xA3;25 per person. We can recommend this modern place, which after a day out shuffling around old museum pieces will certainly fill your belly.&lt;/p&gt;
      &lt;div id="brother-marcus" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/brother-marcus-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Rip and Dips Platter&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/brother-marcus-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Pan-fried Halloumi&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/brother-marcus-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Crispy Aubergine&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/brother-marcus-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Crispy Calamari&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/brother-marcus-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Lamb Koftas&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('brother-marcus', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('brother-marcus', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/brother-marcus.html</guid>
      <pubDate>Fri, 30 Aug 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Mountain</title>
      <link>https://derickrethans.nl/mountain.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_mountain"/&gt;Friday Night Dinner: Mountain&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, August 23rd 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 16-18 Beak Street, London W1F 9RD&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://mountainbeakstreet.com/"&gt; https://mountainbeakstreet.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Starters: &amp;#xA3;4.80-&amp;#xA3;18.50; Small(er) Plates: &amp;#xA3;14.80-&amp;#xA3;26; Mains: &amp;#xA3;36-&amp;#xA3;95; Wines: from &amp;#xA3;34&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Another hip restaurant, one, that recently had acquired a Michelin star, although they don't seem to mention that on their website. There was however a difference in prices between booking and eating.&lt;/p&gt;
      &lt;p&gt;When we arrived, we were explained that the menu consists of three sections: a selection of starters, a selection of smaller plates, and mains. They recommended getting a starter and small place each, and a main to share. We have heard this spiel before, and knew it was going to be too much (quantity of food and cost).&lt;/p&gt;
      &lt;p&gt;We did our own thing, and had a starter and small plate each instead.&lt;/p&gt;
      &lt;p&gt;For our starters, my wife chose the cured dairy beef, lovely thinly sliced meat with some almond shavings. It was perfectly moist with an earthy flavour. I picked the anchovies and cheese, which were served on sourdough bread. The cheese was whipped, with some oil sprinkled over it. As you expect from anchovies, they were salty, which the whipped cheese was a perfect accompaniment for.&lt;/p&gt;
      &lt;p&gt;As my main course I selected a mackerel with grilled peas. The mackerel came wholly grilled on a bed of caramelised chopped onions, and the aforementioned grilled peas. There was a sprinkling of herbs on top as well, to make the plate less beige. The combination of the meaty fish and caramelised onions worked great. My wife opted for an omelette, stuffed with girolle mushrooms. The omelette was fluffy, wonderfully moist, and filling!&lt;/p&gt;
      &lt;p&gt;With our meal, we also enjoyed a lovely bottle of Psarades, a Cretian white wine.&lt;/p&gt;
      &lt;p&gt;The food at Mountain was great, and the atmosphere inviting with a large open kitchen. Do make sure to request a table on the ground floor though. It is a bit on the pricier side, especially if you also share (or not) a main as well.&lt;/p&gt;
      &lt;div id="mountain" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/mountain-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Cured Dairy Beef&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/mountain-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Anchovies and Cheese&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/mountain-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Girolle Ommelette&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/mountain-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Mackerel&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('mountain', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('mountain', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/mountain.html</guid>
      <pubDate>Fri, 23 Aug 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Polanco</title>
      <link>https://derickrethans.nl/polanco.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_polanco"/&gt;Friday Night Dinner: Polanco&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, August 9th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 43 Chamberlayne Road, London NW10 3NB, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://polancomex.co.uk/"&gt; https://polancomex.co.uk/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Tacos/Small Plates: &amp;#xA3;7-&amp;#xA3;12; Cocktails: &amp;#xA3;10-&amp;#xA3;12; Wines: &amp;#xA3;23-&amp;#xA3;36&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We have been to this location before, back when it was called Morso, which has now moved to St. John's Wood. There are a few other restaurants next door, which we might also try at some point.&lt;/p&gt;
      &lt;p&gt;It was a very warm evening, and my wife had arrived much earlier than our table was booked for. She'd ordered a margarita to spend the time, and "convinced" me to get one too. One showed up right when I entered the cosy restaurant. We were on the earlier side and it was mostly empty.&lt;/p&gt;
      &lt;p&gt;Polanco serves contemporary Mexican food, and their menu consists of tacos and small plates to share. We ordered baja fish tacos, a quesadilla rustica, green chicken enchiladas, and tortilla chips with guacamole to enjoy while we were waiting.&lt;/p&gt;
      &lt;p&gt;With our food, we also got a bottle of white wine. Usually we would probably have had beer, but their beer selection was really only the boring macro lagers.&lt;/p&gt;
      &lt;p&gt;The guacamole was well-made, and a little spicy. Smooth, but still with some crunchy bits. The green chicken enchiladas were doused in a slightly spicy green sauce. A dollop of cream on top smoothed things out. My favourite were the fish tacos &amp;#x2014; crispy fried fish, served with chipotle mayonnaise and habanero sauce, and topped with pickled cabbage. The rustic part of the quesadilla consisted of molten cheese, shopped cherry tomatoes, a habanero sauce, and some cream.&lt;/p&gt;
      &lt;p&gt;All the dishes were a little spicy, but not so much that it overpowered. By the time we were done with our meal, the restaurant was buzzing with nearly every table occupied.&lt;/p&gt;
      &lt;div id="polanco" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/polanco-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Tortilla Chips with Guacamole&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/polanco-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Green Chicken Enchiladas&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/polanco-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Fish Tacos with Pickled Cabbage&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/polanco-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Quesadilla Rustica&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('polanco', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('polanco', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/polanco.html</guid>
      <pubDate>Fri, 09 Aug 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: July 2024</title>
      <link>https://derickrethans.nl/xdebug-update-july-2024.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_july_2024"/&gt;Xdebug Update: July 2024&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Wednesday, August 7th 2024, 18:10 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; and &lt;a href="https://xdebug.org/support"&gt;Pro/Business supporters&lt;/a&gt; will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;On GitHub sponsors, I am currently 42% towards my $2,500 per month goal, which is set to allow continued &lt;strong&gt;maintenance&lt;/strong&gt; of Xdebug. This is less than last month.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 15 hours on Xdebug, with 21 hours funded. I also spent 6 hours on the Native Path Mapping project.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="php_8_4"/&gt;PHP 8.4&lt;/h2&gt;
        &lt;p&gt;I spent some time making sure that Xdebug will be ready for PHP 8.4, once that comes out later in the year. There are always some incompatibilities, such as the new &lt;a href="https://github.com/php/php-src/pull/12461"&gt;frameless calls&lt;/a&gt; and some deprecations.&lt;/p&gt;
        &lt;p&gt;I also did a deep dive into supporting a potential large change into the way PHP handles the &lt;code&gt;exit&lt;/code&gt; keyword. There is a &lt;a href="https://wiki.php.net/rfc/exit-as-function"&gt;proposal&lt;/a&gt; to change that from a language instruction to an actual function, but this impacts Xdebug fairly significantly &amp;#x2014; it uses the instruction for path and branch analysis, and to make sure profiling files get stored on disk in full. At the moment, it is unsure whether this change will be adopted.&lt;/p&gt;
        &lt;p&gt;Beyond preparatory work for PHP 8.4, I also spend some time on improving the out-of-band socket communication support to make it easier for IDEs to use. This work will continue to be ongoing for a while.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="native_xdebug_path_mapping"/&gt;Native Xdebug Path Mapping&lt;/h2&gt;
        &lt;p&gt;I have started on the &lt;a href="https://xdebug.org/funding/001-native-path-mapping"&gt;Native Xdebug Path Mapping&lt;/a&gt; project.&lt;/p&gt;
        &lt;p&gt;As 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 &lt;a href="https://xdebug.org/funding/001-native-path-mapping"&gt;project page&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;As an exception, I am including it here:&lt;/p&gt;
        &lt;p&gt;In this first month, or rather, the last week of July, I have been working on setting up a testing framework for the parser. Previously Xdebug only had tests in &lt;a href="https://qa.php.net/write-test.php"&gt;PHPT&lt;/a&gt; form, PHP's standard for testing syntax and functions. However, this is rather more an integration test framework, as it compares the output of a script with an expected output.&lt;/p&gt;
        &lt;p&gt;For low-level features, such as testing the implementation of the parser that parses the path mapping files, PHPT tests are not suitable. Instead, the testing framework tests the return values and generated structures directly, without PHP having to be involved. The &lt;a href="https://cpputest.github.io/manual.html"&gt;CppUTest&lt;/a&gt; framework that I use for this, is much more similar to PHPUnit. It is also a framework that I have used for testing &lt;a href="https://github.com/derickr/timelib"&gt;timelib&lt;/a&gt;, the library that powers PHP and MongoDB's date/time functionality.&lt;/p&gt;
        &lt;p&gt;Beyond the testing framework, I have also made a start on the parser itself. It can currently parse the remote_prefix and local_prefix stanzas, as well as mapping lines, although it does not distinguish between directory maps, file maps, or line maps yet, nor does it apply the prefix stanzas yet.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have created no new videos since last month, but you can see all the previous ones on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;If you have any suggestions, feel free to reach out to &lt;a href="https://phpc.social/@derickr"&gt;me on Mastodon&lt;/a&gt; or via &lt;a href="http://derickrethans/who.html"&gt;email&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last month, one new business supporter signed up:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.clever-age.com/"&gt;Clever Age&lt;/a&gt;.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;p&gt;If you want to contribute to specific projects, you can find those on the &lt;a href="https://xdebug.org/funding"&gt;Projects&lt;/a&gt; page.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-july-2024.html</guid>
      <pubDate>Wed, 07 Aug 2024 17:10:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Turmeric Kitchen</title>
      <link>https://derickrethans.nl/turmeric-kitchen.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_turmeric_kitchen"/&gt;Friday Night Dinner: Turmeric Kitchen&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, August 2nd 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 55 Westbourne Terrace, London W2 3UY, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://turmerickitchen.co.uk"&gt; https://turmerickitchen.co.uk&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; &amp;#xA3;8-&amp;#xA3;10; Mains: &amp;#xA3;9-&amp;#xA3;15; Wines: &amp;#xA3;25-&amp;#xA3;60&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On the hottest Friday of the year (so far) we found ourselves at Turmeric Kitchen. Situated inside The Chilworth Hotel, a stone throw away from Paddington station.&lt;/p&gt;
      &lt;p&gt;It was quite dark inside, with little natural light, and wood panelled walls. The decor is more fitting for a winter's meal than a bright summer's day.&lt;/p&gt;
      &lt;p&gt;The menu is fairly varied, with some traditional dishes such as Murgh Makhani (Butter Chicken) and Biryanis, but there are also some more interesting dishes &amp;#x2014; and an "around the world" section including burgers, fish and chips, and steak.&lt;/p&gt;
      &lt;p&gt;As a starter, we shared the Avocado Bombs, spicy smashed avocado with mustard seats and deep-fried, like bitterballen. They were served with a beetroot chutney and a pomegranate seed. A tasty appetiser.&lt;/p&gt;
      &lt;p&gt;As my main meal, my wife ordered the aforementioned Murgh Makhani, with some plain naans on the side. The curry was a little spicy, which I hadn't expected for a butter chicken. But it wasn't overpowering and left a nice warmth in the mouth. I opted for the Laal Maas, a slow cooked spicy lamb curry. I paired that with a pilau rice. The curry was tender and had just the right amount of heat.&lt;/p&gt;
      &lt;p&gt;Normally we would have had a beer with curry, but the selection was poor. There were only small bottles of macro brewery beers with ridiculous prices. We had a bottle of Sauvignon Blanc instead. A bit odd, but it worked fairly well.&lt;/p&gt;
      &lt;p&gt;To conclude our meal, we finished with a sorbet &amp;#x2014; my wife had the raspberry, and I had the mango. The serving (one scoop) was disappointingly small for the price.&lt;/p&gt;
      &lt;p&gt;After having refreshed, we went back outside into the heat for some exiting beers at &lt;a href="https://www.thebearpaddington.com/"&gt;"The Bear"&lt;/a&gt;, a nearby pub.&lt;/p&gt;
      &lt;div id="turmeric-kitchen" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/turmeric-kitchen-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Avocado Bombs&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/turmeric-kitchen-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Murgh Makhani&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/turmeric-kitchen-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Laal Maas&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/turmeric-kitchen-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Icecreams&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('turmeric-kitchen', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('turmeric-kitchen', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/turmeric-kitchen.html</guid>
      <pubDate>Fri, 02 Aug 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Vinum</title>
      <link>https://derickrethans.nl/vinum.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_vinum"/&gt;Friday Night Dinner: Vinum&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, July 26th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; Rua do Agro 141 (Caves Graham's), 4400-003 Vila Nova de Gaia, Portugal&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://vinumatgrahams.com/en/"&gt; https://vinumatgrahams.com/en/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Starters: &amp;#x20AC;8-&amp;#x20AC;24; Mains: &amp;#x20AC;22-&amp;#x20AC;34; Dessert: &amp;#x20AC;7-&amp;#x20AC;15; Wines: &amp;#x20AC;19-&amp;#x20AC;1250&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After one of our entertainments, a tour and tasting of Graham's port wines, we had booked a table at Vinum. Situated at Graham's Port Lodge with magnificent views over Porto, the Douro river, and Vila Nova de Gaia. It had come recommended by a colleague.&lt;/p&gt;
      &lt;p&gt;First we were briefly seated outside for a drink with a great view, which was unexpected (and a little chilly). After this confusion was resolved, we were seated at a large table, in an airy and bright room, and the great view&amp;#x2014;they don't guarantee you get that though. It was also fairly quiet when we got there, at 18:30.&lt;/p&gt;
      &lt;p&gt;The restaurant also does a tasting menu (with wine pairing, if you desire), but we went &amp;#xE0; la carte again. We forwent our starter, and instead had four very plumb oysters.&lt;/p&gt;
      &lt;p&gt;As main course I selected the grilled tuna, which was wrapped in chard and slightly seared &amp;#x2014; which is how it is supposed to be. It came with a charred pepper and garlic mash. My wife picked the "Vace Velha" tataki, which was served with a roast potato and caramelised onions. The port lodge's owners also produce Duoro wines, so to go with our meal we selected a bottle of Altano Reserva 2021, a rich and complex white wine.&lt;/p&gt;
      &lt;p&gt;We still had some space for desserts, and my wife choose a baked peach with vanilla ice cream, and I had a pineapple dish. As we were in a port lodge, we paired this with a Graham's 20 years old Tawny, which was served in a gigantic 4.5l bottle. The tray that came on, also contained a &lt;a href="https://www.grahams-port.com/wine/ne-oublie/20"&gt;port from 1882&lt;/a&gt;, but at &amp;#x20AC;900 a glass, a little over budget.&lt;/p&gt;
      &lt;p&gt;The food was good, and the service excellent. The view magnificent, and the atmosphere relaxing. It was a "bit" of a hike up the hill, but certainly worth visiting &amp;#x2014; especially after also having done a tour of their warehouses.&lt;/p&gt;
      &lt;div id="vinum" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/vinum-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Fat Oysters&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/vinum-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Seared Tuna Wrapped in Chard&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/vinum-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Vace Velha Tataki&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/vinum-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Big Bottle of Graham's 20&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/vinum-6.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Baked Peach with Vanilla Ice Cream&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/vinum-7.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Pineapple Many Ways&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('vinum', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('vinum', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/vinum.html</guid>
      <pubDate>Fri, 26 Jul 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Apego</title>
      <link>https://derickrethans.nl/apego.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_apego"/&gt;Friday Night Dinner: Apego&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, July 19th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; Rua de Santa Catarina 1198, 4000-457 Porto, Portugal&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.thefork.co.uk/restaurant/apego-r413165"&gt; https://www.thefork.co.uk/restaurant/apego-r413165&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Starters: &amp;#x20AC;28, Mains: &amp;#x20AC;54, Wine &amp;#x20AC;34 (4 glasses), Dessert + Digestive: &amp;#x20AC;35&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We recently visited Porto in Northern Portugal, where we were also in need of dinner. A while away from the busy hubbub of the riverside and the touristic areas of the city, we found ourselves on an unremarkable street in front of Apego.&lt;/p&gt;
      &lt;p&gt;We were welcomed in, and seated on a nice table near the kitchen in the calm and rustic restaurant. You can either choose a tasting menu of 5 courses, or eat &amp;#xE0; la carte. Five courses seemed a bit much, and we wanted to select our own courses, so we picked the latter option.&lt;/p&gt;
      &lt;p&gt;The menu is not very extensive, but each course did come with wine recommendations. As a started, I picked the Atlantic bonito crudo on a bed of beetroot and cr&amp;#xE8;me fra&amp;#xEE;che with a seeded cracker. My wife decided on the corn empanada with mushrooms, cucumber, and lime. Usually I have a red wine, and my wife a white, but in this case the recommended wines were of the opposite colour. The red to go with my wife's empanada wasn't totally fitting, and she liked my white more.&lt;/p&gt;
      &lt;p&gt;This meant that for our main courses she disregarded the recommendation and instead had the wine I had with my starter. As main course, she selected the artichoke with egg, pesto and Parmesan, whereas I opted for the pork shank, which was served with a crispy potato dish. Just like the starters, the mains were well cooked, with balanced flavours, with a delightful presentation.&lt;/p&gt;
      &lt;p&gt;The deserts looked great too, and to finish our meal, I picked the coffee tarte, while my wife choose the "Chou", served with strawberries and basil. We paired that with a Madeira, and, as we were in Porto, a glass of port.&lt;/p&gt;
      &lt;p&gt;Apego was a really nice experience, with great food and atmosphere. It's a little out of the way, but well worth visiting.&lt;/p&gt;
      &lt;div id="apego" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/apego-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Atlantic Bonito Crudo&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/apego-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Corn Empanada with Mushrooms&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/apego-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Pork Shank&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/apego-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Crispy Potato Dish&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/apego-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Artichoke with Egg, Pesto and Parmesan&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/apego-6.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Chou&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/apego-7.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Coffee Tarte&lt;/div&gt;
          &lt;div class="numbertext"&gt;7 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('apego', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('apego', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/apego.html</guid>
      <pubDate>Fri, 19 Jul 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: The Chamberlayne</title>
      <link>https://derickrethans.nl/the-chamberlayne.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_the_chamberlayne"/&gt;Friday Night Dinner: The Chamberlayne&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, June 27th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 83 Chamberlayne Road, London NW10 3ND, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://thechamberlayne.com/"&gt; https://thechamberlayne.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Starters: &amp;#xA3;18 (&amp;#xA3;10-&amp;#xA3;18); Mains: &amp;#xA3;45 (&amp;#xA3;16.50-&amp;#xA3;28); Pudding: &amp;#xA3;6 (&amp;#xA3;3-&amp;#xA3;10); Wines: &amp;#xA3;32 (&amp;#xA3;28-&amp;#xA3;78)&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Back when I just moved to London, now nearly 15 years ago, I would frequent the Chamberlayne a lot. It was the closest pub with a good food selection, and the best chips in town.&lt;/p&gt;
      &lt;p&gt;It has changed hands, and name, a few times in the intervening time, but it's now back as the Chamberlayne, and we decided to try them out again.&lt;/p&gt;
      &lt;p&gt;We started with a happy hour, but then of Oysters and not drinks. The selection included Jersey and Carlingford oysters, as well as the river oysters Louet Feisser. Oysters have started to grown on me. I wouldn't touch them a decade ago, but would now happily shuck them myself.&lt;/p&gt;
      &lt;p&gt;After our starters, I opted for a Grilled Cornish gurnard, a lovely chewy fish served on a bed of haricot beans with bagna cauda, a garlic and anchovies pur&amp;#xE9;e, and some herbs. I am not usually a fan of beans, but these were nice and soft and buttery and worked well with the fish and pur&amp;#xE9;e.&lt;/p&gt;
      &lt;p&gt;My wife went for a more traditional choice: a beef burger served with chips. The burger was well seasoned and moist, with some enjoyable pickles. The chips were good too, but were not living up to the standard that I remembered from all these years ago.&lt;/p&gt;
      &lt;p&gt;They had several ice creams and sorbets for dessert. We were already reasonably happy, and had a single scoop each. I had a raspberry swirl, and my wife a salted caramel. Both excellent to finish our meal.&lt;/p&gt;
      &lt;p&gt;The Chamberlayne had a pleasant and relaxed atmosphere, with good food at reasonable prices. An excellent local option.&lt;/p&gt;
      &lt;div id="the-chamberlayne" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-chamberlayne-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Selection of Oysters&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-chamberlayne-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gurnard on Haricot Beans&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-chamberlayne-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Beef Burger with Chips and Pickles&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-chamberlayne-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Raspberry Swirl Ice Cream&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-chamberlayne-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Salted Caramel Ice Cream&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('the-chamberlayne', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('the-chamberlayne', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/the-chamberlayne.html</guid>
      <pubDate>Thu, 27 Jun 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: The Devonshire</title>
      <link>https://derickrethans.nl/the-devonshire.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_the_devonshire"/&gt;Friday Night Dinner: The Devonshire&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, June 14th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 17 Denman Street, London W1D 7HW, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.devonshiresoho.co.uk/"&gt; https://www.devonshiresoho.co.uk/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Starters: &amp;#xA3;32 (&amp;#xA3;8-&amp;#xA3;16); Mains: &amp;#xA3;53 (&amp;#xA3;19-&amp;#xA3;39); Wine: &amp;#xA3;50 (&amp;#xA3;32-&amp;#xA3;130); Pudding: &amp;#xA3;8 (&amp;#xA3;8-&amp;#xA3;16); Dessert Wine: &amp;#xA3;20&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After trying to get a table for a long while, we finally managed to snag one. We have been to this location before (when it was a Jamie's Italian), and it's situated right next to Piccadilly Circus. The downstairs is a pub, and upstairs there are a dozen of tables and a large roaring grill.&lt;/p&gt;
      &lt;p&gt;The menu is handwritten, and has sections on starters, grilled items, mains, sauces, and sides. While we were looking at it, some bread and butter appeared. And a few minutes later our wine. After our waiter poured a glass, she took it away to keep it cool in a fridge. Both of us are not keen on this practise &amp;#x2014; we'd really rather see our wine so that we can pour our own, at &lt;strong&gt;our&lt;/strong&gt; time of choosing.&lt;/p&gt;
      &lt;p&gt;From the starters section, I selected a white crab salad, which came with slices of crisp apple, and crunchy chicory leaves. The crab meat was nicely seasoned and slightly sweet. My wife had three juicy scallops with a crispy topping, served with malt vinegar and some lardons. The scallops were cooked just right.&lt;/p&gt;
      &lt;p&gt;At this point it was time to top up our glasses, and we convinced our new waiter to leave the bottle on our table, even though that meant it wasn't cooled.&lt;/p&gt;
      &lt;p&gt;For her main, my wife had the fillet of halibut, while I opted for the lamb cutlets. The mains don't come with anything, so we also had duck fat crisps, and a pea, onion, and bacon dish to go with our meal. That did mean we had to assemble our plates ourselves, as they all came separately. My lamb cutlets were great. Perfectly cooked, and still moist. My wife's halibut was well seasoned and also splendid.&lt;/p&gt;
      &lt;p&gt;It was still early, and sometimes it just feels right for pudding. After some discussion we decided to share the sticky toffee pudding, with a side of some dessert wine. I am usually not too keen on sticky toffee pudding, but I was really getting my fork into this one. I secretly wished we hadn't shared it!&lt;/p&gt;
      &lt;p&gt;It was a great meal out, and I now understand why it is so hard to get a table, especially earlier in the evening.&lt;/p&gt;
      &lt;div id="devonshire" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/devonshire-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;White Crab Salad with Apple and Chicory&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/devonshire-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Scallops with Crispy Topping&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/devonshire-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Halibut Fillet, with Duck Fat Crisps and Bacon Peas&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/devonshire-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Lamb Cutlets, with Duck Fat Crisps and Bacon Peas&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/devonshire-6.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Sticky Toffee Pudding&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('devonshire', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('devonshire', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/the-devonshire.html</guid>
      <pubDate>Fri, 14 Jun 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: May 2024</title>
      <link>https://derickrethans.nl/xdebug-update-may-2024.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_may_2024"/&gt;Xdebug Update: May 2024&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, June 11th 2024, 16:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; and &lt;a href="https://xdebug.org/support"&gt;Pro/Business supporters&lt;/a&gt; will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;On GitHub sponsors, I am currently 44% towards my $2,500 per month goal, which is set to allow continued &lt;strong&gt;maintenance&lt;/strong&gt; of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 23 hours on Xdebug, with 22 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_4"/&gt;Xdebug 3.4&lt;/h2&gt;
        &lt;p&gt;I created the first alpha release of Xdebug 3.4 &amp;#x2014; with some preliminary PHP 8.4 support. The main reason for this was to test out the PIE tool, that &lt;a href="https://phpc.social/@asgrim"&gt;James Titcumb&lt;/a&gt; is working on as part of his work for the &lt;a href="https://thephp.foundation/"&gt;PHP Foundation&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;This new tool uses &lt;a href="https://github.com/xdebug/xdebug/blob/master/composer.json"&gt;composer-style&lt;/a&gt; definition files. It also means that extensions like &lt;a href="https://packagist.org/packages/xdebug/xdebug"&gt;Xdebug can now be found on Packagist&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;PIE is still in early development, but I shall be continuing to test out while it matures.&lt;/p&gt;
        &lt;p&gt;The &lt;a href="https://xdebug.org/announcements/2024-05-31"&gt;3.4.0alpha1 release itself&lt;/a&gt; adds a new &lt;a href="https://bugs.xdebug.org/2239"&gt;XDEBUG_IGNORE HTTP variable&lt;/a&gt; to prevent Xdebug from initiating a debugging session for this request only. This feature was requested by the &lt;a href="https://github.com/symfony/symfony/pull/52950#issuecomment-1884680470"&gt;Symfony project&lt;/a&gt;, to prevent debugging sessions for the debugging toolbar.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="native_xdebug_path_mapping"/&gt;Native Xdebug Path Mapping&lt;/h2&gt;
        &lt;p&gt;In the previous update I wrote about Xdebug's new &lt;a href="https://xdebug.org/funding"&gt;projects section&lt;/a&gt;, and the first project that I am hoping to fund through this: &lt;a href="https://xdebug.org/funding/001-native-path-mapping"&gt;Native Xdebug Path Mapping&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;After my announcement, several companies and individuals reached out. The funding is now nearly there, with good hopes that it will conclude soon.&lt;/p&gt;
        &lt;p&gt;&lt;a href="https://xdebug.org/support/buy/001-native-path-mapping"&gt;You could be part of this too&lt;/a&gt;!&lt;/p&gt;
        &lt;p&gt;Once we cross the line, I will start with the implementation, which I intend to include into Xdebug 3.4.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have created no new videos since last month, but you can see all the previous ones on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;If you have any suggestions, feel free to reach out to &lt;a href="https://phpc.social/@derickr"&gt;me on Mastodon&lt;/a&gt; or via &lt;a href="http://derickrethans/who.html"&gt;email&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last month, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;p&gt;If you want to contribute to specific projects, you can find those on the &lt;a href="https://xdebug.org/funding"&gt;Projects&lt;/a&gt; page.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-may-2024.html</guid>
      <pubDate>Tue, 11 Jun 2024 15:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Lita</title>
      <link>https://derickrethans.nl/lita.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_lita"/&gt;Friday Night Dinner: Lita&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, June 7th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 7-9 Paddington Street, London W1U 5QH, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://litamarylebone.com/"&gt; https://litamarylebone.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; &amp;#xA3;20 (&amp;#xA3;8-29); Mains: &amp;#xA3;44 (&amp;#xA3;14-&amp;#xA3;160); Drinks: &amp;#xA3;36 (carafe, bottles from &amp;#xA3;54)&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Following the lead of a better-known, piano-playing food critic, we visited Lita, a new restaurant in Marylebone, on a nice spring evening. We didn't want to sit outside with the smokers, so we chose to sit inside. What we hadn't expected was to be sat right in a corner in the back&amp;#x2014;the darkest (and most humid) spot in the restaurant.&lt;/p&gt;
      &lt;p&gt;With the menu came a spiel of: "We recommend a starter each, and then two or three of the small plates, and then one or two from the big plates. The small plates are just little bites." &amp;#x2014; I am paraphrasing here, but you get the gist. Without looking at the menu, we already thought that, taking the advice would mean we would end up with way too much food &amp;#x2014; we've been in similar situations before. Seeing the price of each of these "small" and "big" dishes were, also put us right off. Ultimately, we can always order another dish.&lt;/p&gt;
      &lt;p&gt;Instead, we opted for a more reasonable selection, at least in our opinion. We started with wild-farmed sourdough, with cultured butter, and smoked Basque sardines with a cherry sauce. I have &lt;em&gt;no&lt;/em&gt; idea what wild-farmed sourdough is, nor cultured butter; but it was nice bread with some good butter. The sardines were nicely cured, and the cherries added an enjoyable sweet tang. It wasn't a lot of chow though.&lt;/p&gt;
      &lt;p&gt;As our intermezzo dish we chose their salad of Provencal asparagus, peas, and broad beans, served with a poached Braddock Whites duck egg. A light and refreshing dish, with the white and green asparagus having just the right amount of crunch.&lt;/p&gt;
      &lt;p&gt;And finally, as our main we picked the poussin, which was served with an apricot jus. On the side we had a basic green leaf salad. The poussin was perfectly cooked, and easily came off the bone. I've never had chicken and apricot, but thought the combination worked really well. The salad was, well, salad. Flopped out of the bag and dressed with a fairly basic oil and vinegar dressing. Being critical the leaves were too large to eat in a mouthful, so a bit of light chopping by a chef would have improved it; alas.&lt;/p&gt;
      &lt;p&gt;With our meal, we shared a carafe of Chardonnay, which was perfectly nice. In most circumstances, we would have had a bottle. But they start at &amp;#xA3;54 here, which is a little over the top.&lt;/p&gt;
      &lt;p&gt;The food that we had, was delicious. But we really ought to have had a look at the price ranges in the original review, or on the menu before we booked. We didn't think the value-for-money ratio worked out here. I don't think we will be back here, also because it felt a little pretentious. Marylebone has both better and more affordable places to dine in.&lt;/p&gt;
      &lt;div id="lita" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/lita-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Soughdough with Cultured Butter&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/lita-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Cured Sardines with Cherries&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/lita-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Asparagus Salad&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/lita-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Poussin with Apricots&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/lita-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;A Bunch of Salad Leaves&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('lita', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('lita', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/lita.html</guid>
      <pubDate>Fri, 07 Jun 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: London Shell Co.</title>
      <link>https://derickrethans.nl/london-shell-co.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_london_shell_co"/&gt;Friday Night Dinner: London Shell Co.&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, May 31st 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; Unit 4 Sonny Heights, Swain's Lane, London N6 6AG, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://swainslane.londonshellco.com/"&gt; https://swainslane.londonshellco.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Starters: &amp;#xA3;17; Mains: &amp;#xA3;60; Dessert: &amp;#xA3;15; Drinks &amp;#xA3;51&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We walked the last mile to the restaurant on a lovely, warm spring evening. It is situated on the east side of Hampstead Heath, not far from Highgate Cemetery. Nearby are several independent shops.&lt;/p&gt;
      &lt;p&gt;As the evening was warm and sunny, many people sat outside, but we sat inside, on one side of the little restaurant. On the other side, there was a fish counter with fresh-looking fish and seafood. The back wall had a rack full of bottles of wine to have in or take out. A fridge next to it was for the white and sparkling wines to have in. The atmosphere was very relaxed.&lt;/p&gt;
      &lt;p&gt;The menu was a blackboard, with numerous tasty-sounding dishes in three different sections: cold plates, hot plates, and sides/desserts. Although nearly all the dishes sounded delicious, we each chose a dressed and undressed oyster to start our meal. But not after we had perused the wines on offer&amp;#x2014;we selected a Greek Savatiano.&lt;/p&gt;
      &lt;p&gt;The dressed oyster had a slightly spicy sauce with a nice burn that did not overpower the oyster's flavour. The undressed oyster was fresh and enhanced with a few drops of lemon juice.&lt;/p&gt;
      &lt;p&gt;After our starters, our mains arrived. My wife had picked a ray wing dressed with salty caper butter, and I had selected the whole plaice with lobster sauce. The lobster sauce alone was to die for&amp;#x2014;lovely, sweet chunks of lobster meat with a powerful tomato undertone. It went very well with my perfectly cooked fish. The other dishes coming from the kitchen also looked enticing. On the side, we shared some new potatoes.&lt;/p&gt;
      &lt;p&gt;We don't usually have three courses &amp;#x2014; two is plenty &amp;#x2014; but it was a lovely spring evening, and a dessert seemed appropriate. My wife had a slice of a traditional British custard tart topped with a little nutmeg, whereas I had opted for the fresh strawberries served with white chocolate cream. Although white chocolate can be cloying sweet, this wasn't, and therefore a delicious final to our meal whilst sipping an accompanying dessert wine: A nice relaxed meal with fabulous fishy food.&lt;/p&gt;
      &lt;div id="london-shell-co" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/london-shell-co-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Four oysters on a place with ice, with a slice of lemon.&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/london-shell-co-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;A whole plaice with lobster sauce.&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/london-shell-co-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;New potatoes in butter.&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/london-shell-co-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;A ray wing covered in butters with capers in it.&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/london-shell-co-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Classic custard tart slice.&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/london-shell-co-6.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Strawberries in white chocolate creak, with crunchy bits.&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('london-shell-co', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('london-shell-co', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/london-shell-co.html</guid>
      <pubDate>Fri, 31 May 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: The Cow</title>
      <link>https://derickrethans.nl/the-cow.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_the_cow"/&gt;Friday Night Dinner: The Cow&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, May 24th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 89 Westbourne Park Road, London W2 5QH, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://thecowlondon.com/"&gt; https://thecowlondon.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Cover Charge: &amp;#xA3;4; Starter: &amp;#xA3;14; Mains: &amp;#xA3;43; Wine: &amp;#xA3;35&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We visited The Cow on a warm spring evening and went through a packed bar downstairs to the much quieter upstairs restaurant. This place had been recommended to us, so we were keen to pop along and try it out.&lt;/p&gt;
      &lt;p&gt;We were welcomed with some lovely bread and butter and had some mackerel pate to share to start with. The pate was nicely flavoured but could have done with being served with more bread, as there was too much pate, for the amount of bread, even if we loaded it on.&lt;/p&gt;
      &lt;p&gt;I chose the Monkfish, which was well seasoned and had its defining chewy bite. The vegetables that came with it added flavour, as did the tomato. What let the dish down was the watery sauce underneath it.&lt;/p&gt;
      &lt;p&gt;My wife selected the cuttlefish with peas. The cuttlefish with the peas and sauce was pleasant. The slice of sourdough helped up mopping the flavourful sauce as well, although it did make the dish a little soggy.&lt;/p&gt;
      &lt;p&gt;When we left, the downstairs area was even busier, with no place to even stand. Overall, whilst it is clearly a local favourite, we found it a bit overhyped, and we will probably not go back.&lt;/p&gt;
      &lt;div id="the-cow" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-cow-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Smoked Mackerel Pat&amp;#xE9; with Sourdough and Butter&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-cow-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Monkfish on a Bed of Courgette and Tomatoes&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/the-cow-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Cuttlefish with Peas and Toasted Bread&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('the-cow', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('the-cow', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/the-cow.html</guid>
      <pubDate>Fri, 24 May 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Local Whispers</title>
      <link>https://derickrethans.nl/local-whispers.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="local_whispers"/&gt;Local Whispers&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, May 7th 2024, 15:15 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;For most of the &lt;a href="https://www.youtube.com/@DerickRethansXdebug/videos"&gt;videos&lt;/a&gt; that I make, I also like to have subtitles, because sometimes it's easier to just read along.&lt;/p&gt;
      &lt;p&gt;I used to make these subtitles with an online service called Otter.io, but they stopped allowing uploading of video files.&lt;/p&gt;
      &lt;p&gt;And then I found &lt;a href="https://openai.com/index/whisper"&gt;Whisper&lt;/a&gt;, which allows me to upload audio files to create subtitles. Whisper is an API from &lt;a href="https://openai.com/"&gt;OpenAI&lt;/a&gt;, mainly known for &lt;a href="https://openai.com/chatgpt"&gt;ChatGPT&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;I didn't like having to upload everything to them either, as that means that they could train their model with my original video audio.&lt;/p&gt;
      &lt;p&gt;Whisper never really worked that well, because it broke up the sentences in weird places, and I had to make lots of edits. It look a long time to make subtitles.&lt;/p&gt;
      &lt;p&gt;I recently found out that it's actually possible to run Whisper locally, with an &lt;a href="https://github.com/openai/whisper"&gt;open source project on GitHub&lt;/a&gt;. I started looking into this to see whether I could use this to create subtitles instead.&lt;/p&gt;
      &lt;p&gt;The first thing that their &lt;a href="https://github.com/openai/whisper?tab=readme-ov-file#setup"&gt;documentation&lt;/a&gt; tells you to do is to run: &lt;code&gt;pip install openai-whisper&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;But I am on a Debian machine, and here Python is installed through distribution packages, and I don't really want to mess that up. &lt;code&gt;apt-get&lt;/code&gt; actually suggests to create a virtual environment for Python.&lt;/p&gt;
      &lt;p&gt;In a virtual environment, you can install packages without affecting your system setup. Once you've made this virtual environment, there's actually Python binaries symlinked in there, that you can then use for installing things.&lt;/p&gt;
      &lt;p&gt;You create the virtual environment with:&lt;/p&gt;
      &lt;pre&gt;python3 -m venv `pwd`/whisper-local
cd whisper-local

&lt;/pre&gt;
      &lt;p&gt;In the &lt;code&gt;bin&lt;/code&gt; directory you then have &lt;code&gt;python&lt;/code&gt; and &lt;code&gt;pip&lt;/code&gt;. That's the one you then use for installing packages.&lt;/p&gt;
      &lt;p&gt;Now let me run pip again, with the same options as before to install Whisper:&lt;/p&gt;
      &lt;pre&gt;bin/pip install -U openai-whisper

&lt;/pre&gt;
      &lt;p&gt;It takes quite some time to download. Once it is done, there is a new &lt;code&gt;whisper&lt;/code&gt; binary in our &lt;code&gt;bin&lt;/code&gt; directory.&lt;/p&gt;
      &lt;p&gt;You also need to install &lt;code&gt;fmpeg&lt;/code&gt;:&lt;/p&gt;
      &lt;pre&gt;sudo apt-get install ffmpeg

&lt;/pre&gt;
      &lt;p&gt;Now we can run Whisper on a video I had made earlier:&lt;/p&gt;
      &lt;pre&gt;./bin/whisper ~/media/movie/xdebug33-from-exception.webm

&lt;/pre&gt;
      &lt;p&gt;The first time I ran this, I had some errors.&lt;/p&gt;
      &lt;p&gt;My video card does not have enough memory (2GB only). I don't actually have a very good video card at all, and was better off disabling it, by instructing "Torch" that I do not have one:&lt;/p&gt;
      &lt;pre&gt;export CUDA_VISIBLE_DEVICES=""

&lt;/pre&gt;
      &lt;p&gt;And then run Whisper again:&lt;/p&gt;
      &lt;pre&gt;./bin/whisper ~/media/movie/xdebug33-from-exception.webm

&lt;/pre&gt;
      &lt;p&gt;It first detects the language, which you can pre-empt by using &lt;code&gt;--language
English&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;While it runs, it starts showing information in the console. I quickly noticed it was misspelling lots of things, such as my name Derick as Derek, and Xdebug as XDbook.&lt;/p&gt;
      &lt;p&gt;I also noticed that it starts breaking up sentences in a odd way after a while. Just like what the online version was doing.&lt;/p&gt;
      &lt;p&gt;I did not get a good result this first time.&lt;/p&gt;
      &lt;p&gt;It did create a JSON file, &lt;code&gt;xdebug33-from-exception.json&lt;/code&gt;, but it is all in one line.&lt;/p&gt;
      &lt;p&gt;I reformatted it by installing the &lt;code&gt;yajl-tools&lt;/code&gt; package with &lt;code&gt;apt-get&lt;/code&gt;, and flowing the data through &lt;code&gt;json_reformat&lt;/code&gt;:&lt;/p&gt;
      &lt;pre&gt;sudo apt-get install yajl-tools
cat xdebug33-from-exception.json | json_reformat &amp;gt;xdebug33-from-exception_reformat.json

&lt;/pre&gt;
      &lt;p&gt;The reformatted file still has our full text in a line, but then a &lt;code&gt;segments&lt;/code&gt; section follows, which looks like:&lt;/p&gt;
      &lt;pre&gt;"segments": [
    {
        "id": 0,
        "seek": 0,
        "start": 3.6400000000000006,
        "end": 11.8,
        "text": " Hi, I'm Derick. For most of the videos that I make, I also like to have subtitles, because",
        "tokens": [
                            50363, 15902, 11, 314, 1101, 9626, 624, 13, 1114, 749, 286,
                            262, 5861, 326, 314, 787, 11, 314, 635, 588, 284, 423, 44344,
                            11, 780, 50960
        ],
        "temperature": 0.0,
        "avg_logprob": -0.20771383965152435,
        "compression_ratio": 1.5128205128205128,
        "no_speech_prob": 0.31353551149368286,
            },

&lt;/pre&gt;
      &lt;p&gt;Each segment has an &lt;code&gt;id&lt;/code&gt;, a &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; time (in seconds), the &lt;code&gt;text&lt;/code&gt; for that segment, and a bunch of auxiliary information.&lt;/p&gt;
      &lt;p&gt;But it is still sort of a sentence at a time, which isn't really what we want. Additionally, I really don't want it to say XDbook and misspell my name.&lt;/p&gt;
      &lt;p&gt;For both of those there are actually options that we can use.&lt;/p&gt;
      &lt;p&gt;To make things easier for us later, we're turning on word timestamps. That allows us to by word see where the time index actually was. You do that with the &lt;code&gt;--word_timestamps True&lt;/code&gt; option.&lt;/p&gt;
      &lt;p&gt;To provide a hint on what the video is about, and to get better words, we can use the initial prompt. The option that I used for this video was: &lt;code&gt;--initial_prompt="This video by Derick introduces a new Xdebug feature,
regarding exceptions"&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;To make things more accurate or less accurate, there's also an option that you can specify which is which model to use. Normally the standard one medium is fine, but in order to speed up generation, you can use &lt;code&gt;--model tiny&lt;/code&gt;. This will give less accurate results.&lt;/p&gt;
      &lt;p&gt;If the model has not been downloaded the before, Whisper will automatically do this.&lt;/p&gt;
      &lt;p&gt;It is also possible to specify the language, which makes things go faster if it's English only as well: &lt;code&gt;--language English&lt;/code&gt;. It supports a bunch of languages.&lt;/p&gt;
      &lt;p&gt;The full command that I used is:&lt;/p&gt;
      &lt;pre&gt;CUDA_VISIBLE_DEVICES="" \
        ./bin/whisper ~/media/movie/xdebug33-from-exception.webm \
        --word_timestamps True \
        --initial_prompt="This video by Derick introduces a new Xdebug feature, regarding exceptions" \
        --language English

&lt;/pre&gt;
      &lt;p&gt;In the output file, we now see another elements in each sentence section:&lt;/p&gt;
      &lt;pre&gt;"words": [
    {
        "word": " Hi,",
        "start": 3.6400000000000006,
        "end": 4.16,
        "probability": 0.6476245522499084
    },
    {
        "word": " I'm",
        "start": 4.28,
        "end": 4.44,
        "probability": 0.9475358724594116
    },
    {
        "word": " Derick.",
        "start": 4.44,
        "end": 4.8,
        "probability": 0.12672505341470242

&lt;/pre&gt;
      &lt;p&gt;For each word, it has the &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;, as well as the probability of it being correct. You see that for &lt;code&gt;Derick&lt;/code&gt; it was only 13% certain.&lt;/p&gt;
      &lt;p&gt;With this information you can do some analysis to create an actual subtitle script out of this. For that I have written a PHP &lt;a href="https://gist.github.com/derickr/f30bc04c394e89573071171459f6a9d4"&gt;script&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;It loops over all the segments, and for each of the segments over all the words. If the difference in time between the end of a word and the start of a new word is more than a quarter of a second, it emits a new section of subtitles.&lt;/p&gt;
      &lt;p&gt;Similarly if a sentence is longer than 60 characters it also breaks it up into an extra line. This keeps all the subtitles reasonably well sorted.&lt;/p&gt;
      &lt;p&gt;The &lt;code&gt;emit&lt;/code&gt; function formats it like how the SRT files are supposed to be.&lt;/p&gt;
      &lt;p&gt;With this script, I now create a new SRT file, overwriting the one that Whisper had created:&lt;/p&gt;
      &lt;pre&gt;php whisper-to-srt.php xdebug33-from-exception.json &amp;gt; xdebug33-from-exception.rst

&lt;/pre&gt;
      &lt;p&gt;The output looks like:&lt;/p&gt;
      &lt;pre&gt;0
00:00:03,640 --&amp;gt; 00:00:04,799
Hi, I'm Derick.

1
00:00:05,919 --&amp;gt; 00:00:10,980
For most of the videos that I make, I also like to have subtitles,

2
00:00:11,640 --&amp;gt; 00:00:15,779
because sometimes it's easier to just read along for various
different reasons.

&lt;/pre&gt;
      &lt;p&gt;These subtitles I can now add when uploading a video to YouTube. I might also create a similar script to generate output that can be used as the base for an textual article. Not everybody likes learning from watching videos.&lt;/p&gt;
      &lt;p&gt;I would also prefer not to use a model that has been trained with questionable sources. I will be investigating if I can use &lt;a href="https://commonvoice.mozilla.org"&gt;Mozilla's Common Voice&lt;/a&gt; project's data instead.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/local-whispers.html</guid>
      <pubDate>Tue, 07 May 2024 14:15:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: April 2024</title>
      <link>https://derickrethans.nl/xdebug-update-april-2024.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_april_2024"/&gt;Xdebug Update: April 2024&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Monday, May 6th 2024, 16:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I have not written an update like this for a while. I am sorry.&lt;/p&gt;
      &lt;p&gt;In the last months I have not spent a lot of time on Xdebug due to a set of other commitments.&lt;/p&gt;
      &lt;p&gt;Since my last update in November a few things have happened though.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_3"/&gt;Xdebug 3.3&lt;/h2&gt;
        &lt;p&gt;I released Xdebug 3.3, and the patch releases 3.3.1 and 3.3.2.&lt;/p&gt;
        &lt;p&gt;&lt;a href="https://xdebug.org/announcements/2023-11-30"&gt;Xdebug 3.3 brings&lt;/a&gt; a bunch of new features into Xdebug, such as &lt;a href="https://derickrethans.nl/flamboyant-flamegraphs.html"&gt;flamegraphs&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;The debugger has significant performance improvements in relation to breakpoints. And it can now also show the contents of ArrayIterator, SplDoublyLinkedList, SplPriorityQueue objects, and information about thrown exceptions.&lt;/p&gt;
        &lt;p&gt;A few bugs were present in 3.3.0, which have been addressed in 3.3.1 and 3.3.2. There is currently still an outstanding issue (or more than one), where Xdebug crashes. There are a lot of confusing reports about this, and I have not yet managed to reproduce any of them.&lt;/p&gt;
        &lt;p&gt;If you're running into a crash bug, please reach out to me.&lt;/p&gt;
        &lt;p&gt;There is also a new experimental feature: control sockets. These allow a client to instruct Xdebug to either initiate a debugging connection, or instigate a breakpoint out of band: i.e., when no debugging session is active. More about this in a later update.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="funding_platform"/&gt;Funding Platform&lt;/h2&gt;
        &lt;p&gt;Last year, I made a &lt;a href="https://github.com/xdebug/xdebug/compare/master...derickr:xdebug:custom-map"&gt;prototype&lt;/a&gt; as part of a talk that I gave at &lt;a href="https://derickrethans.nl/talks/xdebug-neoscon23"&gt;NeosCon.io&lt;/a&gt;. In this talk I demonstrated native path mapping &amp;#x2014; configuring path mapping in/through Xdebug, without an IDE's assistance.&lt;/p&gt;
        &lt;p&gt;In collaboration with Robert from &lt;a href="https://www.neos.io/"&gt;NEOS&lt;/a&gt;, and Luca from &lt;a href="https://theaveragedev.com/"&gt;theAverageDev&lt;/a&gt;, we defined a &lt;a href="https://xdebug.org/funding/001-native-path-mapping"&gt;project plan&lt;/a&gt; that explains all the necessary functionality and work.&lt;/p&gt;
        &lt;p&gt;Adding this to Xdebug is a huge effort, and therefore I decided to set up a way how projects like this could be funded.&lt;/p&gt;
        &lt;p&gt;There is now a dedicated &lt;a href="https://xdebug.org/funding"&gt;Projects&lt;/a&gt; section linked from the home page, with a list of all the projects. The page itself lists a short description for each project.&lt;/p&gt;
        &lt;p&gt;For each project, there is a full description and a list of its generous contributors. The &lt;a href="https://xdebug.org/funding/001-native-path-mapping"&gt;Native Xdebug path Mapping&lt;/a&gt; project is currently 85% funded. Once it is fully done, I will start the work to get this included in Xdebug 3.4. &lt;a href="https://xdebug.org/support/buy/001-native-path-mapping"&gt;You could be part of this too&lt;/a&gt;!&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have created several videos since November.&lt;/p&gt;
        &lt;p&gt;Two for &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;Xdebug&lt;/a&gt;:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://youtu.be/4EocpeKxI0k"&gt;Xdebug 3.3: Flamegraphs&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://youtu.be/3FLdpMLBqMk"&gt;Xdebug 3.3: New Features in xdebug_get_function_stack()&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;And several for writing PHP extensions, as part of a new &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1hW4z0J-546qaFpysjlo27x"&gt;series&lt;/a&gt;:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://youtu.be/WjbKYHzoKM0"&gt;1. Writing PHP Extensions: Creating a Skeleton&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://youtu.be/8N8Rk-BE0d4"&gt;2. Writing PHP Extensions: Importing the Library, and &amp;#x2026;&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://youtu.be/-Tb_f55fc0k"&gt;3. Writing PHP Extensions: Implementing the rdp_simplify &amp;#x2026;&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;If you have any suggestions, feel free to reach out to &lt;a href="https://phpc.social/@derickr"&gt;me on Mastodon&lt;/a&gt; or via &lt;a href="http://derickrethans/who.html"&gt;email&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last month, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;p&gt;If you want to contribute to specific projects, you can find those on the &lt;a href="https://xdebug.org/funding"&gt;Projects&lt;/a&gt; page.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-april-2024.html</guid>
      <pubDate>Mon, 06 May 2024 15:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Sudu</title>
      <link>https://derickrethans.nl/sudu.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_sudu"/&gt;Friday Night Dinner: Sudu&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, May 3rd 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 30 Salusbury Rd, London, NW6 6NL, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl http://sudu.uk"&gt; http://sudu.uk&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food &amp;#xA3;39; Drinks &amp;#xA3;22&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We went on a rainy Saturday evening. Sudu is pretty close to where we live, but this was our first time.&lt;/p&gt;
      &lt;p&gt;The exterior is painted a dark grey and is a little unprepossessing, however once inside, we were in for a treat.&lt;/p&gt;
      &lt;p&gt;We were quickly seated in a busy restaurant and saw many delicious-sounding things on the menu. My husband chose the beef rendang, which he had served with plain basmati rice. I picked the chicken satay served with coconut rice and a plain roti. This was washed down with a couple of tiger beers. The service in Sudu was quick and attentive but not intrusive.&lt;/p&gt;
      &lt;p&gt;The food arrived fairly quickly. My husband's beef rendang was nice and spicy, as it should be, with nice tender chunks of beef that worked well with the rice. My chicken satay came as chicken pieces on skewers with a bowl of a spicy, peanutty satay sauce into which the chicken could be dipped. The coconut rice was subtly flavoured with coconut. Once the chicken skewers were finished, I poured the remaining satay onto my rice. The roti was delicious, slightly crispy on the outside but soft and a little fluffy on the inside and not overly greasy.&lt;/p&gt;
      &lt;p&gt;The food coming out to neighbouring tables also looked great, so it is likely we&amp;#x2019;ll be going back to try something else from the menu.&lt;/p&gt;
      &lt;div id="sudu" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/sudu-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Chicken Satay&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/sudu-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Roti&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/sudu-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Beef Rendang&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('sudu', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('sudu', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/sudu.html</guid>
      <pubDate>Fri, 03 May 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Granger and Co</title>
      <link>https://derickrethans.nl/granger-and-co.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_granger_and_co"/&gt;Friday Night Dinner: Granger and Co&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, April 26th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 105 Marylebone High St, London, W1U 4RS, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://grangerandco.com/marylebone"&gt; https://grangerandco.com/marylebone&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food &amp;#xA3;78; Drinks &amp;#xA3;29&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We went to the branch on Marylebone High Street, in a building previously occupied by Patisserie Valerie. The front of Granger and Co. is pretty unassuming, however once inside it really opens up. The rear dining room is a large modern airy dining space around two floors high, with comfortable seating and art on the walls. It has a slightly mid-century modern vibe. Despite the size and height of the room, the acoustics was great, and we could hear our conversation perfectly.&lt;/p&gt;
      &lt;p&gt;I arrived a little early and was seated in a corner seat. From there, I could admire the room while perusing the menu. Once my wife arrived, we quickly settled on our food choices.&lt;/p&gt;
      &lt;p&gt;We started with courgette chips with an aioli. The chips (slices of courgette) had a lovely crisp batter, with juicy courgette inside and arrived sprinkled with black sesame seeds. We squeezed a few drops of lemon juice over them, which really brought them to life, especially when dipped in the delicious aioli.&lt;/p&gt;
      &lt;p&gt;For the main course, we both selected an onglet steak&amp;#x2014;medium rare. It was well-cooked, flavourful, and moist. It was served with some greens, baby lettuce, and onion rings. We enjoyed a bottle of Tule Rosso wine, which worked well with the food.&lt;/p&gt;
      &lt;p&gt;After our main course, we both fancied a little dessert. Not too much, as we were mostly full of delicious steak. We settled on a tiramisu, which had good, slightly boozy coffee flavour and was nice and creamy, and formed a delicious end to our meal at this Australian restaurant.&lt;/p&gt;
      &lt;div id="granger" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/granger-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Courgette Chips&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/granger-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Onglet with Vegetables&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/granger-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Tiramisu&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('granger', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('granger', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/granger-and-co.html</guid>
      <pubDate>Fri, 26 Apr 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Concealing Cacophony</title>
      <link>https://derickrethans.nl/concealing-cacaphony.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="concealing_cacophony"/&gt;Concealing Cacophony&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, April 16th 2024, 14:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Over the last few weeks I have been publishing a &lt;a href="https://www.youtube.com/watch?v=WjbKYHzoKM0&amp;amp;list=PLg9Kjjye-m1hW4z0J-546qaFpysjlo27x"&gt;series of videos&lt;/a&gt; on writing PHP extensions.&lt;/p&gt;
      &lt;p&gt;I record these videos through &lt;a href="https://obsproject.com/"&gt;OBS&lt;/a&gt;, and then slice and dice them with &lt;a href="https://kdenlive.org/en/"&gt;Kdenlive&lt;/a&gt;. This editing is necessary to make up for my mistakes, shorten the time we wait for things to compile, and to remove the noise of me hammering away on my keyboard.&lt;/p&gt;
      &lt;p&gt;Editing takes a lot of time, and I still wasn't always pleased with the result as there was still a fair amount of noise while I am talking.&lt;/p&gt;
      &lt;p&gt;For the &lt;a href="https://phpinternals.news"&gt;PHP Internals News podcast&lt;/a&gt;, I used a set of noise cancellation filters, which worked wonders. But it turns out that Kdenlive does not come with one built in.&lt;/p&gt;
      &lt;p&gt;I had a look around on the Internet, and learned that there is a &lt;a href="https://en.wikipedia.org/wiki/LADSPA"&gt;LADSPA&lt;/a&gt; Noise Suppressor for Voice plugin. LADSPA is an open API for audio filters and audio signal processing effects. LADSPA plugins can be used with Kdenlive.&lt;/p&gt;
      &lt;p&gt;Some Linux distributions have a package for this LADSPA Noise Suppressor for Voice, but my Debian distribution bookworm does not.&lt;/p&gt;
      &lt;p&gt;I found &lt;a href="https://kentwest.neocities.org/westk/librnnoise"&gt;instructions&lt;/a&gt; that explain how to build the plugin from source. These instructions worked after some tweaks. I ended up creating the following script:&lt;/p&gt;
      &lt;pre&gt;#!/bin/bash

sudo apt install cmake ninja-build pkg-config libfreetype-dev libx11-dev libxrandr-dev libxcursor-dev
git clone https://github.com/werman/noise-suppression-for-voice /tmp/noise
cd /tmp/noise
cmake -Bbuild-x64 -H. -GNinja -DCMAKE_BUILD_TYPE=Release
sudo ninja -C build-x64 install

&lt;/pre&gt;
      &lt;p&gt;After running this script, and restarting Kdenlive, I found the installed plugin when I searched for it.&lt;/p&gt;
      &lt;p&gt;With the plugin loaded, I now have much clearer sound, and I also don't have to edit the sections where I am typing, as the plugin automatically handles this.&lt;/p&gt;
      &lt;p&gt;I will still have to edit out my mistakes.&lt;/p&gt;
      &lt;p&gt;I then also had a look at how it worked. It turns out that &lt;a href="https://github.com/werman/noise-suppression-for-voice"&gt;this plugin&lt;/a&gt; uses neural networks to cancel the noise.&lt;/p&gt;
      &lt;p&gt;In the background, it uses the &lt;a href="https://github.com/xiph/rnnoise"&gt;RNNoise&lt;/a&gt; library which implements an algorithm by Jean-Marc Valin, as outlined in this &lt;a href="https://arxiv.org/pdf/1709.08243.pdf"&gt;paper&lt;/a&gt;. There is an easier to read version of how the &lt;a href="https://jmvalin.ca/demo/rnnoise/"&gt;algorithm works&lt;/a&gt; on his website.&lt;/p&gt;
      &lt;p&gt;The &lt;a href="https://media.xiph.org/rnnoise/README"&gt;data to train the model&lt;/a&gt; is also freely available, and uses resources from the &lt;a href="http://www.openslr.org/"&gt;OpenSLR&lt;/a&gt; project. Noise data is also available there. From what I can tell, all this data was contributed under reasonable conditions, and not scraped from the internet without consent. That is important to me.&lt;/p&gt;
      &lt;p&gt;Hopefully, from the third video in the series, you will find the sound quality much better.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/concealing-cacaphony.html</guid>
      <pubDate>Tue, 16 Apr 2024 13:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Pascor</title>
      <link>https://derickrethans.nl/pascor.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_pascor"/&gt;Friday Night Dinner: Pascor&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, April 12th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 221 Kensington High Street, London, W8 6SG, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.pascor.co.uk/"&gt; https://www.pascor.co.uk/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Wine: &amp;#xA3;40, Food: &amp;#xA3;25, Desert: &amp;#xA3;18.5&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;em&gt;From the archive: We visited Pascor in January 2023&lt;/em&gt;
      &lt;/p&gt;
      &lt;p&gt;Right on Kensington High Street, near the Design Museum is Pascor. A Levantine &amp;#x201C;Fire&amp;#x201D; restaurant, which we picked as our first place to go to in the new year.&lt;/p&gt;
      &lt;p&gt;The restaurant is over two levels, with the lower part smaller, and close to a chilly door. Luckily we were sat in the roomier first floor, with cosy decorations. The restaurant is a tapas-y affair, and we shared the Challah Bread, the Reverse Tabbouleh Salad, a whole roasted aubergine, and the evening&amp;#x2019;s special: fish cakes, which were really fish cake croquettes. The dishes all came with sauces. Although they were fairly simple, they all packed a great flavour. The dishes came out as they were ready, and they all went great with the Lebanese red wine that we picked (a Ch&amp;#xE2;teau Ksara Le Prieur&amp;#xE9; Rouge 2018).&lt;/p&gt;
      &lt;p&gt;We also did indulge in desserts. My wife picked a Coconut &amp;#x201C;Beirut Meets Bangkok&amp;#x201D; Malabi, which was lovely sweet and moist with strong hints of pineapple. I choose the Chocolate Cr&amp;#xE9;meux which was rich and indulgent with a flavourful blueberry sauce.&lt;/p&gt;
      &lt;p&gt;My only regret is not picking one (or two!) more dishes to share! Which is all the more reason to return, and sample some other delicious things that we saw coming out of the kitchen &amp;#x2014; perhaps when the weather is a little better.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/pascor.html</guid>
      <pubDate>Fri, 12 Apr 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: 50 Kalò</title>
      <link>https://derickrethans.nl/50-kalo.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_50_kal"/&gt;Friday Night Dinner: 50 Kal&amp;#xF2;&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, April 5th 2024, 18:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; 7 Northumberland Ave, London WC2N 5BY&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.50kalo.it/ciro__salvo.php"&gt; https://www.50kalo.it/ciro__salvo.php&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#xA3;40, Drinks: &amp;#xA3;27&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;For tonight's meal, we walked to 50 Kal&amp;#xF2;, a busy restaurant just off Trafalgar Square, and situated in The Grand Hotel. Although you don't notice that it&amp;#x2019;s a restaurant attached to a hotel.&lt;/p&gt;
      &lt;p&gt;50 Kal&amp;#xF2; is a pizza restaurant and an off-shoot of their original Naples-based restaurant. It came with great reviews, so we punted on it. When we got there, we were quickly seated at a small table, with my chair nearly touching a chair on the table behind me. I am not keen on being boxed in like this, and despite the small gap, the staff still pushed through the gap between me and the diner behind, which was quite irritating. Fortunately, my wife spotted another free table without this constraint, and we moved.&lt;/p&gt;
      &lt;p&gt;The menu is full of Neapolitan pizza&amp;#x2014;in fact, that's what this restaurant specialises in. I selected a Prosciutto Cotto&amp;#x2014;roasted ham on a white base, with shavings of aged Parmesan. My wife chose the Del Monaco, which had a traditional tomato base, and came topped with salami. The pizzas were big and freshly cooked, arriving quickly. The pizza crust was slightly toasted and lovely and chewy, but in my opinion, the base could have been a little crispier. The shavings of fresh parmesan also added something extra to the overall flavour.&lt;/p&gt;
      &lt;p&gt;The restaurant also has its "own" beer, (three varieties) brewed in collaboration with Birra Amarcord, from Rimini in Italy. We both started with a "Forte," and during our meal, we enjoyed the other two, (a blonde and a red) as well. The beers were nice and complemented the pizza, but whilst tasty, they weren&amp;#x2019;t the most exciting beers.&lt;/p&gt;
      &lt;p&gt;Although we thought we were full from our large pizza, our waitress convinced us to have a special Easter-related dessert. The almond and orange cake was delicious, nice and fluffy, with a lovely freshness from the orange. It was a fitting end to the meal.&lt;/p&gt;
      &lt;p&gt;All in all, it was a reasonable meal out. The pizzas were nice, the service was quick, and the interior was lovely. This would be a good place to eat after a day of tourist-ing, and avoiding the nearby chain restaurants.&lt;/p&gt;
      &lt;div id="50-kalo" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/kalo-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Prosciutto Cotto&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/kalo-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Del Monaco&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/kalo-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Almond and Orange tarte&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('50-kalo', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('50-kalo', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/50-kalo.html</guid>
      <pubDate>Fri, 05 Apr 2024 17:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: The Porchester</title>
      <link>https://derickrethans.nl/the-porchester.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_the_porchester"/&gt;Friday Night Dinner: The Porchester&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, March 29th 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 88 Bishops Bridge Road, London W2 5AA&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.theporchester.co.uk/"&gt; https://www.theporchester.co.uk/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#xA3;41, Drinks: &amp;#xA3;35&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We were not planning to go here, but due to unforeseen circumstances with our planned dinner venue, we had to change plans at the last moment, and this pub was close by.&lt;/p&gt;
      &lt;p&gt;It's a fairly typical Young's pub, with their standard taps, including a Real Ale &amp;#x2014; the Young's Original. I ordered fish and chips, sorry, the "Ale Battered Haddock". My partner ordered the bavette steak. The fish had a nice crispy coating, and as a first for me, came with curry sauce as well as tartare sauce. It worked better than I expected. The chips were a bit on the chewy side, but then again, I like mine mega crunchy on the outside, and fluffy on the inside &amp;#x2014; like good fries should be!&lt;/p&gt;
      &lt;p&gt;The portions were large, and we were properly full by the end. I have to admit I was struggling a little.&lt;/p&gt;
      &lt;p&gt;It got busy soon after we finished our meal and was a little too loud and shouty for my liking. Therefore, we made a swift exit and headed home.&lt;/p&gt;
      &lt;div id="porchester" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/porchester-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Ale Battered Haddock&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/porchester-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Bavette Steak&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('porchester', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('porchester', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/the-porchester.html</guid>
      <pubDate>Fri, 29 Mar 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Nazuki Garden</title>
      <link>https://derickrethans.nl/nazuki-garden.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_nazuki_garden"/&gt;Friday Night Dinner: Nazuki Garden&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, March 1st 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 161 Whitfield Street, London W1T 5ET, UK&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.nazukigarden.co.uk/"&gt; https://www.nazukigarden.co.uk/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#xA3;60, Wine: &amp;#xA3;28 (from &amp;#xA3;28, also by the glass)&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once in a while, you want to try something different. So we found ourselves on a cold and rainy Friday evening at Nazuki Garden. I had just come back from a work trip to Berlin, and was in need of a good meal.&lt;/p&gt;
      &lt;p&gt;My partner had booked Nazuki Garden several weeks earlier, at a time which would make it easy enough for me to make it on time to. With London City's efficiency, I was way too early and ended up walking for half an hour first so that I didn't have to sit in the restaurant by myself for an hour.&lt;/p&gt;
      &lt;p&gt;We were sat at the back of the room, far away from the door, but that unfortunately didn't stop the draft when somebody opened that door.&lt;/p&gt;
      &lt;p&gt;Their menu is extensive, with lots of tempura, sushi, sashimi, temaki, nigiri, and rolls. However, it was a cold evening, and we preferred something warm.&lt;/p&gt;
      &lt;p&gt;Luckily, their menu also has a large selection of cooked dinner. Soups and donburis.&lt;/p&gt;
      &lt;p&gt;We began our meal with a starter of vegetable gyozas and Japanese fried chicken. The gyozas were nice and crisped up, with a slightly bubbly texture. The Japanse Fried Chicken also crisp, spicy, and served with a lovely flavoured mayonnaise.&lt;/p&gt;
      &lt;p&gt;While we were enjoying our starters and Merlot (we got a bottle, it was Friday, bite us), a fair amount of other punters came to the restaurant. I was happy to see a large Japanese contingent as well. It's often a good sign that restaurants with a specific country's cuisine are frequented by people from that specific country. It adds a flair of authenticity.&lt;/p&gt;
      &lt;p&gt;After our main, we both had the Teriyaki BBQ Roasted Pork Donburi &amp;#x2014; slices of well seasoned moist roasted pork in a delicious sauce.  It was perhaps not the most adventurous dish on their menu, but sometimes you just want to get fed well. And we were.&lt;/p&gt;
      &lt;p&gt;After dinner, we were still a little peckish, and shared a chocolate ganache mochi ice cream. A little rice cake richly filled with chocolate ganache icecream. A perfect way to end our meal.&lt;/p&gt;
      &lt;p&gt;At some point, in summer, we probably should return and try our the sushi (and friends) side of the menu as well.&lt;/p&gt;
      &lt;div id="nazuki-garden" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/nazuki-garden-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Vegetable Gyoza&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/nazuki-garden-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Japanese Fried Chicken&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/nazuki-garden-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Teriyaki BBW Roasted Pork Donburi&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/nazuki-garden-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Chocolate Ganache Mochi Ice Cream&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('nazuki-garden', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('nazuki-garden', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/nazuki-garden.html</guid>
      <pubDate>Fri, 01 Mar 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Akub</title>
      <link>https://derickrethans.nl/akub.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_akub"/&gt;Friday Night Dinner: Akub&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, February 16th 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 27 Uxbridge Street, Notting Hill Gate, London&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.akub-restaurant.com/"&gt; https://www.akub-restaurant.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Beer: &amp;#xA3;12; Pudding: &amp;#xA3;9; Food: &amp;#xA3;55&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;em&gt;From the archive: We visited Akub in January 2023&lt;/em&gt;
      &lt;/p&gt;
      &lt;p&gt;Just off the main road near Notting Hill Gate station is this cosy multi-floor restaurant serving Palestinian food. Opened last year, and the menu contains mostly sharing dishes.&lt;/p&gt;
      &lt;p&gt;We started off our drinks with two Palestinian beers, a White, and an IPA, which fitted very well with our selection of mezzes/starters/whatever you want to call it. Before the starters showed up, we ordered a bowl of salted lupin beans, called Turmous, which were very tasty. Similar to a mix of almonds and perhaps Edamame? At least, the way you eat them was like the Japanese bean snack, as it involved removing the skin in your mouth &amp;#x2014; if you were so inclined. I was; my partner wasn't.&lt;/p&gt;
      &lt;p&gt;The starters that we ordered included three balls of a goats cheese (Labaneh) covered in three different kinds of spices. Sumak, and two others that I can&amp;#x2019;t remember right now. Besides that, we got a grilled Nabulsi cheese, which was covered in some oil and seeds, and was slightly squishy like fried halloumi can be, a little salty like feta, but overall a better texture than I think that over-fried halloumi could be. Our third starter were spiced squash dumplings, Shish Barak with Beetroot, which was also delicious.&lt;/p&gt;
      &lt;p&gt;Our "main" to share was the short rib Fatteh, which was slow cooked beef with spices, with garlic yoghurt, crispy (like really crispy) onions, with some fried focaccia squares to add some more texture.&lt;/p&gt;
      &lt;p&gt;Even after that, we were still not 100% satisfied, and had a rich chocolate cremeux and pistachio ice cream to finish. It was all so tasty that we forgot to take any photos!&lt;/p&gt;
      &lt;p&gt;The service was attentive, and our waitress explained approximately how many things we should order from the menu, and she was spot on.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/akub.html</guid>
      <pubDate>Fri, 16 Feb 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Volta do Mar</title>
      <link>https://derickrethans.nl/volta-do-mar.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_volta_do_mar"/&gt;Friday Night Dinner: Volta do Mar&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, February 9th 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 100 Draycott Avenue, Chelsea, London SW3 3AD, UK&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.voltadomar.co.uk/"&gt; https://www.voltadomar.co.uk/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Cocktails: &amp;#xA3;29, Food: &amp;#xA3;70, Drinks: &amp;#xA3;17&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We had been to Volta do Mar before, before they moved from their old location in Covent Garden, to their new location in Chelsea.&lt;/p&gt;
      &lt;p&gt;The restaurant specialises in Portuguese food, including cuisines from countries along Portuguese trade routes.&lt;/p&gt;
      &lt;p&gt;While we were reading the menus to select our dishes, we enjoyed a cheeky cocktail. I had a take on a Caipirinha, spruced up with blueberries. And my partner had a Martini with added spiced pear.&lt;/p&gt;
      &lt;p&gt;After making our choices, we found out that beyond the dishes on the menu, they also have a short set of specials. This also meant that their Iberico Pork Bafassa was replaced with an Iberico Pork burger, with added foie gras. As we don't really want to eat that, it meant that my partner had to change to a different main.&lt;/p&gt;
      &lt;p&gt;In the end, we choose to share a Sardine P&amp;#xE2;te and Sourdough snack, and Ham Hock and Chorizo Croquettes. The p&amp;#xE2;te was smooth and flavourful, and spread excellently on the sourdough. The croquettes full of porky goodness. The other starters on the menu also sounded appetizing.&lt;/p&gt;
      &lt;p&gt;For our main, we picked their Piri Piri Chicken, served with chips. The chicken was delicious, moist and well spiced and the pot of sauce that came with it was ideal to dip the chicken and chips into.&lt;/p&gt;
      &lt;p&gt;We had a glass each of their house wine with our main, I had red, but my partner had the white, both wines were lovely and worked nicely with the food.&lt;/p&gt;
      &lt;p&gt;We enjoyed our meal at Volta do Mar. The food was great and the atmosphere relaxing, and the staff attentive. It certainly was no Nando's!&lt;/p&gt;
      &lt;div id="volta-do-mar" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/volta-do-mar-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Blueberry Caipirinha&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/volta-do-mar-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Sardine P&amp;#xE2;te with Sourdough&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/volta-do-mar-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Ham Hock and Chorizo Croquettes&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/volta-do-mar-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Piri Piri Chicken&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('volta-do-mar', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('volta-do-mar', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/volta-do-mar.html</guid>
      <pubDate>Fri, 09 Feb 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Burn's Night at Browns</title>
      <link>https://derickrethans.nl/browns.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_burn_s_night_at_browns"/&gt;Friday Night Dinner: Burn's Night at Browns&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, February 2nd 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 82-84 St Martin's Lane, London WC2N 4AG, UK&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.browns-restaurants.co.uk/restaurants/london/covent-garden#/"&gt; https://www.browns-restaurants.co.uk/restaurants/london/covent-garden#/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food and Drinks pairing: &amp;#xA3;110&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;At the end of January, more shops start stocking haggis again. Haggis is a traditional food of Scotland and the main event of a Burns supper, where the life of the poet Robert Burns is celebrated. It is often paired with neeps and tatties (mashed swede and potatoes).&lt;/p&gt;
      &lt;p&gt;With my partner having Scottish ancestry, we usually prepared our own. In the earlier years with friends and family, in the form of "drink some of Derick's whisky". In later years just for the two of us. This year, we chose to not prepare our own, and instead enjoy somebody else cooking it for us.&lt;/p&gt;
      &lt;p&gt;We have been to Browns in Covent Garden a few times before &amp;#x2014; we even had our engagement party there. We know it as a reliable place with good food, and tasty cocktails. For Burns Night they were offering a short set menu, with a whisky pairing that sounded to our liking.&lt;/p&gt;
      &lt;p&gt;As a starter we both had the seared scallops. They were sweet and bouncy, and just cooked right. There were herbs sprinkled over them, and they were served with Parmesan crisps and a creamy sauce. It was paired with a 12-year-old Glenfiddich, which paired perfectly.&lt;/p&gt;
      &lt;p&gt;After waiting for a while &amp;#x2014; too long really &amp;#x2014; the main event showed up. Three thick slices of haggis, slightly crisped up on the outside, and served on a bed of the aforementioned neeps and tatties. Served with a sweetened gravy, of which more could have been served. I thought that the crisped up edges added a little extra texture to the otherwise well spiced and prepared haggis. This was paired with a 15-year-old Glenfiddich, which is a little spicier itself.&lt;/p&gt;
      &lt;p&gt;For our desert, the two of us picked something different. My partner had the traditional Scottish Cranachan, where I chose the crumble. I can't resist a good crumble, and this one was certainly one.&lt;/p&gt;
      &lt;p&gt;In the end, I thought it was a good meal, and certainly filling. The service was a little slow, and some confusion did ensue while we were waiting for our whisky to be paired with the haggis main course. I also thought it was a little on the pricier side of what it is.&lt;/p&gt;
      &lt;p&gt;I think next year we'll cook our own again, even though means we'll have to do the dishes too!&lt;/p&gt;
      &lt;div id="browns" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/browns-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Scallops&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/browns-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Haggis, Neeps, and Tatties&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('browns', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('browns', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/browns.html</guid>
      <pubDate>Fri, 02 Feb 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: East Street by Tampopo</title>
      <link>https://derickrethans.nl/east-street.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_east_street_by_tampopo"/&gt;Friday Night Dinner: East Street by Tampopo&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, January 26th 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 3&amp;#x2013;5 Rathbone Place, London W1T 1HJ, UK&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://tampopo.co.uk/fitzrovia/"&gt; https://tampopo.co.uk/fitzrovia/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#xA3;50; Drinks: &amp;#xA3;35&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The idea behind going for a different restaurant every Friday is to try out a wide variety of places, but also of cuisines. We are lucky that in London, we have access to pretty much any sort of dishes we fancy.&lt;/p&gt;
      &lt;p&gt;Sometimes, you can even find a wide variety of different culture's food in one place, and East Street is such an establishment. It is situated just North of Oxford Street, close to Tottenham Court Road station. It specialised in what can only be described as pan-Asian.&lt;/p&gt;
      &lt;p&gt;Their menu is extensive, from Szechuan dishes via Japan and Korea to Indonesian and Malay. We started with two of their small plates, the Malaysian Satay Chicken and Korean Popcorn Chicken. They were both delicious, very flavourful and moorish. Good Satay Chicken I remember from my parent's Indonesian friends, and this was just like it. With our starters, we enjoyed a lovely Hokkaido Negroni as we didn't think a bottle of wine would fit with this menu.&lt;/p&gt;
      &lt;p&gt;Choosing the small plates was hard, as there are so many nice sounding ones. Instead of ordering them all, we also picked a large plate each. I ordered a Rendang Beef Curry, again, with memories of the Indonesian Restaurants you find in the Netherlands. It was accompanied by rice, peanuts, boiled eggs, and some pickled cucumber. My companion ordered a Tamarind Chicken, slices of well cooked moist chicken in a delicious sticky tamarind sauce. It came served with rice, broccoli and crispy onions, this was one of the non-spicy options on the menu, but despite the lack of chillies still had a bit of a kick. Again, not wanting wine, we picked a bog-standard Tiger beer to wash all the delicious flavours down, which paired pretty well.&lt;/p&gt;
      &lt;p&gt;Although we were pretty full, we could not quite resist the churros, and shared three with a tasty caramel sauce. I don't quite understand how they fit in an Asian kitchen, but they were delightful regardless.&lt;/p&gt;
      &lt;p&gt;If we were to return, which seems likely, we would probably have a meal made up of more of the smaller dishes (all of which sounded delicious) instead of going for the traditional starter plus main course approach.&lt;/p&gt;
      &lt;p&gt;The place was pretty full, and when we left I remarked that we were probably amongst the oldest of the clientele, but we didn't feel out of place. Which I think is a good sign.&lt;/p&gt;
      &lt;div id="east-street" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/east-street-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Interior&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/east-street-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Chicken Satay&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/east-street-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Popcorn Chicken&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/east-street-4.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Tamarind Chicken&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/east-street-5.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Rendang&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('east-street', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('east-street', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/east-street.html</guid>
      <pubDate>Fri, 26 Jan 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Empire Empire</title>
      <link>https://derickrethans.nl/empire-empire.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_empire_empire"/&gt;Friday Night Dinner: Empire Empire&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, January 19th 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 16 All Saints Road, London, W11 1HH, UK&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.empire-empire.restaurant/"&gt; https://www.empire-empire.restaurant/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#xA3;50, Drinks: &amp;#xA3;12&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We visited Empire Empire on a chilly January evening. The restaurant was fairly quiet but even at 18.30 there were some tables seated and enjoying their food.&lt;/p&gt;
      &lt;p&gt;The restaurant features an old fashioned jukebox type vinyl record player close to the entrance and has a photobooth for some fun snaps should you be so inclined.&lt;/p&gt;
      &lt;p&gt;We had a beer each from 40ft Brewery in Hackney, which was lovely. It's great to see an Indian restaurant branching out from the usual cobra and kingfisher options. We started with poppadoms and dips, and then I had a well spiced biryani with incredibly tender lamb falling off the shank and a pastry lid. My companion really enjoyed her Empire Butter Chicken and a naan bread. This was not as rich as some butter chicken curries, but was incredibly flavourful with a nice level of spicing and kick. Unfortunately we were both too full to move onto try what sounded like tasty desserts from the menu.&lt;/p&gt;
      &lt;p&gt;Service at Empire Empire was very welcoming and attentive (and quick, but not rushed) we were out and heading home on the bus about an hour after sitting down.&lt;/p&gt;
      &lt;div id="empire-empire" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/empire-empire-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Butter Chicken&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/empire-empire-3.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Lamb Biryani&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('empire-empire', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('empire-empire', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/empire-empire.html</guid>
      <pubDate>Fri, 19 Jan 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Lokkanta</title>
      <link>https://derickrethans.nl/lokkanta.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_lokkanta"/&gt;Friday Night Dinner: Lokkanta&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, January 5th 2024, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 31 Westbourne Grove, London W2 4UA, United Kingdom&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://lokkantaturkishrestaurant.co.uk/"&gt; https://lokkantaturkishrestaurant.co.uk/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#xA3;45, Drinks: &amp;#xA3;25&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;As first restaurant of the year, we wanted something low-key. Not far from Paddington station, on Westbourne Grove, there is a whole row of such places. We settled on Lokkanta, a place that specialises in Turkish food.&lt;/p&gt;
      &lt;p&gt;We started off with Turkish sausage slices with halloumi, while we were waiting for our main course. At the same time, we started enjoying our delicious red wine from Turkey.&lt;/p&gt;
      &lt;p&gt;The front section of the restaurant features a well ventilated charcoal grill upon which most of the meats were roasted. In my case, a well cooked and flavoured lamb shish. My partner picked a Yogurtly Adana, minced grilled lamb with bread and basted in a tomato sauce and yoghurt.&lt;/p&gt;
      &lt;p&gt;The service was speedy, and we did not have to wait long. Perhaps that was mostly because when we arrived at 18:30, there was only other table enjoying dinner, so we were almost the only customers. When we left, there were a few more people enjoying their dinner. However, with the restaurant being quite empty, it perhaps lacked a bit of ambience and the tiled interior made it feel a little clinical, I think it would be quite different if it was busy with plenty of hustle and bustle.&lt;/p&gt;
      &lt;p&gt;In short, the food and wine was good, but the atmosphere was unfortunately missing.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/lokkanta.html</guid>
      <pubDate>Fri, 05 Jan 2024 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Ma Petite Jamaica</title>
      <link>https://derickrethans.nl/ma-petite-jamaica.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_ma_petite_jamaica"/&gt;Friday Night Dinner: Ma Petite Jamaica&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, December 29th 2023, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; 4-6 Inverness Street, London, NW1 7HJ, UK&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://www.mapetitejamaica.com/"&gt; https://www.mapetitejamaica.com/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#xA3;65, Drinks: &amp;#xA3;25&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;What do you need on a cold and dark winter evening? Exactly, a bit of tropical warmth. Our booking was a little last minute, as we hadn't really thought about arranging something for the last Friday of the year. My wife, who often takes the lead in picking our Friday evening restaurant, suggested this Jamaican place in Camden, not too far from where we live.&lt;/p&gt;
      &lt;p&gt;We arrived to find the dining room partially full, with Jamaican musing playing and (fake) palm trees. It gave a happy and homely feel to the dining room.&lt;/p&gt;
      &lt;p&gt;I had never had Jamaican food, so decided that I wanted to try the staples. As my starter I picked the ackee and salt fish, which was served with fried dumplings. My wife chose the chickpea and pumpkin curry. We also decided to share a portion of the jerk chicken spring rolls. All three small plates were very flavourful. With enough hints of scotch bonnets to add a kick, but nothing too overpowering. The dumplings were great for dipping up the sauces.&lt;/p&gt;
      &lt;p&gt;Because we felt we needed to escape from the cold, we enjoyed a pair of Jamaican Mule cocktails, with our starters, and later mains. The first set was half price as it was still happy hour! There were also a number of Jamaican beers on offer, with a Red Stripe on tap.&lt;/p&gt;
      &lt;p&gt;I selected the curried goat with rise and peas as my main course. My wife wanted to order a wrap, which they were no longer serving, although they were on the menu. She ended up with their vegetable curry with a roti. Both were excellent.&lt;/p&gt;
      &lt;p&gt;Our only regret was probably ordering too much food. One and a half starter, and a full main per person was certainly too much. But that's not the worst problem to have if your dinner was so tasty.&lt;/p&gt;
      &lt;div id="ma-petite-jamaica" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/ma-petite-jamaica-1.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Fried Dumpling, with Ackee and Saltfish&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/friday-night-dinners/ma-petite-jamaica-2.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Curried Goat&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('ma-petite-jamaica', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('ma-petite-jamaica', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/ma-petite-jamaica.html</guid>
      <pubDate>Fri, 29 Dec 2023 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Friday Night Dinner: Noon</title>
      <link>https://derickrethans.nl/noon.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem fridayNightDinner"&gt;
      &lt;h1&gt;&lt;a name="friday_night_dinner_noon"/&gt;Friday Night Dinner: Noon&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, December 22nd 2023, 18:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; Griend 7, 6221 AJ Maastricht, The Netherlands&lt;/div&gt;
        &lt;div class="url"&gt;
          &lt;a href="https://derickrethans.nl https://noonmaastricht.nl/"&gt; https://noonmaastricht.nl/&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="costs"&gt; Food: &amp;#x20AC;70, Drinks: &amp;#x20AC;26&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Even when we're out of the country, we try to keep our tradition in place, and so we found ourselves on a cold and rainy evening at Noon, in Maastricht, in the Netherlands.&lt;/p&gt;
      &lt;p&gt;When we arrived just after 18:00, the restaurant was already quite full. With a few dozen tables, some high tables, and a bar where a bar keep was making plenty of colourful cocktails. We were seated at a high table right in the middle of the stylishly appointed establishment.&lt;/p&gt;
      &lt;p&gt;While enjoying a glass of cava, we shared a couple of starters. The Drunken Salmon (salmon cured in gin and yoghurt), and the Asian slow-roasted Pork Belly. Both were excellent. Flavourful and succulent.&lt;/p&gt;
      &lt;p&gt;For my main, I chose the Asian Ribs. I realised it was another Asian-flavoured dish &amp;#x2014; I know, "Asia" isn't a country. I am usually not keen on ribs, but these were boneless, and that made all the difference. That, and the lovely, and slightly spicy sauce that was slathered over the ribs with a few tiny bits of red chilli.&lt;/p&gt;
      &lt;p&gt;My partner's choice was the butter steak, medium rare. That came with carrots and a delicious mushroom foam. The sauce was made with Pedro Xim&amp;#xE9;nez sherry, and had a nice shine to it. With our mains, we each enjoyed a glass of Merlot. The only (minor) let down were their chips that were served with our mains. They were slightly chewy.&lt;/p&gt;
      &lt;p&gt;It was a very enjoyable meal in a charming environment, and with very reasonable prices. A great birthday meal!&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/noon.html</guid>
      <pubDate>Fri, 22 Dec 2023 18:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>The Ridgeway</title>
      <link>https://derickrethans.nl/the-ridgeway.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="the_ridgeway"/&gt;The Ridgeway&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, November 21st 2023, 09:48 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I have walked some of the UK's local and national trails in the past, first the London LOOP and Capital Ring, then the Thames Path and North Downs.&lt;/p&gt;
      &lt;p&gt;I had meant to walk the South Downs since 2020, but then the world changed, and I walked the length of the  &lt;a href="https://tube.derickrethans.nl"&gt;tube network&lt;/a&gt; instead.&lt;/p&gt;
      &lt;p&gt;But it is now 2023, and it is time to tick off one more of the national trails. I originally wanted to walk the &lt;a href="https://www.nationaltrail.co.uk/en_GB/trails/south-downs-way/"&gt;South Downs&lt;/a&gt;, following the &lt;a href="https://www.nationaltrail.co.uk/en_GB/trails/north-downs-way/"&gt;North Downs&lt;/a&gt;, and the &lt;a href="https://www.westsussex.gov.uk/leisure-recreation-and-community/walking-horse-riding-and-cycling/downs-link/"&gt;Downs Link&lt;/a&gt;. But it turns out that &lt;a href="https://www.nationaltrail.co.uk/en_GB/trails/the-ridgeway/"&gt;The Ridgeway&lt;/a&gt; is celebrating its fiftieth anniversary, which would be more fitting for this year. The South Downs will be there next year too.&lt;/p&gt;
      &lt;p&gt;Like with the Thames Path between the source and Oxford, public transport between the stages can be complicated. I started planning the first two stages sometime in July and opted to do the first two 32 km sections on a Thursday and Friday in early September, as the temperature would be sensible.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;
        &lt;strong&gt;Day 1: Avebury to Bishopstone&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;I booked my hotel, &lt;a href="https://helenbrowningsorganic.co.uk/royal-oak/"&gt;Helen Browning's The Royal Oak&lt;/a&gt; in Bishopstone, on the Monday before my walk, so I was pretty sure it would not rain much these first two days.&lt;/p&gt;
      &lt;p&gt;On Thursday, September 7th, I took an early train from Paddington to Swindon. Even my advance ticket was expensive, at &amp;#xA3;59. I left plenty of time, about 27 minutes, to catch the hourly bus to Avebury.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Avebury Stones" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0315_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Avebury Stones&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Not unusually when relying on UK railways, this plan failed as soon as I got to Paddington. My train left a little under 20 minutes late, meaning I would have less than 10 minutes to get to the bus station. When I got to Swindon, those 10 minutes had dropped to 4. I had to sprint to the bus station and managed to catch the bus as it was about to leave, already drenched.&lt;/p&gt;
      &lt;p&gt;The bus to Avebury takes about half an hour, and I ended up chatting to a fellow Ridgewalker. He had already done most of it, but not linearly.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Avebury"&gt;Avebury&lt;/a&gt; is a fascinating place. The village is surrounded by a stone circle. Not as impressive as Stonehenge, but certainly more extensive.&lt;/p&gt;
      &lt;p&gt;I spent some time exploring before setting off to the start of the Ridgeway on &lt;a href="https://en.wikipedia.org/wiki/Overton_Hill"&gt;Overton Hill&lt;/a&gt;. On the way there I walked through the majestic &lt;a href="https://www.english-heritage.org.uk/visit/places/west-kennet-avenue/"&gt;West Kennet Avenue&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/The_Sanctuary"&gt;The Sanctuary&lt;/a&gt;, looking out over the valley to Avebury.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="West Kennet Avenue" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0318_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;West Kennet Avenue&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The walk started for real on Overton Hill. I was already sweaty because I had to walk up this hill. Instead of a lovely cool autumn morning, it was already pushing 30&amp;#xB0;C with high humidity.&lt;/p&gt;
      &lt;p&gt;From the start, the route gently ascends on easy-going paths. You can cycle or ride a horse for most of the Ridgeway, and the trails are usually reasonably wide.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 60%"&gt;
        &lt;img title="Two Horses" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0364_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Two Horses&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;At the top of the first gentle incline, I ended up at Hackpen Hill. This hill has a white horse in chalk on the side. I wanted to visit a few archaeological sites while walking the route. This was an early opportunity.&lt;/p&gt;
      &lt;p&gt;The path towards the chalk white horse was blocked by an actual white horse. Therefore, I set off along the S-bend road instead. A large concrete mixer approached me, belching out black smoke, or so I thought. I took a deep breath and closed my nose until I realised it wasn't smoke but a nice, cooling, fine water spray!&lt;/p&gt;
      &lt;p&gt;Once I reached the bottom, I walked along the footpath back up the hill, only to find that I couldn't see much of the chalk horse. It's a bummer for such a steep climb. And then, the horses blocked access to the gate to get out of the field again! This time, I gently squeezed past them.&lt;/p&gt;
      &lt;p&gt;Once recovered from the steep way up the hill, I continued and soon came upon &lt;a href="https://en.wikipedia.org/wiki/Barbury_Castle"&gt;Barbury Castle&lt;/a&gt;, The route went straight through the middle of it, but as there was little to see beyond the round embankment, I continued without stopping.&lt;/p&gt;
      &lt;p&gt;The view opened up after going through a wood, and a path was visible for a long way down into a valley. I chatted with a few fellow Ridgeway walkers, and they were surprised that I was going all the way to Bishopstone. They were doing the more traditional set of sections and finishing not far away in Ogbourne St George.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Rolling Hills" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0369_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Rolling Hills&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The path was fairly undulating for a while, and once I got down to the bottom, it was blocked by a herd of cows. I had to go slightly up the hill to get around them. Luckily, they did not seem to even acknowledge my presence.&lt;/p&gt;
      &lt;p&gt;As it was a hot day, I was quite pleased to find a stretch covered by trees on my way south of Ogbourne St George to cross the A346. This road lies in a valley, meaning you need to descend into it and climb back up to the Ridgeway on the other side. However, you get a good view of the village.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Tractor at Work" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0376_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Tractor at Work&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The route also turned north, alleviating the strong sunshine on the right side of my face. Near Lower Upham, I rested on a bench under the trees. My energy levels were really low, and I had little water left. In hindsight, I did not have enough for a long walk in this warm weather. Even my energy bars had all melted together and were hard to eat. But as I had no other option, I set off after about half an hour.&lt;/p&gt;
      &lt;p&gt;The views from this section were excellent, though, with rolling hills, villages, and cities in the background. A fair number of tractors were also out on the fields.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Tractor at Work" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0380_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Tractor at Work&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After bypassing another hill fort at &lt;a href="https://en.wikipedia.org/wiki/Liddington_Castle"&gt;Liddington Hill&lt;/a&gt;, the route brought me out out on a fast-moving road with the same name.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="&amp;quot;Ridgeway National Trail&amp;quot; Along the Road" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0382_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;"Ridgeway National Trail" Along the Road&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Here, a road section of the Ridgeway starts. It is along a road with no pavement and only a tiny verge. This was rather unpleasant, and I wonder why not some arrangements can be made for walkers. The sign with "Ridgeway National Trail" alone wasn't cutting it.&lt;/p&gt;
      &lt;p&gt;I could see Charlbury Hill from here, though, which I knew was near the finish of today's walk. Unfortunately, it meant I had another 60 metres of climbing to do, luckily no longer along a road with traffic.&lt;/p&gt;
      &lt;p&gt;It was now getting slightly darker, and after a short while, I finally could head down to Bishopstone for a shower, meal, and sleep. That last stretch down from the Ridgeway was enjoyable and almost like going through a canyon.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Towards Bishopstone" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0387_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Towards Bishopstone&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I arrived at &lt;a href="https://helenbrowningsorganic.co.uk/royal-oak/"&gt;Helen Browning's Royal Oak&lt;/a&gt; a little after five. The small complex includes a pub, a farm shop, and a hotel.&lt;/p&gt;
      &lt;p&gt;I entered through the first, picked up my keys in the second, and then headed to my room. The first thing I did when getting to my room was to drink at least 2 litres of water before enjoying a lovely cold shower.&lt;/p&gt;
      &lt;p&gt;I relaxed a bit and then headed to the pub for a well-deserved lager, which I enjoyed in the lovely beer garden. I had a table for dinner booked for seven but ended up ordering a little earlier because I was ravenous. Unfortunately, my order had gone slightly wrong (they lost it), and dinner only showed up around eight. Their venison burger was amazing, though, and so was the complimentary salad I received because of the food order mess up.&lt;/p&gt;
      &lt;p&gt;After dinner, I went to the hotel's communal area, where I relaxed a little and read. Not soon after, I went to have a nice long sleep in a bed.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;
        &lt;strong&gt;Day 2: Bishopstone to Chilton&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;After a restless but relatively long sleep, I rose early to enjoy breakfast at the hotel &amp;#x2014; their home-made apple juice was delicious. I wanted to beat the warmest part of the day, and therefore, I wanted to leave as early as possible.&lt;/p&gt;
      &lt;p&gt;I left just before nine and explored the village a bit &amp;#x2014; mostly because I got lost! After finding the little path between two cottages, I headed to the Ridgeway. This second day's walk would be slightly less hilly, but the forecast still called for temperatures around 30&amp;#xB0;C and a few more high clouds. I had created a "Plan B" in case it would be too rough again: I would stop the walk earlier at Wantage.&lt;/p&gt;
      &lt;p&gt;Although today's whole route was a little hilly, the first thing I had to do in the morning was to get back onto the Ridgeway, which involved a fairly long climb. Again, I was sweating before I even started the walk.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Broad Path" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0394_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Broad Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;But the Sun wasn't beating this hard today, and the walk started by going over the nice wide paths. There was also some more shade from trees and brambles. I enjoyed quite a few juicy blackberries in the places where they looked good enough.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 40%"&gt;
        &lt;img title="Rose &amp;amp; Crown" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0400_cropped_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Rose &amp;amp; Crown&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After about 2 km, I came upon a farm, and the farmer had kindly provided a water tap. This meant I could empty one of my water bottles and instantly fill it. This was welcome and alleviated my concern that water would be a problem again today.&lt;/p&gt;
      &lt;p&gt;Not far after that, I spotted a sign to the Rose &amp;amp; Crown: "Down the Hill". Having recently climbed up to the Ridgeway and been going for around an hour, I decided that this was not a good offer and continued along the top.&lt;/p&gt;
      &lt;p&gt;A little further along, I stumbled upon &lt;a href="https://www.english-heritage.org.uk/visit/places/waylands-smithy/"&gt;Wayland's Smithy long barrow&lt;/a&gt;, used for burials over 5,500 years ago. I looked around before continuing my walk. I was glad for more tree cover and those light, hazy clouds that tempered the Sun's impact.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Wayland's Smithy" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0408_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Wayland's Smithy&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The next point of interest was the ancient hill fort at White Horse Hill. It has another chalk white horse on the site, but this time, I decided not to walk down the hill to see if I could see it. Aerial imagery will have to do.&lt;/p&gt;
      &lt;p&gt;I did walk around the hill fort in the same location for a while, and there were some great views of the surrounding countryside.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Path With a View" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0416_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Path With a View&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Near the top of the next hill, I spotted a bunch of butterflies. They weren't straightforward to photograph as they kept flying away!&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 40%"&gt;
        &lt;img title="Red Admiral" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0427_cropped_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Red Admiral&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I was lucky with this lovely Red Admiral, which sat still long enough.&lt;/p&gt;
      &lt;p&gt;Amazingly, there was another water point not far away. I repeated my routine of checking whether it was working, drinking all the water I was carrying, and refilling my bottles. But this time, I had around a third of this day's 20 miles left. On I went.&lt;/p&gt;
      &lt;p&gt;The walk was going much easier than the day before, helped by the clouds, and having enough water. Although the sky was a little hazy, the views were still great. I had a lovely time walking and decided not to cut the walk short at Wantage.&lt;/p&gt;
      &lt;div id="ridgeway2" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0438_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;View from the Ridgeway&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0440_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;The Path Ahead&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0442_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Wittenham Clumps&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0444_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Hill Side Farm&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0457_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Rolling Hills&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09c-the-ridgeway-1/d52_0459_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Didcot Power Station&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('ridgeway2', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('ridgeway2', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;From the Ridgeway, I could see the Wittenham Clumps, Didcot Power Station, and, nearing the end, the &lt;a href="https://www.harwellcampus.com/"&gt;Harwell Campus&lt;/a&gt; with the &lt;a href="https://www.diamond.ac.uk/Home.html;jsessionid=B648D01F4F5DD095272EE118D524726A"&gt;Diamond Light Source&lt;/a&gt;, the UK's synchrotron.&lt;/p&gt;
      &lt;p&gt;After crossing underneath the A34 through a dodgy tunnel, I had finished my stretch along the Ridgeway, and it was time to head down the hills towards Chilton, where I was hoping to catch the once-an-hour bus to Didcot.&lt;/p&gt;
      &lt;p&gt;Of course, I ended up missing it by a few minutes. Instead of standing around, I walked to the next possible bus stop, which was about a 15-minute walk away. A bus comes every half hour- but not at this time of day, apparently.&lt;/p&gt;
      &lt;p&gt;So I set off once more to a stop, which I knew had a service every 15 minutes. I knew it was the location of the Diamond Light Source, but I had yet to notice that this was right in the middle of the UK's atomic energy and space flight campus.&lt;/p&gt;
      &lt;p&gt;The bus to Didcot was uneventful, and once I got to the train station, I bought a big bottle of water. I was still thirsty, even with my extra supply of on-route water. By this time, the light clouds had disappeared.&lt;/p&gt;
      &lt;p&gt;I was lucky with the trains, as one to Paddington arrived just as I got to the platform.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;
        &lt;strong&gt;Day 3: Chilton to Wallingford&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;A week later, I was again on my way to Chilton by train and bus to walk the third section to Wallingford. The temperature was in the mid-20s, and it was a bright day.&lt;/p&gt;
      &lt;p&gt;The bus route also gave me a tour of the whole Harwell Campus, with all the space and atomic energy research places. And big "Keep Out" signs.&lt;/p&gt;
      &lt;p&gt;Once I got to Chilton, it was time to start walking. As I had come down from the Ridgeway last time, I had to climb back up again.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Farm in the Valley" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0482_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Farm in the Valley&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The first 2&amp;#xBD; km was primarily flat, over nice wide paths. On each side were galloping courses for horses, with a few riders out on this lovely morning. Then, the route turned due east towards Goring. This section was quite up-and-downy, with beautiful views peeking through the hedges. A few red kites were out and about.&lt;/p&gt;
      &lt;p&gt;I enjoyed the views, including a field with many poppies.&lt;/p&gt;
      &lt;div id="ridgeway3" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0491_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Poppies&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0494_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Green Valley&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0496_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Crossing Paths&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0498_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Tractor Eggs&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 4&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('ridgeway3', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('ridgeway3', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;After a section through a lane of very green trees, I ended up on a road with a mansion, a golf course, and finally, the outskirts of Streatley. The closer to the village, the more traffic there was. At some point, a very narrow pavement appeared before getting to the High Street with a lovely row of brick buildings.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Brick Village Houses" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0513_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Brick Village Houses&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After crossing Goring Bridge, the route heads north along the Thames. I previously walked the &lt;a href="https://www.nationaltrail.co.uk/en_GB/trails/thames-path/"&gt;Thames Path&lt;/a&gt;, but its route is on the other side of the river. I understand why, as you can get closer and see the river.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 50%"&gt;
        &lt;img title="Butterfly on the Wall" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0518_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Butterfly on the Wall&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After a wall with butterflies, where I spotted this lovely Red Admiral, the walk was mainly behind riverside properties. From South Stoke, the route finally gets close to the river for a little while. This section of the walk is flat because it is next to the Thames. The paths are often well-trodden grass, making for a relatively easy hike.&lt;/p&gt;
      &lt;p&gt;The route into North Stoke was mainly on the east side of the treeline bordering the Thames, which provided lovely open views of the surrounding hills.&lt;/p&gt;
      &lt;p&gt;At North Stoke, the route passed through a churchyard along a lovely row of bright pink-flowered houses.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Row of Houses" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09e-the-ridgeway-2/d52_0537_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Row of Houses&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;North of the village, the Ridgeway crosses a golf course. Luckily, you can't see much of it as the route is lined with trees and bushes. Just south of the A4130, the walk's route goes east, but for me, this was the end of this section.&lt;/p&gt;
      &lt;p&gt;I walked into Wallingford along the Thames Path and was again lucky to catch the bus into Reading, which was ready to go.&lt;/p&gt;
      &lt;p&gt;This was really a section of two halves. The first half is hilly, with great views and the occasional horse. The second half is along the Thames, which, sadly, I rarely saw. It being flat made for a nice change, though.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;
        &lt;strong&gt;Day 4: Wallingford to Lewknor&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;I took the "River Rapids" bus to Wallingford from Reading. At &amp;#xA3;2, it is still a bargain. I hope this scheme will be extended and/or made permanent.&lt;/p&gt;
      &lt;p&gt;I decided to walk on the other side of the Thames &amp;#x2014; the side not on the Thames Path &amp;#x2014; to get back to the Ridgeway for some variety. The paths were grassy and, if not for a herd of cows, also pretty quick.&lt;/p&gt;
      &lt;p&gt;After crossing underneath the A4130, I got stuck behind a group of teenagers. Looking at their gear and maps, they were probably on a &lt;a href="https://www.dofe.org/"&gt;Duke of Edinburgh's Award&lt;/a&gt; walk. I got confused and walked in the wrong direction to get ahead, meaning I now had to follow them for half a mile on a narrow path through the woods.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Winding Path" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09h-the-ridgeway-3/d52_0613_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Winding Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I managed to get ahead of them again after a moderately dangerous crossing of the B4009, where the path continued going through the woods on a steady but slight incline.&lt;/p&gt;
      &lt;p&gt;The path was windy and narrow, and the Sun was straight ahead. It was a lovely morning, and I was enjoying myself immensely.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 45%"&gt;
        &lt;img title="Grim's Ditch" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09h-the-ridgeway-3/d52_0622_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Grim's Ditch&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The path through the woods lasted about five kilometres, crossing a few farm roads. Eventually, the route followed South Oxfordshire's &lt;a href="https://en.wikipedia.org/wiki/Grim%27s_Ditch#South_Oxfordshire"&gt;Grim's Ditch&lt;/a&gt;, right next to the path to the north.&lt;/p&gt;
      &lt;p&gt;A little before Nuffield, at Grimsdyke Cottage, I found another water point. The day was not nearly as hot as the first two days of my walk, but the water was undoubtedly still very welcome.&lt;/p&gt;
      &lt;p&gt;After another 5 minutes, the path reached one of its higher points and turned northward. There were good views over the Thames Valley, although part of it was occupied by the Huntercombe Golf Club at Nuffield. The path was strictly set out with a series of "numbered white painted bollards", but the promised numbers were missing.&lt;/p&gt;
      &lt;p&gt;At the top, I had to cross the nearly empty A road towards Nettlebed, home of the famous &lt;a href="https://www.nettlebedcreamery.com/the-cheese-shed"&gt;Cheese Shed&lt;/a&gt;. It was tempting but would have been an hour's detour. And to get to cheese, that is even too far for me.&lt;/p&gt;
      &lt;p&gt;The route continued down a path through a freshly harvested field before becoming steep on the way to Ewelme Park. The view towards where I came from was fantastic.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Fields" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09h-the-ridgeway-3/d52_0650_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Fields&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The route became slightly undulating here, with woodland sections, before coming up at the church at Swyncombe, where a bunch of crows were flocking about on Rectory Hill. After having reached the top, the Ridgeway continued along a field of sheep at the bottom near a stream. There was also a good view of the hill that I had to walk up next to the side of &lt;a href="https://en.wikipedia.org/wiki/Swyncombe_Downs"&gt;Swyncombe Downs&lt;/a&gt;. The woods were fresh and green, protecting me from the bright Sun for a while.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 60%"&gt;
        &lt;img title="North Farm" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09h-the-ridgeway-3/d52_0683_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;North Farm&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After coming around the bottom of a field, a manor house, North Farm, on the next hill came into view through the trees. The path was lined with bushes with many red berries.&lt;/p&gt;
      &lt;p&gt;Near the farm, the route changes direction again and heads straight for Lewknor and the village of Watlington in the valley below. The path widens, similar to the section between Chilton and Goring. It is partly exposed but also passes through the woods.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 45%"&gt;
        &lt;img title="Walkers on the Path" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09h-the-ridgeway-3/d52_0706_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Walkers on the Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After about a mile, I encountered a few walkers with race numbers. The stream of them became denser and denser, and my lovely, relaxed walk became more arduous. I had to step out of the way and dart from left to right on the path. At first, I greeted them, which was alright.&lt;/p&gt;
      &lt;p&gt;I became quickly fed up, though, as the people coming towards me only had to say hello once, or step out of the way once, to be able to pass. I had to do that several hundred times. It was a real chore, making the rest of my walk significantly less fun &amp;#x2014; I get out of the city to not encounter crowds!&lt;/p&gt;
      &lt;p&gt;After a while, I could see my finish point for the day becoming larger and larger, with the occasional sound of the M40. There were many sheep in front of the &lt;a href="https://www.chilternsaonb.org/map_marker/aston-rowant-national-nature-reserve/"&gt;Aston Rowant Nature Reserve&lt;/a&gt;'s hill.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Sheep at the Foot of the Hill" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-09h-the-ridgeway-3/d52_0708_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Sheep at the Foot of the Hill&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I crossed under the M40, and shortly after that, I left the Ridgeway and headed to a new form of transport, the &lt;a href="https://www.oxfordtube.com/"&gt;Oxford Tube&lt;/a&gt;,  a coach service between Oxford and London. It had a convenient bus stop just off the M40 called the Lewknor Turn. Once I got to the stop, the coach arrived nearly instantaneously. It goes every 15-20 minutes, so it would not have been a problem if I missed it. For &amp;#xA3;20, you get a three-month open return. The coach was comfortable and speedy until the outskirts of London near Hillingdon. There was a lot of traffic, so I will try to catch it further from Victoria Coach station for the next and penultimate section.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;
        &lt;strong&gt;Day 5: Lewknor to Wendover&lt;/strong&gt;
      &lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Up Through The Tunnel of Leaves" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0864_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Up Through The Tunnel of Leaves&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Today's walk started with a bus ride to my coach stop. I had booked a return on the Oxford Tube, and as I was unwilling to sit in London traffic, I headed to Notting Hill Gate instead of Victoria to alleviate some of this.&lt;/p&gt;
      &lt;p&gt;The coach ride was uneventful, although it was a bit busier, even this early morning. With the days getting dark earlier, I thought setting off early was wise.&lt;/p&gt;
      &lt;p&gt;After arriving at Lewknor, I had to get up to Ridgeway level, which involved a steep climb along a narrow road lined with colourful trees, creating a tunnel effect. Once at the top, the low Sun blinded me as it reflected on the slightly wet road.&lt;/p&gt;
      &lt;p&gt;Once on the Ridgeway, it became clear that autumn had properly started. Large amounts of leaves were on the path, and the trees had burst into every colour.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="The Start of Autumn" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0868_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Start of Autumn&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;This section of the Ridgeway was very much on a ridge, with occasional expansive views to both the left and right for a while. The path was easy-going.&lt;/p&gt;
      &lt;p&gt;Like the previous section, another race was going on on the route. This time, it was about half a hundred bicycles. It was a lot less annoying than five hundred walkers.&lt;/p&gt;
      &lt;p&gt;Just after Chinnor, my walk led me through the lovely Bledlow Great Wood before going southeast for a while with beautiful "scenes from the Windows Start-up Screen".&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="The Start of Windows" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0891_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Start of Windows&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From here, my walk slowly trended downwards while continuing to produce great views of cows in distant but very green fields.&lt;/p&gt;
      &lt;p&gt;Soon, a steep climb up a hill produced sweat, and stunning 360&amp;#xB0; panoramic views at Lodge Hill.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 30%"&gt;
        &lt;img title="Cows Blocking the Path" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0903_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Cows Blocking the Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On the other side of the summit, a herd of cows blocked my path. Instead of trying to squeeze past them, I decided to have a little detour to avoid them, as I did not fancy my chances with this lot.&lt;/p&gt;
      &lt;p&gt;Then, finally, the route left the high grounds of the Ridgeway and let me down the slopes towards Princess Risborough along some field boundaries and through a tree tunnel, keeping me away from yet another golf course.&lt;/p&gt;
      &lt;p&gt;After a level crossing, I had to scale another hill to cross the other single track of the &lt;a href="https://en.wikipedia.org/wiki/Chiltern_Main_Line"&gt;Chiltern Main Line&lt;/a&gt;. A single poppy in a field led me along a quiet road to the much busier A4010, which I followed towards the town.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Autumn Trees in a Plowed Field" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0922_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Autumn Trees in a Plowed Field&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Although the road could have been more pleasant to walk along, the views of colourful trees and freshly ploughed fields to the right of me were more enticing.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 33%"&gt;
        &lt;img title="Buzzard" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0927_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Buzzard&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Thankfully, the section along the road was short, and I soon found myself on a quiet gravel path. Annoyingly, it was on an incline, but that did not stop me from enjoying myself. Like me, a buzzard was following the edge of a field towards the foot of Brush Hill.&lt;/p&gt;
      &lt;p&gt;The hill is steep, but steps cover nearly half of the incline. I am usually not very keen on these, but here, it makes sense. The view from the top was worth the effort.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="View From Brush Hill, with Bonus Trigpoint" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0946_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;View From Brush Hill, with Bonus Trigpoint&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I rested here for a while, enjoying snacks and water, and watched red kites swooping and soaring through the sky.&lt;/p&gt;
      &lt;p&gt;After lunch, I continued walking. The route went down and then up again to another view over the valley at Whiteleaf Hill. While descending through the lovely "Hangings", the Sun lit up the first hints of autumn colours. Unlike earlier sections, the trees had yet to start losing their leaves here.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 40%"&gt;
        &lt;img title="Mushroom Village" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0983_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Mushroom Village&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From here on, the route became familiar, as I had walked it a while ago on one of my  &lt;a href="https://beta.slowways.org/"&gt;SlowWays&lt;/a&gt; adventures, but in the opposite direction. First came the open hillsides of &lt;a href="https://www.bbowt.org.uk/nature-reserves/grangelands-and-rifle-range"&gt;Grangelands and The Rifle Range&lt;/a&gt;, a peculiar name.&lt;/p&gt;
      &lt;p&gt;At the top of yet another hill, I spotted a bunch of mushrooms. I expected to see many more on my autumnal walk, but these were the only bunch.&lt;/p&gt;
      &lt;p&gt;After crossing a field, the Ridgeway skirts around outside the &lt;a href="https://en.wikipedia.org/wiki/Chequers"&gt;Chequers Estate&lt;/a&gt;, the Prime Minister's country party place. Menacing signs are warning you to keep out. At the moment, there isn't a fence on the section down the hill towards their driveway, which you'll end up crossing.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Chequers" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0987_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Chequers&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="img-container-right" style="width: 30%"&gt;
        &lt;img title="Tree Branches" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_0998_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Tree Branches&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;When leaving the estate, I headed the wrong way first and walked past a farm shop. I was tempted to get lunch there, but the queue was too long. I decided to continue walking instead. A dog refused to move, as it had not been bought a sausage!&lt;/p&gt;
      &lt;p&gt;The short climb into Linton's Wood revealed a path through the leaves cut out by the rain, which reminded me of walking around in the forest where I grew up. I enjoyed some of the more exposed tree trunks, which had few leaves and were still remarkably green.&lt;/p&gt;
      &lt;p&gt;After crossing and following a quiet road, I ended up on the slopes of &lt;a href="https://en.wikipedia.org/wiki/Coombe_Hill,_Buckinghamshire"&gt;Coombe Hill&lt;/a&gt;. The clouds were getting sparser, which created interesting patterns on the fields in the valley below.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Cloud Patterns" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_1011_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Cloud Patterns&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A tall pillar memorializing the &lt;a href="https://en.wikipedia.org/wiki/Second_Boer_War"&gt;Second Boer War&lt;/a&gt; sits at the summit of Coombe Hill. I spent some time with my longish lens taking pictures of a wind turbine and a fire on a hill across the valley.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 45%"&gt;
        &lt;img title="HS2 Building Works" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_1017_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;HS2 Building Works&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Towards Wendover, you can clearly see the extensive works that are part of the building efforts of HS2, the new high-speed railway that now unfortunately does not go to more useful places.&lt;/p&gt;
      &lt;p&gt;After taking a little break and admiring the views, I proceeded towards the finish, down the hill through the Bacombe Hill Nature Reserve.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 45%"&gt;
        &lt;img title="Kite Fight" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_1108_web_cropped.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Kite Fight&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;It took me some time as there were so many red kites about. Flying, and hunting, and attacking each other. Most of them were just too far away for good photos. Their aerial acrobatics were a sight to behold.&lt;/p&gt;
      &lt;p&gt;After a while, I finished the walk and headed to Wendover station. As I descended, I enjoyed the last views of the valley.&lt;/p&gt;
      &lt;p&gt;Just before the station, the footpath was narrow due to HS2 building works. A footbridge across the tracks straight into the station's west side was blocked, so I crossed the tracks and used the main entrance.&lt;/p&gt;
      &lt;p&gt;I took the train back to London from Wendover, concluding the fourth and penultimate leg of the Ridgeway.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;
        &lt;strong&gt;Day 6: Wendover to Ivinghoe Beacon&lt;/strong&gt;
      &lt;/p&gt;
      &lt;div class="img-container-left" style="width: 45%"&gt;
        &lt;img title="Wendover Station" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10c-the-ridgeway-4/d52_1118_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Wendover Station&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Trains to Wendover go from London Marylebone only once an hour on Saturdays. I went for the 08:27, as I thought the one an hour later would make it trickier to finish the walk before it got (too) dark. It is a good thing that I did, as the 09:27 ended up being cancelled due to a lack of staff. Which isn't really acceptable for a once-an-hour service.&lt;/p&gt;
      &lt;p&gt;It was not the nicest of days, but I was keen on finishing the Ridgeway before daylight saving time kicked in, and there would be way less time in the afternoon for walking. I dislike the early darkness.&lt;/p&gt;
      &lt;p&gt;I arrived at Wendover, therefore, reasonably early. It was early enough to see the morning fog lifting out of the forests that surround the city.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Wendover Fog" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1130_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Wendover Fog&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The walk through town was short, and I soon found myself walking around a lake and a church, climbing up the hill along a wooded lane. The trees on the hill to the north all had splendid colours. Autumn is the best season for this, although the clouds hadn't yet risen.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 45%"&gt;
        &lt;img title="Early Morning Clouds" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1144_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Early Morning Clouds&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Soon after that, I found myself climbing through a forest. The leaves had yet to quite colour as much, and it had an eerie feel. Especially with the ground slightly muddy and springy.&lt;/p&gt;
      &lt;p&gt;The path widened a little after a while before ending up with a lovely view and some steps down into a narrow and muddy gully, which I followed to the road and crossed into some fields.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 45%"&gt;
        &lt;img title="Munching Cows" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1163_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Munching Cows&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Unfortunately, halfway across these fields, on the other side of a gate and fence, a herd of cows was on its way to block my path. As I mentioned, I am not a fan of national paths going through fields with cows. Therefore, I decided to backtrack and walk around the farm.&lt;/p&gt;
      &lt;p&gt;My diversion was pleasant, even though I had to wade through mud. Although fully overcast, the view into the valley with colourful trees was lovely.&lt;/p&gt;
      &lt;p&gt;Once I had completed my detour, I ended up on the official route and into Northhill Wood. The trees hadn't entirely changed their colours here yet, so it was fresh and green. The wide path was easy, too.&lt;/p&gt;
      &lt;p&gt;After a short section along quiet lanes, I ended up in Bishop's Wood, at the top end of Tring Park. It is a lovely wide boulevard, and at this time of the day, it was full of people walking their dogs. The Sun was playing with the colours of the trees.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Tring Park Boulevard" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1191_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Tring Park Boulevard&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;There were some excellent views over the town, but soon, I left the park and moved onwards to cross the A41. The path was easy-going again, and a lovely herd of sheep was grazing to my right.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 45%"&gt;
        &lt;img title="View From The Bridge" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1214_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;View From The Bridge&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I am usually not keen on having my walk interrupted by a busy road, but the view from the high pedestrian bridge across the A41 was pretty good. Colourful trees flanked each side, with the finish of the Ridgeway in the distance.&lt;/p&gt;
      &lt;p&gt;However, before I would get to my final set of hills, I wandered along another straight path with a slight incline to cross the Grand Union Canal.&lt;/p&gt;
      &lt;p&gt;The section just beyond Tring's railway station was along a road with a very narrow pavement. Fortunately, the section was short, and I went uphill again through the woods &amp;#x2014; first on a slight incline, then up a long stretch of uneven steps.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 45%"&gt;
        &lt;img title="Cloudy View" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1232_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Cloudy View&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once at the top, the route continues north along the side of the ridge, with sporadic open views to the west. By this time, it had become slightly brighter, with few clouds. However, it was getting a little windier.&lt;/p&gt;
      &lt;p&gt;Some of the paths were a little narrow here and sometimes a little muddy. The views were improving, especially with the unevenly lit lands below.&lt;/p&gt;
      &lt;p&gt;A single tree marked the first peak of this final section at Pitstone Hill. A few walkers were out, as it was a nice day. From here, I could also see my finish point, Ivinghoe Beacon.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Ivinghoe Beacon" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1234_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Ivinghoe Beacon&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;But I was not quite yet there. From Pitstone Hill, you dip through a little depression in the hillside before getting up to Paul's Knob. I did not take the opportunity to go up it, as it was not the Ridgeway's route. I did, however, on my return to Tring. As if I needed to do more hills...&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 50%"&gt;
        &lt;img title="Rainy Cloud" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1243_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Rainy Cloud&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this final section, it was getting a lot busier. A lot more so than at the start of the route at Overton Hill. I understand why, as the landscape is much nicer here, especially going up Steps Hill (without any steps). In the distance, I could now see a rain cloud coming, creating the "fingers of god" effect.&lt;/p&gt;
      &lt;p&gt;After coming down from Steps Hill a bit, there was one more push towards the finish. I didn't take the broader path with many people; instead, I followed the Ridgeway along its mapped route. I did not quite run, but I certainly put in some extra effort to race to the top and finish my adventure at the summit of &lt;a href="https://en.wikipedia.org/wiki/Ivinghoe_Beacon"&gt;Ivinghoe Beacon&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Ivinghoe Breacon Trigpoint" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1251_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Ivinghoe Breacon Trigpoint&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I spent a little time lounging around and enjoying a later lunch to relax and wait until people stopped blocking the things I wanted to take photos of.&lt;/p&gt;
      &lt;p&gt;There is a fair expanse of walking paths here, which makes for a lovely day out. However, I still had to get home, and after about half an hour, I set off. The rain clouds were now certainly nearer, too.&lt;/p&gt;
      &lt;p&gt;On my way back, I decided to get up all the little hills I had bypassed &amp;#x2014; I was here after all. After coming down from Paul's Knob, it started to rain a little. I thought the weather for my whole walk was pretty &amp;#x2014; albeit a little hot for the first two days.&lt;/p&gt;
      &lt;p&gt;Red kites were hunting again on the hillsides. I like watching these birds soar and occasionally dive to catch prey.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 60%"&gt;
        &lt;img title="Tring's Train Station" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-10e-the-ridgeway-5/d52_1295_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Tring's Train Station&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;When I got to the station at Tring, I found that the ticket machine at the regular entrance was stuck in a mode that didn't accept key presses.&lt;/p&gt;
      &lt;p&gt;I was a little lost until I realised another ticket machine was at the parking lot side. Luckily, that one worked.&lt;/p&gt;
      &lt;p&gt;I had to wait a little for my train back to London. I used that time to get the mud out from under my shoes and reflect on the different sections of the Ridgeway &amp;#x2014; From the "ridge" walking in 30&amp;#xB0;C+ heat in the first two days, walking out of the hills, and along the river Thames on the third outing, the battle with 500 walkers going to opposite direction on my walk to Lewknor, my first encounter with autumn's colours while walking around the Chequers Estate, and finally this last section to the finish at Ivinghoe Beacon.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;You can find more photos on in Flickr album &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72177720312737004"&gt;"The Ridgeway"&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/the-ridgeway.html</guid>
      <pubDate>Tue, 21 Nov 2023 09:48:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: October 2023</title>
      <link>https://derickrethans.nl/xdebug-update-october-2023.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_october_2023"/&gt;Xdebug Update: October 2023&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, November 9th 2023, 15:00 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 35% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 32 hours on Xdebug, with 25 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="towards_xdebug_3_3"/&gt;Towards Xdebug 3.3&lt;/h2&gt;
        &lt;p&gt;In &lt;a href="https://derickrethans.nl/xdebug-update-september-2023.html#towards_xdebug_3_3"&gt;last month's update&lt;/a&gt; I explained that I was investigating whether Xdebug can make use of PHP's Observer API. It turns out that it can be used to intercept function calls, but only &lt;code&gt;include&lt;/code&gt; or &lt;code&gt;require&lt;/code&gt; calls if the included files contain code, and not just class definitions. As Xdebug treats &lt;code&gt;include&lt;/code&gt; and friends as actual function calls, I can unfortunately not solely rely on the Observer API.&lt;/p&gt;
        &lt;p&gt;In the wake of checking out the Observer API, I also thought I should have a look at some performance improvements. For example, I noticed that Xdebug would always collect local variables with each function call. This is only really needed when showing local variables, in stack traces, or through the step debugger.&lt;/p&gt;
        &lt;p&gt;Another optimisation that I worked on was to optimise the way how function breakpoints are checked against. These breakpoints trigger when a function gets called, or returned from. This is not a feature that many people often use, but Xdebug would always do some work to be able to compare the configured breakpoints against a normalised function name reference.&lt;/p&gt;
        &lt;p&gt;These two optimisations together resulted in a 20% reduction in CPU instructions (roughly equivalent to execution time) with the front page of WordPress' demo site.&lt;/p&gt;
        &lt;img src="derickrethans.nl/images/content/debug-optimisation.png"/&gt;
        &lt;p&gt;The third optimisation that I worked is related to file/line breakpoints. Xdebug would evaluate whether an IDE has set a line breakpoint on the current line. For this, it had to loop over all the existing breakpoints and compare them. Each additional breakpoint would be checked after every statement, meaning that the number of breakpoints affected the running time of the script.&lt;/p&gt;
        &lt;p&gt;My optimisation alleviates this by moving the check on whether line breakpoints exist for a function or method to the function call itself. If no breakpoints are set in the whole function, then Xdebug skips the check for line breakpoints after each statement. This shifts the factor of performance loss for having line breakpoints from the &lt;strong&gt;number of statements&lt;/strong&gt; to the &lt;strong&gt;number of function calls&lt;/strong&gt;. This shift results in a roughly 25% performance boost with only four line breakpoints enabled.&lt;/p&gt;
        &lt;img src="derickrethans.nl/images/content/breakpoint-optimisation.png"/&gt;
        &lt;p&gt;After attending IPC and speaking to fellow Xdebug users, a question came up about long running scripts. Right now, Xdebug's step debugger can only be activated when the script starts or by calling &lt;a href="https://xdebug.org/docs/all_functions#xdebug_connect_to_client"&gt;xdebug_connect_to_client()&lt;/a&gt;. Breakpoints can also only be configured when Xdebug is waiting for a command to continue a script (after a step, an existing breakpoint, or at the start of the script). While a script is running, you can not interrupt the execution to break, or add new breakpoints.&lt;/p&gt;
        &lt;p&gt;This let me to experiment with a control socket, currently only available on Linux. Through this socket you can then ask Xdebug for information, or request a breakpoint so that you can then use your IDE to add more breakpoints, or inspect the current state.&lt;/p&gt;
        &lt;p&gt;At the moment, I have implemented the "show me some information" feature, which allows me to show the running PHP scripts, with PID, memory usage (in kb), running time, and Xdebug version. The &lt;code&gt;xdebug&lt;/code&gt; command line tool allows you to control Xdebug through the socket:&lt;/p&gt;
        &lt;img src="derickrethans.nl/images/content/xdebug-ps-small.png"/&gt;
        &lt;p&gt;I have not merged this feature yet, but I hope to do so once I have the step debugger interruption feature as well.&lt;/p&gt;
        &lt;p&gt;Beyond this, I will continue to work on the features and issues on the &lt;a href="https://bugs.xdebug.org/roadmap_page.php?version_id=101"&gt;3.3 roadmap&lt;/a&gt;, without any guarantees these tickets will be implemented.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have not published any new videos in the last month, but I did record one. It is set to premiere on November 7th. To get notified, you can subscribe to my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;, or follow &lt;a href="https://phpc.social/@derickr"&gt;me&lt;/a&gt; or &lt;a href="https://phpc.social/@Xdebug"&gt;Xdebug&lt;/a&gt; on Mastodon.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last month, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-october-2023.html</guid>
      <pubDate>Thu, 09 Nov 2023 15:00:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Flamboyant Flamegraphs</title>
      <link>https://derickrethans.nl/flamboyant-flamegraphs.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="flamboyant_flamegraphs"/&gt;Flamboyant Flamegraphs&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, November 7th 2023, 15:00 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this article, I am showing you how to make a flamegraph, a new feature in Xdebug 3.3.&lt;/p&gt;
      &lt;p&gt;Flamegraphs are an interesting way of showing where an application spends a lot of time.&lt;/p&gt;
      &lt;p&gt;To show you the functionality, I will be using Xdebug's own website, which I run locally at port 9874.&lt;/p&gt;
      &lt;p&gt;First of all, we need to configure Xdebug to make our flamegraphs. We do that in a configuration file. With &lt;code&gt;php --ini&lt;/code&gt; I find out which file to use:&lt;/p&gt;
      &lt;pre&gt;Configuration File (php.ini) Path: /usr/local/php/8.2dev/lib
Loaded Configuration File:         /usr/local/php/8.2dev/lib/php.ini
Scan for additional .ini files in: /usr/local/php/8.2dev/lib/conf.d
Additional .ini files parsed:      /usr/local/php/8.2dev/lib/conf.d/20-mongodb.ini,
/usr/local/php/8.2dev/lib/conf.d/zzz-xdebug.ini

&lt;/pre&gt;
      &lt;p&gt;If you are running Apache or Nginx, I would suggest you use &lt;code&gt;phpinfo()&lt;/code&gt; output in the browser to find the same information instead.&lt;/p&gt;
      &lt;p&gt;I have a specific Xdebug INI file called &lt;code&gt;zzz-xdebug.ini&lt;/code&gt;. Its contents are currently:&lt;/p&gt;
      &lt;pre&gt;zend_extension=xdebug.so
xdebug.mode=develop,debug

&lt;/pre&gt;
      &lt;p&gt;Flamegraphs are part of Xdebug's tracing functionality, which we need to enable by changing the &lt;code&gt;xdebug.mode&lt;/code&gt; line to:&lt;/p&gt;
      &lt;pre&gt;xdebug.mode=develop,debug,trace

&lt;/pre&gt;
      &lt;p&gt;The tracing functionality supports multiple formats. The flamegraph is number three, so we need to set that as well by adding:&lt;/p&gt;
      &lt;pre&gt;xdebug.trace_format=3

&lt;/pre&gt;
      &lt;p&gt;By default, Xdebug Tracer will put files into the &lt;code&gt;/tmp&lt;/code&gt; directory, and use a hash of the current working directory to create a trace file name. We want distinct flamegraphs for each URL, so we need to change that by setting:&lt;/p&gt;
      &lt;pre&gt;xdebug.trace_output_name=xdebug.%R

&lt;/pre&gt;
      &lt;p&gt;We start all files with &lt;code&gt;trace.&lt;/code&gt;, and then we use &lt;code&gt;%R&lt;/code&gt; to configure to use the URI. Xdebug also supports many other &lt;a href="https://xdebug.org/docs/trace#trace_output_name"&gt;formatting specifiers&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;By default, all file names will also be postfixed by &lt;code&gt;.xt.gz&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;After making INI changes, you need to restart the web server.&lt;/p&gt;
      &lt;p&gt;To initiate the tracer, I use an &lt;a href="https://xdebug.org/docs/step_debug#browser-extensions"&gt;Xdebug Helper&lt;/a&gt; browser extension available for Chrome, Firefox, and other browsers.&lt;/p&gt;
      &lt;p&gt;I click on the debug icon and then on trace:&lt;/p&gt;
      &lt;img src="derickrethans.nl/images/content/browser-ext.png"/&gt;
      &lt;p&gt;After requesting the home page, and documentation page, Xdebug's tracer created the following files in the &lt;code&gt;/tmp&lt;/code&gt; directory:&lt;/p&gt;
      &lt;pre&gt;derick@gargleblaster:~$ ls -l /tmp/trace.*
-rw-r--r-- 1 derick derick  123 Sep 26 03:31 /tmp/trace..05d7ef.xt.gz
-rw-r--r-- 1 derick derick 2560 Sep 25 16:55 /tmp/trace._core2_css.xt.gz
-rw-r--r-- 1 derick derick 3550 Sep 25 16:55 /tmp/trace._docs_.xt.gz
-rw-r--r-- 1 derick derick 2419 Sep 25 16:55 /tmp/trace._fonts_IBMPlexSans-RegularItalic-Latin1_woff2.xt.gz
-rw-r--r-- 1 derick derick 2474 Sep 25 16:55 /tmp/trace._images_logos_11com7_svg.xt.gz
-rw-r--r-- 1 derick derick 2507 Sep 25 16:55 /tmp/trace._images_logos_io_svg.xt.gz
-rw-r--r-- 1 derick derick 2530 Sep 25 16:55 /tmp/trace._images_logos_private-packagist_svg.xt.gz
-rw-r--r-- 1 derick derick 2455 Sep 25 16:55 /tmp/trace._images_logos_typo3_svg.xt.gz
-rw-r--r-- 1 derick derick 2523 Sep 25 16:55 /tmp/trace._images_logos_xdebug-cloud_svg.xt.gz
-rw-r--r-- 1 derick derick 6165 Sep 25 16:55 /tmp/trace._.xt.gz

&lt;/pre&gt;
      &lt;p&gt;Because we go through our PHP router process, there are also files for images and fonts.&lt;/p&gt;
      &lt;p&gt;The important ones are:&lt;/p&gt;
      &lt;pre&gt;-rw-r--r-- 1 derick derick 3550 Sep 25 16:55 /tmp/trace._docs_.xt.gz
-rw-r--r-- 1 derick derick 6165 Sep 25 16:55 /tmp/trace._.xt.gz

&lt;/pre&gt;
      &lt;p&gt;The contents of these files look like:&lt;/p&gt;
      &lt;pre&gt;{main};require_once;require_once 3046
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;require 7043
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;spl_autoload_register 9408
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::loadClassLoader;require 3176
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::loadClassLoader 41368
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;dirname 6061
&amp;#x2026;

&lt;/pre&gt;
      &lt;p&gt;In order to create a flame graph, we need to pass this through a Perl script. You can find this script by cloning the flamegraph GIT repository at &lt;a href="https://github.com/brendangregg/FlameGraph"&gt;https://github.com/brendangregg/FlameGraph&lt;/a&gt;&lt;/p&gt;
      &lt;p&gt;Xdebug automatically compresses trace files, which means we need to use &lt;code&gt;zcat&lt;/code&gt; as the &lt;code&gt;flamegraph.pl&lt;/code&gt; script tool does not understand that. The output needs to be redirected to a file. On one line, we enter:&lt;/p&gt;
      &lt;pre&gt;zcat /tmp/trace._docs_.xt.gz
        | ~/dev/brendangreeg-FlameGraph/flamegraph.pl
        &amp;gt; /tmp/flame-docs.svg

&lt;/pre&gt;
      &lt;p&gt;You can now open this SVG file you can then open in a browser.&lt;/p&gt;
      &lt;img src="derickrethans.nl/images/content/flamegraph-docs.png"/&gt;
      &lt;p&gt;The stack shows how deep the code goes, and interestingly, for most of it, you'll see that a lot of time is taken up by Composer, as well as requiring other files.&lt;/p&gt;
      &lt;p&gt;You can dive in by clicking on specific bits. For example, I'll click on my template default controller:&lt;/p&gt;
      &lt;img src="derickrethans.nl/images/content/flamegraph-docs2.png"/&gt;
      &lt;p&gt;You can reset the zoom in the top left.&lt;/p&gt;
      &lt;p&gt;Xdebug's website is not very complex, and for your own code expect to see a lot more complicated flamegraph.&lt;/p&gt;
      &lt;p&gt;Once you're done, please don't forget to turn off the tracer, as it will fill up your hard drive.&lt;/p&gt;
      &lt;p&gt;This new flamegraph trace format is new in Xdebug 3.3, out soon.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/flamboyant-flamegraphs.html</guid>
      <pubDate>Tue, 07 Nov 2023 15:00:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: September 2023</title>
      <link>https://derickrethans.nl/xdebug-update-september-2023.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_september_2023"/&gt;Xdebug Update: September 2023&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, October 10th 2023, 15:00 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 37% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 28 hours on Xdebug, with 25 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="towards_xdebug_3_3"/&gt;Towards Xdebug 3.3&lt;/h2&gt;
        &lt;p&gt;In September I released a first alpha release of Xdebug 3.3 so that people trying out PHP 8.3 Release Candidates have a compatible Xdebug to test with.&lt;/p&gt;
        &lt;p&gt;This quickly followed by a second alpha version due to issues with the PECL website. Instead of mangling UTF-8 characters, it stopped accepting them altogether.&lt;/p&gt;
        &lt;p&gt;I have reintroduced the &lt;code&gt;xdebug.collect_params&lt;/code&gt; setting, which I had removed in Xdebug 3.0. Instead of the setting, Xdebug would just always collect functions' and methods' arguments while tracing. However, some users were suggesting that this created too much information which was not always needed. With the setting restored, you can now again hide these function arguments from trace files.&lt;/p&gt;
        &lt;p&gt;As frameworks are getting more complicated, they are more likely to hit Xdebug's default &lt;code&gt;xdebug.max_nesting_level&lt;/code&gt; limit of &lt;code&gt;256&lt;/code&gt;. In Xdebug 3.3, this will now be &lt;code&gt;512&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;The maximum nesting level setting is now less important that it was all these years ago. The PHP engine now uses stack in a more economic way. This feature unfortunately is negated when extensions override PHP's internal execution method, which is what Xdebug has to do to capture function calls for tracing, profiling, and certain breakpoints.&lt;/p&gt;
        &lt;p&gt;In PHP 8.1 a new Observer API was added, which would allow extensions to observe user-land function calls without having to override the internal execution method. This means that the stack is used more sparingly again. It also would allow for these extensions to work better with opcache enabled.&lt;/p&gt;
        &lt;p&gt;I am currently in the process of investigating whether Xdebug can make use of this Observer API as well, while maintaining all its functionality and without BC breaks. I will keep you updated in the next monthly update.&lt;/p&gt;
        &lt;p&gt;Beyond this, I will continue to work on the features and issues on the &lt;a href="https://bugs.xdebug.org/roadmap_page.php?version_id=101"&gt;3.3 roadmap&lt;/a&gt;, without any guarantees these tickets will be implemented.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one new videos in the last month:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=_3RkGZK-UC8"&gt;Xdebug 3: Using the DBGp Proxy&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Let me know what you'd like to see!&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last month, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-september-2023.html</guid>
      <pubDate>Tue, 10 Oct 2023 14:00:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: August 2023</title>
      <link>https://derickrethans.nl/xdebug-update-august-2023.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_august_2023"/&gt;Xdebug Update: August 2023&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, September 12th 2023, 09:27 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 36% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 27 hours on Xdebug, with 32 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="towards_xdebug_3_3"/&gt;Towards Xdebug 3.3&lt;/h2&gt;
        &lt;p&gt;In August I mostly spent my time on improving Xdebug's xdebug_get_function_stack() function and stack traces with regard to chained exceptions.&lt;/p&gt;
        &lt;p&gt;A &lt;a href="https://bugs.xdebug.org/1562"&gt;feature request&lt;/a&gt; asked whether it would be possible to add the local variables for each stack frame that is returned with the xdebug_get_function_stack() function. Xdebug can already show local variables for the top most frame when it shows stack traces (through the &lt;a href="http://xdebug.org/docs/all_settings#show_local_vars"&gt;xdebug.show_local_vars&lt;/a&gt; setting), but the function's result don't include them.&lt;/p&gt;
        &lt;p&gt;When implementing this feature, I noticed that arguments were being returned as strings, instead of actual values, as part of each stack frame. I created &lt;a href="https://bugs.xdebug.org/2194"&gt;an issue&lt;/a&gt; for that and implemented that as well.&lt;/p&gt;
        &lt;p&gt;When the original requester tried out the new feature, it turned out that he wanted to do this in a user-defined exception handler. However, at that stage, the original stack has been destroyed, and Xdebug no longer could access that information.&lt;/p&gt;
        &lt;p&gt;To work around this, I now cache the stack when an exception gets &lt;strong&gt;thrown&lt;/strong&gt; so that the cached version then can be requested when calling &lt;code&gt;xdebug_get_function_stack()&lt;/code&gt; with the new &lt;code&gt;from_exception&lt;/code&gt; option.&lt;/p&gt;
        &lt;p&gt;That looks like:&lt;/p&gt;
        &lt;pre&gt;&amp;lt;?php
class Handlers
{
    function __construct(private string $title, private float $PIE) {}

    static function exceptionHandler($exception)
    {
        $s = xdebug_get_function_stack( [ 'from_exception' =&amp;gt; $exception ] );
        var_dump($s);
    }
}

class Error_Entry
{
    public function __construct($base, $errno)
    {
        throw new Exception();
    }
}

set_exception_handler(['Handlers', 'exceptionHandler']);
$e = new Error_Entry(1, 2);

?&amp;gt;

&lt;/pre&gt;
        &lt;p&gt;Xdebug's cache is eight items big, which allows for 8 rethrown/chained exception stacks to be remembered.&lt;/p&gt;
        &lt;p&gt;Because of this cache it was now also (finally) possible to resolve &lt;a href="https://bugs.xdebug.org/450"&gt;issue #450&lt;/a&gt; and &lt;a href="https://bugs.xdebug.org/476"&gt;issue #476&lt;/a&gt;. This now means that chained and rethrown exceptions are now displayed when Xdebug shows a stack trace, whether it is on the CLI, or in an HTML context.&lt;/p&gt;
        &lt;p&gt;Over the next few months I will continue to work on the features and issues on the &lt;a href="https://bugs.xdebug.org/roadmap_page.php?version_id=101"&gt;3.3 roadmap&lt;/a&gt;, without any guarantees these tickets will be implemented.&lt;/p&gt;
        &lt;p&gt;If you have comments, suggestions, or if your company wants to help fund features, please &lt;a href="mailto:derick@xdebug.org"&gt;reach out&lt;/a&gt;, or leave comments on the document.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one new videos in the last month:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=u420A89tIMY"&gt;PHP: Debugging FFI and PHP&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Let me know what you'd like to see!&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last few months, two new business supporters signed up:&lt;/p&gt;
        &lt;p&gt;&lt;a href="https://rewe-digital.com"&gt;REWE Digital GmbH&lt;/a&gt; through the Supporter Scheme, and &lt;a href="https://www.clever-age.com/en/"&gt;Clever Age&lt;/a&gt; on Patreon.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-august-2023.html</guid>
      <pubDate>Tue, 12 Sep 2023 08:27:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: July 2023</title>
      <link>https://derickrethans.nl/xdebug-update-july-2023.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_july_2023"/&gt;Xdebug Update: July 2023&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, August 8th 2023, 09:52 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past two months. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 37% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 15 hours on Xdebug, with 25 hours funded. This is much less than I wanted, but instead I have been busy implementing features for PHP.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="towards_xdebug_3_3"/&gt;Towards Xdebug 3.3&lt;/h2&gt;
        &lt;p&gt;I have been keeping up with changes in PHP 8.3's development, and had to adjust some tests as PHP has changed a few things, making my expected results incorrect.&lt;/p&gt;
        &lt;p&gt;I also fixed a number of crash bugs, resulting in the release of Xdebug 3.2.2 early in the month.&lt;/p&gt;
        &lt;p&gt;Now PHP 8.3 has its first beta release, it is soon time to make an alpha release of Xdebug so that it can be installed through PECL, instead of by having to checkout the Git repository by hand.&lt;/p&gt;
        &lt;p&gt;Over the next few months I will continue to work on the features and issues on the &lt;a href="https://bugs.xdebug.org/roadmap_page.php?version_id=101"&gt;3.3 roadmap&lt;/a&gt;, without any guarantees these tickets will be implemented.&lt;/p&gt;
        &lt;p&gt;If you have comments, suggestions, or if your company wants to help fund features, please &lt;a href="mailto:derick@xdebug.org"&gt;reach out&lt;/a&gt;, or leave comments on the document.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published no new videos in the last few months.&lt;/p&gt;
        &lt;p&gt;Let me know what you'd like to see!&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last few months, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;Some of the supporters that I reached out to, have supplied their logos, making the &lt;a href="https://xdebug.org/#business_supporters"&gt;front page less bland&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-july-2023.html</guid>
      <pubDate>Tue, 08 Aug 2023 08:52:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Concealed Code</title>
      <link>https://derickrethans.nl/concealed-code.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="concealed_code"/&gt;Concealed Code&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, August 3rd 2023, 09:55 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Last week, the author of the &lt;a href="https://github.com/xdebug/vscode-php-debug"&gt;PHP Debug Adapter for Visual Studio Code&lt;/a&gt; asked me to look at an &lt;a href="https://github.com/xdebug/vscode-php-debug/issues/919"&gt;issue&lt;/a&gt;. A user noticed that configured breakpoints in the editor would be greyed out for any request besides the first one for each process when using PHP's built-in web server.&lt;/p&gt;
      &lt;p&gt;Xdebug "resolves" breakpoints when it sees code compiled by PHP and then notifies IDEs that the configured breakpoints are valid. Sometimes it also means it moves them to a line with executable code on it, as in some cases, PHP is "confused" about where lines of code live.&lt;/p&gt;
      &lt;p&gt;I spent some time delving into this, and initially I could not reproduce this. On my side (Linux, PHP 8.1/8.2) with &lt;code&gt;php -S&lt;/code&gt; the behaviour was always correct, with the breakpoints resolved for each request through the dev server.&lt;/p&gt;
      &lt;p&gt;When I had another good look at the &lt;code&gt;phpinfo()&lt;/code&gt; output from the user, I noticed:&lt;/p&gt;
      &lt;pre&gt;Zend Engine v4.2.8, Copyright (c) Zend Technologies
        with Xdebug v3.2.2, Copyright (c) 2002-2023, by Derick Rethans
        with Zend OPcache v8.2.8, Copyright (c), by Zend Technologies

&lt;/pre&gt;
      &lt;p&gt;The above shows that Xdebug is loaded first and OPcache second, which the &lt;a href="https://xdebug.org/docs/compat#compat"&gt;documentation&lt;/a&gt; says you shouldn't do:&lt;/p&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Zend Opcache&lt;/p&gt;
        &lt;p&gt;Can be loaded together with Xdebug, but it is not 100% compatible.&lt;/p&gt;
        &lt;p&gt;Load Xdebug after Opcache in &lt;code&gt;php.ini&lt;/code&gt; for better compatibility. When running &lt;code&gt;php -v&lt;/code&gt; or when looking at &lt;code&gt;phpinfo()&lt;/code&gt; output, Xdebug should be listed below Opcache.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;p&gt;After I switched the loading order of the two Zend extensions, loaded on the command line after ignoring (through &lt;code&gt;-n&lt;/code&gt;) the normal &lt;code&gt;php.ini&lt;/code&gt; file from:&lt;/p&gt;
      &lt;pre&gt;XDEBUG_MODE=debug XDEBUG_TRIGGER=yes \
        php -n -d zend_extension=opcache -d zend_extension=xdebug \
        -S localhost:9112 -t /tmp

&lt;/pre&gt;
      &lt;p&gt;To:&lt;/p&gt;
      &lt;pre&gt;XDEBUG_MODE=debug XDEBUG_TRIGGER=yes \
        php -n -d zend_extension=xdebug -d zend_extension=opcache \
        -S localhost:9112 -t /tmp

&lt;/pre&gt;
      &lt;p&gt;I &lt;strong&gt;could&lt;/strong&gt; reproduce this issue.&lt;/p&gt;
      &lt;p&gt;The explanation for this is that both Xdebug and OPcache override PHP's compile file handler.&lt;/p&gt;
      &lt;p&gt;Xdebug uses this to analyse newly loaded files for lines of code that can have breakpoints to resolve them. Before doing its magic, it calls the already present handler, nominally, the built-in PHP one that converts a PHP script into byte code that the PHP engine can run.&lt;/p&gt;
      &lt;p&gt;OPcache uses the handler to see whether it sees a file being converted (parsed) for a second time. If it is in its cache, it doesn't call PHP's original compile handler again but instead returns the byte code from its cache.&lt;/p&gt;
      &lt;p&gt;If OPcache is loaded first and then Xdebug, the following sequence occurs:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;OPcache replaces the compile file handler with &lt;code&gt;opcache_compile_file&lt;/code&gt;, and remembers the previous one, &lt;code&gt;php_compile_file&lt;/code&gt;.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Xdebug replaces the compile file handler with &lt;code&gt;xdebug_compile_file&lt;/code&gt;, and remembers the previous one, now &lt;code&gt;opcache_compile_file&lt;/code&gt;.&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;In this situation, when PHP runs the compile file handler, it first calls &lt;code&gt;xdebug_compile_file&lt;/code&gt;, which then calls &lt;code&gt;opcache_compile_file&lt;/code&gt; and all is well.&lt;/p&gt;
      &lt;p&gt;The process reverses if OPcache is loaded last:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;Xdebug replaces the compile file handler with &lt;code&gt;xdebug_compile_file&lt;/code&gt;, and remembers the previous one, &lt;code&gt;php_compile_file&lt;/code&gt;.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;OPcache replaces the compile file handler with &lt;code&gt;opcache_compile_file&lt;/code&gt;, and remembers the previous one, now &lt;code&gt;xdebug_compile_file&lt;/code&gt;.&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;When PHP runs the compile file handler, it calls &lt;code&gt;opcache_compile&lt;/code&gt; first. OPcache checks whether it has seen the file already and, if not, calls the previous handler (&lt;code&gt;xdebug_compile_file&lt;/code&gt;), but if it &lt;strong&gt;has&lt;/strong&gt; seen the file already (the second request through a php -S server), it does &lt;strong&gt;not&lt;/strong&gt; call the previous compile file handler.&lt;/p&gt;
      &lt;p&gt;Typically, that is what you want, as compiling files is expensive. However, because it does not call the previous compile file handler, that means that &lt;code&gt;xdebug_compile_file&lt;/code&gt; does not get run, which means Xdebug doesn't know anything about which lines of code can have breakpoints on them. It can not resolve them henceforth.&lt;/p&gt;
      &lt;p&gt;I can not work around this in Xdebug.&lt;/p&gt;
      &lt;p&gt;Luckily, there are workarounds:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;Make sure to load Xdebug &lt;strong&gt;after&lt;/strong&gt; OPcache &amp;#x2014; which is what the documentation says you should do.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Disable OPcache by setting &lt;code&gt;opcache.enable=0&lt;/code&gt;.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Don't load OPcache by commenting out the &lt;code&gt;zend_extension=opcached&lt;/code&gt; line in &lt;code&gt;ext-opcache.ini&lt;/code&gt; (or similar filename).&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;Loading Xdebug after OPcache is what you should strive for.&lt;/p&gt;
      &lt;p&gt;I usually name the xdebug.ini file 99-xdebug.ini and the INI file for OPcache &lt;code&gt;10-opcache.ini&lt;/code&gt;, to enforce the loading order by respecting the sorting order of INI files as stored on the file system.&lt;/p&gt;
      &lt;p&gt;Alternatively, if you only have one INI file, make sure that Xdebug is listed &lt;strong&gt;after&lt;/strong&gt; OPcache in this file, such as in:&lt;/p&gt;
      &lt;pre&gt;zend_extension=opcache
zend_extension=xdebug

&lt;/pre&gt;
      &lt;p&gt;From Xdebug 3.3, Xdebug will include a warning in the Diagnostic Log section of &lt;code&gt;xdebug_info()&lt;/code&gt; output to warn users that you should load Xdebug after OPcache.&lt;/p&gt;
      &lt;p&gt;As with all warnings in the HTML version of Xdebug's Diagnostic Log, there is also a &lt;a href="https://xdebug.org/docs/errors#DBG-W-OPCACHE"&gt;link to documentation&lt;/a&gt; which explains what the problem is and what possible solutions are.&lt;/p&gt;
      &lt;p&gt;I have also made a video about the Xdebug 3 Diagnostic Log, which you can find on &lt;a href="https://www.youtube.com/watch?v=IN6ihpJSFDw"&gt;YouTube&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/concealed-code.html</guid>
      <pubDate>Thu, 03 Aug 2023 08:55:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Shetland</title>
      <link>https://derickrethans.nl/shetland.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="shetland"/&gt;Shetland&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, July 20th 2023, 09:15 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;My wife and I went on holiday to Shetland at the beginning of June. Our decision to visit these isles was sparked after seeing the TV series with the same name. Although it's a crime series, the scenery was stunning. We did not anticipate encountering any murders.&lt;/p&gt;
      &lt;p&gt;Somewhere last year, I had mentioned visiting Scotland to my parents. Mum was especially keen to go with a small group touring company like Rabbie's, which my wife and I had used on our whisky distillery tours from Edinburgh many years ago. After looking into it, we decided that while they were touring some of the Inner Hebrides, we would visit Shetland to share the days travelling from London to Edinburgh and spend some days in Edinburgh together. It was earlier in the year than we would have gone, but we felt that that was fine.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;London to Edinburgh &amp;#x2014; Jun 1st&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;The first event of the trip was to get to Edinburgh with my parents in tow. King's Cross was its usual chaos, and it was likely busier than expected because there were rail strikes on the day before and would be the day after. We were early, and found an uncomfortable seat to wait until our departure. As I had booked the tickets, all stored on my phone, I would have to let the whole group through the barriers individually. In the end, we found a gate with its barrier missing, making that a lot easier.&lt;/p&gt;
      &lt;p&gt;The train left nicely on time, and we got breakfast and lunch, and beverages as we desired due to us travelling in first. As long as you book that early enough, it is not that expensive, especially when you also have a Two-Together Railcard, which costs &amp;#xA3;30 for a year for 33% off. My wife and I have used this Railcard for several years, and we also bought one for my parents as even on a single long journey, you make money back. The train ticket came to &amp;#xA3;152 per person for a four-and-a-half-hour trip there and back again in first class.&lt;/p&gt;
      &lt;p&gt;When we left London, it was warm but grey. As the train was moving north, the weather became lighter and lighter. The East Coast Main Line gets pretty beyond York, and I knew we should look out for a prominent hill figure near Thirsk, the &lt;a href="https://en.wikipedia.org/wiki/Kilburn_White_Horse"&gt;Kilburn White Horse&lt;/a&gt;. It is pretty amusing that it has "Kilburn" in the name, as that is also the area of London where I live, although it is nowhere near. I had visited the &lt;a href="https://en.wikipedia.org/wiki/North_York_Moors"&gt;North York Moors&lt;/a&gt; national park before for a hike and actually got close up to &lt;a href="https://www.flickr.com/photos/derickrethans/7720741122/in/photolist-FHkD2b-cLfPmf"&gt;it&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;As such, for a while, I was peaking out of the western window of the train to see whether I could point it out, but I would never have found it there. Luckily, my mum spotted it on the other side of the train, where I had not expected it.&lt;/p&gt;
      &lt;p&gt;The train was pleasant and uneventful, and the approach to Durham and the stretch through Newcastle are particularly impressive. After zooming into Scotland near Berwick, we made it to Edinburgh on time.&lt;/p&gt;
      &lt;p&gt;For our first night, we booked the Travelodge on Rose Street. It was a basic room, but it had a good bed and was reasonably roomy. Both for the bed, as well as the bathroom.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Edinburgh's Royal Mile" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6869_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Edinburgh's Royal Mile&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;For dinner, we had booked with &lt;a href="https://korabytk.com/"&gt;Kora&lt;/a&gt;, a restaurant by renowned chef Tom Kitchin as a little treat. Around a week before, we received an email stating that it would be closed for the night we would be there. Instead, they offered us a table at their &lt;a href="https://scranandscallie.com/"&gt;Skran and Scallie&lt;/a&gt; gastropub, not too far away in Stockbridge. On top of that, they offered to pay for all our food. This was not expected but certainly very welcome.&lt;/p&gt;
      &lt;p&gt;Typically, restaurant reviewers don't do reviews for compensation, but I'm willing to make an exception ;-). The food and the service were excellent. I enjoyed some scallops as a starter, and their fish pie as a main, finishing with a chocolate tort. My other companion's food also looked amazing. As the food was free, we did punt for a more expensive bottle of wine and made sure to leave a tip according to what the full price of the meal would likely have been.&lt;/p&gt;
      &lt;p&gt;After dinner, we walked back towards the hotel. My parents went right to sleep, whereas my wife and I ended up at &lt;a href="https://www.fiercebeer.com/bars/edinburgh-bar"&gt;Fierce Beer&lt;/a&gt; for a cheeky half or two.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Edinburgh to Aberdeen/On the Ferry &amp;#x2014; Jun 2nd&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;After a good night's rest, albeit being woken up a little earlier than I had hoped by the binmen, we met up with my parents and had a quick lunch at Pret on the way to the bus station, from where they were leaving for their &lt;a href="https://www.rabbies.com/en/scotland-tours/from-edinburgh/5-6-day-tours/iona-mull-the-Isle-of-skye-5-day-tour"&gt;Iona, Mull, and Isle of Skye Tour&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 25%"&gt;
        &lt;img title="Edinburgh's St. Andrew Square" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6872_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Edinburgh's St. Andrew Square&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After they had left, we wandered back to get some supplies for our train ride to Aberdeen. We were initially booked with LNER, but our train was cancelled due to strikes. We had anticipated this in advance and had booked a secondary ticket with ScotRail, who would not be on strike. LNER would have fed us again, but as ScotRail wouldn't, we headed to M&amp;amp;S to buy some sandwiches and muesli bars for when we would be walking in Shetland.&lt;/p&gt;
      &lt;p&gt;Getting into M&amp;amp;S was reasonably straightforward, but it took us a while to leave it as it was a gigantic maze. We eventually managed, and after picking up our luggage, we headed to Waverley to wait for our train. We didn't know our platform yet, so we stayed in the waiting room with its lovely ceiling and a cup of tea/coffee.&lt;/p&gt;
      &lt;p&gt;Once the platform was announced right at the last moment, we walked to the train and sat in the carriage. It was more comfortable than LNER, but it was also more squeaky.&lt;/p&gt;
      &lt;p&gt;It was a lovely sunny day, and the train going north offered some great views. Not long after leaving, we crossed the iconic &lt;a href="https://en.wikipedia.org/wiki/Forth_Bridge"&gt;Forth Bridge&lt;/a&gt;, and the views were charming along the coast north of Dundee, going through Arbroath and Stonehaven.&lt;/p&gt;
      &lt;p&gt;We arrived in Aberdeen on time, and the weather was still lovely. The station had no toilets, but we found them in the adjacent shopping centre. While waiting for her to be ready, I saw on my map that this shopping centre also had a Brewdog. Considering they are from near Aberdeen and that we had to wait at least two hours to board the ferry, we decided it would be much nicer to remain there than in the terminal's waiting room. So we had some cheeky halves and picked up some beers to enjoy on the ferry, as we didn't think it would have a reasonable beer selection.&lt;/p&gt;
      &lt;p&gt;When the time to find the ferry finally came, we walked over to the building along a busy road. It could have been a nicer walk as the area seemed very car-focused. We did board reasonably early and found our cabin for the night. A relatively small but well-appointed one with a shower, tea and coffee-making equipment, and a bunk bed to sleep in. I got to use the top one!&lt;/p&gt;
      &lt;p&gt;As we were early and the weather was nice, we set up on the deck in the sun for some relaxing and reading. Once the ferry left and became colder, we moved inside to investigate what was on the boat. Although it has a (tiny) cinema, there was nothing on, that we fancied, so we headed to the Magnus Lounge for a drink and some comfy seats. Access to the lounge came with our more expensive &lt;a href="https://www.northlinkferries.co.uk/the-journey/accommodation/"&gt;Premium/Executive cabin&lt;/a&gt;. If you're going on holiday, I recommend booking one of these. They also come with two drinks vouchers and a continental breakfast in the morning.&lt;/p&gt;
      &lt;p&gt;Once a table came free in the dining section of the lounge, we sat down for dinner. The menu is extensive, and many ingredients are sourced from "local" producers &amp;#x2014; local being anything between Aberdeen and Lerwick. We opted for fish and chips, which seemed most reasonable on a boat! They were pretty good, with nice crispy batter. The food is the same as outside the lounge, but there is table service, and the Magnus Lounge has a much more relaxed atmosphere.&lt;/p&gt;
      &lt;p&gt;After dinner, we headed upstairs to the deck again to walk around to get to our 10,000 steps. As it was pretty cold, we left pretty soon for the lounge for a beer. We ended up reading until the internet finally cut out, as we were too far from land for mobile phone signals to reach. At that time, we used one of our vouchers for a nightcap &amp;#x2014; an excellent Highland Park 12-year-old &amp;#x2014; to finish the day.&lt;/p&gt;
      &lt;p&gt;We climbed into bed just before midnight when the ferry was mooring at Kirkwall on the Orkney Islands.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Lerwick &amp;#x2014; Jun 3rd&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;We set our alarm for six o'clock to have time to wake up, shower, and get ready for breakfast. Although our alarms woke us up after a relatively resting sleep on the ferry. We were really awake when, at six thirty, the ferry's announcement system announced that breakfast was now open.&lt;/p&gt;
      &lt;p&gt;After we finished our preparations, we headed down to the Magnus lounge again for our basic but tasty continental breakfast. The only hold-up was for coffee, as the coffee (and tea!) machine took around 2 minutes per drink &amp;#x2014; an age if you want to get caffeinated to wake up.&lt;/p&gt;
      &lt;p&gt;You can enjoy breakfast until half seven, but we did not need that long, and after packing, we left the ferry in search of our rental car. We rented our cat through &lt;a href="https://www.boltscarhire.co.uk/car-hire"&gt;Bolts Car Hire&lt;/a&gt; &amp;#x2014; ostensibly the mayor, if not only, car rental company on Shetland. You literally see their cars everywhere. We went for their smallest model, a Skoda Citigo. We're not transporting cows and sheep, after all. At around &amp;#xA3;300 for 6 days, it was pretty good value too, not that we had any other choice!&lt;/p&gt;
      &lt;p&gt;It had been a while since I drove, and it took me some time to figure out which pedal did what again, and which way the steering wheel steered. After a few minutes, it luckily came back to me, and we navigated out of the crowded ferry-terminal parking lot &amp;#x2014; it was crowded because of parked cars, not because so many vehicles were being driven. She was navigating as I was driving, and after a five-minute drive, we ended up at our B&amp;amp;B, Woosung. Our room wasn't quite ready yet. It was just after eight o'clock, so we dropped off our luggage and headed into Lerwick to explore.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 60%"&gt;
        &lt;img title="Lerwick's Commercial Street" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6880_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Lerwick's Commercial Street&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We walked up the hill and into Lerwick's Commercial Street. At so early in the morning, it was eerily empty. Once we got to the harbour, I loaded up the first walk of the holiday, the &lt;a href="https://www.walkhighlands.co.uk/shetland/lerwick-explorer.shtml"&gt;Lerwick Explorer&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;Before our trip, I had searched for some good walks of various lengths across the islands. We were certainly not only going to walk, but it is the best way to get to the most scenic places. The &lt;a href="https://www.walkhighlands.co.uk/"&gt;walk highlands&lt;/a&gt; website as well as &lt;a href="https://amzn.to/3D6dd3n"&gt;Orkney and Shetland Pathfinder Walking Guide&lt;/a&gt; from Ordnance Survey. Many routes overlapped.&lt;/p&gt;
      &lt;p&gt;The route around Lerwick started at the port and followed Commercial Street up towards the east. Just after Bain's Beach, we looked at a dog playing on the beach and took photos of the house just to the east. We later found out that this building acted as Jimmy Perez's house from the Shetland series.&lt;/p&gt;
      &lt;p&gt;The wind picked up around the eastern point, as the walk was pretty exposed. It wasn't freezing, but the weather was mostly grey. We spotted an odd duck in the cemetery, prompting us to investigate it thoroughly. We encountered Dutch sailors' graves as well.&lt;/p&gt;
      &lt;p&gt;From the cemetery, we climbed up along the coast with great views and through a golf course on this outcrop called The Knab, before heading down to the waterline at a place called "The Sletts", which has a natural slope of rocks into the bay.&lt;/p&gt;
      &lt;p&gt;After a little while along the road, we explored &lt;a href="https://en.wikipedia.org/wiki/Broch_of_Clickimin"&gt;Clickimin Broch&lt;/a&gt;, situated on the shore of Clickimin Loch. &lt;a href="https://en.wikipedia.org/wiki/Broch"&gt;Brochs&lt;/a&gt; are Iron Age stone buildings with a specific shape, found mainly on Scotland's Atlantic Coast. No longer occupied by people, but rather its walls house dozens of starling nests. The starlings were very busy delivering worms to their screaming young.&lt;/p&gt;
      &lt;div id="lerwick1" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6881_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Bressay Ferry&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6884_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Welcome to Shetland&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6885_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Lerwick Harbour&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6886_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Jimmy's Hus&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6892_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Dutch sailors in the cemetery on the Knab&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6898_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Wild Flowers&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6899_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;The Sletts&lt;/div&gt;
          &lt;div class="numbertext"&gt;7 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6910_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Clickimin Broch&lt;/div&gt;
          &lt;div class="numbertext"&gt;8 / 8&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('lerwick1', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('lerwick1', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;Once done with the visit of the broch, we walked back to the B&amp;amp;B to pick up our car to head to Scalloway to look at the castle and the museum. Once we crossed the hills, the sun also came out, instantly making it feel more like a holiday. We parked at a small parking place near a stony beach and walked to the castle and museum to only find them both closed, and the castle in scaffolding.&lt;/p&gt;
      &lt;p&gt;Instead, we wandered through Scalloway along its shoreline and discovered their Norwegian connection. During the second world war, it was a location from which the &lt;a href="https://en.wikipedia.org/wiki/Shetland_bus"&gt;Shetland Bus&lt;/a&gt; operated to support the Norwegian resistance. There are a few plaques and places scattered around town, including the &lt;a href="https://www.scallowaymuseum.org/blog/historic-prince-olav-slipway-to-be-reconstructed-in-scalloway-as-wartime-exhibit"&gt;Prince Olav Slipway&lt;/a&gt; which was opened by the then-Norwegian crown prince.&lt;/p&gt;
      &lt;div id="scalloway" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6921_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Prince Olav Slipway&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6929_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Harbour&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6931_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Main Street&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 3&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('scalloway', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('scalloway', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;After an ice cream on the beach, we drove back to Lerwick to drop off the car and investigate Fort Charlotte, situated on Lerwick's harbour front. By then, we were tired and decided it was time for a well-deserved pint.&lt;/p&gt;
      &lt;p&gt;Finding an actual pub was not easy. We first had a peak into The Lounge Bar, but it was full and uninviting. We did not want to have a drink at the same place that we had booked dinner at and ended up at &lt;a href="https://www.thedowry.co.uk/"&gt;The Dowry&lt;/a&gt;. They luckily could squeeze us in near the bar. Many people after us were turned away because they were full. Both for dinner and drinks (although there were a few window bar stools available). We concluded that because there are so few places for so many people, we should book into a restaurant for every night we were there, and not just our day of arrival and the following Monday. We decided to just have fish and chips at the harbour on Sunday.&lt;/p&gt;
      &lt;p&gt;After our drinks, we smooched down a few doors to &lt;a href="https://www.no88shetland.com/"&gt;No 88&lt;/a&gt;, where we had booked. This was also full, with no more available seating. You really have to book in Lerwick. Our dinner was nice there, and we enjoyed a nice bottle of wine. At that point, we also decided to book for every other night we would be in Shetland.&lt;/p&gt;
      &lt;p&gt;After dinner, we walked back to our B&amp;amp;B to finally check in and chatted with the lovely host. After retiring, I quickly looked at the photos I took today and wrote down some notes. These notes were crucial for me to write this all up!&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Sumburgh Head &amp;#x2014; Jun 4th&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;We started the day at a reasonable time. And after having breakfast, we drove to the mainland's southern point Sumburgh Head. We parked at Jarlshof, the location of several ancient settlements. Still, instead of exploring that right away, we looked for the coastal path towards the lighthouse. This was going to be one of our walks on Shetland.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 50%"&gt;
        &lt;img title="&amp;#x2190; Coastal Walk" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6940_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;&amp;#x2190; Coastal Walk&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The walk starts just behind a wall and is near the entrance to Jarlshof, which I continuously kept calling Jarlsberg, the name of the Norwegian "cheese". In any case, there was an excellent big sign saying "coastal walk". However, that was superfluous as the lighthouse was in the distance up on the outcrop, and the path was clearly going to follow the coast.&lt;/p&gt;
      &lt;p&gt;The walk up to the lighthouse is along a gradually rising path, which was easy to walk on. The views to the right were great. We encountered some sheep with little lambs. Most of them ran away when we approached, but a family clearly just posed for the camera. There were a few stiles and walls to climb, and with one nearer to the lighthouse, I spotted a few puffins just off to the right. I had seen them previously in Iceland, but never this close. After a few minutes of looking at and photographing them, we continued to the lighthouse. The last stretch was pretty steep, but we made it.&lt;/p&gt;
      &lt;p&gt;At the top, we walked around the peninsula, looking down at the cliffs, where there were many birds, including puffins sitting, flying, and fishing. After observing a bunch of Norwegians trying to take photos of birds in flight, we decided it was time for some tea and a snack.&lt;/p&gt;
      &lt;div id="sumburgh" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6941_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Looking back at Jarlshof&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6951_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Posing Sheep&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6957_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Oyster Catchers&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6964_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Puffins [1]&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6976_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Puffins [2]&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_6980_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Puffin&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7001_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Guillemot Colony&lt;/div&gt;
          &lt;div class="numbertext"&gt;7 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7003_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Coastal View&lt;/div&gt;
          &lt;div class="numbertext"&gt;8 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7014_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Fulmars&lt;/div&gt;
          &lt;div class="numbertext"&gt;9 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7044_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Puffin&lt;/div&gt;
          &lt;div class="numbertext"&gt;10 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7049_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Jagged Cliffs&lt;/div&gt;
          &lt;div class="numbertext"&gt;11 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7053_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Lighthouse&lt;/div&gt;
          &lt;div class="numbertext"&gt;12 / 12&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('sumburgh', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('sumburgh', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;The caf&amp;#xE9; at the lighthouse was open, but as they were short staffed could only do us drinks and some takeaway croissants, which we ate sitting outside on a bench looking out over the cliffs (and parking lot).&lt;/p&gt;
      &lt;p&gt;After having regained our strength, we had a look at the foghorn and the museums. The site has four distinct things to visit: the lighthouse and foghorn, a hut showing how the world war II radar station looked like, a room with stories about all the lighthouse keepers, and a museum about the local marine life, including explanations of the warm water due to the gulf stream, and the recent decline in bird populations.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 33%"&gt;
        &lt;img title="Clifftop Lighthouse" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7067_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Clifftop Lighthouse&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once we were done with the museums, we continued our walk back to Jarlshof, first by going down a little bit before going up again to go over the local hill, which had some views over the headland with the lighthouse. On the other side of the hill, we had a good view of Shetland's main airport.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 33%"&gt;
        &lt;img title="Wheelhouse at Jarlshof" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7120_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Wheelhouse at Jarlshof&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Back where we started our walk, we explored the Jarlshof site. They provided a free audio tour with the ticket, which guided us through the many stages of settlement on the site. From the Iron Age broch and wheelhouses through Viking settlers, and finishing as a Scottish Laird's home. The site is very complex and well worth spending some time exploring.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 25%"&gt;
        &lt;img title="Red Pool of Virkie" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7126_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Red Pool of Virkie&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once we were done, it was still relatively early, and we intended to explore the south mainland as much as possible. Online I found out about the Red Pool of Virkie, a specific pool of water near the coast that turns very red every summer due to the decomposition of sea algae. It was a little drive away along a single-track road, and we parked our car on the side of the road. There wasn't a lot of space, but we were not in anybody's way.&lt;/p&gt;
      &lt;p&gt;The walk to the pool was through fields with sheep and their dung, with plenty of stiles. By having to go over so many, our technique for using them improved. After about 20 minutes, we got to the pool. Although I had expected it to not be very red yet as it was earlier in the year, we were happily surprised by being very clearly so. There was also an unexpected rock arch nearby.&lt;/p&gt;
      &lt;p&gt;We walked back to the car and then drove to &lt;a href="https://en.wikipedia.org/wiki/St_Ninian%27s_Isle"&gt;St. Ninian's Isle&lt;/a&gt; along another single-track road. To get to the island, you walk over the beach, but there is sea on both sides! This kind of formation is a &lt;a href="https://en.wikipedia.org/wiki/Tombolo"&gt;tombolo&lt;/a&gt;, and there are few of these. We only walked around part of the island but trekked up to the ruined chapel on the hill. The hike up was taxing due to the sandy nature of the path. There were some excellent views, although it was raining a little.&lt;/p&gt;
      &lt;div id="stninian" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7159_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;The Beach&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7163_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Broken Rocks&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('stninian', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('stninian', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;Once we were done, we were ready for dinner and drove back to Lerwick to drop off the car. We walked to the fish and chips place on the harbour side we spotted earlier. To our surprise, it was closed. As a matter of fact, nearly all restaurants were closed or fully booked. We ended up at the Golden Couch, a restaurant serving almost every Asian cuisine that you can think of. It was nothing spectacular, but still pretty decent. And the only option.&lt;/p&gt;
      &lt;p&gt;Back at the B&amp;amp;B after dinner, I spent out the ferry reservations for our drive to Unst on Wednesday. Although Shetland has an extensive ferry network, figuring out how it works could be more apparent. The schedules aren't set up logically and mostly show departures but not necessarily the destination &amp;#x2014; this is particularly problematic on the Mainland/Yell/Fetlar ferries. And it is absolutely recommended that you book, as they are not very often and you don't want to be stuck! Back more about this later.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Noss Boat Tour &amp;#x2014; Jun 5th&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;After breakfast, we wandered into town. Several months ago, I had booked to go on a birdwatching tour, but the morning sailing was already booked out. Therefore, our tour wasn't leaving until noon.&lt;/p&gt;
      &lt;p&gt;We had dressed already warmly, as it tends to get cold on windy open deck boats, so we set off to buy some gloves. She bought a nice set of bright-coloured Shetland knitted ones, but I wanted a little more technical. The few chain sports shops had nothing beyond boxing gloves, but they had directed me to a fishing supplies shop. They had grippy gloves for finishing, and I tried on a few pairs. Initially, I tried fingerless gloves, but I wanted fully covered ones. Only after leaving the shop did I notice that the ones I had bought were full-fingered, except for the thumb and index finger. This was great; I could wear the gloves and still handle my camera well.&lt;/p&gt;
      &lt;p&gt;We still had some time to spare, and as we were going to be on the boat for well over two hours, we decided to have a cup of tea and some cake. We found the C'est La Vie caf&amp;#xE9; at one end of Commercial Street, and after some time, we managed to draw some attention to get seated. There was really only one table left for us. We ordered coffee and tea, and the last two slices of cake. While enjoying it, many people, some from cruise ships, were also interested in tea and cake, but had to be turned away as it was full. Beyond not having enough restaurants for dinner, Lerwick could also do with more cafes for snacks and cake!&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 40%"&gt;
        &lt;img title="Cheeky Seal" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7173_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Cheeky Seal&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We wandered towards the harbour to wait for our boat to board, and while doing so, there was a cheeky seal, just looking over the edge of the quay. I bet it was after some of the fish the boat people had for later in our tour.&lt;/p&gt;
      &lt;p&gt;Our boat, the Seabird, was small, with only twelve spaces for guests. Although it has a little cabin, we all opted to sit outside as that's where the fun would happen.&lt;/p&gt;
      &lt;p&gt;After leaving the harbour, the guide pointed out Jimmy's house before heading towards the lighthouse on Bressay. We took photos and entered a cave where a few Shags were nesting. There was also a rock arch that we went through before setting course for the main colonies at Noss.&lt;/p&gt;
      &lt;div id="nossbirds" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7200_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Guillemots, both variants&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7241_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannets on a Ledge&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7242_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannet Spreading its Wings&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7245_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;The Two Types of Guillemots&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7254_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Noss Cliffs&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7267_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannets in Love&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7275_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannet Colony&lt;/div&gt;
          &lt;div class="numbertext"&gt;7 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7319_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Guillemots on the Edge&lt;/div&gt;
          &lt;div class="numbertext"&gt;8 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7335_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannet in Flight&lt;/div&gt;
          &lt;div class="numbertext"&gt;9 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7385_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Great Skua in Flight&lt;/div&gt;
          &lt;div class="numbertext"&gt;10 / 10&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('nossbirds', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('nossbirds', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;There were so many, many birds. It was mostly gannets, but we also saw guillemots and their bridled variant, which can be separated by a particular white line near their eyes. There were also a few fulmars, kittiwakes, puffins and skuas. The majestic gannets were my favourite.&lt;/p&gt;
      &lt;p&gt;The boat crew had brought fish snacks to show us how the gannets dive to catch their dinner underwater, and they most certainly showed us how they did that. There were a few squabbles in case they couldn't swallow the whole fish underwater, and a grey skua also tried to steal some of them, but not very successfully.&lt;/p&gt;
      &lt;div id="nossfish" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7392_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Skua Making a Splash&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7415_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannet Taking Off&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7427_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Skua Wanting to Steal the Fish&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7485_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannet in Flight&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7500_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Seal Seeing Us Off&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 5&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('nossfish', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('nossfish', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;After the fish were gone, the boat departed for a little bay where the Noss nature reserve wardens have their house.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 45%"&gt;
        &lt;img title="Great Skua in Flight" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7522_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Great Skua in Flight&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On the way there, we were followed by a Great Skua right next to the boat. It stayed there for quite some time, as the boat crew threw some snacks into the air for it to catch.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 40%"&gt;
        &lt;img title="The Wardens' House" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7581_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;The Wardens' House&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once we got to the bay, we saw the ferry that is operated by the nature reserve, which you can use if you want to visit Noss without having to take a boat tour. The ferry is just a dinghy which you need to call by waving at the wardens. When we went there, it wasn't operational, as they have Mondays and Thursdays off.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 33%"&gt;
        &lt;img title="The Face" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7589_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;The Face&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this little bay, the boat crew served us tea and biscuits, an excellent way to warm up. After about fifteen minutes of chit-chat, we headed back to Lerwick by going the other way around the island, where a face in the rock wished us welcome.&lt;/p&gt;
      &lt;p&gt;When we returned to Lerwick, we picked up our car to drive to Scalloway to try the museum again. We arrived over an hour before closure and thought that would be plenty of time. We were pretty wrong, as there was a lot of material about Scalloway as a town, but even more about the history and operations of the Shetland bus, with lots of Norwegian flags and descriptions in Norwegian. Which was still reasonably easy to read for me. We did have to rush, as an hour wasn't quite enough. An hour and a half would have been better.&lt;/p&gt;
      &lt;p&gt;We returned to the B&amp;amp;B to change from our warm boat-going clothes to some more presentable fashion for dinner. We had a little time and managed to grab a little table at The Dowry, which we had also booked for dinner for later. We enjoyed some local beers, and after chatting with the staff, they could seat us at our table a little earlier than we had initially planned. Again, they had to turn away many people, as they were the only place open besides the Golden Coach.&lt;/p&gt;
      &lt;p&gt;Dinner was pretty lovely. I had a Duck Confit, and she had a burger. We enjoyed two more beers in a bottle with dinner as well. After dinner, we decided to go for a little walk. With the boat tour, and the museum, we had yet to walk more, and we did want to get to our 10 000 steps. We walked along the Knab with some sun before returning to the B&amp;amp;B. I quickly looked at the 100s of photos I took while enjoying one of the beers we had bought in Aberdeen.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Esha Ness Cliff Walk &amp;#x2014; Jun 6th&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;I enjoyed breakfast, with a haggis slice, alone at the B&amp;amp;B. Although the location was great and the host very welcoming, there was a pervasive smell of cigarette smoke. Although I have no sense of smell, it put her right off having breakfast. While enjoying my haggis, our host explained that it was her last year, as new fire regulations meant she had to make too many changes to the building.&lt;/p&gt;
      &lt;p&gt;After breakfast, we drove to Northmavine and the lighthouse at Esha Ness. The first section out of Lerwick North was an easy drive, with lots of building works on the hills surrounding us, where many new energy-generating wind turbines were built. There is plenty of wind on Shetland, so that made perfect sense to me.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 40%"&gt;
        &lt;img title="Esha Ness Lighthouse" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7618_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Esha Ness Lighthouse&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After a while, the road became narrower, and after being stuck behind a hearse for a bit, we saw a car being on fire near a cafe. We turned off the main road just before Hillswick, which turned into a single track to the lighthouse, where we parked.&lt;/p&gt;
      &lt;p&gt;Near the lighthouse, it was fairly busy with people looking at the well-known majestic cliffs. Although the Ordnance Survey book on circular walks had a short 3.5km walk, the Walk Highlands website had a longer 14km one, which we walked instead. The walking along the cliffs was pretty spectacular, and there were quite a few sheep. We went past a dried-up waterfall, an inlet under the rocks through to the sea, and a fair amount of stony beaches and ponds. The landscape was very distinct from the south mainland and Sumburgh Head.&lt;/p&gt;
      &lt;div id="eshaness" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7619_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Cliffs&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7638_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Eroded Inlet&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7654_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Rolling Hills&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7676_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Left and Right&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7682_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;The Lighthouse on the Cliffs&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7690_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Oyster Catcher&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7708_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Craggy Sheep&lt;/div&gt;
          &lt;div class="numbertext"&gt;7 / 7&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('eshaness', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('eshaness', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;After going up and down and chasing away some sheep, the second section of the walk was along quiet roads. However, just when we got there, we startled two dogs who were quite insisting on barking at us.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 40%"&gt;
        &lt;img title="Views from Land" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7729_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Views from Land&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Although this section was along the road and inland, the views were still good, as this was on slightly higher land. There was a nice stack in the sea in the distance as well.&lt;/p&gt;
      &lt;p&gt;The inland section ends at the &lt;a href="https://www.tangwickhaa.org.uk/"&gt;Tangwick Haa&lt;/a&gt; museum, which is open and free. They also serve coffee, tea, and biscuits and only ask for donations to cover the costs. We did enjoy the tea in their lovely garden, where a lamb was bleating a lot &amp;#x2014; we later saw it when it was trying to get &lt;em&gt;back&lt;/em&gt; into the enclosure where its mum was.&lt;/p&gt;
      &lt;p&gt;Before continuing our walk, we perused the museum, which focussed on life in Northmavine with historical photos, stories, and a setup of a traditional living space. It was an excellent resting place during our walk, and because of the tea and coffee, we did not stop at the Braevik cafe, which I had originally planned. As a matter of fact, I specifically spend time to make sure that for each of our walks, there would be a nearby cafe or shop open to have lunch in or at.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 40%"&gt;
        &lt;img title="The Museum and a Beach" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7745_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;The Museum and a Beach&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The third section of the walk is along the coast again. But unlike the high cliffs, the landscape here was more rolling hills with lovely beaches. Although the water was probably freezing, it didn't deter seals from sticking their heads out. The other main feature in this section was Dore Holm, just off the coast &amp;#x2014; a rocky formation resembling a drinking horse.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Dore Holm" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7756_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Dore Holm&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Leaving the rocky horse behind, the walk continued along the top of the cliffs, where there was also a big wooden cross on a little hill. From there on, it was pretty undulating. At some point, we came upon an abandoned house with a statue of a Viking. The last section of the walk went uphill and back to the lighthouse. A coastguard helicopter flew over reasonably low in a big circle when we were nearly there. I don't think they were looking for us!&lt;/p&gt;
      &lt;p&gt;The plan back in Lerwick was to go to the Lerwick Brewery, but we were now too late to make it. Instead, we planned to visit them on our last day on the island, just before getting the ferry back.&lt;/p&gt;
      &lt;p&gt;For dinner, we booked a table at the &lt;a href="https://www.maryfieldhousehotel.co.uk/"&gt;Maryfield House Hotel&lt;/a&gt;, on the other side of the Bressay sound. This meant that we had to take the ferry. After exchanging our walking outfits for more going-out clothes, we wandered down to the ferry terminal in the harbour. We were really early, so we would have to wait about 40 minutes as per the schedule. But after about fifteen minutes, the ferry showed up, and we could board.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 40%"&gt;
        &lt;img title="Maryfield House Hotel, Bressay" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7811_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Maryfield House Hotel, Bressay&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After a 10-minute ride, walking up the hill to the hotel took us a few minutes. Although we were early here too, they could seat us in the small but nicely appointed dining area. The food was excellent &amp;#x2014; the best we had in Shetland &amp;#x2014; and had a pleasant atmosphere. We did not want dessert, and as they had no after-drinks menu, our waitress suggested we just look at what the bar had to offer. However, we could not see any whiskies whatsoever except for a few Irish ones. As we were in Scotland, I asked whether they had any whiskies in the bar. We were disappointed when the answer was negative until she pointed out that they have a whole whisky room! After chatting with the proprietor, who explained that during the Covid period they refurbished the whole place, including their new whisky room.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 25%"&gt;
        &lt;img title="Fivla, the Ferry" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7818_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Fivla, the Ferry&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;While we were enjoying our drams, we ended up chatting to one of the Germans, who were also having a whisky, about the wildlife and birds that they had seen, and we had seen. We suggested trying out Sumburgh Head to spot puffins, which they had yet to see.&lt;/p&gt;
      &lt;p&gt;When they left for the ferry, we followed them shortly after finishing our tipple, thinking it would leave at 20:00. But after walking to the ferry head, it turned out that we had to wait half an hour before it would actually go. Instead of staying in the windy weather, we sped back up the hill to the hotel to enjoy another dram. And we returned to the ferry terminal well on time to see the Germans boarding at the same time as we did.&lt;/p&gt;
      &lt;p&gt;When we returned to our B&amp;amp;B, we enjoyed another lovely beer, a La Trappe/BrewDog collaboration we also bought in Aberdeen. We had an early night; we had to get up early the next day.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Hermaness Nature Reserve &amp;#x2014; Jun 7th&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;We woke up and had breakfast early, as we had a long drive in front of us. All the way to Shetland's, and hence the UK's most northerly island: Unst.&lt;/p&gt;
      &lt;p&gt;The drive went smoothly, and we made it to the Yell ferry early enough to get an earlier ferry. We booked one, but their policy is that they'll take you if they have space for you and your vehicle.&lt;/p&gt;
      &lt;p&gt;What I suspect many people do on Yell is drive straight to the ferry to go to Unst. If we ever return, we can explore Yell too, as I felt sorry for the island. Although we got an earlier ferry to Yell, there was no space on the next ferry to Unst, so we had to wait for our booked ferry that was leaving about 30 minutes later.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Broadwalks on Moor Land" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7831_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Broadwalks on Moor Land&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once on Unst, we still had to drive a fair amount to the nature reserve's car park, following roads that became narrower and narrower. At the reserve, there was a little cabin with information boards and also a toilet, which we used.&lt;/p&gt;
      &lt;p&gt;The weather was grey and a little drizzly for about 15 minutes. Because of this, we marched along the new boardwalks all the way to the top of the hill. When crossing this moorland, you can't hear the sea or have any indication of what is to come. Once we arrived, we were greeted with a fantastic view of the cliffs, with the lighthouse to our far right.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="View from the Cliffs" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7833_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;View from the Cliffs&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Instead of going right, we followed the cliffs south towards the gannet colony at Saito, where 10s of thousands of gannets nest. I noticed I was still wearing my regular trainers instead of my fancy new walking ones. Luckily this didn't cause any trouble, and the ground was firm and dry enough.&lt;/p&gt;
      &lt;p&gt;We spend a fair amount of time walking the kilometre to the colonies, watching the birds and explaining the wonders of our &lt;a href="https://heroclip.co.uk/"&gt;Heroclips&lt;/a&gt; and &lt;a href="https://www.wwt.org.uk/wetland-centres/london/"&gt;London Wetland Centre&lt;/a&gt; &lt;a href="https://shop.wwt.org.uk/collections/optics"&gt;binoculars&lt;/a&gt; that we brought to a small group of people. They were amazed at how much more they could see with these. Besides the large amounts of gannets, we spotted some puffins too. And plenty of sheep with lambs ignored the "weak cliff, stay out" signs.&lt;/p&gt;
      &lt;div id="saito" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7843_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Saito Bird Colonies&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7853_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannets Nesting&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7861_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Gannet in Flight&lt;/div&gt;
          &lt;div class="numbertext"&gt;3 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7885_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Puffin on the Rocks&lt;/div&gt;
          &lt;div class="numbertext"&gt;4 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7932_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Birds in Flight&lt;/div&gt;
          &lt;div class="numbertext"&gt;5 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7944_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Sheep with Lamb&lt;/div&gt;
          &lt;div class="numbertext"&gt;6 / 6&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('saito', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('saito', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;Once we were done looking at and photographing the birds, we walked back up the minor incline to the top over the soft and springy ground while watching some skuas hunting on the moor.&lt;/p&gt;
      &lt;p&gt;From the top, where the broad walk finishes, we continued down the hill along the coast towards the most northern isle in the United Kingdom and the lighthouse perched on Muckle Flugga. The path was uneven and steep in sections, although the ground was a little springy but dry. Still fine for my regular city trainers.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 40%"&gt;
        &lt;img title="Did We Come From There?!" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7981_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Did We Come From There?!&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;At the bottom, we looked back upwards, as our original plan was to go back up the way we came after our trip to the lighthouse. Neither of us was looking forwards to this challenge.&lt;/p&gt;
      &lt;p&gt;The walk along the cliffs to the lighthouse was lovely, and there were a few more bird colonies. When we got to the vantage point, we spent some time looking at Out Stack, the most northerly island in the United Kingdom, and the lighthouse on Muckle Flugga. And, of course, more photos were taken.&lt;/p&gt;
      &lt;div id="muckleflugga" class="slideshow-container"&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_7995_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Bird Colonies on the Rocks&lt;/div&gt;
          &lt;div class="numbertext"&gt;1 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="mySlides fade"&gt;
          &lt;div style="text-align: center"&gt;
            &lt;img src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8001_web.jpg"/&gt;
          &lt;/div&gt;
          &lt;div class="text"&gt;Muckle Flugga Lighthouse, and Out Stack&lt;/div&gt;
          &lt;div class="numbertext"&gt;2 / 2&lt;/div&gt;
        &lt;/div&gt;
        &lt;a class="prev" onclick="plusSlides('muckleflugga', -1)"&gt;&amp;#x276E;&lt;/a&gt;
        &lt;a class="next" onclick="plusSlides('muckleflugga', 1)"&gt;&amp;#x276F;&lt;/a&gt;
      &lt;/div&gt;
      &lt;p&gt;When I originally planned the route, the information stated that the path over Hermaness Hill was closed. Still, it looked like it was open again. And we could see several information boards and walking posts that went straight over the hill. I looked at the map on my watch, including contour lines. From this, the way over the hill would be the easier option, so we decided to take this route.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Skua in Flight" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8041_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Skua in Flight&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;This was an excellent choice, even though getting up the hill was a little rough. The path was good, straight, and no annoying zigzags. Once we reached the top, the way back down was mainly over boardwalks again or otherwise well-trodden paths. We also saw several skuas.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Viking Ship (Replica)" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8050_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Viking Ship (Replica)&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We had booked our ferry to leave Yell at 16:45, but it was only 14:30, so we had some time to explore a little more on the island. First, we headed to the Shetland Reel gin distillery on the site of the old army base at Saxa Vord. This is also where a new spaceport is being built for launching small rockets into orbit. There was nothing to see of that yet, so instead, we rang the bell at the distillery so she could have a little tasting. I was driving, so I was just left standing there like a lemon. We did buy some gin to take home and to enjoy in the evening.&lt;/p&gt;
      &lt;p&gt;On the drive to the ferry terminal, we visited a replica Viking longhouse and ship. The ship was supposed to sail from Sweden to North America but only made it as far as Shetland. We stopped at the Unst Bus Shelter, also called Bobby's Bus Shelter. It was created by local boy Bobby McCauley when he was at school on the island. Bobby, who lived nearby, growing tired of the often long, cold and wet waits in the morning, took matters into his own hands and wrote a letter to the local newspaper requesting a new shelter for him to wait in. Since then, it has been furnished with many useful and useless things.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Bobby's Bus Shelter" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8056_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Bobby's Bus Shelter&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We arrived at the ferry terminal early, and luckily because our car was so tiny, they could make space for us, but not the 5 slightly bigger cars ahead of us. This also meant we had an earlier ferry to return to the mainland, arriving in Lerwick around 18:00.&lt;/p&gt;
      &lt;p&gt;For our last dinner in Shetland, we had booked a table at &lt;a href="https://restaurantguru.com/Da-steakhoose-Lerwick"&gt;Da Steak Hoose&lt;/a&gt;, Lerwick's premier (and only) steak house. I enjoyed their haggis bonbons and steak, while she enjoyed the steak and potato scone, with as main the scallops. When we arrived, there was a large group doing speeches, some kind of leaving do. Once they left, it quieted down, and the atmosphere was more relaxed. Like so many other restaurants, they're mainly family owned and run, and are therefore closed on Sunday and Monday.&lt;/p&gt;
      &lt;p&gt;Instead of heading back to our B&amp;amp;B, we headed to Tesco to find some tonic to go with a small bottle of gin we had picked up at the distillery. The sun came out nicely on our way back, illuminating the Knab. We took some photos before retiring and enjoying our gin and tonics. Then bed.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;South Mainland, and Travel to Aberdeen &amp;#x2014; Jun 8th&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;We got up a bit later; we were so busy the previous day. After breakfast chat with some Germans giving them puffing-watching tips, we started packing. Inadvertently I had paid the B&amp;amp;B &amp;#xA3;100 too much, which she returned in cash, mocking me a little. We put out luggage in the car and headed back to Sumburgh Head &amp;#x2014; mainly to buy our traditional souvenir magnet. We drove all the way instead of walking along the coast and found the parking place full. Mostly because some people didn't stay in between the lines. We parked in a safe space and then walked up the hill to the lighthouse. On the cliffs were two puffins looking cute, which I pointed out to a tour guide with many Americans in tow.&lt;/p&gt;
      &lt;div class="img-container-right" style="width: 50%"&gt;
        &lt;img title="Crofthouse Museum" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8094_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Crofthouse Museum&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After our whirlwind stop at the lighthouse, and with a new fridge magnet, we bought a ticket to the &lt;a href="https://www.shetlandmuseumandarchives.org.uk/visit/crofthouse-museum"&gt;Croft House Museum&lt;/a&gt; which was not far away. We were the only two there for most of the time, and the host told many stories about how people lived in crofts and how the &lt;a href="https://en.wikipedia.org/wiki/Crofters_Holdings_(Scotland)_Act_1886"&gt;Crofter's Act&lt;/a&gt; broke the grasp of the Lairds. Visiting is well worth the visit.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Fulmar" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8135_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Fulmar&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After our tour, we walked to its water mill and continued along the coast to a waterfall, which turned out dry. While photographing birds, we got a herd of curious cows that followed us for a while too. It was unlikely that the fence would have stopped them in case they would have been more curious. I had also already packed my walking trainers and did our little walk with my regular trainers. Again, this was fine as the ground was dry and not rocky.&lt;/p&gt;
      &lt;p&gt;As this was our last day, we drove back into Lerwick and filled the car with fuel to be able to return it at the ferry terminal. We continued going to the Shetland Museum for lunch and perhaps looking around. To my great fright, there I noticed that my phone was missing. There was still no sign of them after a frantic search in the car and underneath the seat. We drove back to the petrol station, where I looked around really well while my wife went into the shop to see whether it was handed in. In London, my phone would have been gone, which would have been a disaster, but luckily somebody had seen it falling out of the car when I closed the door.&lt;/p&gt;
      &lt;p&gt;We went back to the museum to have coffee and a tasty cake. Their lunch looked good too. We then decided not to visit the museum as it was too late. Instead, we chose to wait our remaining time at &lt;a href="https://www.lerwickbrewery.co.uk/"&gt;Lerwick Brewery&lt;/a&gt; after dropping off the car. My research had shown that the brewery was right across from the terminal. Unfortunately, I got that wrong, and it was 2 miles uphill. Having turned in our car keys already, we also could drive up to at least get a take-out.&lt;/p&gt;
      &lt;p&gt;Therefore, we had to wait at the ferry terminal and got on board just after five. We had a few more walking rounds on the deck to get out steps in, and I took some photos. Our cabin was slightly different, with two single beds and no bunk bed.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Good Bye Shetland" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8240_web.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Good Bye Shetland&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;We watched Lerwick and Shetland glide away when the ferry left, and shortly after that, we had fish and chips in the Magnus lounge, just like our trip to the islands. After a beer from Lerwick and Orkney, we finished our day with a wee dram.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Afternoon in Edinburgh &amp;#x2014; Jun 9th&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;We woke up early on the ferry at 06:00 because the boat announced that breakfast was now being served. We enjoyed our complimentary continental breakfast and left the ferry for the train station around 07:30.&lt;/p&gt;
      &lt;p&gt;Aberdeen's station has few facilities. Still, as it's adjacent to a shopping centre, we found the Black Sheep cafe there, where we camped out with tea and coffee until our train was announced just before 10:00.&lt;/p&gt;
      &lt;p&gt;There was no strike this time, and we travelled on our booked LNER service back to Aberdeen. The upside of LNER in first class is that they serve you breakfast and refreshments.&lt;/p&gt;
      &lt;p&gt;In Edinburgh, we went to our hotel, &lt;a href="https://angelssharehotel.com/"&gt;Angels Share&lt;/a&gt;, to check-in. Unbeknownst to us, my parents had been waiting at Waverley to greet us. We missed them, so they met us for a light lunch at the hotel. We intended to do some touristy things, but we were on the late side for this and decided to avoid travelling and tire us out more.&lt;/p&gt;
      &lt;div class="img-container-left" style="width: 50%"&gt;
        &lt;img title="Edinburgh Castle" src="https://s3.drck.me/derickrethans-blog-photos.s3.eu-west-2.amazonaws.com/2023-06a-shetland/d51_8264_web.jpg" style="width: 100%"/&gt;
        &lt;div class="img-overlay"&gt;Edinburgh Castle&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Instead, we took my dad to the Black Cat to finally enjoy some whiskies together. We had several nice ones and finished with a lovely beer before picking up my mum and heading for dinner. I thought the restaurant was a twenty-minute walk away, but it turned out to be near. &lt;a href="https://www.markgreenaway.com/grazing-restaurant"&gt;Grazing by Mark Greenway&lt;/a&gt; was a little posher than we had expected and was actually situated inside the Waldorf Astoria. The meal was excellent and relatively reasonably priced. We did feel underdressed, though.&lt;/p&gt;
      &lt;p&gt;After finishing my 10 000 steps while walking through Edinburgh during twilight, we finished with a few drinks in the hotel, first in the bar and then in the lobby once a band started playing too loud in the bar area.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Travel Home to London&amp;#xA0;&amp;#x2014; Jun 10th&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;We started with a lazy morning with a great breakfast at the hotel before heading towards Waverley and our train home. We arrived on time and waited a little in the sun on the platform. The trip back into London was uneventful, and the train beer much welcome.&lt;/p&gt;
      &lt;p&gt;To conclude our holiday, we finished with a pizza at our local pizza joint, a favourite of us: &lt;a href="http://www.theredpepperrestaurant.co.uk/"&gt;The Red Pepper&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;The holiday finished more than a month ago, and it has taken me this long to write up the story and process all the &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72177720308992881"&gt;photos&lt;/a&gt; &amp;#x2014; there is only a small selection in this story&amp;#xAD;. At some point soon, I also intend to turn the best photos, with descriptions, into a physical photo album.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/shetland.html</guid>
      <pubDate>Thu, 20 Jul 2023 08:15:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: June 2023</title>
      <link>https://derickrethans.nl/xdebug-update-june-2023.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_june_2023"/&gt;Xdebug Update: June 2023&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, July 4th 2023, 09:52 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past two months. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 38% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend around 10 hours on Xdebug, with 24 hours funded. This is much less than I wanted, but instead I have been busy implementing features for PHP, and been on holiday. I expect to spend a significantly more amount of time on Xdebug in July.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="towards_xdebug_3_3"/&gt;Towards Xdebug 3.3&lt;/h2&gt;
        &lt;p&gt;Now PHP 8.3 has its first alpha releases made, it is time to have a look at what needs to be added to Xdebug to support these new features. At the moment, it looks like there are no actual breaking changes in PHP, and Xdebug's master branch on GIT compiles and runs fine with PHP 8.3.&lt;/p&gt;
        &lt;p&gt;I will have to investigate the following features to see if I can add things to Xdebug to make these more useful:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://wiki.php.net/rfc/typed_class_constants"&gt;Typed Class Constants&lt;/a&gt; &amp;#x2014; I could perhaps show these as part of the representation of classes during debugging.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://wiki.php.net/rfc/readonly_amendments"&gt;Readonly Amendments&lt;/a&gt; &amp;#x2014; PHP's classes can now also be marked as &lt;code&gt;readonly&lt;/code&gt;, and having this reflected in &lt;code&gt;xdebug_var_dump()&lt;/code&gt; and the debugging protocol would likely be useful too.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;In addition to PHP 8.3 specific features, I have also done some research into Xdebug-side path mappings. As part of this, I have drafted a document &lt;a href="https://docs.google.com/document/d/1uGFocdX3WtlyGIUOCH_lej4oWyi4GPa9ayyaxM0ab1I/edit?usp=sharing"&gt;"Native Xdebug Path Mappings"&lt;/a&gt; to collect ideas and a draft specification. This would allow for applications written in PHP to define their own path, file, and line mappings, instead of relying solely on IDEs to implement this. This is a large amount of work, and hence I am intending to "Crowd Fund" this in a specific way. I have already received pledges for about half of the time.&lt;/p&gt;
        &lt;p&gt;If you have comments, suggestions, or if your company wants to help fund this feature, please &lt;a href="mailto:derick@xdebug.org"&gt;reach out&lt;/a&gt;, or leave comments on the document.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published no new videos in the last few months.&lt;/p&gt;
        &lt;p&gt;I have continued writing scripts for videos about Xdebug 3.2's features, and am also intending to make a video about "Running Xdebug in Production", and the updated "xdebug.client_discovery_header" feature (from Xdebug 3.1).&lt;/p&gt;
        &lt;p&gt;Let me know what you'd like to see!&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In the last few months, three new business supporters signed up:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.11com7.de"&gt;11com7&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://b13.com"&gt;b13&lt;/a&gt;.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.iodigital.com"&gt;IO Belgium&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I have also reached out to all other existing supporters to ask for a logo, to replace their text only mentions on the Xdebug home page.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-june-2023.html</guid>
      <pubDate>Tue, 04 Jul 2023 08:52:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Southall to Uxbridge</title>
      <link>https://derickrethans.nl/southall-to-uxbridge.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_southall_to_uxbridge"/&gt;Walking: Southall to Uxbridge&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, May 16th 2023, 09:32 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;There were strikes on this weekend, so instead of taking a train out of London for a walk, I decided to do a few urban Slow Ways routes, from Southall via Hounslow, Harlington, and Iver, to Uxbridge.&lt;/p&gt;
      &lt;p&gt;Southall has a brand new station, built for the Elizabeth Line, to replace the slightly dingy one just to the south. From here, I walked a short stretch along a few residential roads, although there was a nice cycle path along the road to the Grand Union Canal.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Fences :-(" src="https://live.staticflickr.com/65535/52897860063_f32770019f_n_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Fences :-(&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Instead of going through Wolf Fields Park, the route took me around it with fences on both side. I don't know what. After a few more residential roads, I crossed under the M4 although the route's surroundings stayed the same. After crossing the A4 the route briefly goes through Lampton Park, where my planned route was blocked due to a new development. The detour &lt;em&gt;through&lt;/em&gt; the park was probably more pleasant though. As it seems like a temporary blockage, I don't think the route needs adjusting.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="A Road" src="https://live.staticflickr.com/65535/52897861238_f6f3f736b0_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;A Road&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From Hounslow Central I returned back towards Lampton Park, where a fun fair was just breaking up. This caused a few annoyances are trucks and cars where on the footpath in the park. Although the route tries to avoid main roads as much as possible, the slog along the A4 towards Heathrow was particularly unpleasant.&lt;/p&gt;
      &lt;p&gt;After crossing the River Crane, the walk finally moved away from a busy road, first along Cranford Park for a little, and then along a lane (with pavement) towards Harlington.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Cranford Park" src="https://live.staticflickr.com/65535/52896842547_25e4791253_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Cranford Park&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After Harlington, the route continued much as before, by going along a lane. It was not busy with traffic, and there was a fair amount of open space so it wasn't that bad in the end. After going through the little village of Harmondsworth, the walk became actually pleasant, even though it started through a graveyard.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Blossom Snow" src="https://live.staticflickr.com/65535/52896845192_21803672b8_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Blossom Snow&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;It was a little muddy going around Saxon Lake, but it was quiet and green with a white dusting of fallen blossom. The crossing underneath the M4 had some graffiti on it. Mostly the annoying kind.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Too Tall for the Tunnel" src="https://live.staticflickr.com/65535/52897806455_a7ac139ac4_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Too Tall for the Tunnel&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The route continued following the River Colne, through some nice green woods. There was then a short (but safe) section without pavement, and a very narrow footpath towards Thorney. Here the route went alongside a golf course, and it some points crossed it. Crossing underneath the Great Western Main Line was haphazard, as the tunnel was not quite high enough for me!&lt;/p&gt;
      &lt;p&gt;The route then followed the Colne Valley trail/footpath for a bit all the way towards the Grand Union Canal's Slough Arm. I always liked walking alongside it and this weekend was no exception.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="The Slough Arm" src="https://live.staticflickr.com/65535/52897807785_fc36d94197_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Slough Arm&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After leaving the canal, the walk into Iver is again along a main road, as bridge across the canal had collapsed a few years ago.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Butterfly" src="https://live.staticflickr.com/65535/52897584069_38bbb144b9_n_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Butterfly&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Beyond Iver, my walk followed a section of the &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72157720179665221"&gt;Beeches Way&lt;/a&gt; which I walked at the end of 2021.&lt;/p&gt;
      &lt;p&gt;After a lovely walk here, I crossed the M25 into London again. After a short stretch along Iver Lane, my walk joined the &lt;a href="https://derickrethans.nl/the-loop-part11-and-12.html"&gt;London LOOP&lt;/a&gt; along the lovely River Colne, with a fair amount of butterflies, to finally end up at some residential streets in Uxbridge, which brought me to the station, and then home (and the pub!).&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/southall-to-uxbridge.html</guid>
      <pubDate>Tue, 16 May 2023 08:32:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug at 21</title>
      <link>https://derickrethans.nl/xdebug-21.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_at_21"/&gt;Xdebug at 21&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Monday, May 8th 2023, 21:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Today Xdebug turned 21.&lt;/p&gt;
      &lt;p&gt;Over these last twenty-one years &lt;a href="https://xdebug.org"&gt;Xdebug&lt;/a&gt; grew from a little hack to make sure PHP wouldn't segfault when having infinite recursion, to a tool that is used by tens of thousands, if not hundreds of thousands, PHP developers.&lt;/p&gt;
      &lt;p&gt;This has mostly been the work by myself, with very few external contributions. That makes sense, as it hard to both understand the PHP engine well enough, as well as programming in C. Especially because lots of PHP internals are not actually documented.&lt;/p&gt;
      &lt;p&gt;Xdebug was developed on a mostly voluntary basis, with more recently through some sponsorship via &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;, and through funding from &lt;a href="https://xdebug.org/support"&gt;Pro and Business supporters&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;Beyond a brief period in &lt;a href="https://xdebug.org/log"&gt;early 2020&lt;/a&gt; when I was rewriting Xdebug to version 3, this amounts to funding for about 25 hours a month, with a steady decline.&lt;/p&gt;
      &lt;img src="derickrethans.nl/images/content/xdebug-funding-2022.png"/&gt;
      &lt;p&gt;Twenty-five hours a month is about the minimum needed to &lt;strong&gt;maintain&lt;/strong&gt; Xdebug for newer versions of PHP, including support for new features, as well as triaging and fixing bugs.&lt;/p&gt;
      &lt;p&gt;If you have been following my monthly reports, you probably have noticed that there is less activity, including in creating the reports and work logs.&lt;/p&gt;
      &lt;p&gt;But there are plenty of things that should be done, and several that would make Xdebug even more powerful in streamlining debugging and improving your applications. These are also things I would &lt;strong&gt;like&lt;/strong&gt; to work on.&lt;/p&gt;
      &lt;p&gt;Current features that (in my opinion) need improvement are:&lt;/p&gt;
      &lt;p&gt;Profiling&lt;/p&gt;
      &lt;blockquote&gt;
        &lt;p&gt;The profiler is old code, and fairly messy. It is only possible to start the profiler for the whole of the request, and not only a part of it.&lt;/p&gt;
        &lt;p&gt;There are also bugs with cycle detection (function A calls function B calls function A) that need investigating.&lt;/p&gt;
        &lt;p&gt;It should be rewritten, which is luckily easier to do after Xdebug's new modes architecture.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;p&gt;Code Coverage&lt;/p&gt;
      &lt;blockquote&gt;
        &lt;p&gt;The current code coverage feature keeps static information about which functions have lines and paths in the same data structure as the dynamic data collection that is recorded when the script runs. This causes problems.&lt;/p&gt;
        &lt;p&gt;I have a &lt;a href="https://github.com/xdebug/xdebug/pull/774"&gt;fix&lt;/a&gt;, but it slows down coverage by 50%. Before I can merge it, that needs addressing.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;p&gt;Among the new features that I like to contribute to Xdebug are:&lt;/p&gt;
      &lt;p&gt;Native Path Mappings&lt;/p&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Currently Xdebug does not map paths between local files, and remote and/or generated files. There are some frameworks which rewrite developer-written-classes to a new version with additional functionality, but as a different file name.&lt;/p&gt;
        &lt;p&gt;Similarly Xdebug can not translate between local and remote paths, which causes confusion such as in this &lt;a href="https://youtrack.jetbrains.com/issue/WI-69488/IDE-Remote-Control-Use-PHP-Server-mappings-to-open-file-links"&gt;PhpStorm ticket&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;Introducing native path mapping would address both these issues.&lt;/p&gt;
        &lt;p&gt;An implementation could also make it possible to debug generated PHP files, say from templates. Although PhpStorm has some capabilities for this for &lt;a href="https://blog.jetbrains.com/phpstorm/2019/05/twig-and-blade-templates-debugging-2/"&gt;Twig and Blade templates&lt;/a&gt;, it is not supported for other template systems.&lt;/p&gt;
        &lt;p&gt;A native implementation in Xdebug also could make this working better and faster for what PhpStorm already does.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;p&gt;Time Travel Debugging&lt;/p&gt;
      &lt;blockquote&gt;
        &lt;p&gt;My tongue-in-cheek &lt;a href="https://xdebug.org/ai"&gt;April Fools' post&lt;/a&gt; hinted at this already.&lt;/p&gt;
        &lt;p&gt;Time Travel Debugging would allow somebody that runs a PHP request (either you as developer, or a customer running your on-premise application) to record its whole execution, including all intermediate states (variable contents, etc.), and source files.&lt;/p&gt;
        &lt;p&gt;By having this available in one file, a wrapper could then play this back pretending it was running a live request, through already existing debugging front-ends, such as the one in PhpStorm, the PHP Debug Adapter for Visual Studio Code, and many others.&lt;/p&gt;
        &lt;p&gt;Besides being able to step forwards, it would also support stepping back, and even seeking to every possible state in the request.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;p&gt;All four of these ideas require a large amount of work, and hence, time. I can not currently dedicate that time as there is not enough support for me to work on Xdebug.&lt;/p&gt;
      &lt;p&gt;I am highly appreciative of my Patreon patrons and GitHub sponsors, but I feel that support for Xdebug (and other Open Source) should come from &lt;strong&gt;companies&lt;/strong&gt; who's developers make use it, and not the individual developers themselves.&lt;/p&gt;
      &lt;p&gt;Xdebug currently has a few Pro, and eight &lt;a href="https://xdebug.org/#business_supporters"&gt;Business supporters&lt;/a&gt;. But there are currently only eight, where the ideal number would be around forty.&lt;/p&gt;
      &lt;p&gt;If you, or ideally your company, uses Xdebug often, or would like to see the above mentioned features in Xdebug, then I would implore to ask your company to &lt;a href="https://xdebug.org/support"&gt;sign up for Business support&lt;/a&gt;. I will gladly sit down with you and your team for an hour as well to discuss problems and answer questions. Feel free to &lt;a href="https://derickrethans.nl/who.html"&gt;contact me&lt;/a&gt; with any questions.&lt;/p&gt;
      &lt;p&gt;In the past 21 years I have enjoyed working on Xdebug immensely, and I hope to be able to do this for another 21 years. Happy Birthday!&lt;/p&gt;
      &lt;img src="derickrethans.nl/images/content/cupcakes.png"/&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-21.html</guid>
      <pubDate>Mon, 08 May 2023 20:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Horsley to Guildford</title>
      <link>https://derickrethans.nl/horsley-to-guildford.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_horsley_to_guildford"/&gt;Walking: Horsley to Guildford&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, April 25th 2023, 09:32 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I had a lovely walk last week, from East Horsley to Guildford via Gomshall, but didn't find the time to write up an article about it then, so here I am catching up.&lt;/p&gt;
      &lt;p&gt;I started my walk at Horsley station, which isn't exactly the start of the &lt;a href="https://beta.slowways.org/Route/Gomeas/8509"&gt;Slow Ways route&lt;/a&gt;. I didn't walk to the starting point along a busy road, so I found myself some footpaths instead. They were fairly muddy, and there was a steepish climb involved.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Sun in the Woods" src="https://live.staticflickr.com/65535/52839921330_d5101d2130_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Sun in the Woods&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;When the real route started, the walk was delightful. So much green, with very little mud. The chalky nature of the North Downs, which I walked some years ago kept the paths easy going.&lt;/p&gt;
      &lt;p&gt;There were many woods, and even a sawmill. At some point the Sun came out which made this walk even nicer. There a few steep ascents, and the descent towards Gomshall was also steep, and very muddy. There was however no alternative.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Baaah!" src="https://live.staticflickr.com/65535/52839959308_3dd7a63cd4_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Baaah!&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In Gomshall, the second route starts, and I got a little lost as to where the path was. Instead of where my map showed it to be, it was well hidden at the back of a village hall car park!&lt;/p&gt;
      &lt;p&gt;After leaving Gomshall along some sports fields, much of the route followed the Pilgrim's Way, a sort of alternative to the parallel North Downs Way, but then on the other side of the valley. Although it had rained, there was very little mud, which I much appreciated.&lt;/p&gt;
      &lt;p&gt;The village of Shere was really nice, and apparently very interesting, as there was a whole bus of Asian tourists to come and have a look at the church. If they had gone slightly passed it, they would also have seen a whole bunch of newly born lambs.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="View of the North Downs" src="https://live.staticflickr.com/65535/52838947137_70bd5db086_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;View of the North Downs&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Further west of Shere, the views of the North Downs were stunning, and I had a really lovely time walking here.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Mile Path" src="https://live.staticflickr.com/65535/52839524086_0371bc70d0_n_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Mile Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;There were empty fields, old oak trees, and rolling clouds. One of the woodlands also had many patches with blue bells. I took some time to explore and attempt some photos. I was fairly pleased that I did not "have" to go up to the top of Martha's Hill though.&lt;/p&gt;
      &lt;p&gt;The walk into Guildford was through a fairly steep ascent along the Mile Path. The ground was dry, and again, all the colours were so fresh and green.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Buzzz!" src="https://live.staticflickr.com/65535/52838984537_d2eae63211_n_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Buzzz!&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;It was fairly busy here, with it being so close to Guildford, and especially on a nice warm sunny day as it was, I can't blame them, or this lovely bumble bee from having a great day out!&lt;/p&gt;
      &lt;p&gt;After crossing Pewley Down it was then a steepish descent into Guildford, and the train home.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/horsley-to-guildford.html</guid>
      <pubDate>Tue, 25 Apr 2023 08:32:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Cobham to Addlestone</title>
      <link>https://derickrethans.nl/cobham-to-addlestone.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_cobham_to_addlestone"/&gt;Walking: Cobham to Addlestone&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, April 13th 2023, 09:32 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;For the Easter weekend walk, I thought I would pioneer a SlowWays walk, followed by a nice one to verify. I settled upon pioneering a route from Cobham to Woking, and then continuing to Addlestone.&lt;/p&gt;
      &lt;p&gt;For once, the route did not start at a train station, and instead I had to walk about a mile from Cobham &amp;amp; Stoke D'Abernon station. It was mostly along some fields, where I was being harassed by an annoying ankle biter when trying to put my coat away. It was such a lovely and warm day that I didn't actually ended up needing one. Once I got the dog and coat situation under control it was a short continuation to the start, at Cobham's clock on the High Street.&lt;/p&gt;
      &lt;p&gt;After leaving Cobham's High Street I walked along a slightly busy road, but only for a short while. Soon after crossing the river Mole (by bridge), the walked turned across pasture which was fairly soggy, but not too much to cause a problem for walking.&lt;/p&gt;
      &lt;p&gt;After a few stiles and bridges across streams I ended up in a very muddy field with two horses who luckily kept their distance, before emerging on the quiet Pointers Road, with no traffic beyond a runner. There I encountered a sign in Welsh (Gardd Triongl), a little unexpected in Surrey, but it was apt, as it pointed towards a very triangular garden. Not much after that I spotted a brilliantly placed red postbox in fresh new green sprouts in the woods.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Green Trees and Red Postbox" src="https://live.staticflickr.com/65535/52805063335_9b2b76e3eb_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Green Trees and Red Postbox&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;My walk then crossed the M25 on a footbridge, before going up steep through some woods. At the top I found a family pick-nicking at Semaphore Tower.&lt;/p&gt;
      &lt;p&gt;The tower is located on the east side of Chatley Heath, which my walked crossed. The paths here were are all easy going across sandy and chalky paths of the fairly open heath. At the west end, I had to go through some more woods, and ended up at a cleared space around the A3 crossing.&lt;/p&gt;
      &lt;p&gt;Here lots of paths have now disappeared, requiring me to propose a new version of the SlowWays route: &lt;a href="https://beta.slowways.org/Route/Wokcob/10426"&gt;Wokcob three&lt;/a&gt;. My walk then continued along the lovely Wisley Common with a pond, and around some fields, before ending up at the little village of Wisley. Here I crossed the river Wey, and ended up at my first golf course of the walk. The route through it was easy going along asphalted paths.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Tree on the Golf Course" src="https://live.staticflickr.com/65535/52805064615_155c4b6905_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Tree on the Golf Course&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After I crossing the River Way Navigation and its lock I ended up at my second golf course. On this one I couldn't follow the golf cart tracks, but instead I had to walk on the verges of fairways, and cross them sometimes. I was not hit on the head by golf balls luckily.&lt;/p&gt;
      &lt;p&gt;After leaving the golf course I ended up on open land with power lines above me. Although there was a narrow section with an electric fence on one side, the walk past the fields was easy going, although there was quite a climb up to Church Hill. After I crossed that road, I ended up on the "Sheep Walk" which goes straight to your third golf course &amp;#x2014; why are there so many golf courses? Although it goes through the golf course, I didn't actually see a lot of it as the path was surrounded by trees and hedges. It ended up being quite a lovely section with lots of yellow Celandine flowers.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Lesser Celandine" src="https://live.staticflickr.com/65535/52805109218_612f4e44d5_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Lesser Celandine&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After having left the golf course and walked briefly along a road, I enjoyed myself a lot again going along the river Hoe on dirt and grass paths. This was perhaps my most favourite section of this walk. This was then followed with my least favourite bit by going towards, and underneath, Woking station, and then along a shopping "paradise" to end up alongside the Basingstoke Canal. By this time, I also arrived at my second SlowWays route, from Woking to Addlestone.&lt;/p&gt;
      &lt;p&gt;The second part of my walk was very distinct from the first part. Instead of fields, hills, cows, and mud, it was all along two canals. I have walked the length of the Grand Union Canal a few years ago, but this had quite a distinctive feel to it. Or rather, two distinctive feels, as the section along the Basingstoke Canal was nothing like the River Wey Navigation.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Reflected Tree Tunnel" src="https://live.staticflickr.com/65535/52804107067_d925a084fb_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Reflected Tree Tunnel&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;There were a few locks on the Basingstoke Canal, with some lovely overhanging branches.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="HULK SMASH!" src="https://live.staticflickr.com/65535/52805111523_08847aa536_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;HULK SMASH!&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The reflections in the canal were great here. Once getting to the River Wey Navigation, the canal became much straighter and the paths muddier. This is also where I crossed back into London underneath the M25 &amp;#x2014; with some fun graffiti.&lt;/p&gt;
      &lt;p&gt;I left the canal at the Coxes Mill Pond, where lots of people were practising their kayaking/canoeing against the outflow from the lock.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Against the Flow" src="https://live.staticflickr.com/65535/52804668196_c46f6c40ee_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Against the Flow&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After a short section along some residential streets I finished my walk at Addlestone's train station, where, as you'd expect from me, I just missed the half hourly train.&lt;/p&gt;
      &lt;p&gt;I have neglected to write about last week's walk from Gomshall to Reigate, but I will make up for that!&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/cobham-to-addlestone.html</guid>
      <pubDate>Thu, 13 Apr 2023 08:32:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: March 2023</title>
      <link>https://derickrethans.nl/xdebug-update-march-2023.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_march_2023"/&gt;Xdebug Update: March 2023&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, April 11th 2023, 09:52 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past two months. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 34% (7% less than two months ago) towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend 18 hours on Xdebug, with 22 hours funded. Sponsorships through GitHub sponsors have now also drastically declined. Unless this is reversed, I would find it hard to spend the effort in making sure Xdebug continues to be updated for newer PHP versions. It certainly makes me think hard as to where to put my dedication towards.&lt;/p&gt;
      &lt;p&gt;This is also why I have not been as diligent with these update reports and been as active in resolving issues and bugs.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_2_1"/&gt;Xdebug 3.2.1&lt;/h2&gt;
        &lt;p&gt;March however did see the release of Xdebug 3.2.1, which finally addressed the longer running issue with Xdebug's &lt;code&gt;xdebug.mode&lt;/code&gt; setting being read and interpreted wrongly, sometimes also causing crashed due to mismatches in what Xdebug thought it had enabled, and what was actually enabled.&lt;/p&gt;
        &lt;p&gt;This does mean, that since Xdebug 3.1, the &lt;code&gt;xdebug.mode&lt;/code&gt; setting now can only be set in &lt;code&gt;php.ini&lt;/code&gt;, and not through per-directory or per-FPM-pool settings with &lt;code&gt;php_admin_value&lt;/code&gt;. This has delayed creating a video about running Xdebug in a production environment as well, as originally I had thought to do that through a specific PHP-FPM pool.&lt;/p&gt;
        &lt;p&gt;I did also work on starting to make Xdebug 3.3, the next version, to be compatible with PHP 8.3 which has made some changes that mostly required changes to Xdebug's test cases.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one new video in the last two months:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=UvElBs37JLg"&gt;Xdebug 3: Debugging Remote Code with VS Code&lt;/a&gt; &amp;#x2014; this is not a common way of debugging code on a remote machine, but it is nevertheless a feature that Xdebug in combination with the VS Code plugin provides.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I have continued writing scripts for videos about Xdebug 3.2's features, and am also intending to make a video about "Running Xdebug in Production", and the updated "xdebug.client_discovery_header" feature (from Xdebug 3.1).&lt;/p&gt;
        &lt;p&gt;Let me know what you'd like to see!&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In February and March, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-march-2023.html</guid>
      <pubDate>Tue, 11 Apr 2023 08:52:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: St. Albans to Berkhamstead</title>
      <link>https://derickrethans.nl/st-albans-to-berkhamstead.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_st_albans_to_berkhamstead"/&gt;Walking: St. Albans to Berkhamstead&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, March 7th 2023, 09:50 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After two weeks away from the trails, this Saturday I set out for another walk to clear my head. I walked from St. Albans to Berkhamstead via Hemel Hampstead, again following some of the &lt;a href="https://beta.slowways.org/"&gt;SlowWays UK&lt;/a&gt; routes.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="St. Albans' Cathedral" src="https://live.staticflickr.com/65535/52728025921_b10420f3a1_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;St. Albans' Cathedral&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Leaving the station at St. Albans I walked along its shopping streets for a while, before going past its magnificent cathedral and into &lt;a href="https://en.wikipedia.org/wiki/Verulamium_Park"&gt;Verulamium Park&lt;/a&gt;, named after St. Albans' Roman name. There are still some Roman things to see, such as mosaics and remnants of the old city walls, by which I left the park on the Western side, but not after having admired the many snow drops that lined the path.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Park Wood" src="https://live.staticflickr.com/65535/52728027231_ebc909fe19_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Park Wood&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On the other side of King Harry Lane sits a newish development which I had to cross through narrowish public footpaths to be able to go up a hill through farmland to the A414, which I crossed with a bridge. On the other side sits Park Wood, with many (incorrect) signs saying "private land, no access". The council recently has established a few new public foot paths in the wood, which would have allowed me to take a little short cut. I did not find out about it after I had already crossed it and ended up on a narrow lane.&lt;/p&gt;
      &lt;p&gt;I did follow the new footpaths for a bit to avoid the lane, but after not much distance my only option was to actually follow the lane. There wasn't much room in the verge, but there was not a lot of traffic, which could have made walking along here dangerous. A blind summit was a little on the scarier side.&lt;/p&gt;
      &lt;p&gt;From Potters Crouch to Bedmond my route went along more lanes, and to be honest, this was the least nice part of the walk. Unfortunately the extensive network of public footpaths in England does not always help with the directions you're trying to walk in.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Top of the Hill" src="https://live.staticflickr.com/65535/52728282439_9811080fe4_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Top of the Hill&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On the other side of Church Hill in Bedmond, my route continued along the edge of a field, followed by a public footpath sign pointing straight across a newly ploughed field. I always feel a little bad about crossing these, but it was my only way through, and I saw other people walking on a different footpath across the same field. By looking through my camera's zoom lens, I found the exit point on the other side of the field, and went for it in a (mostly) straight line. I hope that the next walked can follow in my footsteps.&lt;/p&gt;
      &lt;p&gt;After crossing a lane, a stile, a field and another stile, my route was suddenly blocked by a field of horses. &lt;a href="https://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt; did not actually contain that specific public footpath, and although I have now added it, I did decide to take a small detour around it. I don't like messing with horses.&lt;/p&gt;
      &lt;p&gt;I followed a path first along the edge of the farmland, where I suddenly came eye to eye with a Muntjac deer. I was too slow to get my camera out to take a photo of this tiny creature, as it trundled through the brambles to a safer space.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Grand Union Canal" src="https://live.staticflickr.com/65535/52728507443_9d468fb93e_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Grand Union Canal&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After going around Abbot's Hill school's vast estate, I ended up along the &lt;a href="https://en.wikipedia.org/wiki/Grand_Union_Canal"&gt;Grand Union Canal&lt;/a&gt; which I followed until the big Sainsbury's on the other side. For some odd reason, the people who drew the SlowWays route made you leave the tranquil canal for a few busy roads, and up a steep path through a tiny bit of lovely woodland, to end up on a dangerous crossing across the A414 where it joins the A41. There were some great views from here, but I do not think it was worth it, and I would have preferred to follow the Grand Union Canal all the way to Hemel Hempstead's station. I will be proposing an alternative route, which also adds the shortcut through the aforementioned Park Wood, and avoids the field of horses.&lt;/p&gt;
      &lt;p&gt;The second part of my walk, all the way to Berkhamstead was very straightforward. I just has to follow the canal! I walked the length of the Grand Union Canal, from London to Birmingham, a few years ago, but that was in summer and autumn. Now it is &lt;em&gt;just&lt;/em&gt; about spring, with the trees still fairly bare, and no little birds to be seen. The path wasn't very muddy luckily, and although it was lovely to walk along the canal again, it was fairly monotonous. I do always like watching boats go through the locks though, but it was too chilly to linger too much.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Berkhamstead" src="https://live.staticflickr.com/65535/52727504252_8ef58706a5_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Berkhamstead&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I left the canal at the &lt;a href="https://en.wikipedia.org/wiki/Berkhamsted"&gt;Port of Berkhampsted&lt;/a&gt; to take the train home into London, where I enjoyed a lovely pint to celebrate yet another successful walk.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/st-albans-to-berkhamstead.html</guid>
      <pubDate>Tue, 07 Mar 2023 09:50:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Didcot to Goring</title>
      <link>https://derickrethans.nl/didcot-to-goring.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_didcot_to_goring"/&gt;Walking: Didcot to Goring&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, February 14th 2023, 09:23 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Last Saturday I decided to walk across some humps that I had seen a few times before, but never ascended.&lt;/p&gt;
      &lt;p&gt;I found myself in a very full train towards Oxford. I was luckily to have gotten a seat, by virtue of walking fast and claiming the first non-reserved seat that I spotted. I didn't ride the train all the way to its destination in Oxford however, and got out at Didcot Parkway.&lt;/p&gt;
      &lt;p&gt;From here I intended to walk two more SlowWays routes &amp;#x2014; from Didcot to Wallingford, and then continuing along the Thames to Goring.&lt;/p&gt;
      &lt;p&gt;Leaving the station I soon found myself through parks in Didcot for a while, before going in the wrong direction at a new housing estate. Unfortunately the maps on my GPS watch had not been updated yet, so it was hard to follow the paths. &lt;a href="https://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt; was of course already up-to-date, which helped me find the right direction.&lt;/p&gt;
      &lt;p&gt;Just after the housing estate I walked past a lovely farm, with the snowdrops out in front of a little lake.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Snowdrops at the Little Lake" src="https://live.staticflickr.com/65535/52685087663_e6c6aa0988_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Snowdrops at the Little Lake&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Crossing Lady Grove road was a little annoying, and I had to wait a little while before it was safe to cross. I ended up chatting with a lady walking her dog for a bit about what I thought I was going to capture with my camera. I mentioned that I was hoping for some deer, kites, and whatever the Thames would have on display. I hadn't quite realised how many kites there actually would be! And I spotted my first few very soon after, albeit to fast to get a decent photo of, and one in a tree, which was too far to get a decent photo of.&lt;/p&gt;
      &lt;p&gt;This part of the walk was through some farmland, which was easy to walk with not too much mud, and more importantly, no cows. There was a tiny bit of road walking, before I got onto &lt;a href="https://earthtrust.org.uk/"&gt;Earth Trust&lt;/a&gt; land which maintains the land around the Wittenham Clumps, which started to loom larger and larger in the distance.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Round Hill and Castle Hill &amp;#x2014; The Wittenham Clumps." src="https://live.staticflickr.com/65535/52685088773_00ae4e4c61_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Round Hill and Castle Hill &amp;#x2014; The Wittenham Clumps.&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I had seen the clumps before while walking the Thames Path, and they're also easily spotted from the train going towards Didcot from London.&lt;/p&gt;
      &lt;p&gt;It was a pretty steep climb up, and I deliberately took the "long way" around the top of the slightly taller Castle Hill to get a better look at the Thames Valley, and the other slightly smaller clump which housed an iron age hill fort back in the days where that was popular.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Kite in the Trees" src="https://live.staticflickr.com/65535/52684076297_0e95410961_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Kite in the Trees&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The route did not make an immediate bee line for the Thames, and instead meandered through a wood where I spotted this kite sitting on a branch in the trees. After going around a farm my walk finally got me to the Thames at Shillingford. From here on my plan was to walk the Thames Path all the way to Goring. I did walk this before a few years ago in the middle of summer.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Boats on the Thames" src="https://live.staticflickr.com/65535/52685090173_8b220f4d39_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Boats on the Thames&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once I crossed the bridge across the Thames, there were many small birds in the hedge roads chirping happily along. The paths on the Thames Path were all very muddy, which wasn't quite a surprise as it was winter, but I think I would prefer walking it in summer instead.&lt;/p&gt;
      &lt;p&gt;At Benson the weir was blocked off, which unfortunately meant a diversion away from the Thames Path, first through a little village, then along a busy road for a short stretch, and then along residential roads into Wallington where the first section finished at its historic market square.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Wallingford" src="https://live.staticflickr.com/65535/52685017790_d19244fdfc_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Wallingford&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From Wallingford onwards, my walk was along the Thames for the rest of its length until Goring. Most of the paths were fairly easy going, but there were muddy sections, and &lt;strong&gt;very&lt;/strong&gt; muddy sections. As I said, I walked this before and I sort of had forgotten that the Thames Path can be quite monotonous, and I think this section is probably the least interesting part.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Cholsey Marsh" src="https://live.staticflickr.com/65535/52685019355_2d7cfa4557_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Cholsey Marsh&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Cholsey Marsh made for a nice photo though, and along this section there were quite a few snowdrops out, with the other side of the river sometimes showing large (and expensive) houses. At other sections, the cackle of geese was hard to miss, and quite loud at times. A man fishing didn't pay them too much attention though.&lt;/p&gt;
      &lt;p&gt;One of my least favourite sections of the Thames Path is the "Moulsford" diversion. It starts just after crossing underneath the Moulsford Railway Bridge, and diverts you away from the Thames around a prep-school, and along the A329 which was too busy to be comfortably walking along. I hope at some point better access can be negotiated here, or perhaps the Thames Path can be relocated to the east side of the river instead.&lt;/p&gt;
      &lt;p&gt;I was quite pleased once I got to the Thames Path again, although it became even more muddy here, and I was sliding all about.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Colourful Houses and Boats" src="https://live.staticflickr.com/65535/52684596116_1141418c00_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Colourful Houses and Boats&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Closer towards Streatley and Goring more and larger houses appeared on the opposite side of the river. Just before crossing Goring Bridge, there is a little nature reserve which was quite pleasant, whereas the walk into and through town, except for the bridge across the Thames itself, was a bit of a drag.&lt;/p&gt;
      &lt;p&gt;I made it to the train with a decent amount of minutes to spare to get all packed and relaxed, before taking it home with a transfer at Reading &amp;#x2014; and having a well deserved pint once I got home.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/didcot-to-goring.html</guid>
      <pubDate>Tue, 14 Feb 2023 09:23:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Hemel Hempstead to Amersham</title>
      <link>https://derickrethans.nl/hemel-hempstead-to-amersham.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_hemel_hempstead_to_amersham"/&gt;Walking: Hemel Hempstead to Amersham&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, February 9th 2023, 09:23 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I had originally planned to continue &lt;a href="https://derickrethans.nl/tring-to-amersham.html"&gt;last week's&lt;/a&gt; walk from Amersham to Chorleywood, but I had decided against that as it would have made that walk a little too long. So instead, I incorporated that section into this next walk, where I walked from Hemel Hempstead (not "Hampstead" as I just found out!) via Chorleywood to Amersham.&lt;/p&gt;
      &lt;p&gt;Before I set off to the beginning of yet another Chiltern walk, I had done a little research on how I could get to Hemel Hempstead as easily and cheaply as possible. I found out that I can actually buy a national rail ticket at my closest overground station (Kilburn High Road), which would also allow for me to use my Network Railcard, giving me 30% off. I would only have to transfer onto a proper train once, at Harrow &amp;amp; Wealdstone. If you travel by train a lot in the south east of the UK, a &lt;a href="https://www.network-railcard.co.uk/"&gt;Network Railcard&lt;/a&gt; at &amp;#xA3;30 is well worth the money.&lt;/p&gt;
      &lt;p&gt;Enough about trains! Once I got to Hemel Hempstead, I had some trouble getting to the south side of the station. Apparently you can only get out on that side if you have a special swipe card. So instead, I had to walk around and cross the very busy London Road to get to the start of the "real" walk, which also shares the same route as &lt;a href="https://chilternsociety.org.uk/the-chiltern-way-2/"&gt;The Chiltern Way&lt;/a&gt; for some sections.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Hedges and Paths" src="https://live.staticflickr.com/65535/52671037554_d5fa5a7fce_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Hedges and Paths&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once I got there, there was a fairly long climb up through Felden along a road with no pavement, but also luckily with little traffic. Much of the first half of the walk would be on a path, track, or road with hedges along each side. But it was never unsafe as there was very little traffic, and the traffic that did show up wasn't moving very fast.&lt;/p&gt;
      &lt;p&gt;I still prefer walking on actual footpaths, and after crossing Rucklers Lane, there was a long trek up and down a hill through grassy farmland. At the bottom a lovely track brought me to "Tower Hill", where footpaths through fields were easy to walk. I did not like the signs "bull in field" though. Luckily, these signs were a lie. After a lovely walk through some woods, with some good views of a village in the valley below, I ended up crossing a road.&lt;/p&gt;
      &lt;p&gt;My pre-planned route had me go along the road, but luckily there is now a permissive footpath that avoids the road, where there was fast traffic. At the end of the field, there was now a pavement to make the walk safe, and a path through the woods allowed me to avoid another road walking section.&lt;/p&gt;
      &lt;p&gt;I soon left the small village of Belsize behind and ended up on a lane, again with hedges on each side. There were soon some field-edge paths against where were quite welcome.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Snowdrops" src="https://live.staticflickr.com/65535/52670747441_d063aaf3fd_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Snowdrops&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After walking past Rosehall Wood, my set-out route suggested I go through some fields to Dawes Common before going over another hill to get to the river Chess. However there were a fair amount of horses in the field, and as I don't really trust these animals I decided to walk around them. Unfortunately that meant a little road walking, but luckily again, there was little traffic. I have proposed a new &lt;a href="https://beta.slowways.org/Route/Chohem/10280"&gt;route&lt;/a&gt; that should avoid the horse problem.&lt;/p&gt;
      &lt;p&gt;The new route avoids a hill, and another few fields of horses. It also meant that I walked along the lovely river Chess for a fair distance, as part of the &lt;a href="https://www.chilternsaonb.org/map_marker/chess-valley-walk/"&gt;Chess Valley Walk&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Little Egret" src="https://live.staticflickr.com/65535/52670748651_c6b56f4b2d_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Little Egret&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I spotted the first snow drops of the year along the lanes and the Chess Valley Walk themselves, and in the river a Little Egret. Once I had crossed the river on a wooden bridge, the rest of this first section went through the Chorleywood House Estate, and Chorleywood Common to end up close to the tube station.&lt;/p&gt;
      &lt;p&gt;I have walked from Chorleywood to Amersham before (or rather, in the opposite direction) as part of my &lt;a href="https://tube.derickrethans.nl"&gt;Tube Walking&lt;/a&gt; project a few years ago. This time however I did not have to visit Chalfont &amp;amp; Latimer's station, which made the whole walk a lot nicer. The route that I ended up walking was not quite the one that I originally was planning to do (&lt;a href="https://beta.slowways.org/Route/Amecho/1882"&gt;Amecho 1&lt;/a&gt;). But it turned out that it was the better variant that was also already verified (&lt;a href="https://beta.slowways.org/Route/Amecho/8817"&gt;Amecho 2&lt;/a&gt;).&lt;/p&gt;
      &lt;p&gt;From Chorleywood's "High Street" I walked along an avenue for a while before crossing into Carpenters Wood. From here on until Amersham, all of the walking was through woods, with no cows insight. There were a few places where I had to cross a road, but that was generally not a problem.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Chenies Manor" src="https://live.staticflickr.com/65535/52670248107_16d9c90643_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Chenies Manor&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After crossing one such road, Amersham Road, the walk brought me along Chenies Manor and through the estate. I very much liked going through all the woods, and there were often also great view of the Chess Valley, and another stately home, &lt;a href="https://en.wikipedia.org/wiki/Latimer_House"&gt;Latimer House&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Daffodils" src="https://live.staticflickr.com/65535/52670751946_ff36231652_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Daffodils&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I also spotted my first daffodils of the season, and a Muntjac (a tiny deer), but it was too fast to be caught on camera. This was not a problem with the daffodils.&lt;/p&gt;
      &lt;p&gt;The last woods that I walked through was the Market Reading Wood. From there on the walk was along pavements and a sports centre, before finishing the walk at Amersham station.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Views of the Chess Valley" src="https://live.staticflickr.com/65535/52671188075_1aa956c716_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Views of the Chess Valley&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Unfortunately, when I got there, the station was shut and there were posters with "rail replacement buses": there were no Metropolitan line services, nor Chiltern services into Marylebone at all. Although I was quite diligent doing research to get to the start of my walk, I neglected to do the same for the return journey!&lt;/p&gt;
      &lt;p&gt;I managed to get on the hourly bus to Rickmansworth quite soon, because it was 10 minutes late. At Rickmansworth I had to wait a while to get onto my second rail replacement service to Wembley Park, another Metropolitan line station. I was hoping to get off at Northwick Park to walk to Kenton, where I then could take the Bakerloo line home. But although the bus stopped at every Met line station, it went straight from Harrow-on-the-Hill to Wembley Park, and didn't stop at Northwick Park. I did make it home about three hours after I finished the walk. Next time: more train research!&lt;/p&gt;
      &lt;p&gt;It was a thoroughly enjoyable walk though, and I bet it would be even nicer when there is more green on the trees again.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/hemel-hempstead-to-amersham.html</guid>
      <pubDate>Thu, 09 Feb 2023 09:23:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: January 2023</title>
      <link>https://derickrethans.nl/xdebug-update-january-2023.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_january_2023"/&gt;Xdebug Update: January 2023&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, February 7th 2023, 09:52 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 41% (4% less than last month) towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend 18 hours on Xdebug, with 26 hours funded. Sponsorships, especially through Patreon, are continuing to decline, which makes it harder for me to dedicate time for maintenance and development.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_2"/&gt;Xdebug 3.2&lt;/h2&gt;
        &lt;p&gt;I have continued to triage new bug reports in Xdebug 3.2, and most notably trying to find the bug that people reported with regards to the &lt;code&gt;xdebug.mode&lt;/code&gt; setting not sticking, or being wrong. So far I have not managed to reproduce this in a reliable environment. If you run into this bug, please get in contact so that I can figure out what the cause is, by being able to reproduce this.&lt;/p&gt;
        &lt;p&gt;During a support call with one of my supporters, we discussed an issue that prevented correct breakpoints from being set through the &lt;a href="https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug"&gt;PHP Debug Adapter for Visual Studio Code&lt;/a&gt; for virtual file systems, such as with the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs"&gt;SSH FS&lt;/a&gt; plug-in. The debug adaptor did not know how to use a path mapping with this specific schema to work. There is now a new release (1.13.0) of the plug-in (&lt;a href="https://marketplace.visualstudio.com/items/xdebug.php-debug/changelog"&gt;https://marketplace.visualstudio.com/items/xdebug.php-debug/changelog&lt;/a&gt;) to make the following work:&lt;/p&gt;
        &lt;pre&gt;"pathMappings": {
    "/home/derick/dev": "ssh://singlemalt/home/derick/dev"
},

&lt;/pre&gt;
        &lt;p&gt;Which maps the server path &lt;code&gt;/home/derick/dev/&lt;/code&gt; to the virtual file path &lt;code&gt;ssh:://singlemalt/home/derick/dev&lt;/code&gt;, which I have added to my workspace.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published no new videos this month.&lt;/p&gt;
        &lt;p&gt;I have continued writing scripts for videos about Xdebug 3.2's features, and am also intending to make a video about "Running Xdebug in Production", the updated "xdebug.client_discovery_header" feature (from Xdebug 3.1), and the new SSH FS path mapping functionality in the PHP Debug Adaptor for VS Code.&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In January, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-january-2023.html</guid>
      <pubDate>Tue, 07 Feb 2023 09:52:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Tring to Amersham</title>
      <link>https://derickrethans.nl/tring-to-amersham.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_tring_to_amersham"/&gt;Walking: Tring to Amersham&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, January 31st 2023, 09:23 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Grand Union Canal" src="https://live.staticflickr.com/65535/52655954287_f44f8aef7f_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Grand Union Canal&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I usually walk multiple &lt;a href="https://slowways.org"&gt;SlowWays&lt;/a&gt; routes in a single walk, but last Saturday I only walked a slightly longer one, from Tring to Amersham. Some of that was because to get to the start of the official route, you first need to get there from Tring station, which means a slog along a busy road into down. But I did get a peek of the Grand Union Canal.&lt;/p&gt;
      &lt;p&gt;I have walked the length of the canal at the end of 2021, and I regret not having written this journey up, nor having taken loads of nice photos. I only took some mobile phone shots sadly.&lt;/p&gt;
      &lt;p&gt;The church in Tring is a lovely building, made better by a bright red postbox right in front of it. I have walked past here a few times before, but it was never quiet enough to get a reasonable shot of it.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="The Church at Tring" src="https://live.staticflickr.com/65535/52656440051_d7c2be0faf_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Church at Tring&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From Tring's High Street I soon followed some narrow public footpaths to cross the A41 (M) on a loopy bridge, and ended up in Tring Park. It was a fair climb up a muddy hill, but it wasn't too bad. The views were pretty good when I looked at where I came from.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Views from Tring Park" src="https://live.staticflickr.com/65535/52655955737_c8e6e3e24d_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Views from Tring Park&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Once at the top, my route went through a wood, and spotted the "Riddle of the Ruin", where I got a little lost as the path was hard to see due to so many leaves on the ground. It wasn't a big deal though and soon I left Tring Park and I continued to follow a foot path at the edge of a field, avoiding the road on the other side. After a little while this was no longer possible and had to walk a little on the road. It wasn't busy though.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="NO CYCLING" src="https://live.staticflickr.com/65535/52655956812_430f82bb10_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;NO CYCLING&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;At the end of the field, the route then proceeded through woods, where the paths were fairly muddy still. After crossing a field with a hedge on the left I walked towards Shire Lane, which I followed for a while before ending up in some private woods where you definitely couldn't cycle, but horse riding was fine.&lt;/p&gt;
      &lt;p&gt;I got a wee bit lost as the paths weren't mapped very well. At the other side and across from the cricket pitch I came upon a lovely windmill.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Windmill" src="https://live.staticflickr.com/65535/52656442666_1a01a745c4_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Windmill&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I walked down the steep Ray's Hill, where the SlowWays route indicated a direction that wasn't possible. I had to continue down the hill along the road for a few hundred metres more, before then following a public foot path again.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Muddy Path" src="https://live.staticflickr.com/65535/52656443806_c277f864ef_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Muddy Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;This stretch of the walk was in the bottom of a valley with a reasonable good foot path, no fence to the left, and woods to my right. The path was a little muddy all the way and along Ramscote Lane.&lt;/p&gt;
      &lt;p&gt;There my walk led me towards Chesham in between hedges and fences. The section through Chesham wasn't very nice, with loads of cars on the road, and parked on the pavement, although the high street itself was okay. After passing a play ground, tennis fields, and an allotment, the walk went underneath the Metropolitan line tracks up the hill and through Chesham Bois Wood.&lt;/p&gt;
      &lt;p&gt;Here a lady asked me whether I had seen her white dog &amp;#x2014; I had not. After coming out of the woods, and crossing Chesham Bois Common, there was a short section to the train station, where I (of course) ended up missing my train by 2 minutes.&lt;/p&gt;
      &lt;p&gt;The Metropolitan line was only going as far as Harrow-on-the-Hill, so I waited for the Chiltern train to Marylebone instead.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Metropolitan Line Train Arriving at the Platform" src="https://live.staticflickr.com/65535/52656728974_02076f6410_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Metropolitan Line Train Arriving at the Platform&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/tring-to-amersham.html</guid>
      <pubDate>Tue, 31 Jan 2023 09:23:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Bushey to Wembley</title>
      <link>https://derickrethans.nl/bushey-to-wembley.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_bushey_to_wembley"/&gt;Walking: Bushey to Wembley&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, January 24th 2023, 09:15 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On my second &lt;a href="https://slowways.org"&gt;SlowWays&lt;/a&gt; walk of the year I walked from Bushey to Wembley.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Fields of Mud" src="https://live.staticflickr.com/65535/52628998055_89f2c81418_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Fields of Mud&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I started at Bushey station, which isn't quite the start of the actual route. From there, I made a bee-line towards the Attenborough Fields. Going directly up them was a bit of a chore, as the fields could more accurately described as a "flood plain". The &lt;em&gt;actual&lt;/em&gt; path was a fast flowing stream, so I wandered along the other side of the hedge up the hill. Here cows blocked my path and I had to divert and jump a fence (sorry) to rejoin the route just before it crosses Merry Hill Lane. From there the paths where mostly different grades of mud, with some standing water. I followed a straight line along Merry Hill circular footpath, where my planned route directed me to cross a stream before turning west. I couldn't get through the scrubs and woods, and across the stream here, so I had to backtrack to one path north, and then go west again.&lt;/p&gt;
      &lt;p&gt;The route that I was following shows to cross the stream on the north-west corner of the golf course. OpenStreetMap shows a ford here. Due to the rain, the stream had turned into a fast flowing, 8 inches deep, river. I checked around for 15 minutes if there was another route across (there wasn't), or if I could find big enough sticks to build a makeshift bridge (there weren't), but ultimately decided to walk through the stream to the other side. I should have worn my hiking boots instead of hiking shoes, as they were certainly not up to the task. Squelch squelch for a few miles!&lt;/p&gt;
      &lt;p&gt;I then continued along the path through the woods between the sections of the golf course, and across another mini ravine, to end up &lt;em&gt;on&lt;/em&gt; the golf course, where this route joins the London LOOP. I followed the well sign posted route all the way to a view point, after deciding I didn't want to walk along the road with traffic. The route as mapped here isn't that accurate, and following the LOOP is probably recommended. There was some construction near Gilberts Lake due to some invasive species.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Gilberts Lake" src="https://live.staticflickr.com/65535/52628044287_009443beef_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Gilberts Lake&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After the view point I went down a minimally muddy path and ended up at Uxbridge Road, which was a little tricky to cross due to a lot of traffic, and had no official crossing point. From this point, I walked for a while along residential streets with an occasional dedicated footpath, and then a long stretch along Harrow View with loads of new flats and other housing, before weaving through buses to end up at Harrow-on-the-Hill station where my first section ended.&lt;/p&gt;
      &lt;p&gt;From Harrow-on-the-Hill station, my route followed College Road and then Station Road to end up on the bottom of a hill covered with grass. I should have paid a little more attention and gone through the station, and leave it through its southern exit. This would have avoided a slog along some shops. That exit also handily has free public toilets, which I have used on previous occasions, when walking the &lt;a href="https://tube.derickrethans.nl"&gt;Tube&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;The path up the hill is steep, but it has pleasant views at the top &amp;#xAD;&amp;#x2014; even on a dreary day as this one was. After following a little muddy path, the route goes straight up the hill to the church, with more great views, and then back down steps to end up at the north end of Church Fields, which I crossed to join the narrow and twisty streets of Harrow. I nearly slid on my bum though due to the mud. If you don't care about the view and don't want to go up all the way to the church, you can walk through the bottom rung of the graveyard instead. Spookier though.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="The View from Harrow on the Hill" src="https://live.staticflickr.com/65535/52628045077_e0bfd886a6_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The View from Harrow on the Hill&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After leaving Harrow-on-the-Hill, I proceeded along the busy Northolt Road for a bit, and turned away from it just before South Harrow station. I then walked along a recreation field, but made sure to not go into the park, as I wouldn't have been able to leave it at the other side. Instead I followed the less glamorous public footpath on the other side of the fence.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="View From the Tube Bridge" src="https://live.staticflickr.com/65535/52628045992_321103f1d9_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;View From the Tube Bridge&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I then crossed the railway and across the Harrow sidings, to continue along the fairly busy Mandeville Road to end up, and finish the second section Northolt tube station.&lt;/p&gt;
      &lt;p&gt;The third and final section was pretty dull, and without much green. From Northolt I walked through a residential crescent, and then I turned right at the church on the hill. More residential streets and busy roads followed, with parades of shops. The little bit of green on this section of the walk was when I went up Horsenden Hill, where my route follows the Capital Ring for a short bit. After another parade of shops on Whitten Avenue West, I walked up onto a bridge to cross the tube tracks, where there was quite a fair view.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Sudbury Town Station" src="https://live.staticflickr.com/65535/52629001055_a2085d6c88_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Sudbury Town Station&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After coming down, I spotted the nice looking Sudbury Town tube station, and continued along boring and car heavy Harrow Road. Barham park is on the other side of the road, which would have been nicer I suppose. I finished my walk at Wembley Central tube station.&lt;/p&gt;
      &lt;p&gt;Hopefully for the next walk the weather is better, so I can pick a nicer walk with less street walking and more green.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/bushey-to-wembley.html</guid>
      <pubDate>Tue, 24 Jan 2023 09:15:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Wembley to Uxbridge</title>
      <link>https://derickrethans.nl/wembley-to-uxbridge.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_wembley_to_uxbridge"/&gt;Walking: Wembley to Uxbridge&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, January 17th 2023, 09:42 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I have been walking &lt;a href="https://slowways.org"&gt;SlowWays&lt;/a&gt; routes for about a year now, but I never put their reviews with photos on my own blog. I like owning my own content, so this year I will be publishing them here in a more prosaic form. So here is the story of my first walk in 2023, from Wembley to Uxbridge via Southall and Northolt.&lt;/p&gt;
      &lt;p&gt;Perhaps it wasn't the wisest day to go out for a walk, with drizzle forecasted for most of the day, with only a sliver of hope for a bit of sunshine in the afternoon. But it was the first Saturday of the year and I couldn't let a good opportunity for a walk slip.&lt;/p&gt;
      &lt;p&gt;As there were National Rail strikes going on, I decided to walk something in London, and opted for routes that I had never done, but were close to being verified &amp;#x2014; each SlowWays route needs three positive reviews for them to get verified (or "snailed").&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="The Grand Union Canal at Alperton" src="https://live.staticflickr.com/65535/52629036823_2f732ee998.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Grand Union Canal at Alperton&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;And so I set off from Wembley along some residential roads before going along Ealing Road and past Alperton station towards the canal. The stint along the canal was very short, but I would return to it for a long stretch later on in the walk. Alperton is mostly dominated by low-height industrial areas, with lots of garages and body-work shops. After crossing the A40 at Perivale the walk became a lot nicer with at least some greenery on the left, before crossing Perivale Park with its golf course.&lt;/p&gt;
      &lt;p&gt;At the far left of the park some burly blokes let their aggressive looking dog of the lead, which promptly came sprinting right at me, but also luckily straight past me. I wasn't particularly pleased with this!&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Perivale Park" src="https://live.staticflickr.com/65535/52628803974_b0b4112138_c.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Perivale Park&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Then the route continued following the River Brent, where the path was fairly muddy, and crossing not just one, but two golf courses in the space of a few kilometres. I don't quite understand why there need to be so many, especially with the housing need that we have. I went a little off-course after crossing Greenford Road, but that was my own fault for not following the route precise enough. The last stretch to Southall was along a brick-walled public footpath.&lt;/p&gt;
      &lt;p&gt;This first section from Wembley to Southall was quite a nice walk, with some minor nits such as the Alperton industriousness, and that bloody dog!&lt;/p&gt;
      &lt;p&gt;I continued on this wet and drizzly winter morning to Northolt, continuing along it's busy "The Broadway", towards the Grand Union Canal, which it follows for most of the walk. It also shares a short section here with the &lt;a href="https://derickrethans.nl/hillingdon-trail.html"&gt;Hillingdon Trail&lt;/a&gt;, which I previously walked. I would see more of that in the third section (Northolt to Uxbridge).&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="The Grand Union Canal" src="https://live.staticflickr.com/65535/52628993020_7dbab49a19_c.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Grand Union Canal&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;It's pleasant along the canal, with plenty of wild life and boaters to keep your attention, although it can get a little monotonous at times. At Northolt I crossed a bridge over the canal, and nearly fell on my bum as the tarmac was suddenly very slippery. Disaster averted, I then climbed up the hill into Belvue Park towards St. Mary's church and the gardens of the former Northolt Manor. The SlowWays route tried to make me go through a field, with a ditch, which was decidedly not possible as there was nearly a foot of water. There was however a nice path along the Northern edge which I followed to avoid having to go for a swim. After leaving the park, it was a short stretch along a road with a few shops and a lovely clock tower (with the wrong time) to Northolt underground station where this second section finished.&lt;/p&gt;
      &lt;p&gt;After leaving Northolt station with its clock tower and shops, the route starts off through Islip Manor Park. After a short stretch along residential roads, I crosses the A40 with a footbridge, and then it was mapped along a foot path straight through to the A4180. This path wasn't passable due to large amounts of water on the path, and my boots weren't high enough. Instead, I followed Compton Crescent and Vanbrought Crescent to by pass the impassable section.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Muddy Paths" src="https://live.staticflickr.com/65535/52628993915_0206a7c32b.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Muddy Paths&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On the other side of the fairly busy West End Road, the route continues first over a tarmac path, then a gravel path, and finally a dirt path through the woods, towards the Yeading Brook Meadows, where the paths were decidedly muddy, but still passable. It was here where the route also started (mostly) following the Hillingdon Trail again, through Ten Acre Wood, on top of banks along Yeading Brook, and then along the edge of the field. I had to make a minor detour here as the path was temporarily closed due to a heavy dead branch in a tree.&lt;/p&gt;
      &lt;p&gt;The next section was narrow, and also still muddy, but it wasn't a disaster. After climbing along a too narrow kissing gate, I did have to jump over a little stream though (and I didn't land on my behind).&lt;/p&gt;
      &lt;p&gt;The final section of the route then proceeds along residential roads. It is mapped to cut off a corner near Park Road/St Andrews Road, and although the path is there, I didn't spot it, and instead walked around the construction area. It's not enough of a bother to redo the SlowWays route as mapped, but I have updated &lt;a href="https://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt; to be more accurate here. I was pleased to see that much of the High Street is now pedestrianised. The route finished at Uxbridge station, which has a lovely interior.&lt;/p&gt;
      &lt;p&gt;And that concludes the first walk of the year!&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Uxbridge Tube Station" src="https://live.staticflickr.com/65535/52628561161_fc4fb5c030_c.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Uxbridge Tube Station&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/wembley-to-uxbridge.html</guid>
      <pubDate>Tue, 17 Jan 2023 09:42:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: December 2022</title>
      <link>https://derickrethans.nl/xdebug-update-december-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_december_2022"/&gt;Xdebug Update: December 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, January 10th 2023, 09:06 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 45% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend 25 hours on Xdebug, with 21 hours funded. Sponsorships are continuing to decline, which makes it harder for me to dedicate time for maintenance and development.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_2"/&gt;Xdebug 3.2&lt;/h2&gt;
        &lt;p&gt;Xdebug 3.2.0 got released at the start of December, to coincide with the release of PHP 8.2 which it supports, after fixing a last crash with code coverage. Since then a few bugs were reported, which I have started to triage. A particularly complicated one seems to revolve on Windows with PHP loaded in Apache, where suddenly all modes are turned on without them having been activated through the xdebug.mode setting. This is a complicated issue that I hope to figure out and fix during January, resulting in the first patch release later this month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="plans_for_the_year"/&gt;Plans for the Year&lt;/h2&gt;
        &lt;p&gt;Beyond that, I have spend some time away from the computer in the Dutch country side to recharge my battery. I hope to focus on redoing the profiler this year, as well as getting the "recorder" feature to a releasable state.&lt;/p&gt;
        &lt;p&gt;Smaller feature wise, I hope to implement file/path mappings on the Xdebug side to aide the debugging of generated files containing PHP code.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published two new videos:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=TNOGhUgY6Sc"&gt;Xdebug 3.2: Return Value Debugging with PhpStorm&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=FMysmRePbb8"&gt;Xdebug 3: Skipping Files when Debugging&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I have continued writing scripts for videos about Xdebug 3.2's features, and am also intending to make a video about "Running Xdebug in Production", as well as one on using the updated "xdebug.client_discovery_header" feature (from Xdebug 3.1).&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In December, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-december-2022.html</guid>
      <pubDate>Tue, 10 Jan 2023 09:06:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: November 2022</title>
      <link>https://derickrethans.nl/xdebug-update-november-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_november_2022"/&gt;Xdebug Update: November 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, December 6th 2022, 09:06 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 45% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In the last month, I spend 30 hours on Xdebug, with 24 hours funded. Sponsorships are declining, which makes it harder for me to dedicate time for maintenance and development.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_2"/&gt;Xdebug 3.2&lt;/h2&gt;
        &lt;p&gt;I spend most of November fixing outstanding bugs for Xdebug 3.2, so that it is ready to be released when PHP 8.2.0 comes out at the start of December.&lt;/p&gt;
        &lt;p&gt;I also a fair amount of time triaging a crash bug with a segfault when code coverage in use, which is likely related to generators, but I haven't managed to fully check out yet. I did also find a use-after-free error that I have now fixed.&lt;/p&gt;
        &lt;p&gt;As part of this, I have released Xdebug 3.1.6 to address a compressed file writing bug on Windows, and Xdebug 3.2.0RC2 so that you are able to test Xdebug 3.2 with PHP 8.2 with all the outstanding bugs addressed.&lt;/p&gt;
        &lt;p&gt;Once Xdebug 3.2 gets released next week, support for PHP 7 and Xdebug 3.1 (and lower) will no longer be available. This of course does not mean that older versions of Xdebug are no longer available for download to use with legacy PHP versions.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Previously Xdebug Cloud was only supported by PhpStorm, but the PHP Debug Adaptor for Visual Studio Code now also supports it.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one new videos:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://youtu.be/N-Hw12bBGDE"&gt;Xdebug 3: xdebug_connect_to_client()&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I have continued writing scripts for videos about Xdebug 3.2's features, and am also intending to make a video about "Running Xdebug in Production".&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In November, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-november-2022.html</guid>
      <pubDate>Tue, 06 Dec 2022 09:06:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: August, September, and October 2022</title>
      <link>https://derickrethans.nl/xdebug-update-october-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_august_september_and_october_2022"/&gt;Xdebug Update: August, September, and October 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, November 8th 2022, 09:06 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 45% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;I did not find the time to write this report in the last two months, sorry for that. So today I present you with a report for the last quarter.&lt;/p&gt;
      &lt;p&gt;In the last three months, I spend 63 hours on Xdebug, with 77 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_2"/&gt;Xdebug 3.2&lt;/h2&gt;
        &lt;p&gt;In the preceding months I worked on a few more specific PHP 8.2 issues, and generic bugs.&lt;/p&gt;
        &lt;p&gt;PHP 8.2 now presents &lt;code&gt;__debugInfo()&lt;/code&gt; for closures, which means that Xdebug now no longer needs to emulate those itself. This does result in minor changes in the output that IDEs present for closures, but not with less information.&lt;/p&gt;
        &lt;p&gt;I also fixed nearly a dozen bugs. Some were related to the new return value debugging feature, or specific PHP 8.2 support.&lt;/p&gt;
        &lt;p&gt;A few more bugs are outstanding, and I intend to release Xdebug 3.2 when PHP 8.2.0 comes out at the end of November. I will also create one more Xdebug 3.1 release (3.1.6), to address a specific crash bug. Xdebug 3.2 will only support PHP 8.0 and later.&lt;/p&gt;
        &lt;p&gt;PhpStorm's latest &lt;a href="https://blog.jetbrains.com/phpstorm/2022/11/phpstorm-2022-3-early-access-5/"&gt;2022.3 EAP #5&lt;/a&gt; release now has support for Xdebug 3.2's return value debugging, as well as a bunch of other new features to make it easier to set up Xdebug.&lt;/p&gt;
        &lt;p&gt;I have also decided to no longer actively test on 32-bit platforms on CI, which also means I will no longer be providing 32-bit DLLs of Xdebug on Windows.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Previously Xdebug Cloud was only supported by PhpStorm, but the PHP Debug Adaptor for Visual Studio Code now also supports it.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published two new videos:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=6CIOxguEQao"&gt;Xdebug 3: Debugging with VIM and Vdebug&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=jEjo6wyTggA"&gt;Xdebug 3: Start Upon an Error&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I have started writing scripts for videos about Xdebug 3.2's features, and am also intending to make videos about "Running Xdebug in Production" and "Debugging Worker Tasks with xdebug_connect_to_client()".&lt;/p&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In August, September, and October, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-october-2022.html</guid>
      <pubDate>Tue, 08 Nov 2022 09:06:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: July 2022</title>
      <link>https://derickrethans.nl/xdebug-update-july-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_july_2022"/&gt;Xdebug Update: July 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, August 9th 2022, 09:06 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In July, I spend 18 hours on Xdebug, with 32 hours funded. I have been on holiday, so was not be able to dedicate as much time as I wanted to.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_2"/&gt;Xdebug 3.2&lt;/h2&gt;
        &lt;p&gt;Most of the work that I did on Xdebug was related to release the first two alpha releases of Xdebug 3.2, which add support for PHP 8.2, and drops support for PHP 7.2, PHP 7.3, and PHP 7.4. I do not enjoy dropping support for older PHP versions, but the additional time it costs to maintain older versions, and have their configurations run on CI, is not really worth my time. Of course, users of PHP 7.2 through PHP 7.4 can continue to use Xdebug 3.1. The guidelines of which PHP versions Xdebug supports is outlined in the &lt;a href="https://xdebug.org/docs/compat"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;Now that PHP 8.2 itself has approached beta state, it was time to release the first alphas of Xdebug 3.2 as well. In the near future, when PHP 8.2 comes into their Release Candidates cycle, I will release beta versions of Xdebug 3.2 as well, with a stable release when PHP 8.2.0 comes out.&lt;/p&gt;
        &lt;p&gt;These alphas and betas are an excellent opportunity to try out Xdebug 3.2, as well as PHP 8.2, to see whether your projects support the latest PHP version, and how Xdebug 3.2 interacts with that.&lt;/p&gt;
        &lt;p&gt;The main new features in Xdebug 3.2 can now also be tested. And these include:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;Support for PHP 8.2.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;The step debugger now introduces an extra step when returning from a function, so that you can inspect the return value. This is supported in the &lt;a href="https://github.com/xdebug/vscode-php-debug"&gt;PHP Debug Adapter for Visual Studio Code&lt;/a&gt;, but not yet in PhpStorm, although there is a &lt;a href="https://youtrack.jetbrains.com/issue/WI-66918/Support-Return-Value-Debugging-in-XDebug"&gt;ticket&lt;/a&gt;.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;You can now configure a list of headers to scan for through the &lt;a href="https://xdebug.org/docs/all_settings#client_discovery_header"&gt;xdebug.client_discovery_header&lt;/a&gt; setting, instead of only being able to set one. The documentation for this is yet to follow.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;The step debugger now supports the pseudo hosts &lt;code&gt;xdebug://gateway&lt;/code&gt; and &lt;code&gt;xdebug://nameserver&lt;/code&gt; as values to the &lt;a href="https://xdebug.org/docs/all_settings#client_host"&gt;xdebug.client_host&lt;/a&gt; setting. These pseudo-hosts instruct Xdebug to try to make a debugging connection to the default gateway and name server (as configured on Linux through &lt;code&gt;/etc/resolv.conf&lt;/code&gt; and friends) respectively. The documentation for this is yet to follow too.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I am intending to create a video for each of these new features for my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="course"/&gt;Course&lt;/h2&gt;
        &lt;p&gt;The first lesson is now nearly fully edited, with just the "tech talk" section to finish. Beyond that, I will need to work on create a web site to publish this course too, so that you can take it. The course will consist of many chapters, with some of them being free.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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 &amp;#xA3;49/month.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published no new videos this month, but you can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In July, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-july-2022.html</guid>
      <pubDate>Tue, 09 Aug 2022 08:06:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: June 2022</title>
      <link>https://derickrethans.nl/xdebug-update-june-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_june_2022"/&gt;Xdebug Update: June 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, July 12th 2022, 09:11 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In June, I spend 25 hours on Xdebug, with 25 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="development"/&gt;Development&lt;/h2&gt;
        &lt;p&gt;Some of the time this month I spend with fixed a few old bugs, and some new ones with the new return value debugging that I spoke about last month.&lt;/p&gt;
        &lt;p&gt;This feature allows you to step into the "return value from function" phase, where PHP returns a value to the caller function. In this step, there will only be one variable available, which is the return value of that function.&lt;/p&gt;
        &lt;p&gt;This is now supported with version 1.27 of the PHP Debug Adapter for Visual Studio Code, if you'd like to try it out.&lt;/p&gt;
        &lt;p&gt;In this GIF you can see how this is useful with fluent interfaces:&lt;/p&gt;
        &lt;img src="derickrethans.nl/images/content/return-value-fluent.gif"/&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="php_version_support"/&gt;PHP Version Support&lt;/h2&gt;
        &lt;p&gt;The other half of my time I spend with adding support for PHP 8.2 for Xdebug 3.2, and dropping support for PHP 7.3 from this same branch. With that, I've also updated the &lt;a href="https://xdebug.org/docs/compat"&gt;version compatibility matrix&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;I have also started on removing PHP 7.4 support for Xdebug 3.2 as well, so that it will only support PHP 8.0 and later. Users of older PHP versions will still be able to use Xdebug 3.1.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="course"/&gt;Course&lt;/h2&gt;
        &lt;p&gt;I have spend no more time writing actual content for the course, but I have been collecting subjects to cover. If you have any suggestions of topics that the course should cover, please get in touch.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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 &amp;#xA3;49/month.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published no new videos this month, but you can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In June, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page, a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;, as well as an &lt;a href="https://opencollective.com/xdebug"&gt;OpenCollective&lt;/a&gt; organisation.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-june-2022.html</guid>
      <pubDate>Tue, 12 Jul 2022 08:11:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 103: Disjunctive Normal Form (DNF) Types</title>
      <link>https://derickrethans.nl/phpinternalsnews-103.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_103_disjunctive_normal_form_dnf_types"/&gt;PHP Internals News: Episode 103: Disjunctive Normal Form (DNF) Types&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Friday, June 24th 2022, 09:07 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I talk with George Peter Banyard (&lt;a href="https://gpb.moe"&gt;Website&lt;/a&gt;, &lt;a href="https://twitter.com/Girgias"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/Girgias"&gt;GitHub&lt;/a&gt;, &lt;a href="https://gitlab.com/Girgias"&gt;GitLab&lt;/a&gt;) about the "Disjunctive Normal Form Types" RFC that he has proposed with Larry Garfield.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-102.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is episode 103. Today I'm talking with George Peter Banyard again, this time about a disjunctive normal form types RFC, or DNF, for short, which he's proposing together with Larry Garfield. George Peter, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hello, my name is George Peter Banyard, I work on PHP paid part time, by the PHP foundation.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Just like last time, we are still got colleagues.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, we are indeed still call it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What is this RFC about? What is it trying to solve?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The problems of this RFC is to be able to mix intersection and union types together. Last year, when intersection types were added to PHP, they were explicitly disallowed to be used with Union types. Because: a) mental framework, b) implementation complexity, because intersection types were already complicated on their own, to try to get them to work with Union types was kind of a big step. So it was done in chunks. And this is the second part of the chunk, being able to use it with Union types in a specific way.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What is the specific way?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  1:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The specific way is where the disjoint normal form thing comes into play. So the joint normal form just means it's a normalized form of the type, where it's unions of intersections. The reason for that it helps the engine be able to like handle all of the various parts it needs to do, because at one point, it would need to normalize the type anyway. And we currently is just forced on to the developer because it makes the implementation easier. And probably also the source code, it's easier to read.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When you say, forcing it up on a developer to check out you basically mean that PHP won't try to normalize any types, but instead throws a compilation error?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  2:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. It's, it's the job of the developer to do the normalization step. The normalization step is pretty easy, because I don't expect people to do too many stuff as intersection types. But as can always be done as a future scope of like adding a normalization step, then you get into the issues of like, maybe not having deterministic code, because normalization steps can take very, very long, and you can't necessarily prove that it will terminate, which is not a great situation to be in. Imagine just having PHP not running at all, because it's stuck in an infinite loop trying to normalize the format. It's just like, oh, I can't compile&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would a potential type alias kind of syntax help with that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  2:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Maybe, I'm not really sure. Actually reading like research about it from computer scientists, in functional programming languages, which is everything is compiled on my head. And they have the whole thing was like, well, they need to type type normalize, and especially with type aliases, they haven't really figured out a way yet. So I'm not sure how we are going to figure out a way if experts and PhD students and researchers haven't really figured out a way.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And is the reason for that mostly, because PHP, resolves types while it is running code sometimes because it has to overload classes, and then it might find out it is an inherited class, for example?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  3:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, I think it's like this weird thing where might maybe PHP has like kind of an advantage, because it doesn't need to, like resolve all of the types at once. And if you have a type alias, it's just oh, if it's used, and you just need to resolve it, and then try to figure it out. There's also the added complexity of like, variance checks, because most functional programming languages, they have variance to some degree, but they don't have the whole inheritance of like typical OOP languages have. It's kind of a very strange field, the fact that yeah, PHP is just like, well, we kind of do stuff at runtime, and you don't necessarily need everything. And it just works is like, well, we'll do. That's mainly the reason why the dev needs to do the normalization step, the form is done. It's also I think, the most easiest to understand, it's just like, Oh, you have this and this, or this group, or stuff, or this group of stuff, or this thing, simple type. The other form would be another normalized form would be conjunctive normal form, which is a list of ANDs of ORs to just have this thing, or X, like (A or B or C) and X and (Y or Z), which I think is harder to understand.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What is the exact syntax then?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  4:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So the exact syntax is, if you want to have an intersection type was in a union type, you need to like bracket it by parentheses. And then you have like the normal pipe union operator and you can mix it with single types, you can mix it with true, you can mix it with false, which are literal types, which now exist, or just normal, bool types.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The parenthesis is actually required. You don't rely on operator precedence to make things work?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  4:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes. Relying on operator precedence is terrible.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yep, I agree.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  4:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'd say Oh, yeah, but I think I've heard this argument on the list like a couple of times, it's just, oh, yeah, but maths, like, has like, and as priority over like, or, I mean, I did three years of a maths degree and not gonna lie. Maths notation is terrible for most of us. People don't even agree on terminology. I'm just gonna say, let's, let's just do better.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I agree. I mean, most coding standards for any sort of variable for like conditions, will already require parenthesis around multiple complex clauses anyway, right? I mean, it's a sensible thing to do, just for readability, in my opinion. So the RFC also talks about a few syntax that you aren't allowed to do, and that you have to normalize or deconstruct yourself, what kinds of things are these?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  5:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;if you would want to have a type which has an intersection of a class A with at least one other class, so let's say X or Y, but you can always convert it into DNF form, how this type would be, it would be (A and X) or (A and Y). This seems to be the more unusual case, I would imagine. One of the motivating cases of DNF types is to do something like Array or (Traversable and Countable). I don't really see mixing and matching various different object interfaces in differencing, the most useful user land cases to be able to do Array or (Traversable and Countable) so that you can use just count or seeing something as an array, or you have like Traversable and Countable and ArrayAccess. And it's just like, Oh, here's an object, which kind of behaves like an array.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think there's currently another RFC just being proposed, that extends iterator_to_array to multiple types as well to accept more things. So that sort of fits into this category of things to do with iterables and traversals then I suppose.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  6:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;yeah&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm hoping to talk to the author of that RFC as well. At the moment where two and a half weeks or so before a feature freeze, you now see a whole flurry of RFCs while it was a bit quiet in the last few months. So because you're adding to the type system, that's also usually has consequences for variance rules, or rather, how inheriting works with return types and argument types, as well as property types. What do DNF types mean for these variance checks?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  7:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The variance is checks, kind of follow the similar rules as before. So property types are easy. They are invariant, so you can't change them. You can reorder types, like was in your union if you want to. But that was already the case with Union types previously, because PHP will just check that, well, the types match. So contravariant, you can always restrict types, meaning you can either add intersections, or you can remove unions, broadly speaking. What you could do, for example, if you have like A or B or C, you could do A and X as a subtype, because you're restricting A to be of an extra, like an extra interface.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So then you will have (A and X) or B or C.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  8:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes. So that's one restriction. You can add how many interfaces you want and do an intersection type, you can add them on every type you can. On the other side, you can just add like unions. So if for contravariance, or like an an argument type, it's like, well, I just want to return something new, well, then you can add unions, but you can't add an intersection to a type, you can only widen types of arguments. So if your type is A or B or C, you can't do A and B, and you can't do (A and X) or B or C, because you're restricting the type. If your type would be (A and X) or (B and Y) or (C and Z), then you could lift the restriction to A or B or (C and Z) because you loosening the requirements on on the type that you're accepting.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;To summarize this: argument types, you can always widen; return types you can only restrict, and, and property types you can't change at all. I specifically wanted to summarize that because I always find contravariance and covariance. These names confuse me. So that's why I prefer to talk about widening types and restricting types instead. Because there are so close together for me. We spoke a little bit about redundant types. What is this new functionality do if you specify redundant types?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  9:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Redundant types how they currently work in PHP are done at compile time. And they do exact class matches or constant class aliasing matches.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That will need an explanation.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  9:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Class names and interface names in PHP are case insensitive. So you can write a lower-case a or upper-case A and it means the same class. If you provide let's say lower-case a or upper-case A, the engine realize this, this is the same class, so we'll serve it on the type error. So PHP has use statements, or use as. So these are compile time aliases. If you define a class A, and then you say use A as B. So B is a compile time alias of A. And then you do a type which has A or B, PHP already knows these things refer to the same class. So it will raise a compile time error.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;These use aliases are per file only, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, that's usually to do with if you import traits or like a namespaces. And you get conflicting class names. That's how you handle it about. PHP has also this feature, which you can do this at runtime, using the function called class_alias. Now, obviously, compile time checks are done at compile time. So it doesn't know at runtime that you aliasing these classes or using this name as an alias. So then PHP won't complain.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But will don't complain during runtime.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You really just wanted to shoot yourself in the foot, we'll let you do this.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  11:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yet, during this at runtime, just as like a whole layer of time, because it's not it's not really useful. Basically, what it means that PHP won't guarantee you the type is minimal. I.e. you might have redundant types, but it will just try to tell you, it's like oh, the- these are exactly the same types. And I know these are the same types, you probably do get mistake. So if it can determine this at compile time, it will tell you.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The variance is still checked when you're passing in things.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  11:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, so variance is checked on inheritance. When the class is inherited and compiled, because it needs to load the parent class, it will then check that it's built properly, and otherwise it will raise an error, that's fine. But just checking that the types is minimal is not possible. A) because inheritance, you don't know how it works, because it will only do the checks on basically on the name of the strings, it will do like compare strings of class names. And if it doesn't know the class name, or if it or if it needs to do some inheritance, it just won't do an instance of check. They just ignore that. It's just like, well, maybe it is maybe it's not I don't know. And that's fine.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Of course, if you pass in a wrong type at runtime, then it will still get rejected during runtime anyway.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  12:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, that hasn't changed.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The only thing that you might end up in a situation where you don't get warned during compile time whether type is redundant.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  12:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes. So that's the behaviour we currently are the behaviour is added. So, it will check that two intersection types within the union are identical using the same class stuff. So for example, if you have class A, and you say use a as B, and then you have a type which is (A and X) or (B and X), it will tell you: Okay, these classes are the same. The check it adds now also it will check that you don't have a more restrictive type with a wider type. So if your type is T or (T and X), because T is wider than T and X, it will error at compile time, it'll tell you well, T is less restrictive than T and X. So the T and X type is redundant.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, so nothing strange. Basically, what you expect to happen will happen. And PHP does its best telling you at compile time whether you've done something wrong or not.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  13:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think we've spoken mostly about the functionality itself and types. I'm a little bit interested in whether you encountered some interesting things while implementing this feature.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  13:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This feature basically, was a bit in limbo for the implementation, because I was waiting on a change to make Iterable, a compile time alias of Array or Traversable, which shouldn't affect userland. Because previously, all of the checks needed to cater to if you get Iterable, then you need to check for the variance. Has it Array , has it a Traversable type, does this accept? Is it why the is it more restrictive, it's identical. It's just this weird edge case, which makes the variance code harder. Moving this to a compile time alias, where now it just uses the standard, a standard union type in some sense, just makes a lot of the variance checks already streamlined and simpler. And because this is simpler, in some sense, was DNF types. When you hit the intersection, you need to recurse one step to check the variance. This helps. This is also kind of why DNF types are enforced like as like the structure on the dev because otherwise, you could potentially get into the whole like, oh, infinite recursion if you do like very nested types, because it's just like, oh, you hit one nested type and so, oh okay, now I'm again in unnecessary time and then you recurse again and then you recurse again, and so that's all you get into the thing: Oh you need to normalize the type. The variance check is: Can you see if it's a union type is the first type a sub list So a list of intersection types, okay, is it balanced? And then just recall the same function in some sense, like, check the types for variance, is this correct? Okay, move to the next type back into the Union and everything. So the implementation is conceptually simple, because all of the implementation details already exist. And all the everything hard has already been done. Now, it's just like, in some sense, it was extracting it into its own function, and then like recurse into it, and not forget to update opcache properly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You mentioned that in order to make the DNF types work, you were waiting on this Array or Iterable or Traversable kind of type. Is this also type people can use it and userland? Or is it internal only?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  15:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It is the standard Iterable type that you can already use. So currently, PHP considered Iterable, a full type in some sense. And what the this implementation change basically makes it Iterable into ... compile time alias of Array or Traversable. Iterable exists since, PHP, 7.1, I think. Can still use it, reflection should still be fine if you use it as a single type.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So to change there is more, instead of: if you encounter Iterable, we check for both Array and Traversable. Then, instead of making the check every time you look at Iterable is already part of the type system, so you don't have to make the check every time.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  16:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly, you basically move when it's being transformed in some sense. Now it has some repercussion on other parts, which needed to be taken care of, which is probably why it was in limbo for 10 months. I had already done the implementation of DNF types, basically, working on my local copy of that branch. It's just like: Okay, this got merged, nice, I can now open the PR onto PHP SRC. So I didn't wait for it to land until start working on it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Things like that also often affect reflection, because you're adding more complex types to the type system. So what kind of changes does that make to PHP's reflection system? And does this end up breaking backwards compatibility?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  17:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So in theory, no, it doesn't. How the reflection API works around the type system is that most method calls will turn a reflection type interface, ReflectionNameType, ReflectionUnionType, and ReflectionIntersectionType, are all instances of a ReflectionType. And methods if you would call on the list. So on a union type, the type it would return if you get like getTypes is a ReflectionType. The type system and how the reflection idea was designed, there is no BC break. How the standard was working, it's like, Oh, if you had like a union type, or an intersection type, if you call the getList or getListOfTypes, or getTypes, I don't remember exactly what the method name is actually called, you will always get an array of reflection name types, because you can only have like one level of list in some sense. However, now, if your top type is a union type, then if you get getTypes, you might get an array of ReflectionNameTypes with ReflectionIntersectionTypes. So that's the case that you now need to cater to. So if you get another ReflectionIntersectionType in between. There, you could only have ReflectionNameTypes, there was no nesting, whereas now if you have a union type, one of the types that you get back from the getTypes method in the array will be a ReflectionIntersectionType. Technically, all of the types of the part of the reflection type, so it's an array of reflection types that you get. How it worked before is that you didn't need to care about this distinction between: Oh, it returns a ReflectionType and a ReflectionNameType because well, it only return a ReflectionNameType. But now this is not the case. So you now need to cater to that that oh, you might have nesting. Which kind of boils down to like if in the future, we decide to like have oh, you can nest union types in an intersection type, then the getTypes method might return a union type with other name types.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You just need to make sure that you check for more than just one thing that it previously would have done. You can't assume not everything is a ReflectionType any more. It could also be ReflecionIntersectionType.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  19:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, exactly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think that sort of what's in the RFC, is there any future scope?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  19:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I mean, the future scope is type alias. As usual. Everything I feel when you talk about the type system, it's like type aliases. At one point when your types gets very complicated. It would be nice to just be able to refer this as a as a named type in some sense, instead of needing to retype every time the whole union slash intersection of it. Hopefully we can get this running for 8.3. We are starting to get kind of complicated types. It would be nice being able to have this feature. The other obvious future scope in some sense, who knows if it's actually desirable is to allow either having conjunctive normal form so you can have like a list of ANDs or ORs&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You call these conjunctive normal forms?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  20:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes. Or just a type, which is not normalized. Not sure if it's really desirable to have this feature, because then you get into the whole thing of, if PHP doesn't, either PHP doesn't know how to like normalize it, or it's not in the best form, and then you get into like, very long compilation units or just checking. It's like, okay, does it respect the type? Does it do all of the instance of checks? And I'm not sure if it's super desirable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So it could be considered future scope. But from what I gather from you, you don't actually know what it is actually a desirable thing to add to the language?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  20:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, George, thank you for taking the time this morning to talk about this new DNF types RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  20:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for having me. As always.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/dnf_types"&gt;Disjunctive Normal Form Types&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-103.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-103.html</guid>
      <pubDate>Fri, 24 Jun 2022 08:07:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: May 2022</title>
      <link>https://derickrethans.nl/xdebug-update-may-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_may_2022"/&gt;Xdebug Update: May 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, June 7th 2022, 09:13 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In May, I spend 25 hours on Xdebug, with 27 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="development"/&gt;Development&lt;/h2&gt;
        &lt;p&gt;I continued my exploration of different set-ups that developers use, and have now merged the branch that adds support for the "pseudo-hosts" &lt;code&gt;xdebug://gateway&lt;/code&gt; and &lt;code&gt;xdebug://nameserver&lt;/code&gt;, which can be used with the &lt;code&gt;xdebug.client_host&lt;/code&gt; setting instead of, and in addition to the Docker specific &lt;code&gt;host.docker.internal&lt;/code&gt;. This pseudo-host automatically evaluates to the network gateway address, or name server as defined in &lt;code&gt;/etc/resolv.conf&lt;/code&gt;, in the container, which will then allow Xdebug to connect to an IDE on the host machine.&lt;/p&gt;
        &lt;p&gt;I have not figured out how to do it will all different set-ups, so if you have extra information, or if I am still missing set-ups, feel free to comment on the &lt;a href="https://docs.google.com/document/d/1W-NzNtExf5C4eOu3rRQm1WlWnbW44u3ANDDA49d3FD4/edit?usp=sharing"&gt;Google Doc&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;In the more complicated set-ups, it would likely be easier to use &lt;a href="https://xdebug.cloud"&gt;Xdebug Cloud&lt;/a&gt; as it has none of these networking complications.&lt;/p&gt;
        &lt;p&gt;The other big feature that I have worked on is the introduction of the capture of return values while debugging. This feature allows you to step into the "return value from function" phase, where PHP returns a value to the caller function. In this step, there will only be one variable available, which is the return value of that function.&lt;/p&gt;
        &lt;p&gt;Right now IDEs will have to opt into this new feature, with PhpStorm and the VS Code Plug-in teams confirming that they will make changes for this.&lt;/p&gt;
        &lt;p&gt;In this GIF you can see how this is useful with fluent interfaces:&lt;/p&gt;
        &lt;img src="derickrethans.nl/images/content/return-value-fluent.gif"/&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="course"/&gt;Course&lt;/h2&gt;
        &lt;p&gt;I have now recorded the first lesson of the course, and I am editing it with the plan to release this in the next few weeks. It will take a little time, as I need to get into the flow of editing and producing them; and of course, a new web site needs to be constructed as well. Stay tuned!&lt;/p&gt;
        &lt;p&gt;For further lessons I have started to draft outlines, and they are in different states of completion.&lt;/p&gt;
        &lt;p&gt;If you want to make sure that the course covers specific tasks that you find hard to do, or what you would like explained, please drop me an email, or leave a comment.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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 &amp;#xA3;49/month.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one new video this month:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=oeHs17vaELU"&gt;Xdebug 3: Debugging with Atom&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;You can find all previous videos on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In May, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-may-2022.html</guid>
      <pubDate>Tue, 07 Jun 2022 08:13:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 102: Add True Type</title>
      <link>https://derickrethans.nl/phpinternalsnews-102.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_102_add_true_type"/&gt;PHP Internals News: Episode 102: Add True Type&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, June 2nd 2022, 09:06 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I talk with George Peter Banyard (&lt;a href="https://gpb.moe"&gt;Website&lt;/a&gt;, &lt;a href="https://twitter.com/Girgias"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/Girgias"&gt;GitHub&lt;/a&gt;, &lt;a href="https://gitlab.com/Girgias"&gt;GitLab&lt;/a&gt;) about the "Add True Type" RFC that he has proposed.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-102.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi I'm Derick. Welcome to PHP internals news, the podcast dedicated to explaining the latest developments in the PHP language. This is episode 102. Today I'm talking with George Peter Banyard about the Add True Type RFC that he's proposing. Hello George Peter, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hello, my name is George Peter Banyard, I work part time for the PHP Foundation. And I work on the documentation.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Very well. We're co workers really aren't we?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, indeed, we all co workers.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Excellent. We spoke in the past about related RFCs. I remember, which one was that again?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Making null and false stand alone types&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's the one I was thinking of him. But what is this RFC about?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So this RFC is about adding true as a single type. So we have false, which is one part of the Boolean type, but we don't have true. Now the reasons for that are a bit like historical in some sense, although it's only from PHP 8.0. So talking about something historical. When it's only a year ago, it's a bit weird. The main reason was that like PHP has many internal functions, which return false on failure. So that was a reason to include it in the Union types RFC, so that we could probably document these types because I know it would be like, string and Boolean when it could only return false and never true. So which is a bit pointless and misleading, so that was the point of adding false. And this statement didn't apply to true for the most part. With PHP 8, we did a lot of warning to value error promotions, or type error promotions, and a lot of cases where a lot of functions which used to return false, stopped returning false, and they would throw an exception instead. These functions now always return true, but we can't type them as true because we don't have it, and have so they are typed as bool, which is kind of also misleading in the same sense, with the union type is like, well, it only returns false. So no point using the boolean, but these functions always return true. But if you look at the type signature, you can see like, well, I need to cater to the case where the returns true and when returns false.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Do they return true or throw an exception?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  2:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, so they either return true, or they either throw an exception. If you would design these functions from scratch, you would make them void, but legacy... and we did, I know it was like PHP 8.0, we did change a couple of functions from true to void. But then you get into these weird shenanigans where like, if you use the return value of the function in a in an if statement, null gets because in PHP, any function does return a value, even a void function, which returns null. Null gets coerced to false. So you now get like, basically a BC break, which you can't really? Yeah, we did a bit and then probably we sort of, it's probably a bad idea. That's also the point of like, making choices, things that are static analysers can be like, more informants being like, Okay, your if statement is kind of pointless here.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, you don't want to end up breaking BC. Now, we already had false and bool, you're adding true to this. How does that work with Union types? Can you make a union type of true or false?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  3:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No. So there are two reasons mainly. A. true and false is the same as like boolean, which is like just use Boolean in this case. But you can say, well, it's more specific, so just allow it. So that's would be reasonable. But the problem is, false has different semantics than boolean. False does not coerce values. So it only accepts false as a literal value. Whereas boolean, if you're not in strict type, which is a lot of code, it will cause values like zero to false one, or any other integers to true. It will coerce every other integer to true, like the true type follows the behaviour of false of being a value type. So it only accepts true, you would get into this weird distinction of does true or false, mean exactly true or false? Or do you get the same behaviour as using the boolean type?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So I would say that true or false would than be more restrictive than bool.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  4:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly, which is a bit of a problem, because PHP internally has true and false and separate types, which also makes the implementation of this RFC extremely easy, because PHP already makes the distinction of them. But at the same time, the boolean type is just a union of the bitmask of true and false. You can't really distinguish between the types, true or false, or the boolean type within the type system. Currently just does it by checking if it only has one then it can do like two checks. Specifically, you would need to add like an extra flag. I mean, it's doable, but it's just like, Well, who knows which semantics we want? Therefore, just leave it for future discussion because I'm not very keen on it to be fair.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;True or false are really only useful for return values and not so much for arguments types, because if you have an argument that that always must be true, then it's kind of pointless to have of course.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  5:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Same as like it was with the null type RFC. Although there might be one case where PHP internal functions might change the value to true for an argument, I can maybe two types, would be like with the define function, this thing being like case insensitive or case sensitive, I don't remember what the parameter actually; could actually either be false or true, because at the moment, I think emits a notice, things do like the this thing is not supported, therefore the values what was ignored. But we could conceivably see that in PHP 9, we would actually implement this as a proper like: Okay, this only accepts true, yes, this argument is pointless, but it's in the middle of the function signature, so you can't really move it. The spl_register_overload function has like as its second argument, the throw on error or not, which since PHP 8 only accepts true, but it's in the middle of the function. The last argument is still very useful. It's prepend, instead of append the autoloader, I think, or might be the other way around, check the docs. Since PHP 8, this only accepts true. So if you pass in false, it will emit a notice and saying you'd like this argument has just been ignored. So whatever. But we can't really remove the argument. Because well, it's, if you use the third argument, as with positional arguments, then you would change like the signature and you would break it. Now, we don't have a way to enforce in PHP to use named arguments, because that would be a solution. It's just like, well, if you want to set this argument, you need to use named arguments, but we can't do that. Otherwise, then creating a new function, which has an alias, which is also kind of terrible. That would be one of the maybe only cases where you would actually get like true as a as an argument&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;is that now currently bool? And there's a specific check for it?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  6:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's currently bool, and if you pass in false enrolment, like a warning, or notice.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How would inheritance work? As return types, you can always make them smaller, right? More restrictive.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  6:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, that's also the thing. But that already exists in some sense a problem of. Like if you go from boolean to false, you're already restricting the type. And that problem existed, even before the restricting, well allowing false as a stand-alone type if you had like, as a union, because you could always say like, I don't know. That problem already existed with Union types. Because you could have something like overturn an array or bool and then you change it to either an array or false. And then if you try to return like zero, then you will get like a coercion problem. So the same problem applies with true, because it only affects return values. And like you control the code within a function compared to like how you pass it, that's less of an issue. It applies also, with argument types where you can go from true to like boolean, or true and like a union type.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So there's nothing surprising here. I see that the RFC also talks a little bit about future scope. Can you tell a bit more about that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  7:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;True and false are part of what are called value types, they are a specific value within the type. One possible future scope would be to expand value types to all possible types. So that you could say, oh, this function returns one, two or three.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would you not rather use an enum for that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  8:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. That's the point I was going to make is that enums serve this purpose, in my opinion. And as a type purist, ideally, I would have preferred that we didn't have to enforce because the code, it kind of goes against the grain in this sense.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We've had it for 25 years, booleans.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  8:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, right. But boolean is its own type, in some sense, which you could say is a special enum. Enums are types. But we have false, and not having true is just so weird to me. It's like, oh, you've got this thing, but you don't have this other thing. And there are loads of cases where functions return true, or due to legacy reasons and to preserve BC, and PHP 8 promoted a bunch of warnings to to error. So now you've got functions which used to return false, don't return false any more. And they only return true. Now, some of the famous examples are probably like array_sort of, like actually, the sorting array functions, return true for basically all of PHP 7. I think there was something changed in PHP 7, probably was the engine or something like that, that they stopped returning false, which is strange. And I've made the discovery somewhat recently, I'm like, this is so pointless, because you see loads of loads of code checking like that the return value of the sort function is correct.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's also that most of the sort functions actually sort by reference instead of returning the sorted array, which I can understand as a performance reason to do but...&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  9:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;it's not very functional. You modify stuff in place and like passing it around. And because yeah, I think the initial thing was that like, well do it would return a false or true because sometimes it could, the sort could fail.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't understand how a sort could failure, but there we go.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  9:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I mean, I suppose if you have like incomparable values within the array like that somewhat logical, I suppose.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Was there anything else in future scope?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  9:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;One of the future scope, I feel was everything type related. It's like type aliases, because when you start making more complicated types, having a way to type alias, it is probably nice. Don't think we'll get this for PHP 8.2. I don't think we any of us had the time to work on it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, we only have a month left anyway.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah. And I mean, I'll probably be back on here. I'm trying to get DNF types working, but...&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Can you explain that these are?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Disjoint normal form types?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That did not help.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But it's the being able to combine union types with intersection types together,&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I can understand that doing that is kind of complicated. You also need to sort of come up with a with a language to define them almost right? I mean, you then get the argument, are you going to require a parenthesis around things?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm requiring parentheses. People have told me the argument of like: Yeah, but in maths like and takes priority, it's just like, have you seen mathematicians, mathematicians don't agree on notation, and it's terrible, or they call stuff and the different they call it something is like, oh, sometimes a ring is commutative, and sometimes it's not. Don't follow mathematicians, don't follow mathematician,&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Type aliases is something that would only apply to single files. See, that's what you're suggesting. And then there's exported type definitions, which I guess could be autoloaded at some point; would be nice to have, I guess.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  11:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think that's the trouble just like defining the semantics. Type aliases within a file are nice, but they're not very useful. Most of the time, you would want to export the type. For example, if you say: Oh, I accept, I don't know, something which looks like an array, which is like an array and like Traversable, and ArrayAccess or something. I'm sure, it's nice to have it in your own file. But like, if you use it around a project, and you need to redefine the type, every single file kind of defeats the purpose.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's kind of tricky to do with type definitions, because you sort of need to make sure that there are available and maybe can be autoloaded, just like classes can be right. And that makes things tricky. Because having a type definition and just three lines in a file, is kind of annoying, but I guess that is sort of necessary to do the kind of thing in a PHP ish way.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  11:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, we talked about it with Ilija because he he was on about it. And I was like: Well, ideally, you would want the separate autoload of types. That's how I initially conceived it, it's like having a different autoloading for types. But then the problem is, is like if anytime you hit a class, like in an argument, if you autoload the type first, it will go through all of the type definitions. And if, okay, at the moment, that wouldn't be there wouldn't be much. But if you go into like importing 30 composer projects, or libraries, which are define their own types, it will go through all of those first, before going to the classes autoloaded, and trying to find it then, which is not ideal. Yeah, it's going to be a tricky problem. It's either you merge these symbols together. But then the class table is not always a class. And sometimes you can't do new type. Like I said, tricky problems.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, that's a tricky problem, but an interesting one.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  12:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So that's future scope then.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  12:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. That is future scope.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Do you have anything else to add?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  12:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Um, no, not really. I think I've said all I have to say it's pretty straightforward. Should be uncontroversial, hopefully.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It currently looks like it's 20 for, and zero again. So I guess it will pass.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  13:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Brilliant.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Who said that, that if your RFC ends up passing unanimously, it is too boring?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  13:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Nikita.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which is not incorrect.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  13:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It is not incorrect. But I mean, at the beginning, because I was like: Well, this is pretty straightforward. So I wrote the RFC, it was tiny. And I put it on to the list and people was like: Yeah, but what's the motivation for? I understand for adding false, because they already exist. But what's the motivation for adding a new type, and I was like, I now need to go back to the drawing board and write more. To be fair, that was a smart, because I then discovered the whole issue about true and false. That false is just a value type and doesn't do coercions. And it's like, okay, how do you handle the semantics and everything?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm glad to hear it. Then all I have to say thank you for taking the time today to talk about this new RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  13:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for having me as usual.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to derick@php internals.news. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/true-type"&gt;Add True Type&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/null-false-standalone-types"&gt;Allow Null and False as Standalone Types&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-102.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-102.html</guid>
      <pubDate>Thu, 02 Jun 2022 08:06:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Luminous Logitech Litra on Linux</title>
      <link>https://derickrethans.nl/luminous-logitech-litra-on-linux.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="luminous_logitech_litra_on_linux"/&gt;Luminous Logitech Litra on Linux&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, May 24th 2022, 16:17 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I have been working on developing a course for Xdebug, PHP's Debugger. I am now close to start making the first recordings, so I thought it would be good to invest in some lighting and a green screen.&lt;/p&gt;
      &lt;p&gt;The light that I bought is a Logitech Litra Glow, but once it arrived I quickly found out that if you want to control its brightness and light temperature, you need a Windows or macOS app. I have neither, bummer. It was not a total disaster as there are buttons on the light to do the same.&lt;/p&gt;
      &lt;p&gt;When I have had "Windows/macOS" only tech in the past, there was usually already somebody who has reverse engineered it. For my old TomTom smart watch, there was &lt;a href="https://github.com/ryanbinns/ttwatch"&gt;ryanbinns/ttwatch&lt;/a&gt;, which I ended up &lt;a href="https://github.com/ryanbinns/ttwatch/commits?author=derickr"&gt;contributing&lt;/a&gt; to.&lt;/p&gt;
      &lt;p&gt;It turned out that the Logitech Litra was no exception. I found a Python implementation of a &lt;a href="https://github.com/kharyam/litra-driver"&gt;command line and UI tool&lt;/a&gt;, which does the job after messing around with some UDEV rules to allow non-root users make use of it:&lt;/p&gt;
      &lt;pre&gt;sudo su -
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c900", MODE:="0666", GROUP="plugdev"' &amp;gt; /etc/udev/rules.d/82-litra-glow.rules
udevadm control --reload-rules &amp;amp;&amp;amp; udevadm trigger

&lt;/pre&gt;
      &lt;p&gt;After I plugged in the light again, I could now control it through the Python UI and command line tools.&lt;/p&gt;
      &lt;p&gt;However, a separate tool is not really what I was after. I rather would like to control it from my Elgato Stream Deck through a &lt;a href="https://github.com/derickr/streamdeck-goui"&gt;Go application&lt;/a&gt; that I have written for it. Although I could configure it to use a command line tool invocation, I thought it would be nicer if I could control it directly from that Go applications. Which meant that I had to write a Go driver for it.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Stream Deck controlling Litra" src="derickrethans.nl/images/content/streamdeck-litra.gif"/&gt;
        &lt;div class="img-overlay"&gt;Stream Deck controlling Litra&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Building on top of the work on the Python driver, I extracted the specific bytes to send to the USB device, and wrapped that with the &lt;a href="https://github.com/derickr/go-litra-driver"&gt;derickr/go-litra-driver&lt;/a&gt;. After some research into how to talk directly with a USB device, that turned out to be not too hard. I could now control the Litra from Go!&lt;/p&gt;
      &lt;p&gt;The next step was to &lt;a href="https://github.com/derickr/streamdeck-goui/commit/3fb5addaba144c93251bef41a4f05bfe1100b0bc"&gt;integrate the driver&lt;/a&gt; into my Stream Deck control app. I &lt;a href="https://github.com/derickr/streamdeck-goui/commit/27661e96f474c19925f3928e683bf7e1d3ec97d5"&gt;added a configuration&lt;/a&gt; with 2 different colour temperatures, and each with three light levels. Combined with a state to turn the light off, that makes seven configurations that the button can cycle through.&lt;/p&gt;
      &lt;p&gt;Success! I can now control the Logitech Litra Glow from my Stream Deck.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/luminous-logitech-litra-on-linux.html</guid>
      <pubDate>Tue, 24 May 2022 15:17:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 101: More Partially Supported Callable Deprecations</title>
      <link>https://derickrethans.nl/phpinternalsnews-101.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_101_more_partially_supported_callable_deprecations"/&gt;PHP Internals News: Episode 101: More Partially Supported Callable Deprecations&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, May 19th 2022, 09:05 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I talk with Juliette Reinders Folmer (&lt;a href="http://adviesenzo.nl/"&gt;Website&lt;/a&gt;, &lt;a href="https://twitter.com/jrf_nl"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/jrfnl"&gt;GitHub&lt;/a&gt;) about the "More Partially Supported Callable Deprecations" RFC that she has proposed.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-101.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, the podcast dedicated to explaining the latest developments in the PHP language. This is episode 101. Today I'm talking with Juliette Reinders Folmer, about the Expand Deprecation Notice Scope for Partially supported Callables RFC that she's proposing. That's quite a mouthful. I think you should shorten the title. Juliette, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  0:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You're starting with the hardest questions, because introducing myself is something I never know how to do. So let's just say I'm a PHP developer and I work in open source, nearly all the time.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Mostly related to WordPress as far as I understand?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  0:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Nope, mostly related to actually CLI tools. Things like PHP Unit polyfills. Things like PHP Code Sniffer, PHP parallel Lint. I spend the majority of my time on CLI tools, and only a small portion of my time consulting on the things for WordPress, like keeping that cross version compatible.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;All right, very well. I actually did not know that. So I learned something new already.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  1:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, but it's nice. You give me the chance now to correct that image. Because I notice a lot of people see me in within the PHP world as the voice of WordPress and vice versa, by the way in WordPress world to see me as far as PHP. And in reality, I do completely different things. There is a perception bias there somewhere and which has slipped in.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's good to clear that up then.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  1:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, thank you.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Let's have a chat about the RFC itself then. What is the problem that is RFC is trying to solve?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  1:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There was an RFC or 8.2 which has already been approved in October, which deprecates partially supported callables. Now for those people listening who do not know enough about that RFC, partially supported callables are callables which you can call via a function like call_user_func that which you can't assign to variable and then call as a variable. Sometimes you can call them just by using the syntax which you used for defining the callable, so not as variable but as the actual literal.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And as an example here, that is, for example, static colon colon function name, for example.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  2:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Absolutely, yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which you can use with call_user_func by having two array elements. You can call it with literal syntax, but you can't assign it to a variable and then call it. Do I get that, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  2:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Absolutely. That's it. There's eight of those. And basically, the original RFC from Nikita proposed to deprecate support for them in 8.2,  add deprecation notices and remove support for them altogether in PHP nine. And the original RFC explicitly excluded two particular things from those deprecation notices. That's the callable type and using the syntaxes in combination with the is_callable function, where you're checking if the syntax is callable. The argument used in the original RFC was to keep those side effect free. The problem with this is that with the callable type, this means you go from absolutely no notice or nothing, to a fatal error in PHP 9. Everything works, and you're not getting any notification. But in PHP 9, its fatal error at the moment that callable is being passed to a function.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This is the callable type in function declarations.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  3:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, absolutely. And with is_callable, I discovered a pattern in my wanderings across the world where people use the syntax in is_callable, but then use it in a literal call. So not using call_user_func, not using a variable to call it, but it's callable static double colon method name, and then called static double colon method name as literal. And that pattern basically, for valid calls would mean that that function would no longer be called in PHP 9 without any notification whatsoever.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So it's a silent change that you can't detect at all.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  4:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, which to me sounded dangerous. I started asking some questions about that. But six weeks ago, the conclusion was, well, maybe this should be changed. But as this was explicit in the original RFC, we can't just change it. We need to have a new RFC to basically amend the original RFC and remove the exception for these two situations and allow them to throw deprecation notices.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What are you proposing to change with this RFC than?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  4:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What this RFC is proposing is simply to remove the exception that the callable type and is_callable are not throwing a deprecation notice. This RFC is proposing that they should throw a deprecation notice, so that more of these type situations can be discovered in time for PHP 9 to prevent users getting fatal errors.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Now, of course, we have no idea when PHP nine is actually showing up, but I don't think it will be this year. Well, I know it won't be this year, and it certainly won't be be next year neither, I think.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  5:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's all the same. I mean, it makes there'll be two, three years ahead, but it doesn't really make sense to have the main deprecation in 8.2 and then have the additional deprecation in 8.4 or something.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Absolutely.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  5:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's a lot more logical to have it all in in the same version. Because it's all related. It's basically the same thing without the exception for callable type. And is_callable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Although there is no current application, would this be able to be found if you had like a comprehensive test suite?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  5:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes and no. Yes, you can find this with a test suite. But one, you're presuming that there are tests. Two, that the tests covered the effected code with enough path coverage. Three, imagine a test you've written yourself at some point in the past where which affected callables, you might have, you know, a data provider where you say: Okay, valid callable function, which you've mocked or, you know, closure, which you've put in and second, this function does not exist. Okay, so now you're testing this function, which at some point in its logic has a callable, and expects that type to receive that type. But are you actually testing with the specific deprecated partially supported callables? Even if you have a test, and the test covers the affected code, if you do not test with one of these eight syntaxes, which has been deprecated, you still cannot detect it. And then, four, you still need to make sure that the tests are routinely run, and in open source, that's generally not a problem. Most open source projects, use GitHub actions by now to run the tests automatically on every pull request, etc. But, have the tests been turned on to actually run against PHP 8.2. Are the tests run against pull requests? I mean, there are still plenty of projects, which don't do that kind of thing. Yes, you can detect it with a good test suite. But there's a lot of caveats when you will not detect it. And more importantly, you will not be able to detect it until PHP 9.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, when your code and stops behaving as you were expecting it to be.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  7:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, because in 8.2, you're gonna get deprecation notices for everything else, but these two situations. But not in 8.2, not in 8.3, not in 8.4, and then whatever eights we're gonna get until nine, you will not be able to detect without deprecation notices, until PHP 9 actually removes support for these partials deprecated callables. Yes, but no.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We already touched a little bit on how you found out for the need for this RFC or for changing behaviours. But as people have stated in the past, adding deprecation notices is a BC break. That's a subject that we will leave for some other time because I don't necessarily believe that. But would, the changes in your RFC not add more backwards compatibility issues?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  8:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The plain and simple the backward compatibility break is in the original RFC. That's where the deprecation is happening. This RFC just makes it clearer where the BC break is going to be in PHP 9. It's not PHP 8.2, which has a backward compatibility break. It's PHP 9 which will have to backward compatibility break. Yes, I've heard all those arguments, people saying deprecation notes are BC break, no they're not. But they are annoying. And Action List, to for everything that needs to be fixed before 9. Given big enough projects, you cannot say: Okay, I'm gonna do this at the last moment, just before 9 comes out. It literally means 10 months of the year I for one am working on getting rid of deprecation notices in project to prepare them all to be ready for PHP 9 when PHP 9 comes round.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But it's still better to have them than to not,.and then you code starts breaking right? Because that is exactly why you're proposing this RFC as far as I understand.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  9:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, absolutely. I mean, I'm always very grateful for deprecation notices, but it would be nice if we had fewer changes, which would cost them, for a year or two, so I can actually catch my breath again.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think PHP 8.2 will have fewer of these changes in there. There will still be some of course.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  9:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, I mean, this one is one deprecation. And then we have the deprecated Dynamic Properties and that one is already giving me headaches before I can actually start changing it in a lot of projects. I'm not joking, that one really is going to cause a shitload of problems.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's definitely for products have been going on for so long, where dynamic properties are used all over the place. And I see that in my own code as well. I just noticed this morning does actually breaks Xdebug.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  10:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I know it's currently breaking mockery, we're gonna have to have a discussion how to fix that or whether or not to fix it. If Mockery is broken, that means all your tests are broken. So the test tooling needs to be fixed first.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's always the case, if you work with CLI tools that make people run code on newer PHP versions, that's always a group of tools that needs to be upgraded first, which is your sniffers, your static analysis, your debugger still will always need to go first.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  10:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which is why I look at things a lot earlier, probably then the majority of people. I mean, I see him huge difference between the open source and closed source community. For open source, I started looking at it well, I've been looking at 8.2 since the beginning. And I started running tests for all the CLI tools. As soon as 8.1 comes out, 8.2 gets added to the matrix for running in continuous integration. And then for applications, it gets added like in you know, once alpha 1-2-3 has come out. For the extensions, it gets added in September once the first RFC gets added. And all of them are trying to get ready before the release of 8.1 or 8.2 in this case, because you do not know as an open source maintainer, what version people are going to run your code on. And you can say IP, you can manage that via Composer, no you can't. Sorry, you can only do that if your users are actually installing via Composer. If your users are downloading a zip file, and uploading it to a web host via FTP, there's literally no way you can control whether they're running on 8.0, or 8.1, except for maybe during check: You cannot run on 8.1 yet.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Upgrading software with version support is an issue that's been going on for 40 years and will go on for at least another 40 more. This is not a problem that we can solve easily.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  12:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But what I see there is like the closed source community is like, oh, yeah, but you know, by the time I want to upgrade my server to 8.1, or 8.2, I just run Rector and all will be fine. And I'm like, yeah, sorry, that does not work for open source. We need cross version compatible with multiple versions. And I try to keep that range of version small for the project, I initiate, I don't always have control over it. If for instance, one of the projects I maintain is Requests. And that's a project which does HTTP requests. It's used by WordPress, it cannot be let go of the minimum of 5, PHP 5.6, until WordPress, lets go of that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, the alternative is that WordPress uses an older version until it can let go of it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  12:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, the only problem then is that we don't want to maintain multiple stable branches. For security fixes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;For Xdebug, what I do is I support what the PHP project support when a PHP release comes out, which is a bit longer than PHP itself usually, but not by much more than a year or two.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  13:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I understand that. And I mean, I applaud Sebastian for at some point, having the guts to say to the community, I'm limiting the amount of versions I'm supporting. And I'm sticking to the officially supported PHP versions. That does not mean that that didn't give a large part of community which does need to support a wider range of PHP versions a problem. I fully support that people limit the amount of fish and stay support and like Sebastian, who I know got half the community up in arms against him when he said, I'm not going to support older PHP versions any more. It did create a problem and but the problem which I've tried to solve for instance with the PHP unit polyfills, which now is solvable by using the PHP Unit polyfills in quite a transparent way, which is helpful for everyone. It takes the complainers of Sebastian's back, and at the same time, it allows them to run the test.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think another good thing that Sebastian recently has done is make sure that deprecation notices are no longer failing your tests.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  14:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't agree. The thing is, I do understand him making that change. But changing that default from not showing those deprecation notices or not not allowing deprecation notes to fail the test, or not in a patched version, I don't think was the right thing to do. That should have been in a minor, let alone or maybe even in a major not in a 9.5.18 patch version. Also with the whole idea, I mean, again, this is very much an open source versus closed source discussion for closed source I completely understands that people say I don't want to know until I actually am ready to upgrade to that version.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I understood it's more of a difference not necessarily between open and closed source, but rather between library maintainers and application maintainers. And the applications can then also be closed source.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  15:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The open source work I work in, I mean, I do want to see them. And the problem with the deprecation notices anyhow, and I've seen various experiments via Twitter fly past for the past year. Say you build something on top of something else, you want to see the deprecation notices and the errors which apply to your code. We don't want to see the ones which come from the framework on which you build on top. The silencing deprecation notices or not, allow tests to error out on deprecation and just not solve that problem.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The only thing it does is make things a little bit less noisy so that fewer people complain to library authors isn't it? That's pretty much what it does.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  15:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The thing would I see what it has done is that people think the tests are passing.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well they are passing, but...&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  15:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, but most people don't read change logs of PHP unit, especially as releases don't get actually have to change log included. When PHP Unit releases its actual release, it doesn't actually post a release on GitHub. So people who watch the PHP unit repo for releasing doesn't, don't get notifications, let alone a changelog. So they actually have to go into the repo to find out what has changed. Most people don't do that. They just get you know depend-a-bot update, which won't say much, because again, it doesn't have release information.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
        &lt;p&gt;Derick Rethans  16:28 It'd be nice, maybe if Composer ,when you upgrade packages, that it can show like the high level changes when you do an upgrade. The Debian project does that if you upgrade packages that have like either critical or behavioural changes, you actually get a log when you run the update.&lt;/p&gt;
        &lt;dl&gt;
          &lt;dt&gt;Juliette Reinders Folmer  16:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And then the change should have been in major or minor, because in a patch release, you don't expect it kind of changes. I also know the struggle there. They've been going through to four PHP units and which is similar to what I'm struggling with with the amount of changes from PHP 8.0 and 8.1 which has to be deal dealt with. Projects are being delayed, we're having trouble keeping up as an open source community, we still need to look after our own mental health as well.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What has the feedback been to far on the RFC or non?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  17:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The feedback on this particular RFC has been next to nothing. And that's not surprising. I mean, basically, the discussion has happened before. And I started the discussion six weeks ago, eight weeks ago, which led to this RFC. So far the responses, which I have seen, either on Twitter or in private or in our people will read through the RFC. They're like, yeah, it makes sense.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think this is quite a nicer way of getting RFCs done, you discuss them first. And if there's then found a need actually spend a time on writing an RFC. In other cases, the other way around happens, right? People write a long, complicated RFC, and then complain that nobody wants to talk about it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  17:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When I started the previous discussion, it was I see this, I noticed this, was this discussed? And then I got back: yeah, nobody actually discussed the previous RFC and I'm like: Okay, so what's this whole point about under discussion if nobody's discussing?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, you can't force people to talk, of course.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  18:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It does make me wonder, again, what we were talking about before, people who work in managed environments versus people who will have to support multiple PHP says, I sometimes wonder how many people who actually have voting rights work in those closed environments, and think, you know, upgrading is something you do with Rector. Now I have a feeling that often open source gets a little forgotten.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, that's perhaps true. Thank you for taking the time this morning to talk about this RFC then.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Juliette Reinders Folmer  18:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you Derick for having me. It was a pleasure to do you like always.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/partially-supported-callables-expand-deprecation-notices"&gt;Expand deprecation notice scope for partially supported callables&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-101.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-101.html</guid>
      <pubDate>Thu, 19 May 2022 08:05:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: April 2022</title>
      <link>https://derickrethans.nl/xdebug-update-april-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_april_2022"/&gt;Xdebug Update: April 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, May 10th 2022, 09:39 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In April, I spend 29 hours on Xdebug, with 27 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="development"/&gt;Development&lt;/h2&gt;
        &lt;p&gt;I continued my exploration of different set-ups that developers user, and have created a prototype branch that adds support for the "pseudo-host" &lt;code&gt;xdebug://gateway&lt;/code&gt; which can be used with the &lt;code&gt;xdebug.client_host&lt;/code&gt; setting instead of, and in addition to the Docker specific &lt;code&gt;host.docker.internal&lt;/code&gt;. This pseudo-host automatically evaluates to the network gateway address in the container, which will then allow Xdebug to connect to an IDE on the host machine.&lt;/p&gt;
        &lt;p&gt;This value will work for:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;PHP/Xdebug running in Docker on Linux, Windows, and macOS; with the IDE on the host.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;PHP/Xdebug running in WSL, with the IDE on the (Windows) host.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;PHP/Xdebug running in Docker in Ubuntu on WSL, with the (Linux) IDE running in WSL.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;It will not work where network isolation is used, for example with the following set-ups:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;PHP/Xdebug running in root-less Docker on Linux, IDE on (Linux) host&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;PHP/Xdebug running in Docker for Windows in WSL, with the Linux version of the IDE inside WSL.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I have not figured out how to do it will all different set-ups, so if you have extra information, or if I am still missing set-ups, feel free to comment on the &lt;a href="https://docs.google.com/document/d/1W-NzNtExf5C4eOu3rRQm1WlWnbW44u3ANDDA49d3FD4/edit?usp=sharing"&gt;Google Doc&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;In the more complicated set-ups, it would likely be easier to use &lt;a href="https://xdebug.cloud"&gt;Xdebug Cloud&lt;/a&gt; as it has none of these networking complications.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="course"/&gt;Course&lt;/h2&gt;
        &lt;p&gt;I have spend a fair amount of time developing the Xdebug course, with the first lesson now written and ready to be recorded. I have decided to include a "Tech Corner" with each lesson, to explain how Xdebug interacts with PHP to do the things that are explained in each lesson. Hopefully you'll find this interesting as well. It will also serve to reduce the bus factor.&lt;/p&gt;
        &lt;p&gt;For further lessons I have started to draft outlines, and they are in different states of completion.&lt;/p&gt;
        &lt;p&gt;If you want to make sure that the course covers specific tasks that you find hard to do, or what you would like explained, please drop me an email, or leave a comment.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_recorder"/&gt;Xdebug Recorder&lt;/h2&gt;
        &lt;p&gt;I have been making little progress as I have been focused on developing the course. There is a persistent bug while creating the recording, which is hard to track down, as it only happens occasionally and does not seem to be easily reproducible.&lt;/p&gt;
        &lt;p&gt;You can follow the development in the &lt;a href="https://github.com/derickr/xdebug/tree/recorder"&gt;recorder&lt;/a&gt; branch.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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 &amp;#xA3;49/month.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one new video this month:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.youtube.com/watch?v=Xgn0EtB4chc"&gt;Xdebug 3: Laravel Sail with PhpStorm&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;You can find all previous videoes on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In April, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-april-2022.html</guid>
      <pubDate>Tue, 10 May 2022 08:39:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>On the Online Safety Bill</title>
      <link>https://derickrethans.nl/online-safety-bill.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="on_the_online_safety_bill"/&gt;On the Online Safety Bill&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, April 12th 2022, 10:35 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;There is currently a &lt;a href="https://bills.parliament.uk/bills/3137"&gt;bill&lt;/a&gt; going through the UK's parliament, titled the "Online Safety Bill". It is a far going piece of legislation with countless stifling effects. I have written the following letter to my MP, Tulip Siddiq. Please feel free to use this as a template when you write to your own MP about this topic.&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;Dear Tulip Siddiq MP,&lt;/p&gt;
      &lt;p&gt;In the last several years I have been following the various different versions of the UK's new Online Safety Bill, and have grave concerns. It is a far-reaching bill that fundamentally changes the UK's approach to the internet, including the suppression of speech.&lt;/p&gt;
      &lt;p&gt;I have been working with internet related things for nearly 25 years now, and I can see massive things wrong with the big tech platforms, most notably the proliferation and promotion of disinformation which has put a dent in the trust in science and research, including new vaccines, and politics.&lt;/p&gt;
      &lt;p&gt;However, the bill does not only apply to the big tech firms (Facebook, Google, Twitter, etc.), but to all sites with user generated content. And there is virtually nobody talking about anything besides just Facebook, to be honest.&lt;/p&gt;
      &lt;p&gt;With this letter I would like to highlight a few of the larger problems with this bill, when applied to smaller sites with user generated content. If the current draft bill becomes law, then these smaller sites and businesses would come under severe duress, and might have to close to UK citizens, or fully.&lt;/p&gt;
      &lt;p&gt;I would like to introduce two examples here, with which I have direct involvement.&lt;/p&gt;
      &lt;p&gt;In the past 6 years I have written, maintained, and hosted &lt;a href="https://dram.io"&gt;Dram.io&lt;/a&gt;. It is a website where users can keep notes about which whiskies they like, with tasting notes and photos. It is primarily used by me and a few friends, and has around a dozen active users. It is open to the public, but most definitely a niche site. It does not promote anything, but it does talk about adult content (alcohol).&lt;/p&gt;
      &lt;p&gt;In the past 20+ years I have been an active contributor to PHP (&lt;a href="https://www.php.net"&gt;https://www.php.net&lt;/a&gt;), a computer language that powers more than 75% &lt;a href="https://derickrethans.nl#_footnote_0_1" class="footnote"&gt;1&lt;/a&gt; of all the websites on the internet, including (through WordPress) your own, &lt;a href="http://tulipsiddiq.com"&gt;http://tulipsiddiq.com&lt;/a&gt;. The PHP language is a volunteer project and organises itself primarily through asynchronous communication methods such as e-mail lists and on-line chat rooms, which are all open to the public to read and write to. These are also user-generated content sites that the bill captures.&lt;/p&gt;
      &lt;p&gt;The Online Safety Bill (OSB) is a complex bill, with many provisions. It almost feels like every pressure group has their own personal agenda. Let me discuss a few of these with the above two projects in mind.&lt;/p&gt;
      &lt;p&gt;First of all, the OSB has provisions about "legal but harmful" content, argued by the bill's proponents to "protect the children". This is content that is not illegal, but could be considered harmful to other people. The bill does not define clearly what harmful is, and leaves this definition to the regulator (OFCOM), at the whims of the culture secretary (currently, Nadine Dorries). Although the bill's proponents often argue that when something is illegal off-line, it should also be illegal on-line, the provisions in the bill go further. The definition of harmful is so wide that basically any content that could be seen as harmful to anybody else, is liable for content control (i.e., removal, or tagged as such).&lt;/p&gt;
      &lt;p&gt;Checking for this content requires active moderation. Active moderation on a large scale, such as with Facebook, is hard to do because there is so much content created that it is impossible to do by humans. I would argue that it is also impossible to do through automation. Although algorithms can be constructed to aid in this, they will never be able to be accurate enough to:&lt;/p&gt;
      &lt;ol&gt;
        &lt;li&gt;
          &lt;p&gt;Flag or block all possible harmful content;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Not flag or block non-harmful content. (Example: the ban by TikTok of "Charles Dickens" &lt;a href="https://derickrethans.nl#_footnote_0_2" class="footnote"&gt;2&lt;/a&gt; because it has a naughty word in it).&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ol&gt;
      &lt;p&gt;In the chat rooms and mailing lists of the PHP Open Source project a lot of content is generated every day. This can not realistically be pre-cleared by moderators. Doing so is not wanted either. It is a large international project where developers should be able to speak their mind. At times, it certainly gets heated, and red lines get crossed sometimes, including in the form of personal attacks. Although this hampers the technical discussions, the PHP project should be in charge to regulate their community, and not OFCON, and certainly not minister Dorries. The discussion platforms that the PHP project uses will fall under the provisions of the OSB. In order to not fall foul of a law, it can be easily argued by the PHP project's leadership that it is not worth opening themselves up to the punishments as set out in the OSB. A likely scenario could be that they decide that the easiest way around it would be to block UK residents and locations from being able to participate. This in turn will dampen innovation, and also directly affects my livelihood, and negatively affects the internet industry in the UK.&lt;/p&gt;
      &lt;p&gt;For sites such as my hobby project, Dram.io, which sees little content added, I could review all content personally. Because it deals with commentary about alcohol products, it can be argued that no children should ever see this content (harmful, but legal), and that it should therefore be limited to visitors aged 18 and older, which brings me to the next point.&lt;/p&gt;
      &lt;p&gt;The bill includes provisions to require age verification for any harmful (to children) content. Age verification is usually done by checking against a credit card or uploading a passport, or something similar. Either to a site directly, or through a third party provider. Large(r) sites such as Facebook can spend time and money to create something for themselves, albeit at a cost. A small site such as my personal project Dram.io does not have the money, or does not want to spend money, on setting up that infrastructure. They would have to use a third party to provide these age verification checks to comply with this provision, at a cost. Many large international Open Source projects such as the PHP language don't even have any money to spend on this, as it is run by volunteers.&lt;/p&gt;
      &lt;p&gt;This would likely mean that I would have to close down Dram.io to not be caught up by the OSB. And the PHP project might &lt;em&gt;have&lt;/em&gt; to decide to not allow British citizens and residents to participate in discussions again.&lt;/p&gt;
      &lt;p&gt;There is also a problem with these third party providers with regards to security. Many adult entertainment businesses are on the front line to provide these services, as they're well placed to provide this (they had to historically). They also have been keenly lobbying the authors of the bill to include age verification requirements as this adds to their bottom line. Do we really want adult entertainment businesses to hold our credit card numbers, or even worse, our personal passport details? I would find this too much of a security risk. Personally, I have no intention to provide any of my own details to third party age verification providers. It is even up to OFCON to "certify" verification check systems for use.&lt;/p&gt;
      &lt;p&gt;There are two more issues that are a little harder to describe, and are more legal changes. First of all, the bill changes the liability of the content (cat videos, comments about news articles) that is being generated. Currently, many sites benefit from provisions in the Defamation Act 2013 &lt;a href="https://derickrethans.nl#_footnote_0_3" class="footnote"&gt;3&lt;/a&gt; that posted content by users does not create liability by the publication (website) that publishes this content. The OSB changes this by making the publishers (websites) liable for what their users post. Although it can be reasonably argued that website's (read: Facebook's) promotion algorithms &lt;em&gt;should&lt;/em&gt; be held liable for the items it suggests (as that is not user generated content), making publishers liable for what their users post goes much further.&lt;/p&gt;
      &lt;p&gt;The bill also tries to redefine the different meaning of Duty of Care &lt;a href="https://derickrethans.nl#_footnote_0_4" class="footnote"&gt;4&lt;/a&gt;, a mechanism in Tort law where companies can be held liable for negligence. The bill redefines as Duty of Care from just between company (publisher) and their customers (content generating users), to also include the interactions between their customers (people writing whisky tasting notes, or technical arguments for including or not, features in the PHP languages). By introducing such a liability, website operators will be forced to be on the safe side, and likely over block and prematurely remove (legal) content, to not fall foul of these provisions. Or if they don't have the resources to screen for such content they might decide that it is not worth it to continue serving Brits. Again, that won't probably be companies the size of Facebook, but it's going to be detrimental to smaller projects.&lt;/p&gt;
      &lt;p&gt;Lastly, the bill does make provisions for journalistic and editorial content, but does not clearly define what journalistic content is as part of a "regulated news publisher" (see Section 16 (8, 14), Section 49 and 50). It is probably clear that websites such as the Guardian and Telegraph will fall in this category, but unlikely that websites such as Wembley Matters &lt;a href="https://derickrethans.nl#_footnote_0_5" class="footnote"&gt;5&lt;/a&gt; are, even though they do provide a democratic task to hold politicians to account. Not having exceptions for this kind of journalistic expression is again limiting rights.&lt;/p&gt;
      &lt;p&gt;I hope by writing this letter that I have highlighted some of the problems that I see with this bill. There is a large possibility for the restriction of expression, both by being unclear what journalistic content is, but also requiring pretty much every website that allows for user generated content to have to be a lot more restrictive of what they can allow to be posted. Even though this content is legal, the extra burdens being put on smaller operators are of such chilling nature that we will very likely see them having to be closed, or not being made available to British citizens. I would hate to see this being the collateral damage from this huge and not well thought out bill.&lt;/p&gt;
      &lt;p&gt;With kind regards, Derick Rethans&lt;/p&gt;
      &lt;hr/&gt;
      &lt;p&gt;Please write to your own MP if you share similar concerns, and feel free to copy parts of this letter and adapt them to your own examples. You can find out how to contact your elected officals on &lt;a href="https://www.writetothem.com/"&gt;WriteToThem&lt;/a&gt;. I also have copied this letter to &lt;a href="https://members.parliament.uk/member/3396/career"&gt;Lord Clement-Jones&lt;/a&gt;, the Liberal Democrat Lords Spokesperson on Digital.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
    &lt;ul class="footnotes"&gt;
      &lt;li&gt;
        &lt;a name="_footnote_0_1"&gt;1&lt;/a&gt;
        &lt;p&gt;&lt;a href="https://w3techs.com/technologies/overview/programming_language"&gt;https://w3techs.com/technologies/overview/programming_language&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;a name="_footnote_0_2"&gt;2&lt;/a&gt;
        &lt;p&gt;&lt;a href="https://www.standard.co.uk/news/uk/charles-dickens-museum-tiktok-four-letter-word-b990097.html"&gt;https://www.standard.co.uk/news/uk/charles-dickens-museum-tiktok-four-letter-word-b990097.html&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;a name="_footnote_0_3"&gt;3&lt;/a&gt;
        &lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Defamation_Act_2013"&gt;https://en.wikipedia.org/wiki/Defamation_Act_2013&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;a name="_footnote_0_4"&gt;4&lt;/a&gt;
        &lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Duty_of_care_in_English_law"&gt;https://en.wikipedia.org/wiki/Duty_of_care_in_English_law&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;a name="_footnote_0_5"&gt;5&lt;/a&gt;
        &lt;p&gt;&lt;a href="https://wembleymatters.blogspot.com/"&gt;https://wembleymatters.blogspot.com/&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/online-safety-bill.html</guid>
      <pubDate>Tue, 12 Apr 2022 09:35:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: March 2022</title>
      <link>https://derickrethans.nl/xdebug-update-march-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_march_2022"/&gt;Xdebug Update: March 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, April 5th 2022, 09:15 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday on or after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In March, I spend 39 hours on Xdebug, with 25 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="development"/&gt;Development&lt;/h2&gt;
        &lt;p&gt;Most of my time in March was spent on investigating and fixing bugs. Ranging from a crash during debugging of closures with static properties, support for showing ArrayObject elements while debugging, improvements to code coverage, and bugs with Xdebug's step-debugger triggering mechanism.&lt;/p&gt;
        &lt;p&gt;I also improved Xdebug's diagnostics by adding warnings. I added one for when systemd PrivateTmp directories are used. And Xdebug now also warns if zlib compression is enabled in situations, such as with the profiler's append feature, where it can not be used.&lt;/p&gt;
        &lt;p&gt;I spend a considerable amount of time &lt;a href="https://docs.google.com/document/d/1W-NzNtExf5C4eOu3rRQm1WlWnbW44u3ANDDA49d3FD4/edit?usp=sharing"&gt;cataloguing&lt;/a&gt; the different set-ups that developers use, and how to configure Xdebug's debugger. This work will result in better documentation and perhaps a flow chart. The research is also useful for the &lt;em&gt;Xdebug Course&lt;/em&gt; that I have mentioned before.&lt;/p&gt;
        &lt;p&gt;I have not figured out how to do it will all different set-ups, so if you have extra information, or if I am still missing set-ups, feel free to comment on the &lt;a href="https://docs.google.com/document/d/1W-NzNtExf5C4eOu3rRQm1WlWnbW44u3ANDDA49d3FD4/edit?usp=sharing"&gt;Google Doc&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;In the more complicated set-ups, perhaps it would be easier to use &lt;a href="https://xdebug.cloud"&gt;Xdebug Cloud&lt;/a&gt; as it has none of these networking complications.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_recorder"/&gt;Xdebug Recorder&lt;/h2&gt;
        &lt;p&gt;I have been making steady progress with a first version, which can now play back recording information and display it in the likeness of an Xdebug trace file. There are still a few bugs outstanding, and I also have not added support for objects yet.&lt;/p&gt;
        &lt;p&gt;I will be recording a video with a demo once I have something to show. You can follow the development in the &lt;a href="https://github.com/derickr/xdebug/tree/recorder"&gt;recorder&lt;/a&gt; branch.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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 &amp;#xA3;49/month.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published no new videos this month. You can find the existing ones on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In March, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-march-2022.html</guid>
      <pubDate>Tue, 05 Apr 2022 08:15:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Memory Malfeasance</title>
      <link>https://derickrethans.nl/memory-malfeasance.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="memory_malfeasance"/&gt;Memory Malfeasance&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, March 29th 2022, 14:30 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A while ago I started getting weird crashes on my desktop machine &amp;#x2014; Gargleblaster. Once in a while, PHP, or Node, would crash. And browser tabs kept turning blank, with Firefox crashing altogether once in a while too.&lt;/p&gt;
      &lt;p&gt;At first I thought there was some memory corruption in a system library, but neither valgrind or GDB would show any issues &amp;#x2014; if the problem could be reproduced at all. It was also very random, but the problem went away for a short while after a reboot.&lt;/p&gt;
      &lt;p&gt;I suspected the worst: Broken memory.&lt;/p&gt;
      &lt;p&gt;In the past I had used tools like &lt;code&gt;memtest86&lt;/code&gt;, and &lt;code&gt;memtest86+&lt;/code&gt; &amp;#x2014; both available as packages on my Debian system. There are some &lt;a href="https://askubuntu.com/questions/917961/can-i-boot-memtest86-if-im-using-uefi"&gt;complications&lt;/a&gt; with both of these on newer UEFI BIOS systems. This meant that when I tried them, the system would not even boot. A new version of &lt;code&gt;memtest86+&lt;/code&gt; was supposed to fix this, but that did not work either for me.&lt;/p&gt;
      &lt;p&gt;I decided to live with it for a while, but after another total loss of tabs (oh dear!), I &lt;a href="https://unix.stackexchange.com/questions/439674/is-there-a-free-libre-open-source-alternative-to-memtest86-that-works-with-ue/439769#439769"&gt;stumbled upon&lt;/a&gt; a different tool: &lt;a href="https://github.com/martinwhitaker/pcmemtest"&gt;PCMemTest&lt;/a&gt;. This &lt;strong&gt;did&lt;/strong&gt; boot, but their documentation page says &lt;a href="https://github.com/martinwhitaker/pcmemtest#known-limitations-and-bugs"&gt;"The UHCI USB controller is not yet supported"&lt;/a&gt;, which is needed for USB keyboards.&lt;/p&gt;
      &lt;p&gt;I was happily surprised that Debian's APT repository also included a package for this memory testing tool. After I installed it, I rebooted my machine to see what it would say. The result:&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="PCMemTest showing broken memory" src="derickrethans.nl/images/content/pcmemtest.jpg"/&gt;
        &lt;div class="img-overlay"&gt;PCMemTest showing broken memory&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;PCMemTest allows you to create a configuration line for the Grub configuration which the Linux kernel uses while booting up to exclude certainly parts of physical memory from being used. However, without the USB keyboard working, I could not not navigate to that feature.&lt;/p&gt;
      &lt;p&gt;Then I &lt;a href="https://askubuntu.com/questions/908925/how-do-i-tell-ubuntu-not-to-use-certain-memory-addresses"&gt;read&lt;/a&gt; that the kernel itself also has a memory test tool built in: the &lt;a href="https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html"&gt;memtest&lt;/a&gt; kernel parameter.&lt;/p&gt;
      &lt;p&gt;To include the memory test when the system boots, update the &lt;code&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;/code&gt; line in &lt;code&gt;/etc/default/grub&lt;/code&gt; to:&lt;/p&gt;
      &lt;pre&gt;GRUB_CMDLINE_LINUX_DEFAULT="quiet pcie_aspm=off memtest=4"

&lt;/pre&gt;
      &lt;p&gt;And then run &lt;code&gt;update-grub&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;Now when the system starts, the kernel will run a memory test and automatically exclude any memory that it finds not working.&lt;/p&gt;
      &lt;p&gt;On my system this looks in the &lt;code&gt;dmesg&lt;/code&gt; output like:&lt;/p&gt;
      &lt;pre&gt;[    0.000000] early_memtest: # of tests: 4
[    0.000000]   0x0000000000100000 - 0x0000000001000000 pattern aaaaaaaaaaaaaaaa
[    0.000000]   0x0000000001020000 - 0x0000000004000000 pattern aaaaaaaaaaaaaaaa
[    0.000000]   0x000000000401e000 - 0x0000000009df0000 pattern aaaaaaaaaaaaaaaa
&amp;#x2026;
[    0.000000]   0x0000000100000000 - 0x0000000180000000 pattern 5555555555555555
[    0.000000] ------------[ cut here ]------------
[    0.000000] Bad RAM detected. Use memtest86+ to perform a thorough test
                           and the memmap= parameter to reserve the bad areas.
&amp;#x2026;
[    0.000000]   5555555555555555 bad mem addr 0x000000016dbc8450 - 0x000000016dbc8458 reserved
[    0.000000]   0x000000016dbc8458 - 0x0000000180000000 pattern 5555555555555555
[    0.000000]   0x0000000180410000 - 0x0000000727200000 pattern 5555555555555555
[    0.000000]   0x000000072980d000 - 0x000000107f300000 pattern 5555555555555555
[    0.000000]   0x0000000000100000 - 0x0000000001000000 pattern ffffffffffffffff
&amp;#x2026;
[    0.000000]   0x000000072980d000 - 0x000000107f300000 pattern 0000000000000000

&lt;/pre&gt;
      &lt;p&gt;The line &lt;code&gt;bad mem addr 0x000000016dbc8450 - 0x000000016dbc8458 reserved&lt;/code&gt; is saying that the kernel excluded that section of memory because it found it to be broken.&lt;/p&gt;
      &lt;p&gt;Since I booted my system 16 days ago, I have no longer seen any unexplained crashes. Yay!&lt;/p&gt;
      &lt;p&gt;At some point I will need to replace this memory, if I find out which of the four memory modules it is. That is a job for some other time.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/memory-malfeasance.html</guid>
      <pubDate>Tue, 29 Mar 2022 13:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 100: Sealed Classes</title>
      <link>https://derickrethans.nl/phpinternalsnews-100.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_100_sealed_classes"/&gt;PHP Internals News: Episode 100: Sealed Classes&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, March 24th 2022, 09:04 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I talk with Saif Eddin Gmati (&lt;a href="https://les-tilleuls.coop"&gt;Website&lt;/a&gt;, &lt;a href="https://twitter.com/azjezz"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/azjezz"&gt;GitHub&lt;/a&gt;) about the "Sealed Classes" RFC that he has proposed.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-100.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, the podcast dedicated to explaining the latest developments in the PHP language. This is episode 100. Today I'm talking with Saif Eddin Gmati about the sealed classes RFC that they're proposing. Saif, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  0:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hello, my name is Saif Eddin Gmati. I work as a Senior programmer at Les-Tilleuls.coop. I'm an open source enthusiast and contributor.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Let's dive straight into this RFC. What is the problem that you're trying to solve with it?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  0:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Sealed classes just like enums and tagged unions allow developers to define their data models in a way where invalid state becomes less likely. It also eliminates the need to handle unknown subtypes for a specific model, as using sealed classes to define models gives us an idea on what child types would be available at run time. Sealing also provides us with a way for restricting inheritance or the use of a specific trait. For example, if we look at logger trait from the PSR log package that could be sealed to logger interface. This way, we ensure that every use of this trait is coming from a logger not from any other class.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm just reading through this RFC tomorrow, again, and something I didn't pick up on reading to it last time. It states that PHP already has sort of two sealed classes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Unknown Speaker  1:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, the throwable class in PHP can only be implemented by extending either error or exception. The same applies for DateTime interface, which can only be implemented by extending DateTime class or DateTime Immutable class.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Because PHP itself doesn't allow you to implement either throwable or DateTimeInterface. I haven't quite realized that that these are also sealed classes really.  What is sort of the motivation behind wanting to introduce sealed classes?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Unknown Speaker  2:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The main motivation for this feature comes from Hack the programming language. Hack contains a lot of interesting type concepts that I think personally, PHP could benefit from and sealed classes is one of those concepts.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What kind of syntax are you proposing?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  2:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The syntax I'm proposing actually there is three syntax options for the RFC currently, but the main syntax is inspired by both Hack and Java. It's more similar to the syntax used in Java as Hack uses attributes. Personally, I have been I guess, using attributes from the start as I personally see sealing and finalizing similar as both effects how inheritance work for a specific class. Having sealed implemented as an attribute while final uses a keyword brings more inconsistency into the language which is why I have decided not to include attributes as a syntax option.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In my opinion, attributes shouldn't be used for any kind of syntax things. What they should be used for is attaching information to already existing things. And by using attributes again, to extend syntax, you sort of putting this syntax parsing in two different places , right? You're putting it both in the syntax as well as in attributes. I asked what the syntax is, but I don't think he actually mentioned what the syntax is.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  3:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The syntax the main set next proposed for the RFC is using sealed and permit as keywords we first have the sealed modifier which is added in front of the class similar to how final or abstract modifiers are used. We also have the permit clause which is basically a list allows you to name a specific classes that are able to inherit from this specific type.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So when you say type here, is that just interfaces and classes or something else as well?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  3:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's classes interfaces and traits. Traits are allowed to add sealing but they are not allowed to permit. Okay for example, an interface is not allowed to permit a trait because a trait cannot implement an interface&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In the language itself, when does this get enforced?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  4:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This inheritance restriction gets enforced when loading a class. So let's say we are loading Class A currently if this class extends B, we check if B is sealed. And if it is we check if B allows A to extend it. But when loading a specific sealed class, nothing gets actually checked. We just take the permit clause classes and store them and move on.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It only gets checks if you're trying to implement an interface.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  4:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This gets enforced when trying to implement an interface, extend that class, or use it trait.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay. What are general use cases for this feature?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  4:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;General use cases for a feature are for example, implementing programming concepts such as Option which is a type that can only have two subtypes. One is Some, other is None. Another concept is the Result where only two subtypes are possible, either success or failure. Another use case is to restrict inheritance. As I mentioned before, for example, logger trait from the PSR log package is a trait that implements some of the method methods in logger interface, and expects whoever is using that trait to implement the rest. However, there is no restriction by the language regarding this, we can seal this trait to a logger interface ensuring that only loggers are allowed use this trait.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When you say that Option has like the value Some or None, just sound like an enum to me. How should I think differently about enums and sealed classes here?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  5:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Enums cannot hold a dynamic value. You can have a value but you cannot have a dynamic value, however, tagged unions will allow you to implement option the same way. Tagged unions are that useful only for this specific case, there is some other cases such as the one I mentioned for traits that cannot actually be implemented using the tagged unions. There is also the I don't know how to say this. Let's say we have a type A that sealed and permitting only B and C. And this case A on itself, as long as it's not an abstract class, is by itself a type. Can be used as a normal class, you can create an instance and use it normally. However with tagged unions, the option itself would not be a type, you either have some or none. That's the main difference between tagged unions until classes&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;A tagged union PHP doesn't have them. So how does a tagged union relate to enums?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  6:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;With tagged unions as the, there is an RFC that's still in draft, I suppose that uses actually it is built on top of enums that that's why.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I reckon once that gets closer to completion, I'll end up talking to the author of that RFC. So something I'm wondering, can a sealed type permit only one other type? Or does it have to be more than one?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  7:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, it can permit only one type. Let's say we have class A that only permits B. However, another thing is class B does not actually have to extend A, like if A is permitting B, B does not actually have to implement A. It's still useful because another class called C can extend B and implement A, so an instance of A B can still exists.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm not quite sure whether I understood that. If you have an interface that says A permits B, then B is not required to implement A, mostly because the moment you loads class B, you don't even know it exists, right? Because it doesn't refer to it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  7:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's just going to break anything?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  7:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hopefully not. The only break would be in the new reserved keywords which are sealed and permits. So those cannot be used as identifiers any more, but depending on the syntax choice, if for example, the second syntax choice wins which that would only take the permits keyword. If the third syntax choice is chosen then no new reserved keywords will be introduced so there will be no breaks.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;From what I see in the RFC the first syntax is using both sealed in front of a as a marker and then using permits. With the second syntax, you don't use seal but you infer that it is sealed from the permits keyword I suppose. And then in the last option you use the for keyword instead of permits and also don't use sealed yet?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  8:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The third syntax choice is will be the one with no breaks as we will not be introducing any new keywords; for is already a reserved keyword in PHP.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What is your preference?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  9:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Personally I prefer the first syntax choice as it's the most explicit. When you start reading the code you can tell from the start this is a sealed class without having to continue reading until you reach permits.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think I agree with you there. Beyond the syntax is there anything else that needs to be changed in PHP itself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  9:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The only other change that will be introduced in PHP is in reflection class. A new method called isSealed will be added to reflection method, which allow you to check if a class the class being reflected is sealed. Another method will be added called getPermittedClasses which returns the list of class names provided in the permits clause. Also a new constant should be added to reflection class that is is_sealed constant which exposes the bit flag used for sealed classes. Some changes will happen to the getModifiers method in reflection class. This method will return the bit flag is sealed set, if the class being reflected is sealed. The getModifierNames method will also return the string sealed if the bit is set, that should be about it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Basically everything that you need in reflection to find out whether it's a sealed class and other permits.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  10:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;See, I see the name of getPermittedClasses has to use, has the word classes in it. Does that mean that the types after permits have to be classes?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  10:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, they can be either classes or interfaces. But PHP refers to both classes and interfaces as classes in the reflection. So we have a reflection class, but that's actually a reflection trait class interface. And basically everything is class-ish.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Class-ish. I like that. Did you look at some other alternatives to implementing the same feature or just the three syntax choices that you came up with?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  10:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I did not consider any other alternatives precisely as the alternatives might be type aliases, tagged enums, package visibility. But I think each of these RFCs focused on a specific problem and expanding that area, while sealed classes focuses on all the problems mentioned on in this RFC tries to solve them in a minimal way. But only in relation to inheritance in classes, interfaces, and traits.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Keeping it short and sweet. What has the feedback been so far?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  11:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The feedback has been pretty mixed. Some people are against adding more restriction to types and inheritance. But in my opinion, this is not about adding restriction, but rather providing the user with the ability to add restrictions. And we already have final classes, which a lot of people seem to dislike.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't understand why. But fair enough.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  11:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I have created a community poll a couple of weeks ago to gather feedback on Twitter. The results were 60% for with over 150 participants. Another poll was created by Peter on Facebook ended with 54 of people voting yes. However, such polls that do vary depending on the audience. So it can be really an accurate representation of the PHP community.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Polls on Twitter are never scientific, or they? I see that the RFC is in voting already. So for people listening to this, and if you have voting rights, then you have until when exactly?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  12:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Until the end of the month.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;March 31. It says yes. Okay. Well, thank you very much for taking the time today Saif about sealed classes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Saif Eddin Gmati  12:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for having me. Hopefully, I get to be here another time in the future.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I hope so too. Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/sealed_classes"&gt;Sealed Classes&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-100.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-100.html</guid>
      <pubDate>Thu, 24 Mar 2022 09:04:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Downs Link</title>
      <link>https://derickrethans.nl/downs-link.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_downs_link"/&gt;Walking: Downs Link&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, March 22nd 2022, 14:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;As I have mentioned in earlier posts, I would like to walk the &lt;a href="https://hiking.waymarkedtrails.org/#route?id=77976&amp;amp;type=relation&amp;amp;map=10.0/50.8986/-0.5208"&gt;South Downs Way&lt;/a&gt; this year. I consider it still a little bit too early in the year and therefore I have been ticking off lots of other walks a little bit closer to home.&lt;/p&gt;
      &lt;p&gt;Now the weather is improving and the days are long enough again, it is getting closer to attempt the South Downs. However, I decided to walk &lt;strong&gt;to&lt;/strong&gt; the South Downs first Way. Starting at the North Downs Way near Guildford, the &lt;a href="https://hiking.waymarkedtrails.org/#route?id=1201604&amp;amp;type=relation&amp;amp;map=10.0/51.0298/-0.4214"&gt;Downs Link&lt;/a&gt; takes you from there to Shoreham-on-Sea on the south costs, crossing the South Downs Way near Upper Breeding (who comes up with these names?).&lt;/p&gt;
      &lt;p&gt;To get to the start of the Downs Link I started at Guildford, which is easy enough to get to by train from London. From the station I climbed Pewley Hill and used The Mile path to get to the North Downs Way.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="The Mile Path" src="https://live.staticflickr.com/65535/51907733611_dec2ae009c_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Mile Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A little further to the east of St. Martha's Hill and its church, the Downs Link then starts going south. The route starts off quite steep going down through narrow and muddy paths before it goes west to join the route of the dysfunctional Wey and Arun canal which it follows for a little while. There is another walking route, the &lt;a href="https://hiking.waymarkedtrails.org/#route?id=1120290&amp;amp;type=relation&amp;amp;map=10.0/51.0659/-0.5265"&gt;Wey-South Path&lt;/a&gt; which mostly follows the whole length of that canal, which also has some conversation work to restore it to a working navigational route again.&lt;/p&gt;
      &lt;p&gt;However, the Downs Link does not follow the canal for very long, and instead mostly follows the path of an two old railway lines: The Cranleigh Line and Steyning line. Both were closed as part of the Beeching Axe. Because it follows these old railway lines, the way is often flat and very straight. I walked the route in spring, and the leaves were starting to grow and the grass trying to push through in many places.&lt;/p&gt;
      &lt;p&gt;In my first section, from south of Guildford to Christ's Hospital it follows the old railway nearly perfectly. There were few walkers around, and the hills around it were dotted with churches and chapels. The occasional old station hinting at that the route really was an old railway.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Waiting Room" src="https://live.staticflickr.com/65535/51908374085_7d743be44f_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Waiting Room&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In some places the path was fairly muddy and some sections still had fallen trees laid across the track. I had to do some climbing to get over them, but at least that was a lot easier for me to do than the occasional cyclist. NCN 222 does share quite a bit with the Downs Link.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Tier Bridge" src="https://live.staticflickr.com/65535/51908080309_2a494eedeb_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Tier Bridge&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;South of Rudgwick the South Downs Way crosses the A281, a very busy road which was hard to cross. I was therefore not surprised to see that there is a &lt;a href="https://bridgethedownslink.org/"&gt;campaign&lt;/a&gt; to reinstate the bridge that was demolished in the 60s.&lt;/p&gt;
      &lt;p&gt;Talking about bridge, the logo used on way markers is a peculiar looking bridge, the Tier Bridge. It has a small view point to get a better photo of it, but I think it could have been put a little bit further away still.&lt;/p&gt;
      &lt;p&gt;From here on, the scenery beyond the trees that surrounded the route became more open, with fields and farms. After a while I spotted a tower in the distance, which turned out to be a tower attached to Christ's Hospital school. This is also the location where the first old railway joined a still working one, with a handy station nearby, aptly named, Christ's Hospital.&lt;/p&gt;
      &lt;p&gt;An hourly train from here brought be back to London Victoria and homewards.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Christ's Hospital Tower" src="https://live.staticflickr.com/65535/51907859863_141312f3c2_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Christ's Hospital Tower&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Two weeks later, it was time to walk the final part of the Downs Link, starting where I left off and finishing at Shoreham-by-Sea. The weather was just as good, if not better, than during the first section.&lt;/p&gt;
      &lt;p&gt;The paths on the southern section of the Link were generally better maintained with lots of gravel, stones, and very little mud. It was also most certainly a lot busier with walkers and runners, especially near the larger town of Southwater.&lt;/p&gt;
      &lt;p&gt;This section follows the route of the old Steyning line from Christ's Hospital to Shoreham-on-Sea.&lt;/p&gt;
      &lt;p&gt;The trees were a little bit greener than two weeks earlier and again I passed many old demolished stations. The one at West Grinstead had an old railway carriage, also acting as an information point for the Downs Link itself.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="West Grimstead" src="https://live.staticflickr.com/65535/51935585274_68a523ef6b_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;West Grimstead&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The scenery was generally flatter and wider, with even more fields and animal husbandry than in the northern section. I saw alpacas, where very definitely looked out of place, for example. There were also more streams and brooks to cross, and the river Adur showed up a few times in the earlier part of the walk as well.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Funding" src="https://live.staticflickr.com/65535/51935343998_784cf1e2ec_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Funding&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;At Partridge Green, the route slightly deviated from the original track bed, and was redirected along a not too busy road. The original route was obstructed by a new trading estate. Luckily the road walking did not take me very long.&lt;/p&gt;
      &lt;p&gt;Near Henfield I spotted a sign talking about the upgrade to the Downs Link, and just like the &lt;a href="https://derickrethans.nl/england-coast-path-1.html"&gt;England Coast Path&lt;/a&gt;, it was apparently part-funded by the European Union Agricultural fund. The path itself was almost never muddy, which made it a lot easier to walk on.&lt;/p&gt;
      &lt;p&gt;Near Steyning the South Downs themself started to appear larger and larger on the horizon and the path once again deviated from the original railway. From here on towards the end there was very little to see of it, and instead the Downs Link started following the river Adur into Shoreham-on-Sea.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Detour" src="derickrethans.nl/images/content/bramber-reroute.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Detour&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Just south of Bramber, I diligently followed the signs for the Downs Link, realising after only a few minutes that it sent me on a stupid 1 kilometre detour, where I instead just simply could have crossed the moderately busy road. I should have followed the route that my watch indicated, which was sourced from the excellent Waymarked Trails website, using &lt;a href="http://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt; data.&lt;/p&gt;
      &lt;p&gt;Not long after the unnecessary detour the Downs Link meets the South Downs Way and they share the route for a little while until the river Adur. The old cement works are clearly visible up against the easterly hills.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Adur Banks" src="https://live.staticflickr.com/65535/51935890135_6bdb22d1d7_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Adur Banks&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Having passed the cement works the route takes you down the Adur towards the finish. Across the river the chapel of Lancing College is hard to miss on the hill, especially with the sun getting lower and creating some great shadows on the building. Not much after that you pass the &lt;a href="https://en.wikipedia.org/wiki/Shoreham_Tollbridge"&gt;Old Toll Bridge&lt;/a&gt;, the last of its kind in the world, from where you can see the chapel on the hill as well.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Old Toll Bridge with Lancing College Chapel" src="https://live.staticflickr.com/65535/51935280221_3f4d95a137_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Old Toll Bridge with Lancing College Chapel&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;My walk finished at the new railway bridge carrying the West Coastway Line. I did consider continuing along the shore to Brighton, but I after 32 kilometres, doing another 10 seems a little bit over the top!&lt;/p&gt;
      &lt;p&gt;I hope you enjoyed this tale of the Downs Link. You can find more photos in my Flickr &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72177720296999596"&gt;set&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/downs-link.html</guid>
      <pubDate>Tue, 22 Mar 2022 14:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Concerning Cassini</title>
      <link>https://derickrethans.nl/concerning-cassini.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="concerning_cassini"/&gt;Concerning Cassini&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, March 15th 2022, 14:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;At the beginning of the year, I saw a tweet by my friend &lt;a href="https://benramsey.com"&gt;Ben Ramsey&lt;/a&gt;, where he quoted &lt;a href="http://carolynporco.com/"&gt;Carolyn Porco's&lt;/a&gt; tweet requesting help saving &lt;a href="https://ciclops.org"&gt;CICLOPS&lt;/a&gt;, the web site of the Cassini Imaging Central Laboratory for Operations, which was under threat of disappearing off the internet.&lt;/p&gt;
      &lt;img src="derickrethans.nl/images/content/ciclops-tweet.png"/&gt;
      &lt;p&gt;I have been enthusiastic about space since I was in my early teens, with at some point expressing the interest to be an astronaut. I never pursued that, but I have continued to express great interest in space exploration.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Comet C/2020 F3 NEOWISE" src="derickrethans.nl/images/content/neowise.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Comet C/2020 F3 NEOWISE&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I have dabbled in some astrophotography, having some mediocre successes with last year's comet NEOWISE. I never got into the field of astronomy nor photography. Instead I started doing web technology, including PHP, which how I know Ben.&lt;/p&gt;
      &lt;p&gt;Tech is cool too, but I always hoped to do something for, and with, space exploration.&lt;/p&gt;
      &lt;p&gt;So when I saw Ben's tweet, I thought this would be something I could help with, so I reached out to Carolyn via DM.&lt;/p&gt;
      &lt;p&gt;The task at hand at that time seemed to create a static copy of the existing CICLOPS website, but after some twitter to-and-fro, an additional ask seemed to be to create a functionally equivalent static search.&lt;/p&gt;
      &lt;p&gt;Over night, Ben had mirrored the CICLOPS website with &lt;code&gt;wget&lt;/code&gt; and I took his copy to make some improvements, and started doing some research into how to do a static search. I had quite some experience with SOLR as well as full text search in general and with &lt;a href="https://derickrethans.nl/mongodb-and-solr.html"&gt;MongoDB&lt;/a&gt;. The problem was that all of these needed something to run on, which would create complications and costs, beyond just hosting a static site on something like S3.&lt;/p&gt;
      &lt;p&gt;After some research through DuckDuckGo, I found a neat JavaScript library, called &lt;a href="https://lunrjs.com/"&gt;Lunr&lt;/a&gt;, which looked perfect for a quick-and-dirty static search engine. Like most other more complex search engines, Lunr creates a reverse index that maps every word back to a location in a document, with some clever maths to rank more specific words higher in the results.&lt;/p&gt;
      &lt;p&gt;I started writing a script to extract the text from the crawled CICLOPS site to pick out the actual descriptions of each post and media item, and then made that index into Lunr's full text search index. With that, I set up a static site on S3 as a demo. This demo could have become a crude final result, and would have saved all the original content and images of the Cassini space probe.&lt;/p&gt;
      &lt;p&gt;That was the easy part.&lt;/p&gt;
      &lt;p&gt;In the course of several weeks, I worked with &lt;a href="https://benramsey.com/"&gt;Ben&lt;/a&gt;, &lt;a href="http://carolynporco.com/"&gt;Carolyn&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/jakubkonecki/"&gt;Jakub&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/davidkavanagh/"&gt;David&lt;/a&gt; to refine the search index, split it into several different categories (the one with the &lt;a href="http://ciclops.org/ir_index_main/Cassini.html"&gt;images&lt;/a&gt; is my favourite!), added pagination, phrase searching, and a ton of other tweaks to make the static CICLOPS site an excellent simile of the original dynamic site, which turned out to be written in PHP!&lt;/p&gt;
      &lt;p&gt;To be honest, this took a lot more work than I originally had thought, with many hours spend on my side, all in the name of science.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Planet Six &amp;#x2014; http://ciclops.org/view/8697/Planet-Six.html" src="derickrethans.nl/images/content/8697_20632_2.png"/&gt;
        &lt;div class="img-overlay"&gt;Planet Six &amp;#x2014; http://ciclops.org/view/8697/Planet-Six.html&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The resulting site is something to be proud of. The search is faster and more capable: &lt;a href="http://ciclops.org/group_caption.php%3Fstatic=search.html"&gt;look at the instructions&lt;/a&gt;! I finally managed to do something space related&amp;#x2014;and that all for my favourite planet!&lt;/p&gt;
      &lt;p&gt;I would explore you to have a &lt;a href="http://ciclops.org/search.php.html"&gt;search&lt;/a&gt; through the rich set of images that is available on the CICLOPS site, and let me know what's your favourite!&lt;/p&gt;
      &lt;p&gt;
        &lt;a href="https://twitter.com/carolynporco/status/1498708491325767681"&gt;CICLOPS lives!&lt;/a&gt;
      &lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/concerning-cassini.html</guid>
      <pubDate>Tue, 15 Mar 2022 14:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 99: Allow Null and False as Standalone Types</title>
      <link>https://derickrethans.nl/phpinternalsnews-99.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_99_allow_null_and_false_as_standalone_types"/&gt;PHP Internals News: Episode 99: Allow Null and False as Standalone Types&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, March 10th 2022, 09:04 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I talk with George Peter Banyard (&lt;a href="https://gpb.moe"&gt;Website&lt;/a&gt;, &lt;a href="https://twitter.com/Girgias"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/Girgias"&gt;GitHub&lt;/a&gt;, &lt;a href="https://gitlab.com/Girgias"&gt;GitLab&lt;/a&gt;) about the "Allow Null and False as Standalone Types" RFC that he has proposed.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-099.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explain the latest developments in the PHP language. This is episode 99. Today I'm talking with George Peter Banyard, about the Allow null and false at standalone types RFC that he's proposing. Hello, George Peter, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hello, my name is George Peter Banyard. I work on the PHP language, and I'm an Imperial student in maths in my free time.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Are you're trying to say you're a student in your free time or contribute to PHP in your free time?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I feel like at this time, it's like, both are true at the same time.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Let's hop into this RFC. It is titled allow null and false as standalone types. What is the problem that it is trying to solve?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  1:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This is the second iteration of this RFC. So the first one was to just allow null initially, and null is the unit type In type theory parlance of PHP, ie the type which only has one value. So null is a type and a value. And the main issue is that when for leads more with like inhabitants, and like the Liskov substitution principle. If you have like a method, like the parent method, which can be told like either null or an object, and your implementation in a child class always returns null, for various reasons, maybe because it doesn't support this feature, or whatever is out, or... If your child method only returns null, currently, you can't document, that you can't type this properly, you can document it in a doc comment or something like that. But due to how PHP type handling works, you need to specify at least like another type with null in the union. Basically resort to always saying like mimicking the parent signature, when you could be more specific. This was the main use case I initially went into.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;If I understand correctly, you can't just have an inherited method that has hinted as to just return null?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  2:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. If you always return null, maybe because you always work or something like that, then you must still declare the return type as like null or exception, which is not a concrete because you say what, like why never fail. And like static analysers, if they can figure it out that you're using a child class, they can't maybe like do some assumptions or work further down that like what you're doing is redundant or things like that. So that's one of the main reasons I initially went with it. And I didn't add false initially, because it was like, well, false, it's not really a type properly. It's, it's what's called a value type. False is one value from the Boolean type. And I was like, Well, okay, we're just going to limit it to like, being the type theory purist, limited to proper types, where null is a proper type, although it's a bit sometimes misunderstood, I feel in the PHP community at large. And then people were like, well, if we add null, then by the only type-ish thing, which you can use in a type declaration, or whatever, which can't be used in a return type on its own, is false. And it's just weird. So why not add it in full. So that was the second thing as to why I added it. Some of PHP internal's functions being terribly designed because they were designed back in the early noughties, return null on success and false on failure, which you can't probably type at the moment. Currently, we need to type them as like Boolean or null, but true can never be returned in this case. And there are some other some other people have reached out to me it's like, well, yeah, but I always return false in this case. Or I also return always true in this case, although true, we have this weird asymmetry that we have false as a value type and not true.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What was the reason for having false but not true?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  3:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When the union type RFC got discussed and passed for PHP 8.0, false was added, because a lot of traditional behaviour of PHP internal functions, was to return false on failure, instead of the technically more correct thing would be to return null. Because loads of functions return a false on failure, and saying that like in returns, these types, or a Boolean would be basically lying because you could never have true, false was included in it. With the restrictions that you can only use false as the complement with other types. So you need to do for example, array, or false, you couldn't just use false.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would it also mean that you can define a return type of a method that inherited a method that returns a bool, as false?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  4:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, that would be now possible with the amended proposal. Yeah, which goes back to this weird a symmetry, we're probably. Adding true to make a complete would be a future RFC to do.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Now, we've talked about return types. But I guess the reverse applies to arguments?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  5:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Arguments and property types also would, would be allowed to, like declare themselves as like null or false. The usefulness here is way more limited. Because if you declare an argument to be of type null, then basically you can only ever pass a null to it. And then therefore, the type doesn't do anything.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But in an inherited method, you could then widen it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  5:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, exactly. You could always say: Well, this argument exists, it's always null. If you extend like your class or message, then you can add other types. But in theory, you can already do that by adding like an argument at the end of the message, because that's LSP compliant. The case for, and properties of those, because they are typing, they're in like their beads. Kind of debatable why you would do that. But it's just that like, well, if you accept types at one point, just restricting them like somewhere else gets very weird. At this point is more like look at the human review, or like use static analysis for the analyser to tell you like this argument is redundant and just remove it or this property doesn't make any sense. Because if it can only ever be null, why does it even exist in the first place?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Right now, you can already use false in union types, but why not with null or false?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  6:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That goes back to the when a union type RFC got introduced. Null got added as a keyword. Before you could only use the question mark, before a type to make the type nullable. If you have a more complex union type, to not use the question mark in front of it. Therefore, the null keyword got added as a proper type. And because the logic was, Well, you shouldn't ever be able to return just null. Because then that function is kind of equivalent to void. Because of that, it was said that like, Well, okay, null and false basically have like kind of the same status is that like, if you just want to use null on its own, you're doing something kind of weird. And if you're returning more than false, like that signature is very strange. I think when that was discussed, nobody knew initially that an actual PHP function within one of the extensions, like in core had such a weird signature. Which mainly, we just started discovering that after this got, like accepted and we could like actually start properly typing the internal functions, and then you discover these weird edge cases where sounds like, that's a bit strange, can't properly document it. We just need to make like a note on the PHP documentation side. And like the type signature kind of lies to you. PHP's type hierarchy is a bit strange, void kind of lives on its own. So if the function is marked as void, it must always like any child inheritance, or whatever needs to be void. And when you type return in the function body, you need to always use return with like a semicolon afterwards, you can't even return null. Although, under the hood, PHP will always return a value when you call a function, even if the function is void, which will be null.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC also talks about question mark null, what is that supposed to be? Is that null or null?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  8:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;PHP has this limited type redundancy checks at compile time. It will basically check if you're duplicating types. So if you write for example, int or int, even if it's capitalized differently, PHP was like, okay, just specifying twice the same type in this union. This is redundant. And then it will throw a compile error, we're basically saying, maybe you're just doing a mistake, maybe you meant something else. In the same vein, basically the question mark, gets like, translated into like, any seeing pipe null. And so if you write null with a question mark in front of it, it's just saying like, well, you're doing null or null, which is basically redundant. Therefore, you'll get like a compile time error telling you like.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That seems sensible to me. What's been the feedback so far?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  8:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The most feedback, I think I've got it when I first proposed it in October. And at the time, it was like, Yeah, this is useful. And it's kind of needed because well, having always more type expressiveness is I think, good in general. But the main feedback at the time was like, Well, why not include false? The other feedback I got was basically, well, for consistency, what shouldn't you also add true? Yes, I do agree with this. I frankly, find it very strange that we landed in this situation where we only have one of these value types, either true and false, or none of them would make more sense to me. But that's expanding the scope. And it's kind of not this is not really concerned with this specific detail. Probably next, another RFC to do, for either myself or somebody else. It's just like propose true as a value type.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Is the implementation of this RFC complicated?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  9:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's very simple. It basically removes checks, because currently in the compile step, which checks for like type signatures, it needs to check that like, Well, are you declaring false or are you declaring null, and these checks get removed, so it makes the code a bit more streamlined. Oh, there's one change in reflection. For backwards compatibility reason, because of the fact of the question mark, any union type which is composed of a only two types, where one of them is null,will get converted in reflection to use the question mark notation, which is kind of a bit weird because it then gets converted into like a name type instead of a union type in reflection. But that's there, because of backwards compatibility reasons. I am breaking this into the more sensible reflection type. If you have a type of null and false, then you'll get a reflection union type instead of a named. From my understanding from reading the reflection code, the intention was always probably in PHP 9, to remove this distinction. So if you get a named type, it's only a single type instead of a possible nullable type. And any nullable types get converted into like a reflection union type when you have like null and the other type. Maybe this is a good test case to see if your code breaks.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I would probably call that a BC break though.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This only happens if you do false union null. You can't use false currently on its own. And I think like, if you get false, as a named argument type, with like a question mark in front of it. Because it would be completely new, and you would never deal with it. It's like, well, this can also break because false can be in the Union type. If your library or the tool supports union types with the reflection thing, it will automatically know how to deal with false because it needs to know how to deal with it. And null. So that was kind of also the logic. It's like, well, okay, like if the tool supports that, which it needs to, then if you put this case into that bracket, it will work. It makes kind of the reflection code a bit more complicated at the moment. The whole fact that we need to juggle between like figuring out like, should we use the old like the backwards compatible thing reflection of like using a name type instead of the Union type, if there's a null and depending on the type, makes a reflection code unwindy and everything. And we have like a special function in C, which is basically just like, okay, which object do I need to create, depending on this type signature?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When do you think you'll be putting this up for a vote?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  11:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I suppose I could put it up for vote immediately now. I am planning on maybe putting this on to vote at the end of the week or something like that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, thank you for taking the time today to talk about this RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  12:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for having me on the podcast.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying development of the PHP language. I maintain a Patreon account for supporters of this podcast, as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/null-false-standalone-types"&gt;Allow Null and False as Standalone Types&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-099.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-99.html</guid>
      <pubDate>Thu, 10 Mar 2022 09:04:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: February 2022</title>
      <link>https://derickrethans.nl/xdebug-update-february-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_february_2022"/&gt;Xdebug Update: February 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, March 8th 2022, 09:25 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday after the 5th of each month.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In February, I spend 26 hours on Xdebug, with 24 hours funded.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="releases_and_development"/&gt;Releases and Development&lt;/h2&gt;
        &lt;p&gt;As first task in February I &lt;a href="https://xdebug.org/announcements/2022-02-01"&gt;released Xdebug 3.1.3&lt;/a&gt; which addressed a bug with the debugging protocol's &lt;code&gt;eval&lt;/code&gt; command and exceptions, an issue with the debugger generating invalid XML, and a memory leak and performance issue with tracing.&lt;/p&gt;
        &lt;p&gt;Since then I have worked on triaging and fixing a few more issues. These have currently not been merged due to changes in GitHub Action's Windows support. I expect that to be resolved by the time you read this.&lt;/p&gt;
        &lt;p&gt;Fixes include a crash while using closures and static properties, something that Symfony Cache seems to use a lot, some memory leaks, and an issue with the legacy &lt;code&gt;XDEBUG_SESSION_START&lt;/code&gt; trigger. I expect Xdebug 3.1.4 to be released imminently.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="priorities"/&gt;Priorities&lt;/h2&gt;
        &lt;p&gt;In the previous &lt;a href="https://derickrethans.nl/xdebug-update-january-2022.html"&gt;update&lt;/a&gt; I wrote about what I had in mind for this coming year. From feedback to this communique, and a highly scientific Twitter poll I've decided to prioritise the following items:&lt;/p&gt;
        &lt;ol&gt;
          &lt;li&gt;
            &lt;p&gt;Creating an &lt;em&gt;Xdebug Course&lt;/em&gt;: explaining in great detail how Xdebug works, how you use it, how you can get the most out of it, and many scenarios on how to set-up debugging in different environments. This needs to go beyond referential documentation pages, and will hence become a combined set of videos and tutorials, with examples and work-along exercises.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;em&gt;Xdebug Recorder and Player&lt;/em&gt;: A new feature in Xdebug which would allow for a full request to be stored in a file, including every intermediate state. Combined with a player, which would allow for replaying the request and interrogating every variable at every point during the execution of said script, through the debugging protocol and interacting with your IDE. The recorded files would be self contained, without needing access to the (original) source code. Besides "step over" it would also have a "step back", and perhaps even a slider to slide back and forwards through time.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;I have started making an outline for the &lt;em&gt;Course&lt;/em&gt;, and a prototype for the &lt;a href="https://github.com/xdebug/xdebug/compare/master...derickr:recorder?expand=1"&gt;Recorder&lt;/a&gt; and Player.&lt;/p&gt;
        &lt;p&gt;Let me know if you have ideas about which specific topics the Course should offer.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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 &amp;#xA3;49/month.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one more video on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://youtu.be/WMGYfgzoap0"&gt;Debugging Unit Tests with PhpStorm&lt;/a&gt; explains how to use PhpStorm to debug Unit Tests, following a question on Twitter.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In February, no new business supporter signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-february-2022.html</guid>
      <pubDate>Tue, 08 Mar 2022 09:25:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 98: Deprecating utf8_encode and utf8_decode</title>
      <link>https://derickrethans.nl/phpinternalsnews-98.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_98_deprecating_utf8_encode_and_utf8_decode"/&gt;PHP Internals News: Episode 98: Deprecating utf8_encode and utf8_decode&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, March 3rd 2022, 09:02 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Rowan Tommins (&lt;a href="https://github.com/IMSoP"&gt;GitHub&lt;/a&gt;, &lt;a href="https://rwec.co.uk"&gt;Website&lt;/a&gt;, &lt;a href="https://twitter.com/Stavron"&gt;Twitter&lt;/a&gt;) about the "Deprecate and Remove utf8_encode and utf8_decode" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-098.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP Internals News, a podcast dedicated to explaining the latest developments in the PHP language. This is episode 98. Today I'm talking with Rowan Tommins about the "Deprecate and remove UTF8_encode and UTF8_decode" RFC that he's proposing. Hi, Rowan, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  0:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Rowan Tommins. I'm a PHP software architect by day and try and contribute back to the community and have been hanging around in the internals mailing list for about 10 years and contributed to make the language better, where I can.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Excellent. Yeah, that's how I started out as well, many, many more years before that, to be honest. This RFC, what problem is this trying to solve?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  1:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;PHP has these two functions, utf8_encode and utf8_decode, which, in themselves, they're not broken. They do what they are designed to do. But they are very frequently misunderstood. Mostly because of their name. And because Character Encodings in general, are not very well understood. People use them wrong, and end up getting in all sorts of pickles that are worse than if the functions weren't there in first place.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What are you proposing with the RFC then?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  1:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Fundamentally, I'm proposing to remove the functions. As of PHP 8.2, there will be a deprecation notice whenever you use them, and then in 9.0, they would be gone forever, and you wouldn't be able to use them by mistake, because they just wouldn't be there.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I reckon there's going to be a way to actually do what people originally intended to do with it at some point, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  2:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So yeah, there are alternatives to these functions, which are much clearer in what you're doing, and much more flexible in what you can do with them so that they cover the cases that these functions sound like they're going to do, but don't actually do when you understand what they're really doing.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think we'll get back to that a little bit later on. You're wanting to deprecate these functions. But what do these functions actually do?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  2:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What they actually do is convert between a character encoding called Latin-1, ISO 8859-1, and UTF-8. So utf8_encode converts from Latin-1 into UTF-8, utf8_decode does the opposite. And that's all they do. Their names make it sound like they're some kind of fix all the UTF 8 things in my text. But they are actually just these one very specific conversion, which is occasionally useful, but not clear from their names.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's certainly how I have seen it used in the past, where people just throw everything and the kitchen sink at it, and expecting it to be valid UTF 8, and then at the end, decode. I mean, the decoding was not even part much of this, right? It's just throw everything at it, and then magically it will all be UTF 8. But I reckon that's not really quite the case. When and how does that go wrong?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  3:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So what actually ends up happening is, because text doesn't know what encoding it's in. Something that people misunderstand about character encoding is they think it's like, the text is a certain colour, and the computer knows what colour it is. And if you tell the computer to make it a different colour, then it will work. But it's not like that. In the computer, there's just the sequence of binary. And the encoding is how to read that binary as text. And if you tell the computer to read it as Latin 1, it will read it as Latin 1. If you take to convert from Latin 1 to UTF 8, it will assume the input is Latin 1, it will convert to UTF 8 on that basis. If your text actually wasn't Latin 1 in the first place, you're just going to end up with garbage. And some of the worst cases of that is when you already have UTF 8, and then you run utf8_encode on it, because the language doesn't know that you've already got UTF 8, so it tries to read its Latin 1, write it out ass UTF 8 and you get this weird Mojibake. I don't know pronouncing that right.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think it's pronounced Mojibake.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  4:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Mojibake.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's a Japanese term, because clearly these things, these issues happened with Japanese text quite a lot because they have a lot more different and difficult characters and encodings as well. With which things often go wrong though?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  4:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Using an unco on text that's already UTF 8 is obviously a big one. Usually obvious, but occasionally people just getting a muddle with that. The other thing that often happens is confusing with similar encoding. Latin 1 is often mistaken for a different coding windows 1252. To the extent that web pages labelled as Latin 1, web browsers will assume that they're actually in Windows 1252. These PHP functions don't make that assumption. If your text is actually in Windows 1252, and it's been mislabelled Latin 1, you might still think you're doing the right thing. So I've got Latin 1 text, but you haven't. And then the characters that are different, are going to get mangled again. And there's a few other related encodings that often look the same. There are a few other encodings that look the same at a glance that again, will go wrong on any character that's different between the different encodings.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How could a function tell which encoding a certain text was in?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  5:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's tricky. There are libraries out there that try to do it. Some encodings that are sequences of bits that aren't a valid character. So if any of those appear, it's definitely not in that encoding. Unfortunately, a lot of encodings, every pattern of bits has a meaning. It's just not necessarily mean. So you can't look at the string and just tell at a  glance. The only way I've seen that does it effectively, is trying to guess based on what language text it might be in. If your text suddenly has a load of symbols in the middle of sentences, you're probably using the wrong encoding. If it's suddenly got a load of capital letters, in the middle of words, you're probably using the wrong encoding. So you can make guesses like that, that ultimately, there are only ever guesses.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's only always going to be a guess, right? You can't really tell for certain what it it is, which I've seen people assume that she can just tell. We have concluded that utf8_encode and decode don't actually do what they say they don't magically encode everything to UTF 8. What if things go wrong? How are errors handled?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  6:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;If you're converting from Latin 1 into UTF 8, there Latin 1 covers all 256 possible eight bit binary strings. Those will correspond directly to a single mapping in Unicode and therefore in UTF 8. So there are no errors as such, when that happens, but it might not be what you want. One of the most notable ones that's different between these encodings is Latin 1 was standardized in 1985, the Euro didn't exist, then. The euro symbol doesn't have an encoding in Latin 1. If you've got a euro sign, you haven't got Latin 1 text, but you might think you've got Latin 1 text, and it will just encode it to what to a control character, which is where the windows 1252 code page puts the euro symbol, it replaces some control characters in Latin 1. One of the reasons why these character encodings are so easily confused is they've all nicely built to being compatible on top of each other. Latin 1 is deliberately an extension of ASCII. Windows 1252 is deliberately an extension of Latin 1, replacing some control characters. UTF 8 is also based on Latin 1, the first section of Unicode is actually the Latin 1, characters UTF 8 will encode and slightly differently so that it can carry on above 256. So in that direction, you can't actually get an error, you could just get a string, that doesn't make sense. Going back the other way. Unicode has, I think, potentially 11 million or something, and actually, at least a million assigned code points. Latin 1 only has 256. So you can't map all those back. And this function, the utf8_decode just replaces any that it can't match with the question mark. Similarly, if the input string isn't valid UTF 8. Again, if you've just misunderstood what strings doing and you haven't actually got a UTF 8 string in the first place, any sequence that doesn't look like valid UTF 8, again, just gets replaced with a question mark. Completely silently you get no warnings in your logs or anything. So you'll just get a few question marks. And problem is, a lot of people are writing text, mostly in English. So it's mostly ASCII. And all of these encodings agree on those first 127 things including all the letters and digits, most of your text will look fine. But if you're using utf8_encode, some of the accented letters will just look a bit funny. If using utf8_decode some of the characters will just turn into question marks. And you might just not notice that for a while until your applications been in production. And now all your strings a messed up.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And I reckon that there's no way to fix that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  9:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No. If you've saved saved the text, particularly with the decode direction. Run utf8_encode wrong, if you're careful and tracked carefully where what you've used, you can retrace your steps back to the original string. But if you've not understood what it was doing in the first place, you might have run it more than once, or put it into a system and then re interpreted it in a different way. And it can sometimes be quite hard to trace back what the original string was. You'll sometimes just have to edit it by hand. And guess that, oh, that's probably any acute because that was the word that was trying to be there. That was probably a curly quote mark that somebody was trying to type and those kinds of things.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Talking about curly quote marks, I just found out that those are actually are code points in the windows 1252 encoding. Because I just had to edit a document that had these things in there. But the file was set as... this is UTF 8, which was a lie. It was a lie to begin with. We've established that these functions are pretty much destructive to text potentially, as well as not really doing what they say they do: encode every random stuff to UTF 8 or the other way around. I saw any RFC that you've done some research into their usage, didn't bring up anything interesting to talk about?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  11:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, so there's a few things. So what I downloaded, it was last year, actually, I kind of had to pause on this RFC for real life happened a bit to me. So last year, I downloaded the 1000, I think top packages on Packagist, I'm most popular downloads, and went through all the uses, I could say of these functions. There were a handful that were using them correctly, they were checking that their input was Latin 1, or the output they needed was Latin 1. And using these, there were a few of those that were questionable, where they might have mistaken Latin 1 for Windows 1252. And actually, they were going to mess up any Euro signs or any of those few extra things that Microsoft added over the top of those control characters. There were a few using strftime, which can do translated Date Time strings. Those it turns out that functions been deprecated itself now, that will become a non issue, some people will have to find a different solution to that anyway. One of the odder ones that I've seen, which technically works, but only accidentally is people use it for what I describe as armour, where they've got a system that wants UTF 8 text, often encoding as JSON or something like that, where it needs to be UTF 8, they've got some unknown encoding that's not UTF 8, they encode  to UTF 8, transmitted through the system. And then on the other end, run utf8_decode and they'll get back the string that they put in, because it never errors, there will always be a mapping of any string of bits that this function will give in UTF 8, it just won't be a meaningful string. You could put a JPEG image through utf8_encode, and you will get a string that is valid UTF 8, it's just not going to be very useful UTF 8. It's kind of a bit of a weird way of doing the thing you might do with base 64, or quoted printable encoding or something like that almost something for transport, it technically works. But this probably isn't the function you want to be doing it with. It's not a very useful encoding. And then there were a good number, which just tried throwing all the functions they could. And I kind of I don't want to call out the people with this. I think they were genuine mistakes, they were genuinely trying to solve a problem. But some of them just in hindsight looking at them or kind of hilarious. I think the one that makes me laugh most is the person who raised the StackOverflow question because their CSV file, some of the fields had grown to 32 kilobytes long, because they'd repeatedly run the same string through utf8_encode so many times, that each time it was encoding a single byte to multiple bytes, and then single bytes of that to multiple bytes. And only when it got to 32 kilobytes in one field, did they question whether they were doing the right thing? By which time their text was probably irrevocably lost in whatever other processing they've done on this file.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Excellent encryption.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  14:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC talks about a few other approaches to instead of deprecating utf8_encode and decode. What are the things that you look at? And why did you reject them in the end?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  14:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;One of the most obvious things you could do? The biggest problem is the name of the functions. Could you just rename them? The problem with that is you'd have to spend a long time doing it because you want to introduce the new name in one version of PHP, then deprecate in a later later version of PHP, and then finally remove. And then at the end of it, you'd have these very specific functions. We could call them latin1_to_utf8 and utf8_to_latin1. If we were designing those functions, if you put an RFC to, to add those functions to the language, it wouldn't pass. There's they're very why, why would we have these specific functions, and we'd still have this problem of Windows 1252, and other related encodings, like Latin 9, which is the official successor to Latin 1, and also has a few differences amongst it. They still wouldn't solve a lot of people's problems. A lot of the people that actually want Latin 1 are going to need the euro symbol. So they don't probably don't actually use Latin 1 any more. Because I guess Canadian French, and Mexican Spanish, need to probably that in one's probably still a decent encoding for but the Western European languages it was originally designed for, probably everyone's going to want a euro symbol. Changing the name just leaves us with these awkward functions still. You could instead or as well add options to them, you could add a parameter to them that indicated what the source or destination encoding was. That defaulted initially to Latin 1, and then you were forced to add it later. And then at least you'd be spelling out what encoding it was. The problem with that is, the more encodings, you add, there's actually quite a lot of code that would need to then be added to the function, and it will be duplicating functions we've already got.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Such as?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  16:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So we've actually in PHP got three functions that can convert between any pair of encodings, including the ones that these functions do. They're all unfortunately in extensions, which are technically optional. Which is something that the way PHP is modular, means that a lot of things that you'd think were kind of just part of the language are technically optional, for one reason or another. But we've got mb_convert_encoding from the mbstring extension. We've got iconv, which uses an external library of the same name.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Are you sure it just doesn't use a GCC function or the glib functionality in PHP?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  17:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The iconv function uses whatever iconv is available on the system, and seems to vary quite a lot between systems. Oddly, one online code running tool I tried, doesn't actually recognize 8859-1 as an encoding in the iconv function. I don't know why. Just something about the libraries, that version of PHP was built, built against. The most powerful one we've got but also the least documented is the intl extension, which is built on the ICU library, made by the Unicode Consortium. That has a lot of options around how you handle errors and missing characters and supports a lot of different character sets. Some was completely undocumented, I've tried to write a manual page for it, which will hopefully get merged and put live soon. So at least, there will be some documentation there's a, there's an object that you can use with lots of options. But there's a static method, which just takes a from and to encoding. So that's one option. The mb_convert_encoding is probably the most widely available. And maybe we should be looking at making that MB string, less optional. I don't know what that looks like, because of the way, unless you force people to compile it in a lot of the Linux distros. Distribute every module they can separately, they make optional.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But they also make it easy for you to install them then.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  18:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;They make it very easy to install. So I don't know how many people actually run PHP with just its minimal set of modules. And how many just install a default set. The default set is a bit vaguely defined, unfortunately. So that's one of the my main hesitation with this removal, that although we've got these alternatives, we've got these three alternatives. They've all got slight problems, and they're all optional.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But considering that utf8_encode and decode don't actually really do well, they say they do, everybody that had to do character set conversions correctly, would have already been using these functions.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  19:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Indeed, yes. So I've seen people misuse all of these. Again, people do just generally misunderstand character encoding. MB string does have a function to guess character encoding. As you're saying earlier, people just kind of assume that that will work. A lot of the time, it can't really tell the difference between different character encodings. It can tell you whether a string is valid UTF 8, it can't tell you whether it's Latin 1 or Windows 1252, or any of these others that are single byte encodings.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think ICU actually as functionality for guessing an encoding as well, but it will give you back an array of possibilities and perhaps even with a confidence. But it's a long, long time since I've looked at that. So I'll have to revisit it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  20:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, that would at least be a more kind of transparent way of doing it that. And that's I guess what I'm trying to do with removing these, is that if you're forced to specify a pair of encodings, as you do for these other functions, at least hopefully, somewhere in your mind, you're going to be thinking about what encodings you might have, rather than just reaching for the first function you find.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yep, exactly. What is the feedback being so far?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  20:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Generally positive. There hasn't been a lot of a lot of comments. But those that have been have generally been supportive. I liked somebody said: All the times they've seen it used, including when they've used it themselves, it's been a misunderstanding. I'd like to hear more feedback of anyone. Anyone does have quite. The main feedback I have had has been around making sure there are alternatives to recommend to people. So anyone who is using these correctly, or nearly correctly, what we tell them to use instead, how do we make sure that's clear, and clearly documented, and we're recommending the right thing. I'm going to think a bit more about that, whether we should be being more definite in recommending one of these options. Particularly I think iconv does seem to have these odd platform issues. They used to be a fourth option. While I was looking at this, they used to be another library called recode. That one seems to have been discontinued. Some references in the PHP manual still refer to recode as an optional option for doing this. But that's been long since shelved. So MB string has the benefit that it doesn't rely on any third party libraries. It's technically a third party library, but it's shipped with PHP, and I don't think anything other than PHP uses it any more. And there have been a lot of there's been a lot of work on that library recently, particularly somebody called Alex Douward, apologies, if you're listening to this, and I pronounce your surname wrong, has done a lot of great work. I've seen recently improving that extension, making sure the detection algorithm is doing as sensible results as it can and improving the test test coverage of that extension and things like that. So that gives me a bit more confidence in that extension, which initially was one of those PHP reinventing the wheel, it felt a bit like, so probably update the RFC to more explicitly say, that's the number one recommended path.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  22:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And of course, you can link that from the utf8_encode and utf8_decode manual pages as well. Please don't use this instead, do this, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  22:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah. And that's again, where it can be a nice clear drop in replacement, so that people are using it right. Here's exactly what to what to use instead. But hopefully, while they're replacing it, they may be at least think about whether it was doing what they what they were hoping for in the first place.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  22:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When do you think you'll be bringing this up for a vote?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  22:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Unless I get more feedback, further changes? I'll probably tweak that wording in terms of the recommendation that we'll put to users. Otherwise, probably in the next couple of weeks, unless I hear any more, to see if any last minute criticism comes out the woodwork when people are asked to vote on it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  23:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah that always happens, right? No comments when there isn't a request for comments. But loads of comments if people are voting on it, and it makes it to Twitter. Okay, Rowan, thank you for taking the time today then to talk about this RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Rowan Tommins  23:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you very much for having me.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  23:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast, as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/remove_utf8_decode_and_utf8_encode"&gt;Deprecate and Remove utf8_encode and utf8_decode&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-098.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-98.html</guid>
      <pubDate>Thu, 03 Mar 2022 09:02:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: Hillingdon Trail</title>
      <link>https://derickrethans.nl/hillingdon-trail.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_hillingdon_trail"/&gt;Walking: Hillingdon Trail&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, March 1st 2022, 14:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Over the last year I have walked many routes in and near London, but I never really wrote about that. I'm planning to change that this year, and have already started that resolution with the &lt;a href="https://derickrethans.nl/england-coast-path-1.html"&gt;England Coast Path&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;This time, I will have the story of the &lt;a href="https://hiking.waymarkedtrails.org/#route?id=156832&amp;amp;type=relation&amp;amp;map=12.0/51.5583/-0.4412"&gt;Hillingdon Trail&lt;/a&gt;, from Cranford to Harefield (with extension to Rickmansworth), that I walked on &lt;em&gt;February 12th, 2022&lt;/em&gt;.&lt;/p&gt;
      &lt;p&gt;The trail starts at Cranford Park, near Hayes and Harlington. I arrived in Hayes and Harlington by tube and train, and after a 20 minute walk I arrived at the trail head, where a priest and some other people were preparing to host a wedding at St. Dunstan's Church. I did not hang around, as I had some walking to do.&lt;/p&gt;
      &lt;p&gt;The trail follows the &lt;a href="https://hiking.waymarkedtrails.org/#route?id=4601&amp;amp;type=relation&amp;amp;map=10.0/51.4851/-0.1208"&gt;LOOP&lt;/a&gt; for a little while until it meets the Grand Union Canal. I know the canal well, as I walk alongside it often on my daily lunch time walk, but also because I walked the length of it last year all the way to Birmingham.&lt;/p&gt;
      &lt;p&gt;The Paddington Arm starts at Bulls Bridge, and this is where the Hillingdon Trail continues.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Bulls Bridge" src="https://live.staticflickr.com/65535/51904266175_85d0f8b2cd_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Bulls Bridge&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After about 2&amp;#xBD; km the walk leaves the canal and starts following Yeading Brook, which it will do for a significant part of its length. There are quite a few open spaces around here near Yeading Brook Meadows, but the ground was fairly spongy. I was happy that I was wearing my walking shoes, instead of just normal trainers. After more of this, and passing through Michael Frost Park, and besides Michael Frost Pond, the route took me past through some woods, with a lot of few stiles. Although not all of them were framed as nicely as these, and one of them was hardly wide enough for me to squeeze through. I'm going to report &lt;strong&gt;that&lt;/strong&gt; one.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Stile at the End of the Tunnel" src="https://live.staticflickr.com/65535/51903950914_8f1f6e1847_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Stile at the End of the Tunnel&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I recently acquired a new Nikon 18-300mm lens which I was trying out for the first time in the field on this trip, and did allow me to take shots like this. I will certainly have to play more with this to get the best out of it. Let's call it a learning experience.&lt;/p&gt;
      &lt;p&gt;Parts of this section of the trail were also very muddy, and I was happy to see that some effort was made to prevent walkers from sinking into it by providing this nice wooden walkway.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Wooden Path" src="https://live.staticflickr.com/65535/51903717463_e2f9051e55_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Wooden Path&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Crossing the Metropolitan Line" src="https://live.staticflickr.com/65535/51904274570_0c1491f0cb_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Crossing the Metropolitan Line&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Not far after this I crossed under the busy A40 "Western Avenue", which was not as conspicuous as I feared. The walk continued for a little stretch along the Yeading Brook, but it soon switched to the Ickenham Stream. It had occasional muddy sections, but eventually turned into a metalled road which led me across the Metropolitan Line.&lt;/p&gt;
      &lt;p&gt;Near Ruislip the trail was diverted due to the construction of HS2. It was not very well signposted, but luckily I had checked the map and did not make a silly de-tour that would have required me to back track. Instead of continuing to follow the small and pleasant Ickenham Brook you cross a golf course. I walked along the wrong side of a hedge and stream here, as I hadn't noticed the path (Clack Lane) that I was supposed to follow. I would have gotten to the same spot, but I am always a bit of a stickler of following the actual signposted route, so reversed a little to follow it.&lt;/p&gt;
      &lt;p&gt;Beyond Ruislip Lido the trail meanders through the Ruislip Woods Nature Reserve, with great names such as Copse Wood, and Mad Bess Wood. The trees were still bare, but that made for an excellent contrasting photo.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Contrasting Trees" src="https://live.staticflickr.com/65535/51902668227_d890d32a0f_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Contrasting Trees&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="The Start of Spring" src="https://live.staticflickr.com/65535/51903722203_db66eb8707_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;The Start of Spring&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Besides the black and white trees, there were also some minor streams where plants were trying to poke through announcing the start of Spring.&lt;/p&gt;
      &lt;p&gt;From here it is a climb into the village of Harefield, and then down again. While descending from the hill, the Sun was very brightly reflecting on Broadwater Lake, between the Grand Union Canal and the river Colne.&lt;/p&gt;
      &lt;p&gt;On the way down I also spotted a good friend further up the hill, the Old Orchard pub, where &lt;a href="https://derickrethans.nl/the-loop-part11-and-12.html"&gt;many years ago&lt;/a&gt; we in interrupted section 12 to enjoy some ciders in their sunny garden. But I digress.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Broadwater Lake" src="https://live.staticflickr.com/65535/51903643146_ed9b70b3d2_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Broadwater Lake&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Instead of going through Harefield, the Hillingdon Trail instead descends to follow the canal for a while, where a Red Kite was on the hunt. It doesn't follow it for very long, and just before Copper Mill lock, the trail again goes up through Park Wood, north of Harefield. That meant a climb but it was worth the effort with great views and quite bird song in the woods.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Red Kite" src="https://live.staticflickr.com/65535/51907976989_9d966422f6_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Red Kite&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From the top it was a slower decent back to the Grand Union Canal at Springwell Lock where the trail's end is.&lt;/p&gt;
      &lt;p&gt;I still had to go home and instead of walking back up the hill to Harewood and get an hourly bus and a tube, I continued walking towards Rickmansworth along the canal. It was a beautiful day, and from Rickmansworth it would be much faster to get home anyway.&lt;/p&gt;
      &lt;p&gt;Between the end of the trail, and the ponds of Rickmansworth Aquadrome there is an old factory on the other side of the canal, with some stuffed toys hanging from supporting beams.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Harefield (Ex-)Limeworks" src="https://live.staticflickr.com/65535/51903653456_e4227723da_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Harefield (Ex-)Limeworks&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The walk was fairly varied with lots of different scenes, with churches, woods, canals, hills, and open country side. I can recommend this 35 kilometre/21 mile walk, which I accomplished in 6h20m.&lt;/p&gt;
      &lt;p&gt;I hope you enjoyed this tale of the Hillingdon Trail. You can find more photos in my Flickr &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72177720296954028"&gt;set&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In my next adventure, I will make exploratory from the North Downs to the South Downs, which I'm intending to walk later this year.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/hillingdon-trail.html</guid>
      <pubDate>Tue, 01 Mar 2022 14:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: England Coast Path (part 3)</title>
      <link>https://derickrethans.nl/england-coast-path-3.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_england_coast_path_part_3"/&gt;Walking: England Coast Path (part 3)&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, February 22nd 2022, 14:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The weekend after my &lt;a href="https://derickrethans.nl/england-coast-path-2.html"&gt;second walk&lt;/a&gt; along the new section of the England Coast Path, I set off to Kent again to walk the third and last stage, from Cliffe to Grain.&lt;/p&gt;
      &lt;p&gt;The day was &lt;em&gt;January 29nd, 2022&lt;/em&gt;, and it was absolutely gorgeous.&lt;/p&gt;
      &lt;p&gt;I finished at the Six Bells in Cliffe in the previous section, which then stipulates that I have to travel there again to continue my walk. I took the train to Rochester where I would pick up the hourly (Saturday) bus to Cliffe. I arrived fairly early, as I did not want to miss it. At the appointed time however, there was no sign of a bus. After about 20 minutes I started looking for alternative plans to get to my walk, with as an option going to the &lt;strong&gt;end&lt;/strong&gt; at Grain, and then walk back. The departures board showed that bus leaving in a few minutes. Just &lt;strong&gt;behind&lt;/strong&gt; the bus to Grain, I spotted my actual bus&amp;#x2014;it was merely 25 minutes late! I am glad it did not come to me taking the bus to Grain, and then walking the route in reverse. More on that, later.&lt;/p&gt;
      &lt;p&gt;After arriving at Cliffe I walked back through the RSPB Cliffe Pools Nature Reserve to the river, to continue the England Coast Path. Although it was a little cold, the Sun was more than warm enough for me to not to have to wear a coat (yet), and I quickly stowed it away while admiring Redham Mead.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Redham Mead" src="https://live.staticflickr.com/65535/51852632434_41991980f9_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Redham Mead&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The path follows the sea wall from pretty much here all the way to the Isle of Grain, with some small detours. Looking over the seawall often showed much rubbish, washed up from either the North Sea or the Thames. It pains me to see that the river is so polluted.&lt;/p&gt;
      &lt;p&gt;On the right hand side (going East) there are the Marshes and Saltings that are so common to this part of Kent.&lt;/p&gt;
      &lt;p&gt;The dyke itself had some barbed wire, but more interestingly a bunch of hardy trees, such as this one. I am surprised it managed to go here on this windy stretch.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Hardy Tree" src="https://live.staticflickr.com/65535/51852385418_daa351f48e_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Hardy Tree&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Did I say windy?&lt;/p&gt;
      &lt;p&gt;Although the day started nice and sunny, with me not needing to wear a coat, the weather steadily deteriorated. Clouds started to move in, and the wind picked up significantly. So much so that when I finally was convinced by the wind making me cold that it was time to put my coat back on again, it was akin to a gale. This was right at a point where the path was going south to north, instead of west to east. A cyclist stopped nearby and we had a bit of a chat while he was also trying to put his coat on. He held up his bike and it quite significantly got picked up by the wind too. While I had started this day's walk at Cliffe, he had started all the way at Woolwich, where I started section one of this three section route.&lt;/p&gt;
      &lt;p&gt;When I was warm and protected from the wind again, I continued towards Grain. Not much after that I met an elderly lady and her grandson, going the opposite direction&amp;#x2014;nose into the strong wind. Here I came to the conclusion that if I had not spotted the bus to Cliffe behind the one to Grain, my faith would also have been to walk the whole 30 km with the wind trying to make me fail!&lt;/p&gt;
      &lt;p&gt;By the time I arrived at Allhallows, the wind had luckily quieted down a little.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Allhallows Beaches" src="https://live.staticflickr.com/65535/51852318616_2d531cd7ef_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Allhallows Beaches&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Just before Allhallows the path leaves the vicinity of the Thames for a while to skirt around the &lt;a href="https://www.geograph.org.uk/snippet/7420"&gt;Dagnam Saltings&lt;/a&gt;. When it returns you end up at the &lt;a href="https://www.haven.com/parks/kent/allhallows"&gt;Allhallows Holiday Park&lt;/a&gt;. I was quite surprised to find it not totally empty at this time of year.&lt;/p&gt;
      &lt;p&gt;Leaving the beach and the resort behind, the path continues along the south bank of the Yantlet Creek and around the Allhallows Marches.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Allhallows Marches" src="https://live.staticflickr.com/65535/51852972820_c7f38a9e17_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Allhallows Marches&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From here you get a good view of the &lt;a href="https://en.wikipedia.org/wiki/Grain_Power_Station"&gt;Grain Power Station&lt;/a&gt; looming in the near distance.&lt;/p&gt;
      &lt;p&gt;It is currently not possible to skirt the full outline of the Isle of Grain. Perhaps in the future there will be a bridge to cross into the "North Level" of the Grain March.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="Sheep!" src="https://live.staticflickr.com/65535/51852395023_71a725baf1_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Sheep!&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;On this stretch I also encountered a flock of sheep, that needed some encouragement to move along and let me pass. At this time I was feeling like I was nearing the end of the walk. The light changed with dusk approaching. A few scattered farms can be seen across the Marshes too.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Funding" src="https://live.staticflickr.com/65535/51852975650_79415bde66_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Funding&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A new section of the path and a sparkly clean and new fence highlighted that part of the funding for this new section of the England Coast Path was provided by the European Agricultural Fund for Rural Development, from the European Union. It continues to amaze me how much the European Union has funded some of Britain's natural, cultural, and social projects. Let's hope that additional funding is made available to extend the England Coast Path further too.&lt;/p&gt;
      &lt;p&gt;At the end of this stretch of this new path I walked into the outskirts of &lt;a href="https://en.wikipedia.org/wiki/Isle_of_Grain"&gt;Grain&lt;/a&gt;, a town of around 1600 people. It is not a very big town and after passing St James Church, I made it to the coast and the end of this section of the England Coast Path.&lt;/p&gt;
      &lt;p&gt;I was fairly early for my bus&amp;#x2014;I had just missed it again&amp;#x2014;so I wandered a little further along the coast before finding the bus stop. In the flats between here and Sheerness lies &lt;a href="https://en.wikipedia.org/wiki/Grain_Tower"&gt;Grain Tower&lt;/a&gt; which had a brief time of operation during the World Wars, but now remains derelict.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Grain Tower, with Sheerness across the Medway" src="https://live.staticflickr.com/65535/51851362272_d65e51b948_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Grain Tower, with Sheerness across the Medway&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I was a little sad to miss the sunset here on the flats, but I did have to make the long trip home by bus and train. I did have a little time to stand on the beach and look at the shells.&lt;/p&gt;
      &lt;p&gt;I hope you enjoyed this tale about the new section of the England Coast Path. You can find more photos in my Flickr &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72177720296328303"&gt;set&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;What will my next adventure be?&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/england-coast-path-3.html</guid>
      <pubDate>Tue, 22 Feb 2022 14:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: England Coast Path (part 2)</title>
      <link>https://derickrethans.nl/england-coast-path-2.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_england_coast_path_part_2"/&gt;Walking: England Coast Path (part 2)&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, February 15th 2022, 14:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The weekend after my &lt;a href="https://derickrethans.nl/england-coast-path-1.html"&gt;first walk&lt;/a&gt; along the new section of the England Coast Path, I set off to Kent again to walk the second stage, from Greenhithe to Cliffe.&lt;/p&gt;
      &lt;p&gt;The day was &lt;em&gt;January 22nd, 2022&lt;/em&gt;. It was another overcast day and the tide was out.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="River Living" src="https://live.staticflickr.com/65535/51851326482_0ceae4c301_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;River Living&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;As it was reasonably early, there were not a lot of people about yet, and I had the path mostly to myself. In the distance I saw a massive electricity pylon, which I ended up walking &lt;a href="https://www.flickr.com/photos/derickrethans/51852294756/in/album-72177720296328303/"&gt;straight underneath&lt;/a&gt;, although that wouldn't be for another 20 minutes.&lt;/p&gt;
      &lt;p&gt;First I peaked through a whole in the whole, neatly outlining the &lt;a href="https://en.wikipedia.org/wiki/Ingress_Abbey"&gt;Ingress Abbey&lt;/a&gt; at Greenhithe, a building and site with a rich history.&lt;/p&gt;
      &lt;p&gt;From Greenhithe the path leads North East for a while to round the Broadness Salt March, before turning near South where you have to divert from the river Thames to go around concrete factories and aggregate terminals.&lt;/p&gt;
      &lt;p&gt;I walked past the Ebbsfleet United football grounds and then headed for the river again. Here was the first diversion of the signed route. Instead of going along public footpaths, the ECP path was directed around the North side of a building-clearance site. I was very much told to keep out of the restricted area.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Restricted Area" src="https://live.staticflickr.com/65535/51852949050_0507c02e5b_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Restricted Area&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;When leaving the building site there was a large queue of HGVs near Lidl's Distribution Warehouse, seemingly not having anything to do at the moment with regards to moving goods around. Soon after that there was another diversion around a building site, where Gravesend is creating a new neighbourhood near Rosherville. This diversion was up quite a steep hill, but and there were many steps to climb, over a hundred.&lt;/p&gt;
      &lt;p&gt;After having returned to the Thames by going down the hill, I started to approach Gravesend, where the bright orange &lt;a href="https://lv21.co.uk/about/"&gt;LV21&lt;/a&gt; could hardly be missed. On the East side of Gravesend there are the Gorden Gardens, with loads of people about enjoying the river side.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Water Breaks" src="https://live.staticflickr.com/65535/51851332687_5f23d5daa3_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Water Breaks&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Progressing East again from the Gardens there was another diversion. Instead of going through an industrial estate, I had to skirt it on its South side to avoid some leaking tires. I don't know what would have been nicer to walk through, as the "detour" was not great, with inadequate footpaths, but when I peeked through the estate it didn't look too nice either.&lt;/p&gt;
      &lt;p&gt;What was however interesting to see was the beginning (or end) of the now disused &lt;a href="https://en.wikipedia.org/wiki/Thames_and_Medway_Canal"&gt;Thames and Medway Canal&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;Having returned back to the river, I looked West to see one of the many jetties that lines this part of the river Thames.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Loading and Unloading" src="https://live.staticflickr.com/65535/51852375378_699db7175c_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Loading and Unloading&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The last section of the walk, after having left industrious Gravesend, became quiet and a lot more deserted. I started to enjoy the walk more now. Although perhaps not as interestingly busy as the first part, I like walking to get out from behind my computer and clear my head. Industrial estate and town centres do not really help with that much.&lt;/p&gt;
      &lt;div class="img-container-left"&gt;
        &lt;img title="It's This Way" src="https://live.staticflickr.com/65535/51852626614_65c32def93_w_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;It's This Way&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;From here on, it is just the Thames to the North, and marshes to the South. Occasional small detours of the dike are necessary. Sometimes to avoid big puddles, and sometimes to avoid ponies.&lt;/p&gt;
      &lt;p&gt;Occasionally there were way pointers, although I don't quite know which other way the path could have gone!&lt;/p&gt;
      &lt;p&gt;It is quite exposed on the dike, and I was happy that I had enclosed myself in a warm and windproof coat. Although grey, there was no rain.&lt;/p&gt;
      &lt;p&gt;The Shorne and Higham marshes on the right hand side of the dike (i.e., the dry side) are a &lt;a href="https://en.wikipedia.org/wiki/Site_of_Special_Scientific_Interest"&gt;Site of Specific Scientific Interest&lt;/a&gt;. They have a fairly stable water level, and are apparently an important habitat for water voles.&lt;/p&gt;
      &lt;div class="img-container-right"&gt;
        &lt;img title="Weird Loop" src="derickrethans.nl/images/content/ecp-weird-loop.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Weird Loop&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Before turning North at the East end of the Higham Marshes, the England Coast Path makes an "interesting" detour with a go-back-on-yourself loop. I don't quite understand why, as the informal &lt;a href="http://www.gps-routes.co.uk/routes/home.nsf/RoutesLinksWalks/hoo-peninsula-path-walking-route"&gt;Hoo Peninsula Path&lt;/a&gt; (HPP on the map) does not bother with this.&lt;/p&gt;
      &lt;p&gt;Although I can see why the route is set out this way&amp;#x2014;there is a possibility of a stream&amp;#x2014;I also think that the England Coast Path should include this loop, as that possibility is also still there at this Southern most point. The path in the loop itself was also not easy to see, with lots of narrow and very muddy trails, where the route that the Hoo Peninsula Path takes seemed much easier going. Perhaps they'll re-adjust this in the future.&lt;/p&gt;
      &lt;p&gt;Having walked this somewhat odd loop, the path continues North with the Higham Saltings on the left, and the Alpha Pool on the right.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Higham Saltings" src="https://live.staticflickr.com/65535/51852957000_8bf6a67dd8_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Higham Saltings&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I finished my near at &lt;a href="https://en.wikipedia.org/wiki/Cliffe_Fort"&gt;Cliffe Fort&lt;/a&gt;, a disused artillery fort built in the 1860s. I could not actually see much of it from the ECP, as it was mostly obstructed by machinery as part of a large aggregate processing operation. The parts of it that I did see looked in disrepair.&lt;/p&gt;
      &lt;p&gt;Another interesting thing here is a &lt;a href="https://en.wikipedia.org/wiki/Brennan_torpedo"&gt;Brennan torpedo&lt;/a&gt; launch slipway. This torpedo is often claimed to be the first guided missile, although that is untrue.&lt;/p&gt;
      &lt;p&gt;From the end of the walk along the Thames, I walked into Cliffe to catch the bus to Rochester to take the train back into London. The bus only runs once an hour on Saturday (and less frequent on Sunday), and of course I ended up missing it by a few minutes.&lt;/p&gt;
      &lt;p&gt;This turned out not to be much of a disaster though, as the bus stop is both the start of its route, and named "The Six Bells". A &lt;a href="https://www.sixbellscliffe.co.uk/"&gt;pub of the same name&lt;/a&gt; is right next to it! I enjoyed a pint while waiting for the bus when a few more walkers showed up. They were walking the &lt;a href="https://hiking.waymarkedtrails.org/#route?id=8864&amp;amp;type=relation&amp;amp;map=10.0/51.1621/0.8872"&gt;Saxon Shore Way&lt;/a&gt;. Perhaps I walk that at some point in the future.&lt;/p&gt;
      &lt;p&gt;The story continues in &lt;a href="https://derickrethans.nl/england-coast-path-3.html"&gt;part 3&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;You can find more photos in my Flickr set &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72177720296328303"&gt;England Coast Path&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/england-coast-path-2.html</guid>
      <pubDate>Tue, 15 Feb 2022 14:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: January 2022</title>
      <link>https://derickrethans.nl/xdebug-update-january-2022.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_january_2022"/&gt;Xdebug Update: January 2022&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, February 10th 2022, 09:47 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update I explain what happened with Xdebug development in this past month. These are normally published on the first Tuesday after the 5th of each month. I am late this month. Sorry.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 45% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In January, I spend my time triaging issues, and planning for this year.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="id_2022_plans"/&gt;2022 Plans&lt;/h2&gt;
        &lt;p&gt;I spend most of my time reflecting on what I can do to make Xdebug even better in 2022, and I have come to the conclusion that this is going to be done through multiple improvements.&lt;/p&gt;
        &lt;ol&gt;
          &lt;li&gt;
            &lt;p&gt;Creating an Xdebug Course: explaining in great detail how Xdebug works, how you use it, how you can get the most out of it, and many scenarios on how to set-up debugging in different environments. This needs to go beyond referential documentation pages, and will hence become a combined set of videos and tutorials, with examples and work-along exercises.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Developing an set-up-free debugger: A new tool that can be used through Xdebug Cloud, that would allow you to debug without IDE.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Xdebug Recorder and Player: A new feature in Xdebug which would allow for a full request to be stored in a file, including every intermediate state. Combined with a player, which would allow for replaying the request and interrogating every variable at every point during the execution of said script, through the debugging protocol and interacting with your IDE. The recorded files would be self contained, without needing access to the (original) source code. Besides "step over" it would also have a "step back", and perhaps even a slider to slide back and forwards through time.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Rewriting Xdebug's Profiler: so that it is more lightweight, and so that it can be enabled for specific parts of an application/request. In addition to this I am looking at sending the profiling data over the debugging protocol, so that visualisation tools do not need to find and read files.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Creating a profile analysis tool: To automatically analyse profiling files and apply logic so that it can point to the most likely cause of bottlenecks.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;Let me know which one of these interests you most, and whether you would be willing to pay for such a tool.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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 &amp;#xA3;49/month.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I did not create any new Xdebug videos this month on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;. But as I mentioned earlier, I am working on a more comprehensive course. Stay tuned!&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In January, one new business supporter signed up:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://www.vema-eg.de"&gt;VEMA eG&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Thank you!&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-january-2022.html</guid>
      <pubDate>Thu, 10 Feb 2022 09:47:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Walking: England Coast Path (part 1)</title>
      <link>https://derickrethans.nl/england-coast-path-1.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="walking_england_coast_path_part_1"/&gt;Walking: England Coast Path (part 1)&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, February 8th 2022, 14:30 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In the last few years I have walked a lot. Longer distance paths such as the &lt;a href="https://en.wikipedia.org/wiki/Thames_Path"&gt;Thames Path&lt;/a&gt;, the &lt;a href="https://en.wikipedia.org/wiki/London_Outer_Orbital_Path"&gt;LOOP&lt;/a&gt;, and the &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72157709293692196"&gt;North Downs Way&lt;/a&gt;. During 2021 I walked the length of the Grand Union Canal, and in the last few months I did one-day hikes on routes in London, with the intention to pick longer walks again in summer, such as the &lt;a href="https://en.wikipedia.org/wiki/South_Downs_Way"&gt;South Downs Way&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/The_Ridgeway"&gt;The Ridgeway&lt;/a&gt;. I use the &lt;a href="https://hiking.waymarkedtrails.org/#route?id=13678910&amp;amp;type=relation&amp;amp;map=12.0/51.4767/0.3905"&gt;Waymarked Trails&lt;/a&gt; website to find the smaller routes, which uses data based on &lt;a href="https://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt;. I have been contributing mapping data to OpenStreetMap for more than a decade now, and find it generally the best mapping data in the UK, especially in the country side.&lt;/p&gt;
      &lt;p&gt;When I was planning my second walk of this year at the beginning of January, I read on Twitter that a &lt;a href="https://www.theguardian.com/travel/2022/jan/12/a-peculiar-beauty-strolling-on-a-new-trail-around-kents-hoo-peninsula"&gt;new section&lt;/a&gt; of the &lt;a href="https://www.nationaltrail.co.uk/en_GB/trails/england-coast-path-south-east/"&gt;England Coast Path&lt;/a&gt; had opened. The new section that goes from Woolwich in London, to the Isle of Grain in Kent. At Woolwich it connects with the &lt;a href="https://en.wikipedia.org/wiki/Capital_Ring"&gt;Capital Ring&lt;/a&gt; and now also the &lt;a href="https://en.wikipedia.org/wiki/Thames_Path"&gt;Thames Path&lt;/a&gt;, which got extended from the &lt;a href="https://en.wikipedia.org/wiki/Thames_Barrier"&gt;Thames Barrier&lt;/a&gt; to the start of the new section of the England Coast Path. As it is a totally new part, it wasn't mapped on OpenStreetMap either yet, something that just &lt;strong&gt;had&lt;/strong&gt; to be added by someone! I decided that someone would be me. Here be dragons.&lt;/p&gt;
      &lt;p&gt;This meant that on &lt;em&gt;January 15th, 2022&lt;/em&gt; I headed out to Woolwich Arsenal on the Tube and DLR to do some proper surveying. I found a GPX file to use in case the England Coast Path wasn't clearly mapped, so that I would not get lost.&lt;/p&gt;
      &lt;p&gt;When I got to the Thames to start, I was greeted with fog. Lots of fog.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Thames in the Fog" src="https://live.staticflickr.com/65535/51852348133_d4bbc95932_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Thames in the Fog&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Who would have thought that a cold day in January would bring fog to the Thames? This however, did not deter me from attempting the first section. From here to Greenhithe.&lt;/p&gt;
      &lt;p&gt;After leaving urban Woolwich Arsenal behind, the route takes past the Plumstead Marshes, around Cross Ness. I then came upon the Victorian &lt;a href="https://en.wikipedia.org/wiki/Crossness_Pumping_Station"&gt;Crossness Pumping Station&lt;/a&gt;, which was used in the 19th and 20th centuries to pump sewer from London into a reservoir which was then released into the Thames &amp;#x2014; downstream from the city. It has now been converted into a &lt;a href="https://www.crossness.org.uk/"&gt;museum&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;The building also marks the start of a stretch along the Thames full of loading docks, piers, and cranes. Some still in use. At one point, there is a viewing platform that allows you look South across the Crossness Nature Reserve (where they stored the poo during earlier times).&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Layers" src="https://live.staticflickr.com/65535/51852277556_f4c537ebea_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Layers&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Between there and Erith, it is more piers, silos, and cranes. Erith is not a particularly interesting town, but it is where nearly a decade ago I started my first long distance walking adventure, the &lt;a href="https://derickrethans.nl/the-loop-part1.html"&gt;LOOP&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;The path East of Erith along the Thames is blocked by a large industrial estate, and you have to divert along a road which lots of heavy traffic, even on a Saturday. It is not a particularly nice section, and for many people this would be the first encounter with the LOOP. I hope it does not put too many people off walking the rest of it, as it gets &lt;strong&gt;much&lt;/strong&gt; better. The England Coast Path follows the LOOP for a significant distance, so I soldiered on.&lt;/p&gt;
      &lt;p&gt;Once you get back to the Thames, there is some pleasant walking, and I believe the path has been restored as I remember it being a mud bath. There were a few other walkers about, and I had a little chat with a couple that was carrying the London LOOP guide book, and assured them it would only get better.&lt;/p&gt;
      &lt;p&gt;Rounding Crayford Ness and the Darent Industrial Park brought the Darent Flood barrier into view.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Darent Flood Barrier" src="https://live.staticflickr.com/65535/51851316182_c98038f7de_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Darent Flood Barrier&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The Thames continues on the other side of the Darent, but there is no bridge which means you have to go around the river, through a small industrial area, along the river Cray, back up, and along a busy dual carriage way, past a quarry, and then back along the river Darent to the Thames. It takes an hour and a half, even at my quick walking pace. It was not always easy walking on the paths either, as many of them were chewed up by dirt bike tires, making it all a muddy mess. Now that I had crossed the river, I had also arrived in Kent.&lt;/p&gt;
      &lt;p&gt;Just east of the river Darent, the Dartfort Clay Shooting Club has their shooting range. I was warned that I should be weary of falling shot due to their activities, but I thought that was more of a joke then the truth. It wasn't, as I actually got hit by falling show on my head. Ow! Luckily neither me, or any of my camera equipment got damaged. I don't understand how they can get away with this, especially as I was so close to the Thames.&lt;/p&gt;
      &lt;p&gt;Continuing along the river the &lt;a href="https://en.wikipedia.org/wiki/Dartford_Crossing"&gt;Queen Elizabeth II Bridge&lt;/a&gt; grows larger and larger, and by the time you pass Amazon's fulfilment centre, it is close enough to make out the individual cables of the cable-stayed bridge that forms part of the Dartford Crossing. The bridge is only used for Southbound traffic.&lt;/p&gt;
      &lt;div class="img-container"&gt;
        &lt;img title="Under the Queen Elizabeth II Bridge" src="https://live.staticflickr.com/65535/51852942190_5a4a175bc5_c_d.jpg"/&gt;
        &lt;div class="img-overlay"&gt;Under the Queen Elizabeth II Bridge&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After another few kilometres zig-zagging through an industrial landscape I came upon Greenhithe, where after nearly 5 and a half hours I finished the first 32km of this new section of the England Coast Path.&lt;/p&gt;
      &lt;p&gt;I took the train home after I found the station, which was fairly well hidden behind a hill and in a valley. At home I enjoyed some tasty &lt;a href="https://untappd.com/user/derickr/checkin/1120639402"&gt;beers&lt;/a&gt; to relax.&lt;/p&gt;
      &lt;p&gt;The story continues in &lt;a href="https://derickrethans.nl/england-coast-path-2.html"&gt;part 2&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;You can find more photos in my Flickr set &lt;a href="https://www.flickr.com/photos/derickrethans/albums/72177720296328303"&gt;England Coast Path&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="patreon"&gt;
        &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
          &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/england-coast-path-1.html</guid>
      <pubDate>Tue, 08 Feb 2022 14:30:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 97: Redacting Parameters</title>
      <link>https://derickrethans.nl/phpinternalsnews-97.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_97_redacting_parameters"/&gt;PHP Internals News: Episode 97: Redacting Parameters&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, January 27th 2022, 09:09 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Tim D&amp;#xFC;sterhus (&lt;a href="https://github.com/TimWolla"&gt;GitHub&lt;/a&gt;) about the "Redacting Parameters in Back Traces" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-097.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Before we start with this episode, I want to apologize for the bad audio quality. Instead of using my nice mic I managed to use to one built into my computer. I hope you'll still enjoy the episode.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is episode 97. Today I'm talking with Tim D&amp;#xFC;sterhus about Redacting Parameters in Backtraces RFC that he's proposing. Tim, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  0:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, Derick, thank you for inviting me. I am Tim D&amp;#xFC;sterhus, and I'm a developer at WoltLab. We are building a web application suite for you to build online communities.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for coming on this morning. What is the problem that you're trying to solve with this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  1:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;If everything is going well, we don't need this RFC. But errors can and will happen and our application might encounter some exceptional situation, maybe some request to an external service fails. And so the application throws an error, this exception will bubble up a stack trace and either be caught, or go into a global exception handler. And then basically, in both cases, the exception will be logged into the error log. If it can be handled, we want to make the admin side aware of the issues so they can maybe fix their networking. If it is unable to be handled because of a programming error, we need to log it as well to fix the bug. In our case, we have the exception in the error log. And what happens next? In our case, we have many, many lay person administrators that run a community for their hobby, they're not really programmers with no technical expertise. And we also have a strong customers help customers environment. What do those customers do? They grab their error log and post it within our forums in public. Now in our forum, we have the error log with the full stack trace, including all sensitive values, maybe user passwords, if the Authentication Service failed, or something else, that should not really happen. In our case, it's lay person administrators. But I'm also seeing that experienced developers can make this mistake. I am triaging issues with an open source software written in C. And I've sometimes seeing system administrators posting their full core dump, including their TLS certificates there, and they don't really realize what they have just done. That's really an issue that affects laypersons, and professional administrators the same. In our case, our application attempts to strip those sensitive information from this backtrace. We have a custom exception handler that scans the full stack face, tries to match up class names and method names e.g. the PDO constructor to scrub the database password. And now recently, we have extended this stripping to also strip anything from parameters that are called password, secret, or something like that. That mostly works well. But in any case, this exception handler will miss sensitive information because it needs to basically guess what parameters are sensitive values and which don't. And also our exception handler grew very complex because to match up those parameters, it needs to use reflection. And any failures within the exception handler cannot really be recovered from, if the exception handler fails, you're out of luck.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Quite a few things to think of to make sure that you're not sharing any secrets. And I certainly have seen almost doing this myself. We now know what the problem is. How is this RFC proposing to fix this?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  4:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Primarily, we want to propose a standardized way for applications or libraries to indicate which parameters hold sensitive values. Our custom exception handler uses reflection as we said before, and it only matches up the parameter's names, but we also have this attribute I am proposing, SensitiveParameter within our application itself. Any parameter names that are not definitely sensitive can be attributed with this attribute. But this only works within our software, but not with any third party libraries we are using, e.g. for encryption or whatever there is. Primarily we want to propose a standardized way an attribute that is in PHP core, anyone can use that and everyone knows what this attribute means. Secondarily, the RFC is proposing a default implementation to keep the exception handler simple. As I said before, we are using reflection. This is very complex, it does not work with the require_once or include_once family, because that are not functions. We need to handle this case to not try to attempt to reflect on those non functions when redacting any parameters. This is complex. And we want to simplify that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;From what I understand this is then a way to make sure that there's a standardized method for marking arguments as being sensitive. And because this is that now standardized, only one solution to the problem has to be found right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  5:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Basically, not every library is using their own attributes, possibly, or we can match parameter names that are not like password, secret, but it can be documented: hey, if you are using sensitive parameters, you should put this attribute and then those exception handlers will be aware that this attribute is sensitive and can strip it, or in case of the RFC PHP itself, will already strip those parameters from the stack trace.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You're suggesting that PHP standard way of showing stack traces also takes care of the sensitive parameter here?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  6:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, exactly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which internal PHP functions are likely to get this attribute?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  6:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Basically anything with a parameter called password or secret, as I said before, examples include PDO's constructor, the database password will be in there and possibly also the user name or host name, which might be considered sensitive. But the password is the most important thing I have on my list. ldap_bind, which possibly includes user passwords; the password_hash function; possibly various OpenSSL functions. One will need to look and this list can be extended in the future as well, if someone realizes we missed anything.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Now, I know sometimes that there's a problem where an application connects to the wrong server with PDO. And as you say, the host name was also in this PDO constructor, would it not then make debugging that specific case harder because the hostname would also be redacted from the stack traces?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  7:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The attribute I am proposing as the parameter attribute, each parameter can be sensitive or non sensitive. We would need to decide whether we consider the hostname sensitive or not. It usually is not. So I would not put the attribute on the host name, or on the DSN string in the first parameter. The password definitely is sensitive. And the username possibly is a grey area. By default, I probably would not put the attribute there. But this is something that needs to be discussed in the greater community possibly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I saw in the RFC that when you request a stack trace in PHP with get back trace or whatever the name of this function is, is that the sensitive parameters are being replaced by an object of the class SensitiveParameter. Why did you pick that instead of just a string, saying something like "redacted".&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  8:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We cannot force users to put the attribute only on parameters that take strings. If we use a redacted string we might violate the type hint. If a function takes some key pair class, or an option of a key pair class, this usually is a sensitive attribute, we cannot simply put a string there. We can but then we would violate the typing. And as we violate the typing in at least some of the cases, we can also violate it in all of the cases and then make it very clear that this parameter was redacted and not a real value that just looks like a string "redacted". Exception handlers would be able to use an instanceof SensitiveParameter check to possibly make it more user friendly when they render the stack trace. When you using an GUI to handle your exceptions as such a Sentry can show some placeholder instead of pretending it's a real string in there.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And of course, the string "redacted" can already exist as an argument value yet anyway, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  9:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Where would attribute be checked?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  9:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;My proposal would extend PHP to check this attribute within the function that generates the stack trace, because as I said, I want to keep my exception handler simple, so they won't need to use reflection to check this attribute. PHP itself will check this attribute when the stack trace is generated. So no exception handler can miss to check this attribute.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would it be possible for code that checks for SensitiveParameter to see what the original value was? I can imagine that in some cases, an exception handler as part of a debugging toolbar, whatever does want to show this extra information, although there's going to be hidden by default.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  9:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Not with the current version of my RFC, but I can imagine that this sensitive parameter replacement value gets an attribute where the original value can be stored. Care would need to be taken, so exception handlers don't simply serialize that value and ship it to a third party service, basically negating the benefit. But a future extension, or maybe the further discussion of my RFC can extend this replacement value. So you can use sensitive parameter, arrow, original value, or whatever.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In PHP attributes are basically markers on parameters or arguments. But they don't necessarily have to have an object implementation. Is your RFC also including the SensitiveParameter class that PHP core implements?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  10:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, in my current RFC, and my current proof of concept implementation, I'm just reusing that attribute class as the replacement value within the stack trace. So we can kill two birds with one stone by doing that, by including proper class, also, any IDE will be able to see that class and know where that attribute can be applied. Because attributes have a property where they say where they can be applied in this case parameters only. And by putting it on the method by accident, you will possibly get an error or the IDE can warn you that you're doing this not correctly,&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You might be aware that I work on Xdebug, a debugger for PHP. And in many cases, some of the users have already previously said that Xdebug should, for example, follow the debug_info() magic method on objects to show redacted information. Now, would you think that when people debug PHP with a debugger such as Xdebug, should they see the contents of the arguments that are set with SensitiveParameter, or should it stack traces show the real value?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  12:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In case of debugging, you're not usually not in production. So within your debugging environment or development environment, you shouldn't really have any sensitive value such as passwords, or credit card numbers, or whatever there is. In that case, debugability and ease of development should be more important. Xdebug, or any other debugger should see through those sensitive attributes and show the real value, possibly with an indicator that this value would usually be sensitive. But you shouldn't need to work around PHP hiding something from you, because you really want or need to see what happens there.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Now Xdebug also override PHP's standard exception handler, and then creates a stack trace of its own. Do you think that should redact the SensitiveParameter arguments?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  13:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm not really sure if people run this in production. If this is something people usually do, then of course, Xdebug should make sure to redact those values, possibly with a special ini flag or something. If that's only used in development. In my case, I only use Xdebug in development and production servers don't have that; you don't really connect to your production server with your IDE and then step through the code. That does not happen. So we don't need Xdebug in production.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I know some people do run Xdebug in production. But I also don't think those are the people that care about leaking sensitive parameters. I think the RFC talks about a few existing features that PHP already has for redacting some values. What are these? And how are they not sufficient?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  13:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There are two php.ini values you can set. One of those is do not collect parameters in stack traces, I don't have the exact name. But basically, all functions will just show an empty parameter list within the stack trace. That makes debugging very hard, especially with PHP and the non-strict typing, it can happen that you pass some completely invalid value to a function, even in production after testing and such. And you really want to know about this value, because it makes debugging very hard. Not collecting the parameters makes the stack traces much, much less useful. So this targeted redaction, as I'm proposing, hides the sensitive values but the non sensitive values will still be visible. And the other one is that the length of collected strings within the stack place can be configured. By default. I think it's on 15, but 15 characters already include user passwords such as password, exclamation mark, or 12345. And also credit card numbers will be exposed to three fourths by then. And the last four digits are shown in clear text on many pages. So that doesn't really help with those type of user credentials. Of course, your database password might be 40 characters completely random. But that's not really the values you want, or need to protect, because the database server will not be exposed to the internet, in many cases.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What has the feedback been so far to this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  15:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Both positive, and "we don't need that nobody does that". It's a bit mixed. I've got some very good feedback. There's a Twitter account that tweets any new RFCs. And so the users on Twitter, the actual users, and not PHP internals list seem to be very happy with my proposal. On the list, many said, just don't log that values, or they don't really see the benefit yet, I think. Not really sure how the feedback is really.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's always a tricky thing, isn't it? Because the people that think "Oh, this is all right", often bother responding, because they don't have anything to add or criticize.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  16:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. People that are happy won't write any reviews for whatever, just the people that complain are complaining.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, it's either the people that are complaining are the people that are really happy about something. Are you expecting there to be any backward compatibility breaks?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  16:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, obviously, when the attribute class name will be taken by default by PHP, userland code cannot use that any more. But I don't think that anyone is using a SensitiveParameter class in the global namespace. I used GitHub search and SensitiveParameter in PHP code only appears in some strings, in the AWS SDK or something like that. The replacement value will break any type signature. So if the exception handler checks, the original parameter types for whatever reason, that will, or might break, but I don't really think that's likely either. I don't expect any major backwards compatibility breaks.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's good to hear. And also good to hear that you have done some research into this. Do you have any extra selling points to convince people?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  17:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;My initial selling point was PDO's constructor. Or not really selling point, but example, because it's very obvious and it's in PHP core. I later expanded that with the credit card numbers and user passwords, and made, attempted to make this more clear that those sensitive values are not just values from your personal computing environment, but also something user input into your application. And that stack traces will be sent to third parties e.g. Sentry, which might even be run as a software as a service solution. And then your deep in GDPR territory. You don't want that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, absolutely not. Tim, thank you for taking the time this morning to talk to me about your RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Tim D&amp;#xFC;sterhus  18:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for having me.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast, as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening. I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/redact_parameters_in_back_traces"&gt;Redacting parameters in back traces&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://twitter.com/PHPRFCBot/"&gt;PHP RFC Bot on Twitter&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-097.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-97.html</guid>
      <pubDate>Thu, 27 Jan 2022 09:09:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: December 2021</title>
      <link>https://derickrethans.nl/xdebug-update-december-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_december_2021"/&gt;Xdebug Update: December 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, January 11th 2022, 08:54 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update 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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In December, I worked on Xdebug directly for only about 26 hours, with funding being around 21 hours. Please become a supporter of Xdebug through Patreon or GitHub.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1_and_further"/&gt;Xdebug 3.1 and further&lt;/h2&gt;
        &lt;p&gt;On the first of the month, I released Xdebug 3.1.2.&lt;/p&gt;
        &lt;p&gt;It addresses a few crash bugs related to PHP 8.1 fibers, a crash bug when Xdebug can't write a profiler file, and an issue with Xdebug's var_dump() not using the magic __debugInfo method.&lt;/p&gt;
        &lt;p&gt;The full list of changes can be found on the &lt;a href="https://xdebug.org/updates#x_3_1_2"&gt;updates&lt;/a&gt; page on the Xdebug website.&lt;/p&gt;
        &lt;p&gt;Since Xdebug 3.1.2 I have fixed a few more bugs, which are not yet in a released version. One fix pertains to the debugger generating not-well-formed XML, and another one improves performance with long strings in the debugger.&lt;/p&gt;
        &lt;p&gt;I spend most of my time in December to investigate issues that have not yet been solved. One of them turned to be a change in PHP behaviour between PHP 8.0 and 8.1. In PHP 8.0 and earlier, the &lt;code&gt;$_GLOBALS[]&lt;/code&gt; superglobal also had a key &lt;code&gt;GLOBALS&lt;/code&gt;, which PHP 8.1 no longer has. PhpStorm was reading values for its &lt;strong&gt;watch&lt;/strong&gt; feature, from the &lt;code&gt;GLOBALS&lt;/code&gt; context, but also added the extra (unnecessary) &lt;code&gt;GLOBALS&lt;/code&gt; array element to read out the real variables. Fixing this in Xdebug is complex, so hopefully this will be addressed in the next version of PhpStorm itself.&lt;/p&gt;
        &lt;p&gt;The second issue turned out to be an issue with PHP-FPM, which is not strictly following PHP's processing model. This can cause a discrepancy between PHP-FPM's control and worker processes, where they do not agree what the value of the &lt;code&gt;xdebug.mode&lt;/code&gt; INI setting is. Ideally this should get fixed in PHP-FPM, but there are further issues that both PHP-FPM and Xdebug probably need changes for.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;To help with funding my work on Xdebug, I have a paid-for-service, called Xdebug Cloud.&lt;/p&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I did not create any new Xdebug videos this month on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;. But I am working on a more thought out set of instructional videos. Stay Tuned!&lt;/p&gt;
        &lt;p&gt;If you would like to suggest a topic for a 5 to 15 minute long video, feel free to request them through this &lt;a href="https://forms.gle/ugjGbxs6ZhiTyvCSA"&gt;Google Form&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In December, two new business supporter signed up:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="http://www.seidengroup.com"&gt;Seiden Group&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://digitellinc.com/"&gt;Digitell, Inc.&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Thank you!&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-december-2021.html</guid>
      <pubDate>Tue, 11 Jan 2022 08:54:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 96: User Defined Operator Overloads</title>
      <link>https://derickrethans.nl/phpinternalsnews-96.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_96_user_defined_operator_overloads"/&gt;PHP Internals News: Episode 96: User Defined Operator Overloads&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, December 16th 2021, 09:24 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Jordan LeDoux (&lt;a href="https://github.com/JordanRL/"&gt;GitHub&lt;/a&gt;) about the "User Defined Operator Overloads" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-096.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is episode 96. Today I'm talking with Jordan, about a user defined operator overloads RFC that he's proposing. Jordan, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  0:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;My name is Jordan LeDoux. I've been working in PHP for quite a while now. This is the second time I have ventured to propose an RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What was the first one?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  0:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The first one was the "never for parameter types", which was much more exploratory. And we talked about it a little bit. And it generated a lot of good discussion that contributed to kind of the idea formation, which was what I hope to get out of it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, but that didn't end up making it into a PHP release. As far as I understand, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  1:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, I withdrew it actually, it was clear that the better way to approach the problem it was trying to solve was with a much more comprehensive solution. That particular solution was something that only required a seven line change to the engine. So I wanted to see if it was something people were okay with, or thought was a decent idea for that particular problem, much more comprehensive, like template classes, or something like that is probably the better route to go.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, I think the RFC that we're talking about today, is going to require quite a bit more than seven lines of code?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  1:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Quite a bit more. Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So what is this RFC that we're talking about today?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  1:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, user defined operator overloads is a way for PHP developers to define the ways in which objects interact with specific operators. So for instance, the plus operator, the plus sign. It's a way for those objects to kind of define their own logic as far as how that's handled, which right now, as of PHP 8.0, those were all switched to type errors. So it's not possible currently to write any code that doesn't result in a fatal error, where objects are used with operators.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Usually, I ask about every RFC, what problem are you trying to solve this? So what problem are you trying to solve this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  2:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The biggest problem that this solves is that objects contain, so objects in most programs represent a value or multiple values that have a program context. That's the most powerful thing about objects is they're contextual, and they understand the state, they understand what state the object is in, and sometimes even what state the whole program is in. And that's necessary for a lot of things. Like for instance, if you're tracking a distance, you know, you might measure that meters, and that would have a number you might have 30 meters of distance, but it also has a unit of meters. You could just represent that as an int. And then the program just knows internally, hey this is always in meters. But if you need to convert that to a different unit, then that becomes: Okay, well, now I need a special case some things, or I need a function just for converting, and I need to remember which unit my number is in. In a lot of cases, you handle that with objects because objects understand state, and they understand state transitions, which is what a lot of methods are about; transitioning the state of the object from one state to another. Operators are also about state transitions. And they're about very specific kinds of state transitions. It's natural in a lot of ways to think that you, you should be able to define how those two things interact. But currently, it's just not possible within PHP.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, does them this magic operator overloading?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  4:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It allows PHP developers to define an implementation logic, which is much like you define a function body that describes how does this object interact with this operator. That's essentially it. There's a lot of other details as to how it does that and what are the restrictions, but that's really the core of the idea.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And in what kind of situations would you use that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  4:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;A lot of them are situations where you're doing very complicated mathematics, or scientific computing or machine learning or things of that nature, where you are going to routinely encounter numbers that have state to them or that have multiple dimensions to them. So for instance, vector mathematics is one where the way that vectors interact with a lot of the operators that we're familiar with, like the multiplication sign is very different than how the number five interacts with the multiplication sign. Complex numbers is another one, you know, to multiply two complex numbers together, you have to treat it like a polynomial where you're multiplying it with the FOIL method: first, outside, inside, last. You know, there's a lot of those sorts of circumstances. But it also could potentially be very useful for some things that are not really mathematical but more quality of life for PHP developers. For instance, scalar objects is something that a lot of developers in PHP have, you know, wanted for a while. It's a thing that's a little more difficult to pin down, how exactly would you go about doing this within the engine, and it's a thing that the engine would kind of have to be very opinionated about by its nature. PHP developers can't provide their own scalar objects. And the main reason for this is that scalars interact with operators and objects can't. So simply allowing PHP developers to define a way for objects to interact with operators would allow user land to develop their own scalar object replacements. It wouldn't make every scalar that object; scalar objects within the engine still has, it's a separate feature. And it's still a thing that would be desirable, probably to a lot of people. But it gets quite a bit of the way there.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It is always interesting that people come up with the example of complex numbers, because I'm not sure how useful that is in a PHP user land context. And then beyond the scalars, I then sometimes struggle to see where this could be used. With the only exception is probably doing calculations with money related issues. The moment you bring up operator overloading, you'll also get people to say that this is going to get abused. Examples of that, in my opinion at least, is where in C++ you have like the &amp;lt;&amp;lt; operator to put things into the stream and stuff like that. What answer would you have to kind of comments?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  6:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Abuse of operator overloads to do things that can create unmaintainable code, because that's really the concern for developers is, does a language feature promote code that's difficult to maintain, that's difficult to understand, that's difficult to follow, and develop, and you know, work with. The RFC, the way that I've gone about this implementation, has had that in mind, because I also have experienced that. This is not a thing where I coming down from the academic high tower with, you know, whatever my my concept of this is, and no, no real world experience with these things. I share a lot of those concerns. Actually, I think this is a very useful feature that has a lot of applications I've encountered. I have had to work with matrix maths, I have had to work with complex numbers, I've had to work with arbitrary precision numbers, and all of those situations would have been served so much better by having operator overloads. I was fighting with the language the entire time, I was trying to do those. But I understand you know, in a lot of web applications, those are not common problems to encounter. My experience of that isn't typical. The thing about the way that it's done is it tries to head off a lot of the ways that it could be misused. An example of that is that the RFC requires typing of the parameters. You can't define an operator method and leave the types blank. If you do, then you get a fatal error during compile. It tells you you must explicitly define a type. And the reason for this is that blank types are assumed to be mixed. So it's the same as putting mixed for the type within the engine. And a mixed type says I can take anything, it doesn't matter what you give me, I can take anything. But that simply isn't true for operators. It's never true. Because even if you think hey, I can accept floats, ints, I can accept any objects, I can figure something out with them. You know, even if you think that's true, what happens when somebody passes you a stream resource? I mean, that's part of mixed. Any implementation that says mixed is probably lying. This RFC requires you to document what are the types that you know how to interact with for this operator. And that's the thing that that developers are kind of going to be forced to think about when they implement this. You know, and that's one example. But there's several other things within the RFC that kind of try and take that concern very seriously. And say, what are the strategies we could design something that is going to be used correctly, most of the time, just by design.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would just not then create an inconsistency in the language where for some methods, you simply have to type the arguments.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  9:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So yes, it's it is different than how other functions are defined. And methods are defined on classes, but that's one of the reasons that I believe very strongly that using a keyword other than function is a good idea. That's one of the other things that this RFC proposes is, instead of saying function plus or whatever, you say, operator plus. One of the things that that does is that signals to the developer, this is a different thing. That's not a trivial aspect of the RFC. It's not something that can just kind of be thrown away. It's like, oh, that sugar. In a very real way communicates to the developers, this is not like other functions, this is a different thing. It is a function internally within the engine. But that's because that's faster to do it that way. And it's a better way to implement it internally, within core. Developers should not be treating it in PHP as a function, it shouldn't be used that way. It's an engine hook.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When you're writing the code. If you do operator plus, for example, then at that point, it's clear what the plus does, but not necessarily, when you read the code, and you see the plots, you don't necessarily know what it means, right? Which I think is one of the bigger criticisms of having operator overloading support. But then you can also make the argument saying that well, operators they have a specific meaning in normal language, right. The plus means adding two things. So the argument would be that only use the plus operator for adding things together, not for example, adding a comment to a blog post, which you technically could do, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  11:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You could.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I definitely say that is something you should definitely not do, which you could, for example.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  11:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's another reason to kind of not treat them as functions in the syntax. You know, I think that having that operator keyword there really communicates that strongly to PHP developers. You know, when you look at a line of code, that's variable A plus variable B, and you're sitting there thinking: Hmm, I wonder if there's an operator overload involved here, because that might be a thing you do have to think about if this were included in core. While that's an additional thing that might have to be investigated, you know, by developers, and that that's not a trivial thing, I completely acknowledge that. It's also not a thing that would happen by accident, it would have to be intentional, because all objects error, if they're used with an operator currently, and after this is introduced, all objects will continue to error unless they define their own overload within the class that's being called, or one of its parents obviously, because inheritance is respected. It's not a thing that would happen by accident, there's no code that's going to accidentally inject an object into an operator, and all of a sudden, PHP makes wild assumptions and your code is spitting out a number that doesn't make sense, or something like that, because it's simply going to error. This is going to error very early. So you're going to get that feedback from the engine right away, when you do something like that. Maybe you didn't intend or that maybe was ambiguous.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I've just realized that in languages like C++, you can define multiple versions of the same operator, because you can have method overloading. This is not something you can do in PHP with normal methods either. So do I understand correctly that you can't do that in this case, either it, you need to accept multiple types in the overloaded operator, and then make a decision yourself.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  13:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It was suggested to me by a couple of people who gave me very early feedback that, hey, C++ accomplishes this with method overloading, you should do method overloading. And I took one look at that and said: One, I'm already doing a lot of work for this, that sounds like double the work. And two, I'm not convinced that's the best way to do it. Three, that's a huge separate change, that should probably be considered separately. And four, I don't think it's necessary. You can accomplish it with Union types, which we have. And that's another thing that maybe this is a guardrail for PHP developers using it incorrectly. If you're unioning, eight different types, and maybe you're not using it correctly. I mean, that'll look ugly. And I'm people might complain: hey, I don't want to have to Union all these things. I want to be able to overload the method directly with multiple versions. Having that feedback, right in your code that: Hey, this looks ugly. Maybe I'm doing it wrong. I see it as a positive thing, in a lot of ways.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I agree. First of all, it's a separate subject that should be discussed separately. Now, so far, we've only mentioned the operator keyword, but we haven't spoken about the rest of the syntax yet. So how would you define an overloaded operator?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  14:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;As we were discussing, there's the keyword operator. So you would define it very similar to how you would define a function. You can give it a visibility, but it can only accept the visibility public, you can omit that if you want. But it can be abstract or final. So you can have an abstract class that forces an implementation, or you can have a class that disallows overriding of the method. You use the keyword on operator, and then where the function name would go for any other function, you use the symbol that you want to overload, so you don't name it the English word plus, you use the actual symbol '+'. And then the rest of it is the way you would define any other function or method because it has a lot of the same concerns that functions do. But it visually looks very different, which I think is another good guardrail. Another good bit of feedback to developers.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What are the arguments that the overload is operating methods need to accept?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  15:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Most of them accept and actually require two arguments. The first is the corresponding operand. The things that are to the right and the left of your operator, they're called operands. And one of them will have this overload and the other one will be some kind of value. You need to accept the other value. And then the second parameter is the operand position, whether or not the operator overload being called; whether it's on the left side of the operator or the right side of the operator, because some some operations depend on whether or not it's on the left or right side.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would you say that most of the time, the operators will be used on two objects of the same class, in which case that doesn't really matter?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  16:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;A lot of the time, I think good implementations of this feature would involve objects that share a base class, share a parent class, or are the same class. I think it would be a very rare circumstance where a good usage of this feature would involve accepting a class that doesn't meet either of those criteria. Maybe it could happen, but I think in most situations, that would be another one of those things that kind of gives you you know, the code smell that a something may be wrong.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Then of course, with the exception that, for example, vectors, you can multiply with a number. And I define number very loosely here. And then in that case, the order is important. So the RFC has a table of having a whole list of operators, but it doesn't include all of them. What kind of categories are included, which ones aren't?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  17:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There's two main categories of operators that are proposed in this RFC, the mathematical operators, you know, your plus, minus, divide, multiply, the pow operator, and the modulo operator. And then the second class of operators are all the bitwise operators. So bitwise and, bitwise or, bitwise not, shift left, shift right, that kind of thing.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And let's see in the table that It all says equals in the spaceship operators in there. But what I don't see in there, it's larger than, or smaller than operators.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  17:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I made the decision very early when I was developing this RFC that I didn't want to support the comparison operators independently. And what I mean by that is, I didn't want to have an object that defined separate logic for the greater than sign than they did for the less than sign. That was mainly to avoid situations where reversing things would change the Boolean logic. Instead, there's a single operator, the comparison operator, or the spaceship operator, that allows you to overload all of them, but only in a way that's self consistent. By implementing that operator overload, you can cover all of the inequality operators, but it will always be consistent with its own output. It's never going to give you things that are logical contradictions with its own data.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would the overloaded spaceship operator implementation also be used for other comparisons, like greater than, less than and greater than equals?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  18:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's correct. Going into the implementation just a little bit. Internally, all of those operators, the greater than sign, the less than sign, greater than, and equals to, all of those are internally done as a comparison. That type of comparison where you're outputting, negative one, zero or positive one, they indicate, is it larger? Is it smaller? Is it equal? This actually keeps the PHP user land implementations more consistent with how things are done internally within the engine and makes it much easier to support all of those things, not just consistently, you know, without logical contradictions, but as far as how it gets done within the engine, it makes it much easier to handle those.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, I see there's another few implied operators in there. For example, if you're like the -= operator, then that gets implied as $a = $a - $b and stuff like; that all seems to be fairly sensible there. And similar it like ++$a, you get $a = $a + 1, which is basically what that means. You mentioned the word implementation detail. And I have a question myself here is: The symbol tables contrary to support a plus or minus? So do they get transformed into a specific name, for example?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  20:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Internally, the function name for a method on a class is stored as a Zend string, which can handle the symbols, it just doesn't. And that's mainly because the lexer can't; the parser is restricted from doing that, because it's kind of ambiguous in all contexts. For instance, outside of a class, following a function, using arbitrary symbols might cause some issues. But that's another thing that the operator keyword makes simpler. The operator keyword in the parser makes allowing the symbols much smaller implementation hurdle, I think that would be something that would be very difficult to do with the function keyword. But internally, it actually does get stored as the symbol. And then it gets put as a kind of an internal pointer with the other Magic Methods. Because internally, it's treated kind of like a magic method.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  21:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Are they flagged with a specific flag or a bit, showing that they are overloaded methods?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  21:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, there's a new flag that's added as part of this. That's only for methods, ZEND_ACC_OPERATOR.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  21:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which I think becomes important if you start looking things like reflection. Because if you list all the methods on a class on the reflection class, then you sort of need to know, what are the already overloaded operator methods or normal methods?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  21:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, that's, that is something that became very important when I went into do the reflection implementation for this, which has also been completed at this point. As part of reflection, actually, I very much didn't want to return the operators with other methods. Because again, I don't think that developers should be encouraged to think of these as methods, in most circumstances. That having the flag there made that a very simple change. It was like three or four lines of code per implementation per method that was affected on the reflection classes, check the flag, and then we're done. We're out.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  22:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In addition to that, of course, you gets operator specific reflection methods, right? Because you do want to check whether you have them.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  22:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;For normal methods, you have getMethod, getMethods, and hasMethod. And so there's three additional methods that are added to reflection class, getOperator, getOperators, and hasOperator, and they behave exactly the same way as the corresponding method ones, but they only deal with the operators.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  22:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC is talking about it an operator methods will be represented by reflection methods, which makes sense, but as you indicate there aren't really methods. And you shouldn't really think of them as methods. So would it not make sense to have a reflection operator method perhaps?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  22:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I did consider that. So when I was looking at the implementation for ReflectionMethod, I was looking at the methods that you have on that. And I was saying to myself, is this something that shouldn't be there for operators that not only, you know, maybe it doesn't provide useful information, like for instance, isPrivate will always be false for operators because you can't make operators private, but it doesn't break for operators, it still works. And all of the methods on ReflectionMethod were of that nature. Some of them were not super useful for operators, but none of them were things that were broken, or that were totally didn't make sense. And so because of that, I thought, well, maybe it's better to just have ReflectionMethod and just use that again, instead of creating a separate one that doesn't really have any additional functionality. It's just a copy, essentially, so that they don't have to be maintained separately.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  23:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I see in the RFC, that you're also adding the isOperator methods to reflection methods, so that you can distinguish between normal methods and operator overloaded methods, right, which is then I suppose the alternative to having a different instance class that represents either the method or the operator?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  24:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So that was the only thing that I really saw as being necessary, necessarily different, is being able to tell is my instance of ReflectionMethod a normal method or an operator method. That could be solved by having a child class instead, that would be another way to do it, I can definitely see advantages of doing it that way. And I thought about doing it that way. It's already a very big RFC. I kind of wanted to reduce the amount of things that people had to think about or that people had to say, well, this is something different. This is already very different from a lot of things in PHP. And it was one of those things where I was like, that seems like a place where it's not necessary for me to create something new for people to consider.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;As you say, this is quite a long and complicated RFC. What's been the feedback been so far?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  25:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;A lot of the feedback so far has revolved around the new keyword, the operator keyword. You know, questions about why is this necessary, as opposed to using the function keyword, which we talked about already a little bit. And kind of going through, what are the implications of that, not just within PHP, but also downstream for tooling to things like Psalm, Rector, tools that PHP developers use IDEs, PhpStorm, you know, what are they going to have to do to handle this? And is that more difficult or less difficult with a keyword? Depending on what the answer to that is? Is that trade off worth it?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  25:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Has there been any of the expected feedback saying: Oh, this is just going to be abused by users all over the place?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  25:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There's been one or two so far, you know, I think operator overloading as a concept as a feature in programming. And this isn't restricted to PHP as a language. This is something that comes up in other languages, too. I think, as a concept, this feature is something that's always kind of been that way to a lot of languages. There's very few languages where people don't have strong opinions about it. Even in those languages, people don't really encounter that often. But it's the kind of thing that people feel strongly about. So I would always imagine that there are going to be people who, quite rightly, from their own experience, believe that this is just a bad idea. And I can understand why they would think that. I disagree, but I can understand why they would think that. I think about the only language I'm aware of that doesn't have that kind of thing going on is maybe R, but R is a language that's kind of designed around nothing but mathematics. So the idea of being able to control operators is kind of central to what the language does. So it's maybe the only example I can think of, but the rest of them, you know, it is somewhat controversial. And I think it kind of always will be, even if it gets accepted.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  26:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Talking about that. When do you think you'd be opening voting for this?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  26:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm thinking more along the lines of early January. I think holding the vote two weeks after I announced it on internals a second time, it would be right almost on top of Christmas, I think that would also kind of be a bit unkind, and also may not serve the RFC well. So I think waiting till January is probably the right idea.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  27:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think that's the nicer way of doing it as well. Yes. Do you have anything to add that we forgot to speak about?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  27:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I wanted to mention going back to the operator keyword, and kind of the discussion around that. And the feedback that's been generated so far on that, a really good way to think about it is that the operator keyword is very similar to the enum keyword. Enums are classes, they simply are, but they're classes with very specific restrictions on them. The operator is a function, but it's a function with very specific restrictions on them. And it's for a lot of the same reasons. Enums are intended to be used for a very specific purpose. Operator overloads are also intended to be used for a very specific purpose. And that's one of the reasons that I think it's not not as bad of a thing. And I think that people really should be thinking about it more in terms of why we have the enum keyword instead of terms like, why don't we just use another magic method or something like that? You absolutely could do it that way, the same way that you could do enums it's just classes, but there's value there and doing it with its own keyword, I think.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  28:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, thank you, Jordan for taking the time this morning or your night, to talk about the operator overloads proposal.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  28:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, thank you for having me.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  28:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Because I've been on hiatus for a while I wanted to jump in with a few newsworthy items. First of all, I would like to thank Nikita for the many years he worked on PHP, while being an employee of JetBrains. He has decided that he wants to work on something else besides PHP and choose to leave JetBrains to work on LLVM. This means that I will be speaking to him on this podcast a lot less, if at all.&lt;/p&gt;
            &lt;p&gt;With Nikita's departure the PHP protect now has nobody working full time on it, as it is desirable for the continuation Nikita's old employer, JetBrains, has banded together with members of the PHP community, including core contributors, companies and sponsors to set up a foundation to fund contributors to work on PHP. Once this is up and running, I will make sure to dedicate an episode to this exciting new development. I have included a link to the foundation on Open Collective in the show notes.&lt;/p&gt;
            &lt;p&gt;Just before Nikita left the project two more RFCs were passed. The first one was to move the PHP bug tracker from &lt;a href="https://bugs.php.net"&gt;https://bugs.php.net&lt;/a&gt; to &lt;a href="https://github.com/phps/php-src"&gt;https://github.com/phps/php-src&lt;/a&gt; repository now accepts your bug reports, whereas the bugs.php.net system has been largely retired. We still accept security bugs on the old issue tracker because we can discuss these in private there before making them public.&lt;/p&gt;
            &lt;p&gt;The second RFC implemented the deprecation of dynamic properties with PHP 8.2. Instead of allowing codes to define a rights to undeclared properties, they will now need to be defined in your class definition, otherwise, you will get a deprecation warning. I have included the link to this RFC in the show notes as well. I'm not sure whether I will produce a specific episode on the subject.&lt;/p&gt;
            &lt;p&gt;With all the news out of the way, I'd like to thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying development of the PHP language. I maintain a Patreon for an account for sponsors of this podcast as well as the Xdebug debugging tool. You should sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/user_defined_operator_overloads"&gt;User Defined Operator Overloads&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/deprecate_dynamic_properties"&gt;Deprecate Dynamic Properties&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://opencollective.com/phpfoundation"&gt;PHP Foundation&lt;/a&gt; on Open Collective&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-096.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-96.html</guid>
      <pubDate>Thu, 16 Dec 2021 09:24:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: November 2021</title>
      <link>https://derickrethans.nl/xdebug-update-november-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_november_2021"/&gt;Xdebug Update: November 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, December 7th 2021, 09:26 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update 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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In November, I worked on Xdebug directly for only about 16 hours, with funding being around 24 hours. Please become a supporter of Xdebug through Patreon or GitHub.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1_and_further"/&gt;Xdebug 3.1 and further&lt;/h2&gt;
        &lt;p&gt;Since my last report, there were no more new issues reported with either functionality or crashes, and I have prepared for the Xdebug 3.1.2 release. Although I didn't publish that in November, I did release it on December 1st.&lt;/p&gt;
        &lt;p&gt;It addresses a few crash bugs related to PHP 8.1 fibers, a crash bug when Xdebug can't write a profiler file, and an issue with Xdebug's var_dump() not using the magic __debugInfo method.&lt;/p&gt;
        &lt;p&gt;The full list of changes can be found on the &lt;a href="https://xdebug.org/updates#x_3_1_2"&gt;updates&lt;/a&gt; page on the Xdebug website.&lt;/p&gt;
        &lt;p&gt;So what's next? Xdebug's profiler needs a rewrite. There are several design and implementation issues, that can only be resolved by a rewrite. To create less overhead it can also use PHP 8's new Observer API as well.&lt;/p&gt;
        &lt;p&gt;But this is going to take a large amount of work, and with the current low, and decreasing, funding levels, I can not put a lot of effort behind this.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;To help with funding my work on Xdebug, I have a paid-for-service, called Xdebug Cloud.&lt;/p&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published more videos on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://youtu.be/_LTKyUBgPaE"&gt;Debugging: Short Closures and Conditional Breakpoints&lt;/a&gt; explains debugging with Short Closures and Conditional Breakpoints.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://youtu.be/MmyxWy8jl7U"&gt;Xdebug 3: Setting up Apache, PHP, VS Code, and Xdebug in 10 minutes&lt;/a&gt; shows how to install Apache, PHP, VS Code, and Xdebug on Ubuntu 21.10, to get a PHP development set-up, all within 10 minutes.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I will continue to create more videos, and also convert some of them to tutorials.&lt;/p&gt;
        &lt;p&gt;If you would like to suggest a topic for a 5 to 15 minute long video, feel free to request them through this &lt;a href="https://forms.gle/ugjGbxs6ZhiTyvCSA"&gt;Google Form&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In November, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-november-2021.html</guid>
      <pubDate>Tue, 07 Dec 2021 09:26:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 95: PHP 8.1 Celebrations</title>
      <link>https://derickrethans.nl/phpinternalsnews-95.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_95_php_8_1_celebrations"/&gt;PHP Internals News: Episode 95: PHP 8.1 Celebrations&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, November 25th 2021, 09:23 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" we're looking back at all the RFCs that we discussed on this podcast for PHP 8.1. In their own words, the RFC authors explain what these features are, with your host interjecting his own comments on the state of affairs.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-095.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick, and this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This is episode 95. I've been absent on the podcast for the last few months due to other commitments. It takes approximately four hours to make each episode. And I can now unfortunately not really justify spending the time to work on it. I have yet to decide whether I will continue with it next year to bring you all the exciting development news for PHP 8.2.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;However, back to today, PHP eight one is going to be released today, November 25. In this episode, I'll look back at the previous episodes this year to highlight a new features that are being introduced in PHP 8.1. I am not revisiting the proposals that did not end up making it into PHP 8.1 feature two features I will let my original interview speak. I think you will hear Nikita Popov a lot as he's been so prolific, proposing and implementing many of the features of this new release. However, in the first episode of the year, I spoke with Larry about enumerations, which he was proposing together with Ilija Tovilo. I asked him what enumerations are.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  1:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Enumerations, or enums, are a feature of a lot of programming languages. What they look like varies a lot depending on the language, but the basic concept is creating a type that has a fixed finite set of possible values. The classic example is booleans. Boolean is a type that has two and only two possible values true and false. Enumerations are way to let you define your own types like that, to say this type has two values Sort Ascending or Sort Descending. This type has four values for the four different card suits, and a standard card deck. Or a user can be in one of four states pending, approved, cancelled or active. And so those are the four possible values that this variable type can have. What that looks like varies widely depending on the language. In a language like C or C++, it's just a thin layer on top of integer constants, which means they get compiled away to introduce at compile time, and they don't actually do all that much they're a little bit to help for reading. On the other end of the spectrum, you have languages like rust or Swift, where enumerations are a robust, advanced data type and data construct of their own. That also supports algebraic data types. We'll get into that a bit more later. And is a core part of how a lot of the system actually works in practice, and a lot of other languages are somewhere in the middle. Our goal with this RFC is to give PHP more towards the advanced end of enumerations. Because there are perfectly good use cases for it, so let's not cheap out on it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In the next episode, I spoke with Aaron Piotrowski about another big new feature: fibres.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Aaron Piotrowski  3:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;A few other languages already have Fibers like Ruby. And they're sort of similar to threads in that they contain a separate call stack and a separate memory stack. But they differ from threads in that they exist only within a single process and that they have to be switched to cooperatively by that process rather than pre-emptively by the OS like threads. And so the main motivation behind wanting to add this feature is to make asynchronous programming in PHP much easier and eliminate the distinction that usually exists between async code that has these promises and synchronous code that we're all used to.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I also asked Aaron about small PHP I actually have a slightly related question that pops into my head as like. There's also something called Swoole PHP, which does something similar but from what I understand actually allows things to run in threats. How would you compare these two frameworks or approaches is probably the better word?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Aaron Piotrowski  4:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Swoole is they try and be the Swiss Army Knife in a lot of ways where they provide tools to do just about everything. And they provide a lot of opinionated API's for things that in this case, I'm trying to provide just the lowest level just the only the very necessary tools that would be required in core to implement Fibers.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Although I discussed several deprecations from Nikita and the last year, I only want to focus on the new features. In episode 76. I spoke with him about array unpacking, after talking about changes to Null in internal functions.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The old background is set we have unpacking calls. If you have the arguments for the call in an array, then you write the free dots and the array is unpacked intellectual arguments. Now what this RFC is about is to do same change for array unpacking, so allow you to also use string keys.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In another episode, I spoke with David Gebler on a more specific addition of a new function fsync. David explains the reason why he wants to add this to PHP.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;David Gebler  5:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's an interesting question, I suppose in one sense, I've always felt that the absence of fsync and some interface to fsync is provided by most other high level languages has always been something of an oversight in PHP. But the other reason was that it was an exercise for me in familiarizing myself with PHP core getting to learn the source code. And it's a very small contribution, but it's one that I feel is potentially useful. And it was easy for me to do as a learning exercise.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And that is how things are added to PHP sometimes, to learn something new and add something useful at the same time. After discussing the move of the PHP documentation to GIT an episode 78, in Episode 79, I spoke with Nikita about his new in initializers RFC. He says:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So my addition is a very small one, actually, my own will, I'm only allowing a single new thing and that's using new. So you can use new whatever as a parameter default, property default, and so on.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The addition of this change also makes it possible to use nested attributes. Nikita explains:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I have to be honest, I didn't think about attributes at all, when writing this proposal. What I had in mind is mainly parameter defaults and property defaults. But yeah, attribute arguments also use the same mechanism and are under the same limitations. So now you can use new as an attribute argument. And this can be used to effectively nest attributes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Static Analysis tools are used more and more with PHP, and I spoke to the authors of the two main tools, Matt Brown, of Psalm, and Ondrej Mirtes of PHPStan. They propose to get her to add a new return type called noreturn. I asked him what it does and what it is used for.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Ondrej Mirtes  7:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Right now the PHP community most likely waits for someone to implement generics and intersection types, which are also widely adopted in PHP docs. But there's also noreturn, a little bit more subtle concept that would also benefit from being in the language. It marks functions and methods that always throw an exception. Or always exit or enter an infinite loop. Calling such function or method guarantees that nothing will be executed after it. This is useful for static analysis, because we can use it for type inference.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Beyond syntax, each new version of PHP also adds new functions and classes. We already touched on the new fsync function, but Mel Dafort proposed to out the IntlDatePatternGenerator class to help with formatting dates according to specific locales in a more specific way. She explains:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Mel Dafert  8:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Currently, PHP exposes the ability for locale dependent date formatting with the IntlDateFormat class, it says basically only three options for the format long, medium and short. These options are not flexible in enough in some cases, however, for example, the most common German format is de dot numerical month dot long version of the year. However, neither the medium nor the short version provide 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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And she continues with her proposal:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Mel Dafert  8:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;ICU exposes a class called DateTimePatternGenerator, which you can pass a locale and so called skeleton and it generates the correct formatting pattern for you. The skeleton just includes which parts are supposed to include it to be included in the pattern, for example, the numerical date, numerical months and the long year, and this will generate exactly the pattern I wanted earlier. This is also a lot more flexible. For example, the skeleton can also just consist of the month and the year, which was also not possible so far. I'm proposing to add IntlDatePatternGenerator class to PHP, which can be constructed for locales and exposes the get best pattern method that generates a pattern from a skeleton for that locale.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Locales and internationalization have always been an interest for me, and I'm glad that this made it into PHP 8.1. I spoke at length with Nikita about his property accessors RFC, in which he was suggesting to add a rich set of features with regard to accessibility of properties, including read only, get/set function calls, and asymmetric visibility. He did not end up proposing this RFC, which he already hinted that during our chat:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I am still considering if I want to explore the simpler alternatives. First, there was already a proposal, another rejected proposal for Read Only properties probably was called Write Once Properties at the time. But yeah, I kind of do think that it might make sense to try something like that again before going to the full accessors proposal, or instead.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;He did then later proposed a simpler RFC read only properties, which did get included into PHP eight as a new syntax feature. He explains again:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This RFC is proposing read only properties, which means that a property can only be initialized once and then not changed afterwards. Again, the idea here is that since PHP 7.4, we have Type Properties. Remaining problem with them is that people are not confident making public type properties because they still ensure that the type is correct, but they might not be upholding other invariants. For example, if you have some, like additional checks in your constructor, that a string property is actually a non empty string property, then you might not want to make it public because then it could be modified to an empty value. For example, one nowadays fairly common case is where properties are actually only initialized in the constructor and not changed afterwards any more. So I think this kind of mutable object pattern is becoming more and more popular in PHP.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Nikita, of course, meant this kind of immutable object pattern, which we didn't pick up on during the episode. Another big change was the PHP type system, where George Peter proposed out pure intersection types. He explains what it is:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  11:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;To explain our pure George Peter says:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  11:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So the word pure here is not very semantically, it's more that you cannot mix union types and intersection types together.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Just after the feature freeze for PHP 8.1 happened in July, another RFC was proposed by Nicolas Grekas to allow the new pure intersection types to be nullable as well. But as that RFC was too late, and would change the pure intersection type to just intersection types, it was ultimately rejected.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The last feature that I discussed in a normal run of the podcasts was Nikita's first class callable syntax support. He explains why the current callable syntax that uses strings and arrays with strings has problems:&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So the current callable syntax has a couple of issues. I think the core issue is that it's not really analysable. So if you see this kind of like array with two string signs inside it, it could just be an array with two strings, you don't know if that's supposed to actually be a static method reference. If you look at the context of where it is used, you might be able to figure out that actually, this is a callable. And like in your IDE, if you rename this method, then this array should also be this array elements will also be renamed. But that's like a lot of complex reasoning that the static analyser has to perform. That's one side of the issue. The second one is that colour bulls are not scope independent. For example, if you have a private method, then like at the point where you create your, your callable, like as an array, it might be callable there, but then you pass it to some other function, and that's in a different scope. And suddenly that method is not callable there. So this is a general issue with both the like this callable syntax based on arrays, and also the callable type, is callable at exactly this point, not callable at a later point. This is what the new syntax essentially addresses. So it provides a syntax that like clearly indicates that yes, this really is a callable, and it performs the callable culpability check at the point where it's created, and also binds the scope at that time. So if you pass it to a different function in a different scope, it still remains callable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This new feature is a subset of another RFC called partial function applications, which was proposed by Paul Crovella, Levi Morrison, Joe Watkins, and Larry Garfield, but ultimately got declined. So there we have it, a whirlwind tour of the major new features in PHP 8.1. I hope you will enjoy them. As I said in the introduction, I'm not sure if I will continue with the podcast to talk about PHP 8.2 features in 2022 due to time constraints. Let me know if you have any suggestions.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/73"&gt;#73&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/enumerations"&gt;Enumerations&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/74"&gt;#74&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/fibers"&gt;Fibers&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/76"&gt;#76&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/array_unpacking_string_keys"&gt;Array Unpacking&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/77"&gt;#77&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/fsync_function"&gt;fsync function&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/79"&gt;#79&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/new_in_initializers"&gt;New in Initialisers&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/81"&gt;#81&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/noreturn_type"&gt;noreturn type&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/85"&gt;#85&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/intldatetimepatterngenerator"&gt;Add IntlDatePatternGenerator&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/86"&gt;#86&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/property_accessors"&gt;Property Accessors&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/88"&gt;#88&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/pure-intersection-types"&gt;Pure Intersection Types&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/90"&gt;#90&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/readonly_properties_v2"&gt;Readonly Properties&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode &lt;a href="https://phpinternals.news/92"&gt;#92&lt;/a&gt;: &lt;a href="https://wiki.php.net/rfc/first_class_callable_syntax"&gt;First-Class Callable Syntax&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-095.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-95.html</guid>
      <pubDate>Thu, 25 Nov 2021 09:23:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: October 2021</title>
      <link>https://derickrethans.nl/xdebug-update-october-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_october_2021"/&gt;Xdebug Update: October 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, November 9th 2021, 09:25 GMT&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update 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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 58% towards my $2,000 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In October, I worked on Xdebug for about 30 hours, with funding being around 25 hours. Please become a supporter of Xdebug through Patreon or GitHub.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1"/&gt;Xdebug 3.1&lt;/h2&gt;
        &lt;p&gt;Xdebug 3.1.0 and 3.1.1 have now been released!&lt;/p&gt;
        &lt;p&gt;Xdebug 3.1 adds support for PHP 8.1, as well as a set of new features. These new features include: file compression for trace and profiling files, the new xdebug_notify() and xdebug_connect_to_client() functions, an API through xdebug_info() to request which modes are enabled, and the possibility to set the Xdebug Cloud ID through Xdebug's triggers, including browser extensions.&lt;/p&gt;
        &lt;p&gt;The full list of changes can be found on the &lt;a href="https://xdebug.org/updates#x_3_1_0"&gt;updates&lt;/a&gt; page on the Xdebug website.&lt;/p&gt;
        &lt;p&gt;Unfortunately Xdebug 3.1.0 introduced some bugs in the thread-safe version, which is most notably used on Windows. After some back and forth with Christoph Becker, the PHP on Windows maintainer, we managed to track down the problem and fix it. This resulted with some other fixes in the Xdebug 3.1.1 release.&lt;/p&gt;
        &lt;p&gt;Since then, users found a few more minor issues which will result in 3.1.2, to be released early in November.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;To help with funding my work on Xdebug, I have a paid-for-service, called Xdebug Cloud.&lt;/p&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;One of the new features in Xdebug 3.1 makes it possible to allow for each team member in a team that uses a (remote) shared development server to have their own debugging session between the development server and their own IDE, without interfering with other developers.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published one new video on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;This video is of a series to explain how to use Xdebug and the new features introduced in Xdebug 3.1:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://youtu.be/aLF6j5qdnvA"&gt;Xdebug 3.1: Improvements to Step Debugging&lt;/a&gt;: Explains how to use and configure the new file compression support for profiling and trace files.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I will continue to create more videos, and also convert some of them to tutorials.&lt;/p&gt;
        &lt;p&gt;If you would like to suggest a topic for a 5 to 15 minute long video, feel free to request them through this &lt;a href="https://forms.gle/ugjGbxs6ZhiTyvCSA"&gt;Google Form&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In October, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-october-2021.html</guid>
      <pubDate>Tue, 09 Nov 2021 09:25:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: September 2021</title>
      <link>https://derickrethans.nl/xdebug-update-september-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_september_2021"/&gt;Xdebug Update: September 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, October 12th 2021, 09:19 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update 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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 57% towards my $2,000 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In September, I worked on Xdebug for about 45 hours, with funding being around 25 hours, which is just under half.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1"/&gt;Xdebug 3.1&lt;/h2&gt;
        &lt;p&gt;I have continued to work on the task list for Xdebug 3.1, cumulating in the release of Xdebug 3.1.0beta1 and beta2, with the latter being a repackaging due to Windows binary file naming. I have changed from using AppVeyor to GitHub Actions for the building of Windows binaries, which take much much time. Unfortunately I swapped the Non-TS and TS binaries for that build.&lt;/p&gt;
        &lt;p&gt;Since 3.1.0beta2, Christoph Becker, with some help from me, has been adding support for file compression on Windows as well, by integrating zlib. This was the last outstanding task which means that Xdebug 3.1.0 is now ready to be released. During the beta phase some bugs were brought to light which I have also addressed.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;To help with funding my work on Xdebug, I have a paid-for-service, called Xdebug Cloud.&lt;/p&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;I have now released the work that I have been doing on the admin site, to make it easier to configure your session tokens and see subscription information.&lt;/p&gt;
        &lt;p&gt;Xdebug 3.1 also has new features to make it possible to allow for each team member in a team that uses a (remote) shared development server to have their own debugging session between the development server and their own IDE, without interfering with other developers. The Xdebug Cloud and Multiple Triggers video that I've linked below, explains this in greater detail.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published three more videos on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;These are part of a series to explain how to use Xdebug and the new features introduced in Xdebug 3.1:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://youtu.be/aZ4eH8J0uuA"&gt;Xdebug 3.1: File Compression&lt;/a&gt;: Explains how to use and configure the new file compression support for profiling and trace files.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://youtu.be/S4Juvb3k3co"&gt;Xdebug 3.1: xdebug_info() Improvements&lt;/a&gt;: Introduces what debugging information &lt;code&gt;xdebug_info()&lt;/code&gt; can provide, and focusses the additions in Xdebug 3.1.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://youtu.be/Jny-RJDf2AM"&gt;Xdebug 3.1: Xdebug Cloud and Multiple Triggers&lt;/a&gt;: Explains how to use the new multiple shared secrets and "Cloud Token" as debugging session ID feature to support more use cases for Xdebug Cloud.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I will continue to create more videos, and also convert some of them to tutorials.&lt;/p&gt;
        &lt;p&gt;If you would like to suggest a topic for a 5 to 15 minute long video, feel free to request them through this &lt;a href="https://forms.gle/ugjGbxs6ZhiTyvCSA"&gt;Google Form&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In September, no new business supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-september-2021.html</guid>
      <pubDate>Tue, 12 Oct 2021 08:19:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: August 2021</title>
      <link>https://derickrethans.nl/xdebug-update-august-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_august_2021"/&gt;Xdebug Update: August 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, September 7th 2021, 09:35 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update 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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 58% towards my $2,000 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In August, I worked on Xdebug for about 50 hours, with funding being around 25 hours, which is only &lt;strong&gt;half&lt;/strong&gt;.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1"/&gt;Xdebug 3.1&lt;/h2&gt;
        &lt;p&gt;I have continued to work on the task list for Xdebug 3.1, with now just one issue outstanding. This means it's nearing a first beta release, which I am hoping to release close to when PHP 8.1 RC1 gets released.&lt;/p&gt;
        &lt;p&gt;The main thing that I worked on is compression support for profiling and trace files. Previously, I already had added preliminary support for compressed profiling files, but it turned out that QCacheGrind could not read them. Because Xdebug would always use compressed files, if the zlib compression library was available, it would generate non-consumable files.&lt;/p&gt;
        &lt;p&gt;With the improved feature it is now possible to disable the compression with the xdebug.use_compression=0 setting. And additionally I have also support to compressed trace files. The zlib/gz drastically reduces the size of files. It is currently not yet available for Windows users.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;To help with funding my work on Xdebug, I have a paid-for-service, called Xdebug Cloud.&lt;/p&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;I have been improving the admin side and I will soon release a new beta that show cases that work.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published two more videos on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;These are part of a series to explain how to use Xdebug:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=iH-hDOuQfcY"&gt;Xdebug 3 Profiling: 3. Analysing Data&lt;/a&gt;, where I show how to use KCacheGrind to read and analyse profiling files to find bottlenecks in code.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=9Fx1beTvR2w"&gt;Xdebug 3: Activation and Triggers&lt;/a&gt;, where I explain how to activate Xdebug's myriad of features with different methods, including cookies, GET/POST parameters, environment variables, and with a browser extension.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I will create more videos in the upcoming month, and if you would like to suggest a topic for a 5 to 10 minute long video, feel free to request them through this &lt;a href="https://forms.gle/ugjGbxs6ZhiTyvCSA"&gt;Google Form&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In August, no new supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-august-2021.html</guid>
      <pubDate>Tue, 07 Sep 2021 08:35:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 94: Unwrap Reference After Foreach</title>
      <link>https://derickrethans.nl/phpinternalsnews-94.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_94_unwrap_reference_after_foreach"/&gt;PHP Internals News: Episode 94: Unwrap Reference After Foreach&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, August 26th 2021, 09:22 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Nikita Popov (&lt;a href="https://twitter.com/nikita_ppv"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/nikic/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://nikic.github.io/"&gt;Website&lt;/a&gt;) about the "First Class Callable Syntax" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-094.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, the podcast dedicated to explaining the latest developments in the PHP language. This is Episode 94. Today I'm talking with Nikita Popov about the unwrap reference after foreach RFC that he's proposing. Nikita, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, Derick. I'm Nikita and I work at JetBrains on PHP core development.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So no changes compared to the last time.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, at the time before that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So what is the problem that is RFC is going to solve?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, it's really a very minor thing. I think it's a relatively well known problem for the more experienced PHP programmers. It's like a classic example, you have a foreach loop by reference. So foreach array as value by reference, and then you do a second loop after that, foreach array as value at the same it's by value. So without the reference sign. The result of that is that your last two array elements are going to be the same, which is kind of unexpected. If you're not familiar with how references in PHP work and scoping in PHP works. So I think it's worth explaining what's going on there.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Can you quickly explain the scoping or rather the lack of it, I suppose?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  1:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, it's really the lack of PHP really only has function scoping. So if you have a foreach array as value, then the value variable is going to stay alive, even after the foreach loop. And usually, that won't make much of a difference. So you will just have like reference to the last element of the array, might even be useful for some cases, you know, before we added the array, I think, array_key_last function. If the last element now is a reference, so if you have a reference to the last element, then you're write into that variable is also going to modify the last element of the array. So if you now have a second foreach loop, using the same variable, that's actually not just modifying that variable, but it's also always modifying the last element of the array.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, just to clarify, it isn't necessarily the last element in the foreach loop. It's the last one that's been assigned to?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  2:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, that's, that's true.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Is this not something that people actually use for some useful reasons?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  2:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;As mentioned before, technically, you could use it to get a reference to the last element and then modify the last element outside the foreach loop. I don't think this is a particularly common use case. But I'm sure people have used in here there. This is a use case we would break with the proposed RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think it is one I have used in the past, it's probably not how I would do it now. But I'm pretty sure I have some point in the past. What are you proposing to change with this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  2:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The change is pretty simple. And that's to unwrap or to break the reference after the loop. You will still have like after the loop, the variable will still contain the value of the last element, or of the last like visited element, but it will no longer be a reference to it. If you write into the variable, it will not modify the original array. And if you have a second loop that writes into the variable that also doesn't modify the original error any more.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;At which point and how is this reference broken?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's at the end of the foreach loop, or as you say, if you break out too early, then of course, it would also get broken. So it's referenced inside the foreach loop and stops being referenced outside the loop.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And that would happen also, if I would use a goto for example?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Oh, that that's a trick question, actually, yes, it should happen. But now that you have mentioned it, I think my current implementation does not handle that particular case, I will have to double check it. But that should happen, yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's good to know that you've thought about it then.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, I didn't think about it. Because I mean, I guess I can mention it here, the way this works is that well, at the end of the foreach loop, we have like an instruction that frees the loop variable. And I can just add an additional one that breaks reference. But if you use things like goto or multi level breaks, or something like that, then we insert these clean-up instructions before the jump. We have to make sure to actually insert the reference breaking instruction there as well. So it's like not automatically handled.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Is this going to be a separate instruction or as we tend to call them opcodes?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm using a separate one, but one could run it as a flag into the instruction that frees the loop variable, but I think it's cleaner to have a separate instruction for it. Like technically one could optimize it away in some cases, like I wouldn't bother but it's like semantically a  different thing.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think it'd be nicer result, because it makes it easier to visualize what's happening, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, it is.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Did you actually check whether some code uses this construct?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I have to admit, I tried checking it using a very basic approach, just look at foreach loops by reference. And then if the variable is used after that. But that kind of primitive approach has way too many false positives, for example, you have a foreach loop inside, and if, and then the variable is reused inside an else. So it like wouldn't flow from the if into the else. So you would have to do some kind of more sophisticated control flow analysis. It's something that can be done, but I didn't bother doing it for a one off backwards compatibility check. So I don't have any hard data on how much code is actually using something like this.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So this is where I'm a little bit on the fence about this change, because it is changing behaviour, that's going to be pretty hard to figure out what is actually going to affect your codebase.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It should be possible to very reliably detect that. It's just something you have to actually implement. But you're right now there is no easy way to check that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's something that static analysers could probably have a look at.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, expect that maybe Psalm or PHPStan, something like that will be easier to implement, because they already have control flow information.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You don't really know how impactful this, which is, in my opinion, a bit of the scary bit. How important do you think you'll find it to have this RFC going through and implemented?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't think it's super important. It's mostly like, small quality of life fix for newer developers . People who have already encountered this issue once won't forget about it again. In fact, it's somewhat common recommendation that you should always unset the loop variable after a foreach by reference loop. So I've seen that as like a policy some people use, that could be avoided. So yeah, I don't think it's a critical feature, just a small improvement.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would it be an alternative idea to instead deprecate the foreach by reference?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, that's the radical approach. Everything is possible. I think that foreach by reference is relatively, I mean, I think it's one of the most common uses of references we have, and one of the most reasonable ones. I mean, the alternative is search into by value loop, and then you modify it by looking up the element by key again, which is a bit more ugly, I would say. I think we shouldn't deprecate foreach by reference, though it would be kind of nice to have a different way to achieve the same. One other unfortunate thing about foreach by reference is that it leaves behind references in the array. The case I'm looking at here is this reference to the last element, where you have like reference structure that's pointed to both from inside the array, and from this loop variable. The other thing that foreach by reference does is that for all the other array elements, you will actually leave behind the reference wrapper that's just used in this one single place for this single array element. Essentially, you are wasting memory, because we will leave behind this that reference wrapper. So after you do the foreach by reference loop over the array, the array will actually grow larger. So if you're storing like integers, and it may grow significantly larger, like from a technical perspective, foreach by references, also not great. But like from a usability perspective, it's nicer then modifying values by key lookup.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I guess it's going to depend on how big the array is, right? I mean, if it's a few elements, it probably doesn't matter.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  8:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But if you have like a 100,000 element array, then you paying for 100,000 reference wrappers that you don't need afterwards any more.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In that case, it's rather better to just modify it through the key that you obtained by doing foreach key as value.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Right. But it's also worth noting that foreach reference actually has different semantics then foreach value, because foreach by value works on the copy of the array. Like it's not an actual copy just like semantically. If you modify the array inside the foreach by value loop, then we will copy the array. Doing the modification with a separate key lookup and foreach by value loop will actually copy the array at that point, while foreach by reference takes account modifications of the array. So even if you like add or remove elements in the array in the foreach by reference loop, it will try on the like best effort basis to still iterate on in a reasonable way on the modified array. It's like not a straightforward replacement.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It all depends on what people intended to do with it. Right? Do you think there are any further situations that are a bit strange? That could benefit from having some subtle changes to the language semantics?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Nothing can who comes to mind immediately.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, I can't think of any either. But I thought maybe maybe have something in the pipeline. Would you have anything else to add to this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, one more thing that's discussed in the RFC is the case of complex variables. A little known fact, in the foreach loop, you don't have to assign to a simple variable, you can also assign to something like an object property, or an object property on the result of a function call that that means that in the loop, this function is getting called on every iteration, and then you assign it to a property on the result. So you can do that kind of weird stuff, we allow it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And does it the work without any weird side effects?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Depends on what you consider weird, but basically does what you expect as if you had written an explicit assignment to the complex variable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I reckon that's how it's instructed out in the oparray then as well.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  11:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, exactly. As far as this RFC is concerned, the problem there is that to unwrap the reference of the loop, we actually have to evaluate the variable again. And if it's a complex variable that might have side effects, for example, the function call. And that's why the RFC says that if the variable is complex, we are not going to do that, like that's probably going to be more unexpected than leaving a reference wrapper around. So we have this extra weird edge case. In the internals discussion, some people already suggested that maybe we should just deprecate support for these kind of complex assignments. One could also mention that an alternative that has been suggested is to actually make the loop variable, scoped to the foreach loop. So we could unset it entirely after the loop, rather than just breaking the reference, which is, of course, a larger change, larger backwards compatibility break. It also doesn't really align with PHP semantics of only having function scope and not block scope.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I probably agree without, it's too much of a change to do that. Because then you sort of expect that all the language constructs should have a scope. I mean, it needs to be either one or the other.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, I mean, other languages like JavaScript have solved that by introducing a separate way to declare scoped variables. So that will be "let", just changing the behaviour in one place is probably not a good idea.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I probably agree with you though. It was a bit of a shorter RFC this time. That's okay with me.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, I used that as an excuse to discuss some foreach behaviour details.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Fair enough. Thank you for taking the time this morning to come and talk to me about the references after foreach RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for having me, Derick, once again.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast, as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening. I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/foreach_unwrap_ref"&gt;Unwrap Reference After Foreach&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-094.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-94.html</guid>
      <pubDate>Thu, 26 Aug 2021 08:22:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 93: Never For Parameter Types</title>
      <link>https://derickrethans.nl/phpinternalsnews-93.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_93_never_for_parameter_types"/&gt;PHP Internals News: Episode 93: Never For Parameter Types&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, August 19th 2021, 09:21 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Jordan LeDoux (&lt;a href="https://github.com/JordanRL/"&gt;GitHub&lt;/a&gt;) about the "Never For Parameter Types" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-093.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is Episode 93. It's been quiet over the last month, so it didn't really have a chance to talk about upcoming RFCs mostly because there were none. However, PHP eight one's feature freeze has happened now, a new RFCs are being targeted for the next version of PHP eight two. Today I'm talking with Jordan LeDoux, about the Never For Parameter Types RFC, the first one targeting this upcoming PHP version. Jordan, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  0:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Certainly. And thanks for having me. My name is Jordan. I've worked as a developer for about 15 years now. Most of my career has been spent working in PHP. Although professionally, I've had experience working in C#, Python, TypeScript, mostly in the form of JavaScript, but a little bit of Node and, you know, a variety of other languages that I haven't spent enough time in to really be proficient in any real way. But recently, I decided to do something that I have thought about doing for many years, but never actually jumped into which is exploring the PHP engine itself and how I could possibly contribute to it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And here we are, but your first our thing.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  1:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, it's exciting.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What is this RFC about, what does it propose?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  1:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, this RFC proposes allowing the never type, which was added in 8.1 as a return value, to parameters for functions and methods on objects. The main idea behind that is that when never was proposed as a return type, it was meant to signal that the function would never return. Not that it returns void, which of course, void signifies which is returning no value or returning, returning without any specified information. And never return signifies that the function will never return, which is a concept that exists in many other languages. And for that purpose in other languages, what's usually used is something called a bottom type. And that's what never ended up being. And I'm proposing that we extend the use of that bottom type to other areas where the type may be helpful.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So a bottom type, that might be a new term for many people, it will certainly for me when I looked at the never RFC for as return types. Can you sort of explain what a bottom type is, especially thinking about object oriented theory with something that we'd like to call the Liskov Substitution Principle? And also, how does it apply to argument types?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  2:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Let's start with the Liskov Substitution. The general idea behind Liskov Substitution is that if A is a subtype of B, then anywhere that A exists, you should be able to substitute B. It has to do with when you have a class hierarchy in in an object oriented language, that that class hierarchy guarantees certain things about substitutionality, like whether or not something can be substituted for something else. That affects language design in ways that a lot of programmers are kind of intuitively familiar with, but maybe not familiar with the theory and the ideas behind it more concretely. But LSP is the principle in SOLID, that's the L and SOLID. And it represents a portion of the whole idea of object oriented programming in PHP. Part of being able to substitute one object for another, based on their class hierarchy, and what they implement, and what they provide is there part of their ability to be substituted is whether or not they can fulfil the same kind of contractual requirements of typing. And with Liskov, that means that preconditions can never be strengthened, and post conditions can never be weakened. So a precondition would be a parameter type requirement. If you require that a parameters accepts an object, for instance, in PHP, you can't strengthen that requirement beyond just any object to a particular object. But you can weaken it from an object to an object or an integer with with unions. That's an example of the precondition side of it. The post condition side of it is that you can't, you can't weaken it. So if you have have, you know, if you have a return type of int, you can't have an inherited implementation return int or float, because that broadens the possible return types. They go in opposite directions. And one of them is covariance and one of them is contravariance.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I can never remember which one is which.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  5:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, basically contravariance go up the tree and covariance go down the tree. If you're thinking about widening, or sorry, narrowing. If you're thinking about narrowing, then covariance go down the implementation tree and contravariance go up the implementation tree.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, so how does the bottom type fit in here?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  5:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The bottom type in any type system represents like the base type that all types originate from. And the best way in my mind to think about it is kind of just integer math. It's a thing that every programmer is going to be familiar with. And it fits, it fits all right. So you can think of the bottom type as zero integers, a lot of people would think of null as zero if they're thinking about a type system, but null is more like negative one. It's like the entire negative side of the integer system. We could say that the string type is one, and the integer type is two. And the float type is three, and maybe int or float, the union of them is five, which would be the two numbers added together. And if you describe type systems this way, then you can say, hey, if I take any type and add the value that represents the other type, then I get my result type. So if I take zero, the bottom type, and I add one, the string type, what I end up with is one, still the string type. So the bottom type is whatever type system or whatever, whatever type, when you add any other type to it, you get the type you added to it and nothing else, you just get your original thing. That's why it's called the union identity for the type system. The top type in PHP is mixed. And that's the opposite side of it. It's just like zero is the additive identity. One is the multiplicative identity. If you multiply anything by one, you're going to get what you originally had. And if you add anything to zero, you'll get what you originally had. So mixed ends up being, or the top type in general, ends up being the intersection identity, and the bottom type, or never, in PHP's case, ends up being the union identity. And all this is like deep type theory, but most programmers don't have to interact with it. It's more something that affects language design usually.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Could you think of mixed as being infinity?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  7:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's actually with my with my crude integer analogy, yeah, it would be like all types, all possible types are added together.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That makes sense then. Okay, so we have explained what the bottom type is, but, and never being the bottom type. So why is it useful to use the bottom type, or never, as this RFC proposes, as a method argument type for parameters?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  8:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The largest benefit has to do with what we were talking about when it comes to covariance versus contravariance. You know, can you strengthen the requirements? Or can you weaken the requirements? When you inherit a method in a system that preserves Liskov Substitution, the parameters can be widened, they can accept more things. If I had an interface that said, it has one parameter, and that parameter is typed as int, then in any implementation, I could say, okay, but actually, the parameter type is int or float, I'm going to accept both. And I could do that in the implementation. But I would have to accept int, because that's part of the contract. That's part of the interface. So I have to accept whatever type is in the interface. I can just additionally add things on top of that. If I make my original definition, my root definition, the bottom type, then I can add any type to it. And I will just get that type. From never, if I had an interface with, you know, a method foo, and it has one argument, and that argument is typed never, I can re-type that argument as int, or I could re-type that argument as string, and all of them would be valid inheritances.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So it's a way of getting around having at least one concrete type like int in an interface.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  9:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Right. And in fact, never is a concrete type. It's a concrete type, that means this code can never be called. For return type, it means this type will never return. But if you're, if what you're trying to do is call it then you can never call it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which is then why never actually makes sense as a type name, because one of my further questions is going to be how does never as a name make sense? But you've now explained it in such a way that it actually does make sense. So there we go.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  10:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;One of the questions that did come up in the internals discussion on this so far, has been a round that choosing never, and because a lot of the examples for use cases are around inheritance, it makes some kind of intuitive sense, if you're describing the inheritance behaviour, to name it something like any or anything, or you know, something about its how permissive it is in its inheritance definition. But the type should really describe the code that it's actually written in. You know, getting outside the idea of an interface or an abstract or something like that. If you have a function, and that function types it as never, or whatever you name, the bottom type. There's no data that can satisfy that. Because any data will have some type other than never. It'll have string, or int, or something. Even null has the null type. You can't provide any data to a function that requires never that will satisfy its type requirement. So that code can never be called. It's really when you start considering how does this affect inheritance that you start getting into this concept of Oh, maybe a different word makes sense. But then that doesn't really reflect the opposite side on the return side, when you're talking about covariance instead of contravariance. And that's why the bottom type for most languages is something like never, or nothing, or nil, something along those lines.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So if you type an argument to a method as never, the engine will, of course, enforce that you can't call it with any data because it wouldn't satisfy. But would it also automatically make a method abstract so that inheritance inheriting classes have to widen it or not?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  12:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So that was part of my original idea behind the RFC, was forcing something that implements it or something that inherits it, to widen it. However, there were a lot of good arguments about why that may not be a good idea. One is that in PHP, an empty type isn't an empty type, it's mixed, not widening, would actually just be saying the type is mixed, which is valid, you can go from the bottom type to the top type in a contravariant way, that's a totally valid way to do it. The problem is that PHP has a weakly enforced typing system. Like that's only a problem in this context, it's actually a very powerful feature of the language in a lot of other contexts. So we don't necessarily want to get rid of that. In addition to that, the actual mixed type as a literal that can be used in the language was only added in 8.0. It would kind of represent a much larger backwards compatibility break to require it to be explicitly widened. That was part of my original concept for a lot of the reasons that you were just talking about. But for PHP, specifically, it would probably present more problems than it would provide kind of solutions and utility. I've kind of been convinced off that point a little bit by the arguments of others.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would it be possible to instantiate a class that has a method with its argument typed as never?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  13:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, as long as he never called that argument directly.Using a never type in a constructor would definitely be a definitely be a No, no, that would result in a type error. As soon as you try to instantiate the class.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It would basically make the constructor private.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  13:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, you would get a slightly less useful error.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  13:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Then you do if you make the constructor private, and then try and call it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It makes no sense to do it. The RFC slightly touches on generics. And it goes in a way talking about why this is sort of slightly like generics. Could you explain the interaction between these two concepts?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  14:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Generics is a feature obviously, that a lot of PHP developers want. And it's also a very complicated feature to do. Way outside of what I was willing to consider for, for my first, my first attempt at something useful. One of the most common ways that generics are used, is within an inheritance structure to allow something similar to type widening, particularly for parameters. Being able to say, I want the type to be able to be widened, but I don't know exactly how it will be widened. That's something that generics offer. Generics offer many other features as well and many other capabilities. But that particular one is something that this can do. It comes with a cost though, because this isn't generics. It is not really the right way to do that. It can be done without generating compile errors now, if you use never, that's the main difference. You still would encounter errors in static analysis and IDE hints, for instance. The IDE, he wouldn't be able to tell if you typed against a interface that had never as a parameter type, it wouldn't be able to tell what sorts of types the implementers have. Because that's not really the point of accepting an interface as a type for a parameter, or for a function call, or something like that. The point is that any implementer of this will be an acceptable type. But that means that from a static analysis perspective, it won't know what the type requirements are, because it won't know what concrete implementations are being provided in the code. So obviously, this is a limitation. And this limitation does not exist in a in an actual generics implementation of some kind. I do view it as an improvement personally. And the main reason is that before, if you tried to do something like this, then the errors that you generated and the problems that you caused, were in your code, in its actual execution. Now, the errors and the problems that you need to solve are going to be in your static analysis or in your IDE. And that's, that's something that's a lot safer for the code in general. It can present some maintainability challenges, it can be annoying for developers to deal with, all of that's absolutely true. And it doesn't provide all the things that you would want from being able to do that. It moves the where the safety problems are from being in code execution, where it can cause real problems into code writing, which is where you have the opportunity to kind of think about it, reason about it and catch it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;From what I understand is that if you have a class doing implementing some kind of generics, then you'd often expect that where this generic type is used in either argument parameter, or return value, that'd be the same for all the methods, whereas with never, you can of course not enforce it, that it isn't being the same type being used, in all the other places where you would otherwise expect or enforce with  generics to be the same type. So I reckon that's one of the differences. I think that was a better explanation that what I read from the RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  17:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That was a explanation and in argument that I wasn't forced to actually articulate until I presented it to other people, because I went through several days of research before even writing the RFC. And sometimes when you do that, particularly for you know, for programming related things, you just absorb the information and you kind of forget about what did I, which things were new, like which things that I just learned, and which things that I already know. You just integrate it all into your new programming knowledge. And so that was definitely something that when I wrote the first draft of the RFC, I didn't, didn't articulate particularly well, because I it just made sense in my head. And I had forgotten: Hey, this is something I didn't know a week ago, I should probably explain it to others.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's why we have the RFC process, right? So that other people also voice the opinion, and perhaps all the slightly confused language that make perfect sense to the author, but not necessarily to other people that read it, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  18:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC kindly mentioned that there's no backwards incompatible changes. So that's always good news, that makes it a little bit easy to accept. What was sort of the biggest pushback against the RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  18:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Initially, actually, the most pushback that I got, when I presented it, was a round choosing never as the name, which I thought would, in my mind, I thought would be something that was barely discussed, actually. But I mean, that again, just like you said, that's why this process exists. So that everybody can actually understand, you know, the things that go into it. I did do the research into that prior, but I couldn't find a single language that had more than one bottom type. The concept of more than one bottom type itself, if you if you go back to the integers concept, that'd be like having what positive zero and negative zero or something like that. It's a concept that just intuitively when you, when you understand how the type system itself works, you feel like okay, so there's probably something wrong from a design perspective, if you have more than one bottom type. It's very easy to not be able to see that intuitively. If you don't go in and take a really deep look at how the type system works or, or how types in general work and what they mean and stuff like that. That was the biggest pushback that I got initially. That mostly just involved explaining the things that I just said about like, why is that the case? Why does that make sense? What are some examples of other languages? Just going into that kind of information. The biggest blocker at the moment, really is about, does it make sense to provide never as a parameter type? If you can't use that statically? If you can't use it in a static analysis situation, then does it make sense to ever use it? And if it doesn't make sense to ever use it, then even if it provides contravariance, is it worth adding? And that's the main discussion that's being had right now, that's not entirely resolved. I think that there is still value in doing that. I think that that argument would carry a lot more weight with me personally, if PHP had a better way of handling the situations where that might happen. That's a much larger undertaking, which I would be interested in, but is also not really not really something that would be as kind from a backward compatibility standpoint.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which we are quite keen on.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  20:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Right, exactly. I don't personally see a way that this type of functionality could be provided, that could satisfy that concern, and not also invalidate enormous amounts of code that currently exist. You kind of have to choose one or the other from my understanding. I will be very pleased if somebody is able to provide me a way to, even if it's a lot of work, provide me a way that that can be accomplished without breaking a lot of code. That was one of my goals is I don't want this, I want this to be an addition to what currently exists, not not something that breaks the current typing that we have, or the way that PHP developers currently interact with the type system or anything like that. That's the current discussion. And I think the thing that is most unresolved.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  21:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think you'll have a hard time trying to introduce breaking changes into the language. And I also think rightfully so.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  21:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, it's it's a good safeguard. And it's a good principle to have in general, I think. I think the way that I described it is that this type of breaking change, the type that would be necessary, wouldn't really be like the type of breaking change you expect in a major version, it would more be like a parallel language syntax. It'd be more like rewriting PHP into a different language with very similar semantics, but very different idea of what the language means underneath. Because fundamentally, in order to do that, typing could no longer be optional anywhere. It would have to be every variable, every piece of data, every function, would have to have an explicit type that the developer is able to control and modify and mutate as they want. I don't even know if type juggling would be possible with the kind of change that would be necessary. And that's, that's half of what PHP consider PHP, so.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  22:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Definitely not requiring types and places. Because I think, as I said, I think you'll have a hard time convincing people to go that way.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  23:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which is the reason I didn't consider going that way, really, so.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  23:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would you have anything else to add that I'm, that we missed discussing this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  23:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This RFC is really interesting to me personally, just from an intellectual perspective. I think that for a lot of users, there's not a lot of use cases where you would use it in your own programs. If you did, it would end up being in like the very core base systems, and only in a few places. In those places, it might really shine, it might be something that's absolutely incredible. Most places in most programs you would never be using, well, you would never be using this type. It's much more critical for some of the internal features things like array access, that interface, and the typing that it requires for parameters. The typing for that's pretty broken. This could be a way that we could fix that possibly, and a couple of the other internal engine features that are implemented through interfaces and things like that would also probably be helped quite a bit by this.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you very much for taking the time today to talk about the Never For Parameter Types RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Jordan LeDoux  24:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for having me.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of a PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool, you can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/never_for_parameter_types"&gt;Never For Parameter Types&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-093.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-93.html</guid>
      <pubDate>Thu, 19 Aug 2021 08:21:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: July 2021</title>
      <link>https://derickrethans.nl/xdebug-update-july-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_july_2021"/&gt;Xdebug Update: July 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, August 10th 2021, 09:03 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update 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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 57% towards my $2,000 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In July, I worked on Xdebug for about 50 hours, with funding being around 25 hours, which is only &lt;strong&gt;half&lt;/strong&gt;.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="php_8_1_support"/&gt;PHP 8.1 Support&lt;/h2&gt;
        &lt;p&gt;Now PHP 8.1's feature freeze has happened, I am working on integrating the missing features into Xdebug. Last month I added support for PHP 8.1's &lt;a href="https://wiki.php.net/rfc/enumerations"&gt;Enum&lt;/a&gt; type, but this required a little bit more work as it was emitting the same XML attribute more than once in some occasions. This came to the surface after adding support for &lt;a href="https://wiki.php.net/rfc/readonly_properties_v2"&gt;Readonly Properties&lt;/a&gt;, another new feature in PHP 8.1.&lt;/p&gt;
        &lt;p&gt;IDEs have so far not yet been updated to make use of these new "facets" that Xdebug's debugger emits. PhpStorm's tracker has an issue for &lt;a href="https://youtrack.jetbrains.com/issue/WI-61669"&gt;readonly&lt;/a&gt; as well as &lt;a href="https://youtrack.jetbrains.com/issue/WI-60860"&gt;enums&lt;/a&gt;. The VS Code plugin's tracker has issues for &lt;a href="https://github.com/xdebug/vscode-php-debug/issues/627"&gt;readonly&lt;/a&gt; and &lt;a href="https://github.com/xdebug/vscode-php-debug/issues/628"&gt;enums&lt;/a&gt; as well.&lt;/p&gt;
        &lt;p&gt;I also had to make some more tweaks with regard to PHP 8.1's changes to internals, most notably related to static properties.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1"/&gt;Xdebug 3.1&lt;/h2&gt;
        &lt;p&gt;Beyond making sure that Xdebug 3.1 works will with PHP 8.1, and continues to work with PHP 7.2 through 8.0, I have been adding some new features too.&lt;/p&gt;
        &lt;p&gt;Xdebug 3.1 will no longer set either a timeout, or use &lt;em&gt;Strict&lt;/em&gt; cookies to manage its debugging session through HTTP. Instead, it now uses a &lt;em&gt;Lax&lt;/em&gt; and relies on the browser closing to clean out the cookie.&lt;/p&gt;
        &lt;p&gt;I have added a new function, &lt;code&gt;xdebug_connect_to_client()&lt;/code&gt;. This function can be used to ask Xdebug to try to connect to a debugging client during a request. Normally, it only tries this at the start of a request. In some cases, with long running processes that run many worker jobs, it is sometimes useful to be able to open a debugging client at a later point, and then allow for Xdebug to try to connect to this debugging client. It will now do so if you call the &lt;code&gt;xdebug_connect_to_client()&lt;/code&gt; function. This feature was requested by &lt;a href="https://tideways.com/"&gt;Tideways&lt;/a&gt;, a &lt;a href="https://xdebug.org/support"&gt;business supporter&lt;/a&gt; of Xdebug.&lt;/p&gt;
        &lt;p&gt;Now that PHP 8.1 has introduced a &lt;a href="https://wiki.php.net/rfc/first_class_callable_syntax"&gt;First Class Callable Syntax&lt;/a&gt;, I've updated Xdebug tracer and variable display routines to add information about which function/method a closure encapsulate as well. This information was previously missing. You can learn more about this PHP feature in the PHP Internals News episode &lt;a href="https://phpinternals.news/92"&gt;First Class Callable Syntax&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;To help with funding my work on Xdebug, I have a paid-for-service, called Xdebug Cloud.&lt;/p&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published two more videos on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;These are part of a series to explain how to use Xdebug's profiling:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ttQgLBSpVvc"&gt;Xdebug 3 Profiling: 1. Setting Up&lt;/a&gt;, where I show how to configure Xdebug for profiling.&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=h-0HpCblt3A"&gt;Xdebug 3 Profiling: 2. KCacheGrind tour&lt;/a&gt;, where I go over KCacheGrind's (and QCacheGrind's) features.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;In an upcoming video I will use a "real life" application to show how to use the profiler to find bottlenecks.&lt;/p&gt;
        &lt;p&gt;If you would like to see a 5 to 10 minute long video on another specific topic, feel free to request them through this &lt;a href="https://forms.gle/ugjGbxs6ZhiTyvCSA"&gt;Google Form&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In July, no new supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-july-2021.html</guid>
      <pubDate>Tue, 10 Aug 2021 08:03:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 92: First Class Callable Syntax</title>
      <link>https://derickrethans.nl/phpinternalsnews-92.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_92_first_class_callable_syntax"/&gt;PHP Internals News: Episode 92: First Class Callable Syntax&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, July 22nd 2021, 09:20 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Nikita Popov (&lt;a href="https://twitter.com/nikita_ppv"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/nikic/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://nikic.github.io/"&gt;Website&lt;/a&gt;) about the "First Class Callable Syntax" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-092.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, the podcast dedicated to explaining the latest developments in the PHP language. This is Episode 92. Today I'm talking with Nikita Popov about a first class callable syntax RFC that he's proposing together with Joe Watkins. Nikita, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, Derick. I'm Nikita and I am still working at JetBrains. And still working on PHP core development.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Just like about half an hour ago when we recorded an earlier episode.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This RFC has no relation to read only properties. What is the first class callable syntax RFC about?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The context here is that PHP has the callable syntax based on literals, which is that if you just use a plain string, it's interpreted as a function name, and an array where the first element is an object, and the second one is a method name, that's methods. Or the first element is the class name, and the second one is method name, that's a static method.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I would consider this concept a bit of a hack, especially the the one with the arrays, and I reckon you feel similar and hence this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  1:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, I do. So the current callable syntax has a couple of issues. I think the core issue is that it's not really analysable. So if you see this kind of like array with two strings inside it, it could just be an array with two strings, you don't know if that's supposed to actually be a static method reference. If you look at the context of where it is used, you might be able to figure out that actually, this is a callable. And like in your IDE, if you rename this method, then this array should also be this array element will also be renamed. But there's like a lot of complex reasoning that the static analyser has to perform. That's one side of the issue. The second one is that callables are not scope independent. For example, if you have a private method, then like at the point where you create your callable, like as an array, it might be callable there, but then you pass it to some other function. And that's in a different scope. And suddenly that method is not callable there. So this is a general issue with both like this callable syntax based on arrays, and also the callable type. It's a callable at exactly this point, not callable at a later point. This is what the new syntax essentially addresses. So it provides a syntax that like clearly indicates that yes, this really is a callable, and it performs the callable callability check at the point where it's created, and also binds the scope at that time. So if you pass it to a different function in a different scope, it still remains callable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And it's guaranteed to always be callable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, exactly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What does the syntax like?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The syntax is the funny bit. As a bit of context. This proposal was created as an alternative or as a subset of the partial function application RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That is just as hard to pronounce as first class callable syntax RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, that's why we say PFA. The PFA RFC has a more general feature. It also allows you to create a reference to a callable as a side effect. But more generally, it allows you to also bind some of the arguments to a fixed value. And has like finer control over for example, you can create a callable that has three required parameters, by passing three question mark arguments. While the new syntax only allows you to use the signature of the original function. But the syntax between both of those is compatible. So the new RFC is a subset of PFA. And that's why it uses the syntax where you do a normal function call, but then pass three dots or an ellipsis as arguments.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Instead of passing the function's or method's normal arguments, you use the three dots.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think like the way to think about the syntax is that this is similar to like a variadic argument, or to the argument unpacking syntax, just that the arguments haven't yet been provided, they will be provided during the actual call. But I think the syntax was definitely the most contentious bit in the discussion of the RFC. I think this is mainly related to the fact that if you the see this code snippet, it looks a bit like, like the example code where the arguments haven't been filled in. While now this is like actual syntax.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm sure there's quite a few tutorials out there explaining how PHP works by using dot dot dot. That is not something you can avoid.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, we can avoid it, but it's fairly tricky question. I mean, the reason for this dot dot dot syntax, on one hand, this the compatibility with partial functions. I mean, the PFA, RFC has recently been declined. But in the future, we could extend the current syntax to full partial functions. And we would not end up with two different ways. So that's one benefit of the syntax. But the other part is that PHP has different symbol tables for different kinds of symbols. People often ask, why can't you just write like strlen as a plain name, not inside a string, and have that be treated as a reference to this function? And the answer to that is that we can't do that because you can't have a constant that's called strlen. Normally, that would be reference to constant and the same actually applies to all other callable types as well. So if you have something like methods, like object or method name, that would right now be interpreted as a property access. And for static methods, it will be interpreted as a as a class constant access. So we have this ambiguity here. Even if we add an additional symbol to this, for example, like for classes, we have the syntax, class name, and then scope operator class, that gives you the class name. We could do something like strlen, scope operator function, or fn, or whatever, and have that return the callable. That would work, but it also has some ambiguities. For example, if you have something like object, arrow methods, and then scope operator fn, you have this ambiguity. Is this referencing the method of that name? Or is it referencing a callable stored inside the property of that name? This is like fundamentally ambiguous. The way we would resolve it is we will just say that this index is only usable with real simple, so it will always refer to a method, and you couldn't use the syntax to convert the callable stored in a property into a proper callable. I'm actually not sure how I should distinguish these two concepts, because we have the existing callable, strings and arrays, and the first class callables, which are really closure objects.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which actually sort of brings me to the next question which just popped in my head, which is: Does this first class scalable syntax, what is returned as return a closure or an existing callable type as we have now, with a callable type being a single string, or this array syntax that we now use.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The syntax returns a closure. Actually, the syntax works essentially the same way as the closureFromCallable method. And we do need to return a closure otherwise, we don't get this behaviour where the scope is bound at the time where the callable is created, rather than called. I think maybe going forward, I would generally recommend that people use a closure type, instead of a callable type in type declarations. I mean, you already cannot use callable for property types. Exactly due to this problem that callability is context dependent. While we only forbid it in property types, the same general problem also exists for argument and return types. And especially with the new syntax being introduced here, I think it's best to use closure instead of callable in the future.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Does that sort of mean that first class scalable syntax is syntactic sugar? Or does it do more than the closureFromCallable method?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  8:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, I think it's effectively just syntactic sugar for closureFromCallable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm actually not sure whether Xdebug is be able to do anything with these closure from callable things to begin with. So that is something I'm going to have to investigate.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  8:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Be able as in like, display that it actually refers to a specific method rather than just some kind of closure?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, because at the moment, it shows you the file name and the line numbers, it doesn't have a name right if you create normal closures, but in this case, it's important to know that it actually refers to specific methods, which is the same thing as the closureFromCallable syntax would also do, but I've never done anything with that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But I think there is a way to get like the underlying prototype for the closure, and you should be able to determine it from there.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The first class callable syntax, are there situations where you can't use it?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;One place where you don't want to use the new syntax as if you don't want to actually create a closure object, and validate callability at the point of creation. For example, creating this first class callable also implies that you have to autoload the class for a static method. If you have some kind of like large definition of of handler, of static handler methods for routes or something like that, then using the first class callable syntax would imply that you have to immediately create closure objects for all of these and immediately load all those classes. That's a use case where you might want to stick with the old syntax.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But wouldn't opcache resolve that issue really?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, opcache is really exactly the reason why you wouldn't want to do that. For example, for my fastroute library, I cache all the data as a static array. And that's something that OpCache can cache very efficiently because it's in shared memory and accessing it is essentially zero cost. If you include something like first class callables in it, then those have to always be created at runtime, because we don't have concept like, like a persistent object. That means that this can no longer, I mean, the whole script can be in shared memory, but it still has to be executed always at runtime to construct the whole data structure. And that's going to be less efficient. To give a more clear answer to your question is that the first class callable syntax has a cost when creating the callable, and if you are in a situation where avoiding that cost is really critical for performance, that's why you wouldn't want to use it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And instead you'd have to use the old scalable syntax that we already have.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  11:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. So for that reason, I think that the old syntax is not going to be removed in the near future at least, though maybe we can deprecate certain aspects of it. For example, the syntax also allows you to do highly context dependent things like referencing self, which is even worse than the situation with a private method, because self could refer to something different every time you call it. Those are some things we might want to deprecate early, but the main syntax itself was probably going to stay for a while.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Because callability is checked when you create the closures does that mean it also checks for strictness then? If your PHP file has been declared with strict types?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  11:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Strictness is handled the same as with closureFromCallable.The strictness is still determined at the time where the call is made, not where the callable was created, which actually, I am not a fan of how PHP handles strict types together with dynamic calls. But that's like a pre existing problem. And this isn't touching on this.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The language has many issues that probably could have been done better if it was designed from scratch. But that ship has sailed 26 years ago.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The strict types are not quite that old.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, that is true. The language itself is of course.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, thank you very much then, for taking the time this morning to talk to me about first class scalable syntax.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for having me, Derick.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/first_class_callable_syntax"&gt;First Class Callable Syntax&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/partial_function_application"&gt;Partial Function Application&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode #89: &lt;a href="https://phpinternals.news/89"&gt;Partial Function Applications&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-092.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-92.html</guid>
      <pubDate>Thu, 22 Jul 2021 08:20:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 91: is_literal</title>
      <link>https://derickrethans.nl/phpinternalsnews-91.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_91_is_literal"/&gt;PHP Internals News: Episode 91: is_literal&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, July 15th 2021, 09:19 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Craig Francis (&lt;a href="https://twitter.com/craigfrancis"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/craigfrancis"&gt;GitHub&lt;/a&gt;, &lt;a href="https://www.craigfrancis.co.uk/"&gt;Website&lt;/a&gt;), and Joe Watkins (&lt;a href="https://twitter.com/krakjoe"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/krakjoe"&gt;GitHub&lt;/a&gt;, &lt;a href="https://blog.krakjoe.ninja"&gt;Website&lt;/a&gt;) about the "is_literal" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-091.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is Episode 91. Today I'm talking with Craig Francis and Joe Watkins, talking about the is_literal RFC that they have been proposing. Craig, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  0:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Craig Francis. I've been a PHP developer for about 20 years, doing code auditing, pentesting, training. And I'm also the co-lead for the Bristol chapter of OWASP, which is the open web application security project.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Very well. And Joe, will you introduce yourself as well, please?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  0:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, everyone. I'm Joe, the same Joe from last time.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, it's good to have you back, Joe, and welcome to the podcast Craig. Let's dive straight in. What is the problem that this proposal's trying to resolve?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  1:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So we try to address the problem where injection vulnerabilities are being introduced by developers. When they use libraries incorrectly, we will have people using the libraries, but they still introduce injection vulnerabilities because they use it incorrectly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What is this RFC proposing?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  1:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We're providing a function for libraries to easily check that certain strings have been written by the developer. It's an idea developed by Christoph Kern in 2016. There is a link in the video, and the Google using this to prevent injection vulnerabilities in their Java and Go libraries. It works because libraries know how to handle these data safely, typically using parameterised queries, or escaping where appropriate, but they still require certain values to be written by the developer. So for example, when using a query a database, the developer might need to write a complex WHERE clause or maybe they're using functions like datediff, round, if null, although obviously, this function could be used by developers themselves if they want to, but the primary purpose is for the library to check these values.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That is a method of doing it. What is this RFC adding to PHP itself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  2:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It just simply provides a function which just returns true or false if the variable is a literal, and that's basically a string that was written by the developer. It's a bit like if you did is_int or is_string, it's just a different way of just sort of saying, has this variable been written by the developer?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Is that basically it?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  2:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's it? Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  2:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It would also return true for variables that are the result of concatenation of other variables that would pass the is literal check. Now, this differs from Google, because they introduced that at the language level, but not only at the language level, at the idiom level. So that when you open a file that's got queries in PHP, commonly, if they're long, basic concatenation is used to build the query and format it in the file so that it's readable. So that it wouldn't really be very useful if those queries that you see everywhere in stuff like PHPMyAdmin, and WordPress, and Drupal and just normal code weren't considered literal, just because they're spread over several lines with the concatenation operator. It's strictly not just stuff that's written by the programmer, but also stuff that was written by the programmer or concatenated, with other stuff that was written by the programmer.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Now in the past, we have seen something about adding taint supports to PHP, right? How is this different, or perhaps similar, to taint checking?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  3:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;At the moment today, there is a taint extension, which is something you need to go out your way to install, and actually learn about and how to use. But the main difference is that taint checking goes on the basis of say, this variable is safe or unsafe. And the problem is that it considers anything that had been through an escaping function like html_entities as safe. But of course, the problem is that escaping is difficult. And it's very easy to make mistakes with that. A classic example is if you take a value from a user, an SSH SSH, their homepage URL, if you use HTML encoding, and then put it into the href attribute of a link, that can also result in HTML injection vulnerability, because the escaping is not aware of the context which is used. Because if the evil user put in a JavaScript URL, that is in inline JavaScript, that has created a problem because taint checking would assume that because you use HTML encoding it is safe, and all I'm saying is that is it creates a false sense of security. And by stripping out all that support for escaping, it means that you can focus on libraries doing that work because they know the context, they understand the domain, and we can just keep it a much simpler, and much safer approach.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would you say that the is_literal feature is mostly aimed at library authors and not individual developers?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  5:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, exactly. Because the library authors know what they're doing. They're using well tested code, many eyes over it. The problem libraries have at the moment is that they trust the developer to write things themselves. And unfortunately, developers introduce a lot of injection vulnerabilities with those strings before they even get into the library.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How would a library deal with with strings that aren't literal then?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  5:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So it really depends on each individual example. And the RFC does include quite a lot of examples of how each one will be dealt with. The classic one is, let's say you're sorting by a column in a database, because if we're dealing with SQL, the field name might come from the user. But that is also quite a risky thing to do if you start including whatever field name the user wrote. So in the RFC, I've created a very simple example where the developer would create an array of fields that you can sort by, and then whatever the user provides, you search through that array, and you pull out the one that you that matches and is fine. And therefore you are pulling out a literal and including into the SQL. To be fair, these ones are quite unique. And each one needs to be dealt with in its own way. But I've yet to find an example where you can't do it with a literal. Having said that, I think Larry Garfield actually gave an example where a content management system changed its database structure. And the way that would work is the library would have to deal with it, they would receive the value for a field, and then that field would be escaped and treated as a field, it understands it as a field, and it will process it as such, then it can include into the SQL, knowing full well that everything else in that SQL is a literal, and then it can just build up SQL in its own way internally.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, talking a little bit about the implementation here. Since PHP seven, we have this concept of interned strings, or maybe even before that actually, I don't quite remember. Which is pretty much a flag on each string and PHP that says, this's been created by the engine, or by coconut. Why would strings have to have an extra flag here to remember that it is created by the programmer?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  7:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, interned does not mean literal. It's an optimization in the engine, should we use strings. We're free to do whatever we want with that. At the moment, it by happenstance, most interned strings are those written by the programmer. If you think about the sort of strings that are written by the programmer, like a class name, when those things are declared internally, by an extension, or by core code, those things are interned as if they were written by the programmer. They don't mean literal, we're free to use interned strings for whatever we want. For example, a while ago, someone suggested that we should intern keys while JSON decoding or unserializing. It didn't happen, but it could happen. And then we'd have the problem of, well, how do we separate out all this other input. There is another optimization attached to interned strings, which is one character strings, where if you type only one character, or you call a Class A or B, or whatever, the permanent interned string will be used. That results in when the chr function is called, that results in the return of that function always being marked as interned. So it would show as literal, which is not a very nice side effect. And that's just a side effect that we can see today. We don't want to reuse the string really, it does need to be distinct. Also, if you're going to concatenate, whether you do it with the VM or a specific function, obviously, you need to be able to distinguish between an interned string and a literal string, which interned means it has a specific life cycle and specific value. And we can't break that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So there are really two different concepts, is what you're saying, and hence, they need to have a special flag for that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  9:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, they're very, two very separate concepts. And we don't we don't want to restrict the future of what interned strings may be used for. We don't want to muddy the concept of a literal.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Of course, any sort of mechanism that languages built into solve or prevent injections in any sort of form, there's always ways around it. Theoretically, how would you go around the is_literal checks to still get a user inputted value into something that passes the is_literal check?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  9:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Generally speaking, you would never need it because the library should know how to deal with every scenario anyway. And it's not that difficult. We're only talking about things like in the database world, you'll be taking value from field names and therefore it should receive field names or table names. And, you know, we are providing a guardrail as a safety net. And what should happen is that the default way in which programmers work should guide them, to do it the right way. We're not saying that you can't do weird things to intentionally work around this. A really ugly version, which you should never do, but use eval and var_export together, it's horrible. But if you are so desperate, you need to get around this. That's what we're doing it. But in reality, we can't find any examples where you'd actually need to do this.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  10:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I would say that, hey, there's this idea that most people writing PHP are using libraries, and they're using frameworks. I don't actually find that to be true. I've been working in PHP for a long time. And most of the big projects I've worked on for a long time did not start out using frameworks. And they did not start out using libraries. They look a bit like that today, but their core, they are custom. There may be a framework buried in there. But there is so much code that the framework is a component and is not the main deal. Most code, we actually do write ourselves, because that's what we're paid to do. I think we don't decide how people are going to use it, and we don't decide where they're going to use it. The fact is, like Craig said, it's a guardrail that you can work around easily. And if you find a use case for doing that, then we shouldn't prejudge, and say, well, that's the wrong thing to do. It might not be the wrong thing to do. For example, an earlier version of the idea included support for integers. We considered integers safe, regardless of their source. If you wanted to do that, in your application, you could do that very easily and still retain the integrity of the guardrail is not compromised. I wouldn't focus on this is for libraries, and this is for frameworks, because these things become so small in the scheme of things that they're meaningless. I mean, most of the code we work on is code that we wrote, it is not frameworks.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That also nicely answers my next question, which is what's happened to integers, which have now nicely covered. The RFC talks about that as hard to educate people to do the right thing. And that is_literal is more focused, so to say, on libraries, and perhaps query building frameworks as the RFC alludes to. But I would say that most of these query building tools or libraries already deal with escaping from input value. So why would it make sense for them to start using is_literal if you're handling most of these cases already anyway?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  12:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;If you look at the intro of the RFC, there's a link to show examples of how libraries currently receive the strings. And you're right about the Query Builder approach is a risky thing, I would still argue it's an important part. That's why libraries still provide them. Doctrine has a nice example of DQL. The doctrine query language is an abstraction that they've created, which is also vulnerable to injection vulnerabilities. And it gives the developer a lot more control over a very basic API. I still think people should try and use the higher level API's because they do provide a nice safe default, but that depends on which library use, they're not always safe by default. So for example, when you're sort of saying: I want to find all records where field parameter one, is equal to value two, a lot of the libraries assumed that the first parameter there is safe and written by the developer. They can't just necessarily simply escape it as though it's a field because that value might be something like date, bracket, field, bracket, and it's sort of relying on the developer to write that correctly, and not make any mistakes. And that hasn't proven to be the case, you know, they do include user values in there.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Just going back a little bit about some of the feedback, because feedback to the RFC has happened for quite some time now. And there were lots of different approaches first tried as well, and suggested to add additional functions and stuff like that. So what's been the major pushback to this latest iteration of the RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  14:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So I think the most pushback has come from an earlier suggestion that we could allow integers to be concatenated and considered literal. We experimented with that, and it is possible, but in order to make it possible, you have to disable an optimization in the engine, that would not be an acceptable implementation detail for Dmitri. It turns out we didn't actually, we don't need to track their source technically, but it made people extremely uncomfortable when we said that, and even when we got an independent security expert to comment on the RFC, and he tried to explain that it was no problem, but it was just not accepted by the general public. I'm not sure why.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;All right. Do you have anything to add Craig?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  14:48&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The explanation given by people is they liked the simpler definition of what that was as if it's a string written by the developer. Once you start introducing integers from any source, while it is safe, it made people feel, yeah, what is this. And that's where we also had the slight issue because we had to find a new name for it. And I did the silly thing of sort of asking for suggestions, and then bringing up a vote. And then we had, I think it's 18 to three people saying that it should be called is_trusted, and you have that sinking moment of going, Oh, this is going to cause problems, but hey, democracy. It creates that illusion that it's something more. So that's why we sort of went actually, while I like Scott's idea of having the idea of maybe calling it is_noble. It is a vague concept, which people have to understand. And it's a bit strange. Whereas going back to the simpler, original example, they've all seem to grasp grasp of that one. And we could just keep with the original name of is_literal, which I've not heard any real complaints about.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think some people were equivalenting is_trusted with something that we've had before in PHP called Safe mode, which was anything but of course.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  16:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, no, definitely.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We're sort of coming to the end of what to chat about here. Does the introduction of is literal introduce any BC breaks?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  16:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Only if the user land version of is_literal, which I'm fairly sure is going to be unlikely. So on dividing their own function called that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Did you check for it?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  16:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So if you haven't found it, then it's unlikely to to exist.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  16:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There are still private repositories, we can't shop through all their show, check through all their code. But yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Did I miss anything?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  16:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We covered future scope, which is the potential for a first class type, which I think would be useful for IDs and static analysers. But this is very much a secondary discussion, because that could build on things like intersection types, but we still need to focus on what the flag does. And there's also possibility of using this with the native functions themselves, but we do have to be careful with that one, because, you know, we got things like PHPMyAdmin. We have to be able to make the output from libraries as trusted because they're unlikely to still be providing a literal string at the end of it. So that's a discussion for the future. And the only other thing is that, you know, the vote ends on the 19th of July.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which is the upcoming Monday. How is the vote going? Are you confident that it will pass?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  17:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Not at the moment, we're sort of trying to talk to the people who voted against it. And we've not actually had any complaints as such. The only person who sort of mentioned anything was saying that we should rely on documentation and the documentation is already there. And it's not working. I think a lot of people just voted no, because they just sort of going well, that's the safe default. I don't think it's necessary. Or, you know, I'd like the status quo. And we still are trying to sell the idea and say: Look, it's really simple. It's not really having a performance impact. And it can really help libraries solve a problem, which is actually happening.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Is this something that came out of the people that write PHP libraries or something that you came up with?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  17:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So I've come gone to the library authors and suggested you know, this is how Google do it. Would you like something similar? And we've certainly had red bean and Propel ORM saw show positive support for that. And I've also talked to Matthew Brown, who works on the Psalm static checking analysis. He's very positive about it, so much so that Psalm now also includes this as well. Obviously, static analysis is not going to be used by everyone. So we would like to bring this back to PHP so that libraries can use it without relying on all developers using static analysis.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you very much. Glad that you were both here to explain what this is_literal RFC is about.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Craig Francis  18:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you very much, Derick.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  18:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for having us.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/is_literal"&gt;is_literal&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-091.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-91.html</guid>
      <pubDate>Thu, 15 Jul 2021 08:19:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 90: Read Only Properties</title>
      <link>https://derickrethans.nl/phpinternalsnews-90.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_90_read_only_properties"/&gt;PHP Internals News: Episode 90: Read Only Properties&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, July 8th 2021, 09:18 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Nikita Popov (&lt;a href="https://twitter.com/nikita_ppv"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/nikic/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://nikic.github.io/"&gt;Website&lt;/a&gt;) about the "Read Only Properties" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-090.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is Episode 90. Today I'm talking with Nikita Popov about the read only properties version two RFC that he's proposing. Nikita, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, Derick. I'm Nikita and I do PHP core development work by JetBrains.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What does this RFC proposing?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This RFC is proposing read only properties, which means that the property can only be initialized once and then not changed afterwards. Again, the idea here is that since PHP 7.4, we have typed properties. A remaining problem with them is that people are not confident making public type properties because they still ensure that the type is correct, but they might not be upholding other invariants. For example, if you have some, like additional checks in your constructor, that string property is actually a non empty string property, then you might not want to make it public because then it could be modified to an empty value for example. One nowadays fairly common case is where properties are actually only initialized in the constructor and not changed afterwards any more. So I think this kind of mutable object pattern is becoming more and more popular in PHP.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:35&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You mean the immutable object?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  1:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Sorry, immutable. And read only properties address that case. So you can simply put a public read only typed property in your class, and then it can be initialized once in the constructor and you can be... You don't have to be afraid that someone outside the class is going to modify it afterwards. That's the basic premise of this RFC.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But it also means that objects of the class itself can modify that value any more, either.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  2:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. So that's, I think, a primary distinction we have to make. Genuinely, there are two ways to make this read only concept work. One is like actually read only or maybe more precisely init once, which is what this RFC proposes. We can only set that once and then even in the same class, you can't modify it again. And the alternative is the asymmetric visibility approach where you say that, okay, only in the public scope, the property can only be read, but in the private scope, you can modify it. I think the distinction there is very important, because read only property tells you that it's genuinely read only, like, if you access a property multiple times in sequence, you will always get back the same value. While the asymmetric visibility only says that the public interface is read only, but internally, it could be mutated. And that might like be, you know, intentional, just that you want to like have your state management private, but that the property is not supposed to be immutable.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How's this RFC different from read only properties, version one?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Read only properties version one was called write once properties. I think the naming is kind of one of the more important differences. The new RFC is also effectively write once, but I think it's really important to view it from an API perspective as read only because that's what the user gets to see. While write once gives you this impression, that is know that you can externally from outside the class like passing the value once I know like dependency injection, that is what they would think of when they hear write ones. And from the technical site, there is a related difference. And that difference is that new RFC only allows you to initialize read only properties inside the class scope. That means if you do something really weird, like leaving a property uninitialized in the constructor, it's not possible for someone outside the class to initialize it instead, just like an extra safety check. Of course, you can, as usual bypass that, like if you're writing a serializer or hydrator, you can use reflection to initialize it outside the class. But normally you won't be able to.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Does that mean that these read only properties can also be initialized from a normal method instead of just from the constructor?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's true. Yes, that's possible.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So the RFC talks about that a read only property cannot be assigned from outside a class. Does that mean it can be set by a different object of the same class?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, that's how scoping works in PHP. Scoping is always class based, not object based, it's a common misconception that if you have like private scope, you can access different objects of the same class.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That was a surprise to me the first time I ran into that, but once you know, it's obvious that it's should work all over the place right. Now, the RFC states that you can only use read only with typed properties. Why is that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So this is related to the initialisation concept, that typed introduced. Typed properties start out, if you don't give them a default value, they start out in an uninitialized state. And we reuse that state for read only properties. You can only assign to the property while it's uninitialized. And once it's initialized, you cannot assigned to it any more or even unset it back to an uninitialised state. For non typed properties, you also can get into this uninitialized state by explicitly unsetting it. But the problem is that this is not the default state. Untyped properties always have no default value, even if you don't specify one, which effectively means that these properties are always initialized. So they will be kind of useless if you used read only with them. Which is why we make this distinction to avoid any confusion. And if you want to use an untyped read only property, you do that by using the mixed type, which is the same but has the initialisation semantics of typed properties.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What would that mean if you have say, a resource or class typed property with a read only keyword? Can you not read or write to a resource any more? Or modify properties on an object, that is the value of a read only typed property?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, you can still modify those, because we have to distinguish the concepts of like exterior and interior mutability here. So objects and resources are... Well, I mean, we often say they are passed by reference, which is not strictly true, because those are not PHP references. But the important part is that they only pass around some kind of handle and you can still modify the inside of that handle. What you can't do is you can't reassign to a different resource or reassign to a different object, it's always the same object, the same resource, but the insides of the objects, those can change. Of course, if your object also only contains read only properties, then you won't be able to change this.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, and that answered another question that I have: how it possible to make the whole object read only or on all of its properties? Where the answer is by setting all the properties to read only.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We could like add a read only class modifier that makes all the properties implicitly read only but maybe future scope.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Is there a reason why read only properties can't have a default value?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So this is, again, same issue with initialization. If they have a default value, then they're already initialized. So you can't overwrite it. Like we could allow it, but you just would never be able to change them from the default value, which is something we could allow it just wouldn't be very useful.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;in PHP, eight zero PHP introduced promoted or constructor promoted properties, I think it's the full name of it. How does this read only property tie in with that? Because can you set the read only flag on a constructor promoted property?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, you can. So that works as expected. Important bit there is that with the promoted properties, you can set the default value. And the reason is that for promoted properties, the default value is not the default value of the property. It's the default value of the parameter. And that works just fine.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But again, it would be a constant.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  8:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, in that case, it's not a constant, because it's just a default value for the parameter and the code we generate, we just assign this parameter to the property IN the constructor.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which means that if you instantiate the class with different arguments, they would of course, override the default value of the constructor argument value, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  8:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's right. If you pass it explicitly, then we use the explicit value. If you don't pass an argument, then we use the default of the argument, but it still gets assigned to the property through the like automatically generated code for the promotion.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Promotion isn't actually... there isn't actually really a language feature, but more of a copy and paste mechanism.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  8:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, this is pure bit of syntax sugar.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Which sometimes can be handy. But all kinds of interesting things that we added to properties or type system in general, usually inheritance comes into play. Are there any issues here with read only and inheritance? What does it do to variants or traits or things like that, all the usual things that we need to take into consideration?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Most of our rules for properties, most of our inheritance rules for properties are invariant, which means that the property in the child class has to basically look the same as the property in the parent class. And this is also true for read only properties. So we say that if the parent property is read only the child property has to be read only, and the same the other direction and for the type as well. So we say that the type of the read only property has to match with the parent property. Those rules are very conservative and like they could theoretically maybe be relaxed in some cases. For read only properties on read only is like kind of return type and return types in PHP are covariant. So one could argue that the type should also be covariant here The problem is that like here, we get into this little detail that read only is really not read only, but init once. So there is this one assignment. And assignment is more like an argument. So is contravariant. So if we made them covariant, then we would basically lie about this one initializing assignment. And we don't like to lie about these things, at least without some further consideration.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Read only doesn't change the variance rules at all, which is different from the property accessors RFC we spoke about a couple of months ago. Talking about that this is actually a competing RFC, or do they tie together?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, I should first say that probably the variance stuff defined in the accessors RFC maybe isn't right, for the same reason and should also like just keep things invariant. But it's more complicated there because it also has abstract properties, or abstract accessors. And then the abstract case, that's where the different variance rules are safe. To get back to your question, they are kind of competing, but could also be seen as just complimentary. So read only is basically a small subset of the accessors feature. I mean, accessors also allow you to implement read only properties as part of a much more general framework. And read only properties cover like only this small but very useful corner in a way that's much simpler. And I think that's not just simpler from a technical perspective, but also simpler to understand for the programmer, because there are a lot of less edge cases involved.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Because we're getting pretty close to feature freeze now. Are you still intending to take the property accessors RFC forward for PHP eight one?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  11:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, definitely not.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;But you have taken the read only properties one forwards because we're already voting on it. At the moment, it looks like the vote is going to pass quite easily. So there's that. We don't have to speculate about that, like we had to do with previous RFCs. Do you think I've missed anything talking about read only properties? Or have we covered everything?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We've missed one important bit. And that's the cloning. So the read only properties RFC is not entirely uncontroversial. And basically all the controversy is related to cloning. The problem are wither methods as they're used by PSR seven, for example, which are commonly implemented by cloning the original object, and then modifying one property in it. This doesn't work with read only properties, because you know, if you clone the object, then it already has all the properties initialized. So if you try to change something, then you'll get an error that you're modifying read only property. So these patterns are pretty fundamentally incompatible. There are possible solutions to the problem primarily a dedicated syntax that goes into the code name of cloneWith where you clone an object, but override certain properties directly as part of the syntax, which could bypass the read only property checks. The contention here is basically there are some people consider this clone support and these wither methods are very important. Well, I mean, read only properties are about immutable objects. And like PSR seven is a fairly popular read only object pattern, they think that without support for cloning or for withers, the feature loses all value. That's why the alternative suggestions are either to first introduce some more cloning functionality. So like this mentioned, cloneWith or instead implement asymmetric visibility, which does not have this problem because inside the class, you can always modify the property. So it works perfectly fine with cloning. My personal view on this is well I personally use cloning in PHP approximately never. So this is not a big loss for me, and I'm happy for this from my perspective, edge case, to be addressed at a later time. I can understand that other people put more value on this then I do.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There doesn't seem to be enough push against that for this RFC to fail. So there is that. Thanks Nikita for explaining the read only properties RFC which will very likely see in PHP eight one. Thanks for taking the time.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  14:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for having me Derick, once again.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool, you can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/readonly_properties_v2"&gt;Read Only Properties&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/write_once_properties"&gt;Write Once Properties&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode #44: &lt;a href="https://phpinternals.news/44"&gt;Write Once Properties&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-090.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-90.html</guid>
      <pubDate>Thu, 08 Jul 2021 08:18:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: June 2021</title>
      <link>https://derickrethans.nl/xdebug-update-june-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_june_2021"/&gt;Xdebug Update: June 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, July 6th 2021, 09:01 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this monthly update 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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. I am currently 55% towards my $2,000 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In June, I worked on Xdebug for about 48 hours, with funding being around 24 hours, which is only &lt;strong&gt;half&lt;/strong&gt;.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="php_8_1_support"/&gt;PHP 8.1 Support&lt;/h2&gt;
        &lt;p&gt;PHP 8.1 recently acquired a new &lt;a href="https://wiki.php.net/rfc/enumerations"&gt;Enum&lt;/a&gt; type, and I added support for that in Xdebug's myriad of modes, such as tracing, profiling, and debugging.&lt;/p&gt;
        &lt;p&gt;Enumerations are implemented as a special case of classes, and the step debugger was already be able to communicate these new enums. However, their name and value are displayed as normal class properties, which is less than ideal. The debugging protocol already has facilities for communicating additional information with data, which is what Xdebug now does. IDEs will need to make use of this additional information though.&lt;/p&gt;
        &lt;p&gt;I also had to make some more tweaks with regard to PHP 8.1's Fibers. Although PHP 8.1 feature freeze is coming up soon, I suspect that I will need to make more tweaks.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1"/&gt;Xdebug 3.1&lt;/h2&gt;
        &lt;p&gt;I have continued to work on the issues that were raised by the developer of the &lt;a href="https://github.com/xdebug/vscode-php-debug"&gt;PHP Debug Adapter for Visual Studio Code&lt;/a&gt;. The main new addition is the xdebug_notify() function that you can use to send variables to the IDE. The IDE can then choose to display this information in a structured way.&lt;/p&gt;
        &lt;p&gt;I have not yet worked on the  &lt;a href="https://bugs.xdebug.org/1964"&gt;UNC paths&lt;/a&gt; issue. In order to reproduce it, I need to be able to run Windows' WSL2, which I can't do in my virtualised Windows, and I don't have (or want!) extra hardware to run Windows natively.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;To make &lt;a href="https://xdebug.cloud"&gt;Xdebug Cloud&lt;/a&gt; applicable in more situations, I recently added the support of being to set your Cloud ID (User Key) through the browser extensions as the value of the &lt;em&gt;Debug Session Name&lt;/em&gt;.&lt;/p&gt;
        &lt;p&gt;I have now improved Xdebug's Shared Secret for triggers, which compares the value that comes in through the browser extensions, with a value as configured in the php.ini file. Only if it matches, would the debugger initiate a connection. The new functionality allows you to specify multiple values, separated by a &lt;code&gt;,&lt;/code&gt; as value for &lt;code&gt;xdebug.trigger_value&lt;/code&gt; so that you can control which &lt;em&gt;multiple&lt;/em&gt; Cloud IDs can initiate a debugging connection. This adds additional protection so that other Xdebug Cloud users with a valid ID can't use the browser extensions against third party web sites to initiate a debug session.&lt;/p&gt;
        &lt;p&gt;Xdebug Cloud is the &lt;em&gt;Proxy As A Service&lt;/em&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published two more videos on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;These are:&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=T9rwW-uySBE"&gt;Xdebug 3: Code Coverage for Websites&lt;/a&gt;, where I show how to make a code coverage report from multiple requests to your application&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=lfS0S29t-xg"&gt;Xdebug 3: Debugging Symfony Console Commands&lt;/a&gt;, where I set up Xdebug to debug command line tools using Symfony Console commands as an example. I also show how to use Exception Breakpoints.&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;If you would like to see a 5 to 10 minute long video on another specific topic, feel free to request them through this &lt;a href="https://www.youtube.com/watch?v=lfS0S29t-xg"&gt;Google Form&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In June, no new supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-june-2021.html</guid>
      <pubDate>Tue, 06 Jul 2021 08:01:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 89: Partial Function Applications</title>
      <link>https://derickrethans.nl/phpinternalsnews-89.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_89_partial_function_applications"/&gt;PHP Internals News: Episode 89: Partial Function Applications&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, June 17th 2021, 09:17 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Larry Garfield (&lt;a href="https://twitter.com/Crell"&gt;Twitter&lt;/a&gt;) and Joe Watkins (&lt;a href="https://twitter.com/krakjoe"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/krakjoe"&gt;GitHub&lt;/a&gt;, &lt;a href="https://blog.krakjoe.ninja/"&gt;Blog&lt;/a&gt; about the "Partial Function Applications" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-089.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Derick. Welcome to PHP internals news, a podcast dedicated to explaining the latest developments in the PHP language. This is Episode 89. Today I'm talking with Larry Garfield and Joe Watkins about a partial function application RFC that they're proposing with Paul Crevela and Levi Morrison. Larry, would you please introduce yourself?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  0:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hello World. I'm Larry Garfield or Crell on most social medias. I'm a staff engineer for Typo3 the CMS. And I've been getting more involved in internals these days, mostly as a general nudge and project manager.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And hello, Joe, would you please introduce yourself as well?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  0:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi, I'm Joe, or Krakjoe, I do various PHP stuff. That's all there is to say about that really.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think you do quite a bit more than just a little bit. In any case, I think for this RFC, you, you wrote the implementation of it, whereas Larry, as he said, did some of the project management, I'm sure there's more to it than I've just paraphrased in a single sentence. But can one of you explain in one sentence, or if you must, maybe two or three, what partial function applications, or I hope for short, partials are?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  1:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Partial function application, in the broadest sense, is taking a function that has some number of parameters, and making a new function that pre fills some of those parameters. So if you have a function that takes four parameters, or four arguments, you can produce a new function that takes two arguments. And those other two you've already provided a value for in advance.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, I feel we'll get into the details in a moment. But what are its main benefits of doing this? What would you use this for?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  2:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Oh, there's a couple of places that you can use partial application. It is what got me interested. It's very common in functional programming. But it's also really helpful when you want to, you have a function that like, let's say, string replace takes three arguments, two of which are instructions for what to replace, and one of which is the thing in which you want to replace. If you want to reuse that a bunch of times, you could build an object and pass in constructor values and save those and then call a function. Or you can just partially apply string replace with the things to search for, and the things to replace with and get back a function that takes one argument and will do that replacement on it. And you can then reuse that over and over again. There are a lot of cases like that, usually use in combination with functions that wants a callback. And that callback takes one argument. So array map or array filter are cases where very often you want to give it a function that takes one argument, you have a function that takes three arguments, you want to fill in those first ones first, and then pass the result that only takes one argument to array map or a filter, or whatever. So that's the one of the common use cases for it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's the benefits and some of its background comes from functional programming, as you've just mentioned. What is the syntax that you're proposing and some of the semantics?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  3:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The syntax that we've developed, are two placeholders that you can use in a function call. So if you're calling a function as you normally would, but for one of the arguments, you pass a question mark, or at the tail end, you have an ellipsis (dot dot dot), then that tells the engine: This is not a function call. This is a partial application. And what it will do is return not the result of the function but return a closure object that has the the arguments that correspond to those question marks. And then when called with those arguments, we'll pass those along with the original function. Probably easier to explain, if I use a concrete example, using the string replace example we talked about before, you would call it with str_replace, the example from the RFC, hello, hi, question mark. What that gives you is a callable, a closure that has one argument, which will take its type and name from str_replace. So the third argument to str_replace essentially gets copied into that closure. And what closure does internally when you call it with that one argument is it just calls string replace with hello, hi, and whatever argument you gave it and returns that value. It is conceptually very, very similar to just writing a short lambda or an arrow function that takes one arguments and calls string replace hello, hi, and that argument. In most cases, it ends up functioning almost exactly like that. There's a few subtle differences in a few places. But most of the time, you can think of it working essentially like that. The question mark means one required argument only. The dot dot dot means zero or more arguments, if you want to, say provide the first argument to a function, and then dot dot dot would mean: And then all of the other arguments, however many there are, even if it's that zero, those are what's left, which languages other languages that have partial application as a first class feature, usually end up doing it that way where you can only pre fill from the left. PHP, because the placeholder lets us do it in any order. So we can skip over arguments if we want to, which is quite nice. But it means that you can take a function and reduce it to, I want to prefill just these two arguments and leave these three arguments for the new function, or I want to prefill these arguments from the left, and then everything else, whatever it is, is left. It also lets you do cute things like if you provide all of the arguments to a function, and then just tack on a dot dot dot the end of it, then you get back a closure that takes essentially zero arguments. But when called, will call that other function. So it's lets lets you really easily build a delayed function as you need to.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When do the arguments to the function get evaluated then?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  6:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Arguments are evaluated in advance. So this is the subtle difference between partial application and the short lambda syntax. In a short lambda, what happens is, essentially, that entire expression on the right hand side gets wrapped up into a closure. And so any arguments that are compound like they have a function call that is inside one of the placeholders, or one of the arguments, that'll get evaluated later. With partial application, the function that is in a parameter position gets evaluated first and reduced to a value. And that value gets partially applied to the function. 90% of the time, that's not going to be an issue. There are a few cases where doing it one way or the other may be subtly different, but you'll spot those fairly easily.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So the RFC talks about things that you can do, but also a few things that you cannot do or don't want to do yet. What are these things that partials won't support, or run support yet, at least?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  7:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The main thing that it doesn't support is named placeholders. You can pre fill a value or an argument with a named named argument. But not a named placeholder. Those have to be positional. Named placeholders are complicated to implement, and run into a question of, if you provide those in a different order, does that also change the order of the arguments in the partially applied function that you get back in that closure? And there's a good argument to be made that either way is logical. And so we're like, no, does not deal with it, too complicated. We'll just positional only. And you cannot specify an optional arguments either. It's just again, too complicated. Things get too weird. If you have those advanced cases, use our short lambda, that works just fine. If you want to just make a new function that defers to a new function, and change its API in the process, short lambda works fine. And it's still quite short.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I know the RFC talks a little bit about references, but I don't like talking about references. So let's skip that part. In my opinion, they should be removed from the language. But I know we can't.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  8:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There's occasionally used for them. But very occasionally.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There's a bunch of technical things that I also want to chat about. And hopefully, Joe, if you want to fill in, I'd be more than welcome to hear your opinions on these things. But the first one is that PHP has this thing called func_get_args. How does that work with these partials? How does that tie in together?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  8:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It should mostly behave as if you've invoked the function directly. We don't want there to be a huge discrepancy between. The callee know whether they've been called through partial application or complete application. It should be the same.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That is good to know. I mean, I always like it how things work as people expect them to work, right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  9:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We already have used the dot dot dot operator for variadics. But you're reusing the dot dot dot, or ellipses, as you more eloquently call it earlier. Here again, as well, is that not going to cause issues? Or does that tie in well together?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  9:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well, there's quite a lot of debate about what's the right symbol to use. I think it's dot dot dot, and I think Larry agrees with me. But there's some people who want to stick an extra question mark on the end, which to me looks like it reads zero to one. And to Larry, it looks like an extra character that's just not needed. Other people say it makes sense for them. But if you can type three characters and not four, I mean, you need a really good argument. The arguments that have been put forward so far don't really make very much sense for me. Maybe we should ask that question and it doesn't really matter. In the end, what the syntax is, is if it's a difference between it getting in and not getting in, then we'll just put the extra question mark on there. I don't really have a really good argument to change it like to be like that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;To be honest, to me, it looks like you then have two placeholders.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  10:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't feel the need for it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  10:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's also another argument because we've introduced this one symbol, and then this other symbol, and then you put them together. And that's two things. I mean, you can't have one and one equals one.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Fair enough. The RFC does touch on another quite interesting thing, I think, which is constructors, which it also be able to partially apply. But of course, you've mentioned that, that arguments get applied immediately when you do the substitution, when you do the partial application. But of course, the constructor is a bit weird because a constructor runs immediately after an object has been constructed. So how does that work together with partials?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  10:47&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So at first, we made it so like if you invoke a constructor with reflection, and you just invoke it over and over again, it'll invoke it on the same object, you won't get back a new object. It's not the constructor that returns the object, it's the new operator. So first, we had a bit dumb. And we did just like what reflection does. And if you applied to a constructor, you'd get back a closure that just repeatedly invokes the constructor, which is, as Larry called it, quite naive. So we went back and revisited that. And so now it acts like a factory. Every time you invoke the closure return from an application, you get a brand new object, which is more in line with what people expect. And it's also quite cool. It's one of my favourite bits, actually as it turns out.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;In my opinion, it also makes more sense than then having an apply to the same object over and over again. Whether I'd like it or not, I don't know yet.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  11:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Oh, the other option is traditional constructors to avoid the surprising behaviour. But that would be just a strange.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  11:45&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;There are a lot of use cases where you want to take a bunch of values, convert them to objects using an array map, supporting constructors for that makes total sense to me.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  11:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And I would probably say, though, that I would prefer not allowing it over it applying over the same object over again. You've touched a little bit on some common cases where you want to use this, do you perhaps have some other ideas where this might be really useful?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  12:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So there's three use cases that we think are probably going to be the lion's share. One is to just use the dot dot dot operator. So you have some function or method call, call it with dot dot dot, and that's it. You prefill nothing, which gives you back a closure that is identical in signature to the function or the method that you're applying it to. Everything we've said about functions applies the methods here as well. Which means we now effectively have a new way to refer to a function or a method and make a callable out of it, that doesn't involve just sticking it into a string. You just say, hey, function called dot dot dot, or an arrow bar, parentheses, dot dot dot, parentheses. And now you can turn any function or method into a callable and pass that around. And it's still, it's not wrapped up into the silly array format, it's still accessible to static analysers and refactoring tools. Hopefully, with this, you will never need to refer to a function name using a string ever again, never refer to a method call as an array of object and method. So that that just is not needed any more in the vast majority of cases.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That alone is probably worth having them, maybe.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  13:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And Nikita had an RFC that was doing just that, and nothing else. It's kind of a junior version of this. I don't think that's necessary, the full full scope here works, and gives us that. The second use case that I think is going to be common are unary functions. That's functions that take a single argument. More to the point, as I mentioned before, a lot of functions take a callback. And that callback needs a single argument, array map, array filter, some validation routines, a lot of other things like that. So it's now stupidly easy to take any arbitrary function or method and turn it into a single parameter function, which you can then pass as a callback to array map, array filter, all these other tools, and it just becomes really easy to pre fill things that way. The third is the other one I mentioned earlier, if you pre fill all the arguments, and then just put a dot dot dot at the very end, which means zero or more, you now have a function that takes no arguments, but calls the original function you specified with all the arguments you specified. This often the case for default values, where I want to have a default value available, but don't want to take the time to compute it in advance because it might be expensive. Whatever function it is that will determine that default value, I just partially apply that and give it all the arguments and I get back a callable. That creating a callable is dirt cheap, but when I actually need that value, I can then call it at that time, but it won't actually get called unless I need it. That's another use case that we expect to be common. There are no doubt others that we haven't thought of, or that will be less common, but still useful. I think this will probably replace a large chunk of the use cases for short lambdas. Not because short lambdas are bad, they're wonderful. But so many of them convert a function to a simpler function. And this gives us an even more compact, more readable syntax for that, with even less extra symbols and flotsam around it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I saw, hopefully as a joke, saying that, instead of using the question mark, we should use dollar sign dollar sign, and then we should call the token name T_BLING.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  15:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This RFC actually has a storied history. Several years ago, Sara Golemon had proposed porting the pipe operator from Hack to PHP. The pipe operator is an operator available in a lot of different languages that lets you string together a series of functions. So you pass a function, pass an argument into one function, its results you pass to the next function, its results, you pass the next function and so on, which is a good case for unary functions. In Hack's syntax, they don't use a function on the right hand side, they use an arbitrary expression, and then dollar dollar as a placeholder for where to put the value from the left hand side from the previous step. It's the only language that does that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The other language that does it is bison.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  16:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Or Bison also does that style of?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:25&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It does something weird like that, yeah. Have a look at the grammar file.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  16:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I've looked in there. It's scary. So at the time, she didn't actually put an implementation in for it. But there was some discussion about it. I joked that if she wanted to do that, she should call it T_BLING. And she thought it was hilarious, but never went anywhere. A year ago, I started working on a pipe operator RFC that did just the pipe part, but used a callable on the right hand side, instead of an expression, more like F#, and Haskell, and other languages that have a pipe operator. And their main response to that was, we'd like this, this is cool, except that just using short lambdas on the right all the time to make unaries is too ugly. We want partial application first. So I spent a while trying to bribe someone with more experience and knowledge than me to work on partial application. I tried bribing Ilya Tovolo, to do so by working with him on enumerations. And we got enumerations in, but he doesn't have the time to work on partial application. Levi and Paul had already written an RFC for partial application that had no implementation. It's just a skunkworks, essentially. Then a few weeks ago, Joe pops up and starts working on an implementation for partials. And I, to this day, don't know what interested him in it. But I'm very happy about this fact. So as we updated the RFC, I knew that people want a bike shed about syntax. So I threw that in as a joke. I don't think we're actually going to do that. It's just a little inside reference that is now no longer inside.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Joe what made you work on partials, then?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  17:58&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's interesting to write. I've had my fun whether it gets in or not.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Sometimes that's the case, right? So just working on this is all the fun.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  18:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Sometimes it's fun to just run down rabbit holes for the heck of it. And sometimes really cool things can come out of that sometimes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;At some point, I might have to implement support for partials like I have for closures in Xdebug as well. Because at some point, people might want to debug these things. So I'm a little bit interested in how do these the closures that it generates? Where does it store the already applied arguments?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  18:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So partials have the same binary struct up to this point or of the closure, and then after that there's some extra fields.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would they still have the names?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  18:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, because named arguments aren't actually named, that information is lost. By the time we've got them, we don't have any name information. We've only got their correct position, according to the call that was made.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  18:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And every argument that hasn't been filled and doesn't have a special placeholder in there, or does it keep track of which ones have been filled in?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  18:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We've got two special placeholders internally, you won't see as undef or null or anything.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, that's good to know. What has the reaction been so far?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  19:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Slightly positive. There were a lot of discussions early on about do we support argument reordering? And should it use a single placeholder or two separate placeholders? Originally, we had one and realized after a while, that doesn't actually work. There're use cases where that will be confusing. Overall, the feedback has been quite positive, and I fully expect that to pass. Really the only question people are still debating about at this point is ellipsis versus ellipses question mark.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  19:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, I think the first version of the RFC was quite well received. Someone said we could document it as to make a partial sprinkle or question mark over it and hope for the best.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Oh, that's good to hear. With feature freeze coming not pretty soon now. When do you think you're putting this up for a vote?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  19:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Probably in the next couple of days. The only question I think is whether we include a second question for which variadic placeholder to use, which syntax/ Or if we just say it's dot dot dot, go away. Other than that it should go to a vote probably before this episode airs.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you very much, both of you for taking the time to me today to talk about partials.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Larry Garfield  20:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you again Derick, hopefully see you once more on this season.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Joe Watkins  20:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks Derick, see you soon.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening, and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/partial_function_application"&gt;Partial Function Applications&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-089.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-89.html</guid>
      <pubDate>Thu, 17 Jun 2021 08:17:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 88: Pure Intersection Types</title>
      <link>https://derickrethans.nl/phpinternalsnews-88.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_88_pure_intersection_types"/&gt;PHP Internals News: Episode 88: Pure Intersection Types&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, June 10th 2021, 09:16 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I talk with George Peter Banyard (&lt;a href="https://gpb.moe"&gt;Website&lt;/a&gt;, &lt;a href="https://twitter.com/Girgias"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/Girgias"&gt;GitHub&lt;/a&gt;, &lt;a href="https://gitlab.com/Girgias"&gt;GitLab&lt;/a&gt;) about the "Pure Intersection Types" RFC that he has proposed.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-088.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hello, my name is George Peter Banyard. I work on PHP code development in my free time. And on the PHP Docs.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This RFC is about intersection types. What are intersection types?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  0:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, I saw that in the RFC. And I was wondering like, well, people actually do that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  1:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The only reason I know that is because of Nikita's slide.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The thing is, if it is possible, people will do it, right. And that's how that works.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  1:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, most of the times.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC isn't actually called intersection types. It's called pure intersection types. What does the word pure do here?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  2:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'm sure we'll get into the variance rules in a moment. What is it actually what you're proposing to add here. What is the syntax, for example?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  2:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So the syntax is any class type with an ampersand, and any other class type gives you an intersection type, which is the usual way of doing and.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;When you say class types, do you also mean interfaces?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  3:04&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, PHP has a concept of class types, which are mostly any class in any interface. There's also a weird exception where parent and self are considered class types, but those are not allowed.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, so it's just the classes that you've defined and the class that are part of the language but not a special keywords, self and parent and static, I suppose?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  3:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, the reason for that is standard types are not allowed to be part of an intersection, because nothing can be an integer and a string at the same time. Now, there are some of the built in types, which can be kind of true. You could have a callable, which is a string, because callables can be arrays, or can be a closure. But that's like very weird and not very great. The other one is iterable. If when you expand that out, you get redundant types, which we can talk about later. And the final thing is parent, self, and static, just makes for some very weird design questions, in my opinion, like, if you ask for something to be an intersection with itself, you basically can only enforce conditions on subclasses. You have a class and you say: Oh, I want it to return self, but also be countable for some reason, but I'm not countable. So if you extend me, then you need to be countable, but I'm not. So it's very weird. parent has kind of the very same weird semantics where you can ask a parent, but it's like, if the base class doesn't support it, and you ask for a parent to be an intersection, then you basically need the child to implement the interface and then a child to return the first child. If you do that main question. Why? Because I don't see any good reasons to do it. And it just makes everything harder.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You've only added for the sake of completeness instead of it being useful. Let's move on birds. You've mentioned which types are supported, which is class names and interface names. You already hinted a little bit at redundant types. What are redundant types?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  4:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Currently, PHP already does that with union types. If you repeat the type twice in a union, you'll get a compile error. This only affects compiled time known aliases. If you use a use statement, then PHP knows that you basically using the same type. However you use a runtime alias, then it can't detect that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;A runtime alias, what's that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  5:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So if you use the function class_alias.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:16&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's new to me!&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  5:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;it technically exists. It also doesn't guarantee basically that the type is minimal, because it can only see those was in its own file. For example, if you say I want A and B, but B is a child class of A, then the intersection basically resolves to only B. But you can only know that at runtime if classes are defined in different files. So the type isn't minimal. But if you do redundant types, basically, it's a easy way to check if you might be typing a bug.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You try to do your best to warn people about that. But you never know for certain.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  5:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You never know for certain because PHP doesn't compile everything into like one big program like in check. Static analyser can help for that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Let's talk a little bit about technical aspects, because I recommend that implementing intersection types are quite different from implementing union types. What kind of hacks that you have to make in a parser and compiler for this?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  6:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Our parser has being very weird. The parsing syntax should be the same as union types. So I just copy pasted what Nikita did. I tried it. It worked for return types without an issue. It didn't work with argument types, because bison, which is the tool which generates our parser, was giving a shift reduce conflict, which basically tells: Oh, I got two possible states I can go in, and I don't know which branch I need to go, because the PHP parser only does one look ahead. Because it was conflicting, the ampersand, either for the intersection type or for to mark a reference. Normally, if the paster is more developed, or does more look ahead, it is not a conflict. And it shouldn't be. Ilia managed to came up with this ingenious idea, which is just redefine the ampersand token twice and have very complicated names, and just use them in different contexts. And bison just: now I have no issue. It is the same token, it is the same character. Now that you have two different tokens it manages to disambiguate, like it's shift produce. So that's a very weird.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I'll have a look at what that actually does, because I'm curious now myself. Beyond the parser, I think the biggest and most complicated part of this is implementing the variance rules for these intersection types. Can you give a short summary of what a variance rules are, and potentially how you've actually implemented them?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  7:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Since PHP seven point four, return types and up covariant, and parameter types are contravariant. Covariant means you can like restrict, we can be more specific. And contravariance means you can be broader or like more generic. Union types already gives some interesting covariance implications. Usually, you would think, well, a union is always broader than a single type, you say: Oh, I want either a traversable or accountable, it seems that you're expanding the type sphere. However, a single type can have as a subtype, a union type. For example, you say,:Oh, my base type is a Class A, and I have two child classes, which are B and C. I can type covariantly that I want either B or C, because B or C is more specific than just A. That's what union types over there allows you to do. And the way how it's implemented. And how to check for that is you traverse the list of child types, and check that the child type is an instance of at least one of the parents types. An intersection by virtue of you adding constraints on the type itself will always be more specific than just a single type. If you say: Oh, I want a class A, then more specifically, so I want something of class A and I want it to be countable. So you're already restrict this, which gives some very interesting implications, meaning that a child type can have more types attached to itself than a parent type. That's mostly due how PHP implements its type system, to make the distinctions, basically, I've added the flag, which is either this is a union, meaning that you need to check it is part of one, or it's an intersection. The thing with intersection types is that you need to reverse the order in how you check the types. So you basically need to check that the parent is at least an instance of one of the child types, but not that none of the child types is a super type of the parent type. Let's say you have class C, which extends Class B and Class B extends Class A. If I say let's say my base type is B to any function, and I give something which is a intersection T, any interface, this would not be a valid subtyping relation to underneath B. Because if you looked it was a Venn diagram in some sense, you've got A which is this massive sphere, you've got B which is inside it, and C which is inside it. A intersection something intersects the whole of A with something else, which might also intersect with B in a subset, but it is wider than just B, which means like the whole variance is very complicated in how you check it because you can't really reuse the same loop.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I can't imagine how much more complicated this gets when you have both intersection and union types in the same return type or parameter argument type.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;One of the primary reasons why it's currently not in the RFC, because it is already mind boggling. And although I think it shouldn't be that hard to like, add support for it down the line, because I've already split it mostly up so it should be easy to check: Oh, is this an intersection? Is this a union? And then you need to branch.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Luckily because standard types aren't included here, you also don't really have to think about coercive mode and strict mode for these types. Because that's simply not a thing.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's very convenient.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Is the future scope to this RFC?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  10:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The obvious future scope is what I call composite types, is you have unions and intersections available in the same type. The main issue is mostly variance, because it's already complicated, adding more scope to it, it's going to make the variance go even harder. I think with most programming languages, the variance code is always complicated to read. While I was researching some of it, I managed to hit a couple of failures, which where with I think was Julia and the research paper I was it was just like focusing on a specific subset. And like, basically proving that it is correct. It's not a very big field. Professors at Imperial, which I've talked to, have been kind of helpful with giving some pointers. They mostly work with basically proper languages or compiled languages, which have this whole other set of implications. Apparently, they have like a bunch of issues about how you normalize the types like in an economical form, to make it easier to check. Which is probably one of the problems that will need to be addressed, when you get like such a intersection and union type. First, you normalize it to some canonical form, and then you work with it. But then the second issue is like how do you want the composite types to actually be? Is it oh, you have got parentheses when you want to mix and match? Or can you use like union precedence? I've heard both opinions. Basically, some people are very dead against using Union as a precedent.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;My question is going to be, is this actually something people would use a lot?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  12:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't think it would be used a ton. The moment you want to use it, it is very useful. One example is with the PSRs, the HTTP interfaces. Or if you want the link interface. Combining these multiple things gets it convenient. One of the reasons why I personally wanted as well, it's for streams. So currently, streams don't have any interface, don't have any classes. PHP basically internally checks when you call like certain string methods. For example, if you try to seek and you provide a user stream, it basically checks if you implement a seek method, which should be an interface. But you can't currently do that. Ideally, you would want to stream maybe like a base class, instead of having like a seekable stream, and rewindabe stream, or things like that. You basically just have interfaces. And then like if somebody wants a specific type of stream, just like a stream, which is seekable, which is rewindable. And other things. We already have that in SPL because there's an iterator. And we have a seekable iterator interface, which basically just ask: Oh, this is there's a seek method. I think it depends how you program. So if you separate the many things into interfaces, then you'll probably use intersections types a lot. If you use a maybe a more traditional PHP code base, which uses union types a lot. Union types are like going to be easier. And you want to reduce that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would you think that lots of people already use union types because it's pretty new as well. Isn't it?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  13:38&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Union types are being implemented in various different libraries. PSRs are updating the interfaces to use union types. One use case, I also have a special method, which was taken the date, it takes a union of like a DateTime interface, a string or an integer. Although intersections types are really new, you hear people when union types were being introduced, you heard people saying, I would promote bad cleaning habits, you shouldn't have one specific type. And if you're using a union, you have a design issue. And I had many people complaining to me why and intersection types of see? Why they haven't intersection types being introduced first, because intersection types are more useful. But then you see other people telling us like, I don't see the point in intersection types. Why would you use an intersection type, just use your concrete class, because that's what you're going to type anyway.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I can give you a reason why union types have implemented first, over intersection types, I think, which is that it's easier to implement.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  14:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's easier to implement. And it's more useful for PHP as a whole, because PHP functions accepts a union or return a union. Functions return false for error states instead of null. It makes sense why union types were introduced first, because they are mostly more useful within the scope of what PHP does.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Do you think you have anything else to add about intersection types? At the moment, it's already up for voting, when is that supposed to end?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  14:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So the vote is meant to end on the 17th of June.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:57&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;At the moment I see there's 15 votes for and two against so it's looking good. What's been your most pushback on this? If there was any at all?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  15:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Mostly: I don't see the point in it. However, I do think proper reasons why you don't want it, compared to like some other features where it's more like have thoughts on what you think design wise. But it is undeniable that you you add complexity to the variance. And to the variance check. It is already kind of complicated. I have like a hard time reading it initially. There's the whole parser hackery thing, which is kind of not great. It's probably just because we use like a restricted parser because it's faster and more efficient.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think I spoke with Nikita about parsers some time ago and what the difference between them were. If I remember which episode it was all the to the show notes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  15:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And I think the last reason against it is that it only accepts pure intersections. You could argue that, well, if you're adding intersections, you should add the whole feature set. It might impact the implementation of type aliases, because if you type alias T to be a union of A and B, and then you use type T in an intersection, you basically get a mixture of unions and intersections, that you need to be able to work with. The crux of this whole feature is the variance implementation. And being able to rationalize the variance implementation and been to extend it, I think it's the hardest bit.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I guess the next thing still missing would be type aliases, right? Like names for types, which you can't define just yet, which I think you also mentioned in the RFC is future scope.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  16:29&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:30&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you, George, for taking the time today to talk to me about pure intersection types.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;George Peter Banyard  16:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for having me on the show.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, the podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/pure-intersection-types"&gt;Pure Intersection Types&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Episode #66: &lt;a href="https://phpinternals.news/66"&gt;Namespace Token, and Parsing PHP&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://en.wikipedia.org/wiki/GLR_parser"&gt;GLR Parser&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://en.wikipedia.org/wiki/LALR_parser#Overview"&gt;LALR(1) Parser&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;
              &lt;a href="https://github.com/nikic/iter"&gt;Iter Library&lt;/a&gt;
            &lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-088.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-88.html</guid>
      <pubDate>Thu, 10 Jun 2021 08:16:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>Xdebug Update: May 2021</title>
      <link>https://derickrethans.nl/xdebug-update-may-2021.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_update_may_2021"/&gt;Xdebug Update: May 2021&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Tuesday, June 8th 2021, 08:56 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;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.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; and &lt;a href="https://github.com/sponsors/derickr/"&gt;GitHub&lt;/a&gt; supporters will get it earlier, around the first of each month.&lt;/p&gt;
      &lt;p&gt;You can &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;become a patron&lt;/a&gt; or support me through &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub Sponsors&lt;/a&gt;. 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 &lt;a href="https://xdebug.org/support"&gt;a subscription&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In May, I worked on Xdebug for about 25 hours, with funding being around 30 hours.&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_3_1"/&gt;Xdebug 3.1&lt;/h2&gt;
        &lt;p&gt;I'm continuing to track PHP 8.1's development and have now added support for &lt;a href="https://wiki.php.net/rfc/fibers"&gt;Fibers&lt;/a&gt; in the debugger. I have not spend time adding support for the new &lt;a href="https://wiki.php.net/rfc/enumerations"&gt;Enum&lt;/a&gt; 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.&lt;/p&gt;
        &lt;p&gt;After meeting with a developer of the &lt;a href="https://github.com/xdebug/vscode-php-debug"&gt;PHP Debug Adapter for Visual Studio Code&lt;/a&gt;, 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.&lt;/p&gt;
        &lt;p&gt;He also raised a bug where Xdebug &lt;a href="https://bugs.xdebug.org/1978"&gt;truncates log messages&lt;/a&gt; and with &lt;a href="https://bugs.xdebug.org/1964"&gt;UNC paths&lt;/a&gt;. I have fixed the first one, but the second one requires more investigation and a "clever solution".&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_videos"/&gt;Xdebug Videos&lt;/h2&gt;
        &lt;p&gt;I have published another videos on how to use Xdebug on my &lt;a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;This one deals about &lt;a href="https://www.youtube.com/watch?v=ZIGdBSD6zvU"&gt;Debugging the Symfony Demo App in Docker with VS Code&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;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.&lt;/p&gt;
        &lt;p&gt;If you would like to see a 5 to 10 minute long video on another specific topic, feel free to email me at &lt;a href="mailto:derick@xdebug.org"&gt;derick@xdebug.org&lt;/a&gt;.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="xdebug_cloud"/&gt;Xdebug Cloud&lt;/h2&gt;
        &lt;p&gt;&lt;a href="https://xdebug.cloud"&gt;Xdebug Cloud&lt;/a&gt; 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.&lt;/p&gt;
        &lt;p&gt;Packages start at &amp;#xA3;49/month, and revenue will also be used to further the development of Xdebug.&lt;/p&gt;
        &lt;p&gt;If you want to be kept up to date with Xdebug Cloud, please sign up to the &lt;a href="https://xdebug.cloud/newsletter"&gt;mailinglist&lt;/a&gt;, which I will use to send out an update not more than once a month.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="business_supporter_scheme_and_funding"/&gt;Business Supporter Scheme and Funding&lt;/h2&gt;
        &lt;p&gt;In May, no new supporters signed up.&lt;/p&gt;
        &lt;p&gt;If you, or your company, would also like to support Xdebug, head over to the &lt;a href="https://xdebug.org/support"&gt;support&lt;/a&gt; page!&lt;/p&gt;
        &lt;p&gt;Besides business support, I also maintain a &lt;a href="https://www.patreon.com/derickr"&gt;Patreon&lt;/a&gt; page and a profile on &lt;a href="https://github.com/sponsors/derickr"&gt;GitHub sponsors&lt;/a&gt;.&lt;/p&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <guid isPermaLink="true">https://derickrethans.nl/xdebug-update-may-2021.html</guid>
      <pubDate>Tue, 08 Jun 2021 07:56:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 87: Deprecating Ticks</title>
      <link>https://derickrethans.nl/phpinternalsnews-87.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_87_deprecating_ticks"/&gt;PHP Internals News: Episode 87: Deprecating Ticks&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, June 3rd 2021, 09:15 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Nikita Popov (&lt;a href="https://twitter.com/nikita_ppv"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/nikic/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://nikic.github.io/"&gt;Website&lt;/a&gt;) about the "Deprecating Ticks" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-087.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi Derick, I'm Nikita, and I'm working on PHP core development on behalf of JetBrains.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:40&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Let's jump straight into what this RFC is about, and that's the word ticks. What are ticks?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:05&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Do you have to specify which function that calls?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  1:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  1:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How does this work, historically, because the RFC talks about the change being made in PHP seven?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  1:22&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What was the intended use case for ticks to begin with?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well I'm not sure what was the intended use case, but at least it was the main use case, and that's signal handling. In the PCNTL extension allows you to register a signal handler, and when the signal arrives, we can't just directly call that signal handler, because signals are only allowed to call functions without that our async signal safe. Which excludes things like memory allocation, and a lot of other things that PHP uses. What we do instead is we only set the flag that okay signal has arrived and then we have to actually run the signal handler at some later point in time. In PHP five, that worked using ticks. You declare ticks, and the PCNTL extension registered the tick handler, and then after this flag was set, it would execute your callback on the next tick. In PHP seven, an attentive mechanism was introduced, that is based on virtual machine interrupts. Those were originally introduced for time-out handling, because there we have a similar problem, that when timeout arrives, we might be in some kind of inconsistent state, like the middle of the allocator right now, and if we just bail out at that point, we are likely to see crashes down the road. So that was a significant problem in PHP five. PHP seven changed that. We now set an interrupt flag on timeout, and then the virtual machine checks this flag at certain points. The interrupt flag is not checked after every instruction, but only, like, just often enough to make sure that it's checked, at some point. So that you can't like go in an infinite loop, that ends up never checking. These points are basically function calls, and jumps that go higher up in the function, PCNTL signals can now use the same mechanism. If you call PCNTL async signals true, then those will also set the interrupt flag, and execute the signal handler on the next opportunity. The next time the interrupt flag is checked. The nice thing about that is that it's essentially free. I mean we already, we already have to do these checks for the interrupt like anyway, adding the handling for PCNTL signals doesn't add any cost on top. Unlike ticks, which have to be like executed on every instruction or at least regularly, and that does add significant cost.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Execution time itself because it's an opcode that needs to be executed.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:33&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So what are you proposing to do but the ticks in PHP eight one then?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I want to deprecate that. So both the declared directive itself, and the register tick function, unregister tick function.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How could users emulate the same behaviour as ticks allows them to do so now?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's a good question. As I mentioned, if the use case is, use case of ticks was signal handling, then by using async symbols. If it was something else, then you have a problem. My assumption when writing this RFC was basically that signal handling was really the main remaining use case of ticks, because other use cases require this kind of you know stream wrapper instrumentation, and I didn't expect that people will be crazy enough to use something like that in production.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:21&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hopefully they catch these rewritten files?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Probably yeah. I think it's possible to make this integrate with opcache. If you use it for other purposes, then, I don't think there is a really good replacement. So I think what they use it for is some kind of well instrumentation, so profiling, memory profiling, for example, and the alternative there of course is to use a tool that is appropriate for that job, for example, Xdebug contains a profiler, but of course it is not a production profiler, but I think there are also production profilers.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;As far as I know all the production or APM solutions. They do this on their own without having to use sticks. They don't need any user land modifications.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, definitely. All the APM solutions support this, they use internal handlers.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Because it's actually removing functionalities that some people use, what's the reaction been to removing this functionality?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well on the mailing list at least positive, but as I mentioned at least some people have like pointed out on the pull request that they are using the functionality.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Enough in such a way to sway for not deprecating them? What is the benefits of getting rid of ticks, if you don't use them?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:31&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's, I think the thing, that there is not really a big benefit to getting rid of them. Like they don't add a lot of technical complexity to the engine. They're pretty simple in that sense. I haven't seen those responses. I'm kind of rolling a bit unsure if we should really remove them, because you could argue that well they don't really hurt anyone. I do have to say that I think all the things that people use sticks for, all the cases I have heard about, and all of those cases ticks are not the right way to solve the problem. They are not the right way to solve the signal handler problem, they are not the right way to solve the profiling problem. And the other one I heard is also they're not the right way to solve the heartbeat problem, to make sure a service stays connected. While people do use them I think they use them for questionable purposes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Developers, if they're using something to rewrite the PHP file to introduce ticks, they can also technically rewrite a file to introduce calls to their own functions, after every statement.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  8:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, I actually have a very nice PHP fuzzing project that rewrites PHP files to introduce instrumentation functions at certain points. That needs a lot more control than ticks, because it's interested in branching statements in particular. That is definitely also possible, but it's kind of even more crazy than just adding ticks. If you're doing it like this, I think, if we want to keep ticks, then we should change ticks from a declare directive to a ini_set, because this kind of rewriting of files to introduce takes that's like not a great solution. On the other hand, that does mean that if you are, I don't know a library, implementing some code and expecting that, you know, it just runs normally, then someone can with by enabling an ini setting will suddenly run code in the middle of your library file that's like essentially any point. So enabling ticks us a major behaviour change, that's something we really don't like to have in ini settings which is I guess also, why does it declare in the first place, because that limits the scope. And you have to go out of your way if you want to not limit it using this rewriting hack. So I'm not really sure ultimately what to do here.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Are you thinking of bringing this up for vote before PHP eight dot one's feature freeze?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:49&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;If I decide to go for it, then definitely before. I'm just not completely sure on this topic yet.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;it'd be interesting to, to hear what other people think about removing this. I have no opinion about this. Other features I do but in this case, I'm happy with them being there, I'm happy with them not being there, because it's something I'm using myself. In any case, thank you for going through this RFC with me today, and we'll see what happens.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for having me, Derick.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast, as well as the Xdebug and debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/deprecate_ticks"&gt;Deprecating Ticks&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-087.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-87.html</guid>
      <pubDate>Thu, 03 Jun 2021 08:15:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
    <item>
      <title>PHP Internals News: Episode 86: Property Accessors</title>
      <link>https://derickrethans.nl/phpinternalsnews-86.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_internals_news_episode_86_property_accessors"/&gt;PHP Internals News: Episode 86: Property Accessors&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="date"&gt;Thursday, May 27th 2021, 09:14 BST&lt;/div&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In this episode of "PHP Internals News" I chat with Nikita Popov (&lt;a href="https://twitter.com/nikita_ppv"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/nikic/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://nikic.github.io/"&gt;Website&lt;/a&gt;) about the "Property Accessors" RFC.&lt;/p&gt;
      &lt;p&gt;The RSS feed for this podcast is &lt;a href="https://derickrethans.nl/feed-phpinternalsnews.xml"&gt;https://derickrethans.nl/feed-phpinternalsnews.xml&lt;/a&gt;, you can &lt;a href="https://derickrethans.nl/media/pin-086.mp3"&gt;download&lt;/a&gt; this episode's MP3 file, and it's available on &lt;a href="https://open.spotify.com/show/1Qcd282SDWGF3FSVuG6kuB"&gt;Spotify&lt;/a&gt; and &lt;a href="https://itunes.apple.com/gb/podcast/php-internals-news/id1455782198?mt=2"&gt;iTunes&lt;/a&gt;. There is a dedicated website: &lt;a href="https://phpinternals.news"&gt;https://phpinternals.news&lt;/a&gt;&lt;/p&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="transcript"/&gt;Transcript&lt;/h2&gt;
        &lt;dl&gt;
          &lt;dt&gt;Derick Rethans  0:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:32&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Hi Derick, I'm Nikita, and I do work on PHP core development, on behalf of JetBrains.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  0:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This is probably the largest RFC I've seen in a while. What in one sentence, are you proposing to add to PHP here?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  0:46&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  2:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  2:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This RFC is titled Property accesses, how do these improve on the situation?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  2:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;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.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;For example, when you then do set, or you can add additional validation to it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Exactly. Originally, you had a simple public property, then you can add a setter that checks okay this string cannot be empty.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:23&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Okay, what it's the syntax that you're proposing?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  3:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I went with these essentially the same syntax that's being used in C#. Looks like you write public foobar, and then you have this sort of semi colon you have a code block. And this code block contains two accessors, so then you have something like get, and another code block that specifies the get behaviour, and set, and the code block that specifies the set behaviour and so on.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  3:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC talks about implicit and explicit implementations of these getter and setter accessors. What is the difference between them and how does it look different in syntax?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah so the difference is, either you can write just get semi colon, set semicolon, that's an implicit implementation, or you actually specify a code block with real custom behaviour. To do the implicit implementation, you're saying that this is really a normal property, and PHP automatically manages the storage for you, is that you have this more fine grained control over how it works. Namely what you can do is you can say that you have get and private set. But that's a property that's publicly read only and internally writeable. You can write just get without set, in which case it's a real read only property both publicly and privately, or to be more precise, it's an init once property so you can assign to it once.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  4:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How do you keep track of the init once?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  4:53&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's same mechanism as for Type Properties, where we distinguish between an initialized and an uninitialized property. You can assign to an uninitialized property, but you can't assign to an initialized one, if it's read only. The only maybe problem there is that this mechanism, requires that the property actually is uninitialized to start with, which means that for accessors you don't have any default values. To say there is no implicit default value, no implicit null value. If you want to have a default value the same as with type properties you have to specify it explicitly. Specifying a default value really only makes sense if the property is both readable and writable. For Read Only properties, if you specify the default then you will you can change that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You have basically have created a constant.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yes, it is essentially a constant.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  5:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You mentioned already, PHP seven four introduced type properties. How do these types interact with the setter and getter accessors?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  5:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I would say in the obvious way. The getter is required to return type of property, modulo the usual weak typing conversions, and the setter also checks before it's called whether the passed value matches the type or not. But enforces that matches the type.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;This does mean that if you provide an explicit implementation for the set accessor, you also need to specify the parameter name?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:15&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;No, or you can specify the parameter name, and if you don't then that's just passed in as the value variable. It's also inspired by how C# and Swift do it. I mean there are some possible variations here we could always require an explicit name, some people for that, or I also heard that some people would like to have the name of this implicit variable match the name of the property, instead of always being just value.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would you have to specify the type though?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  6:43&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;You wouldn't have to and you're actually not allowed to. So the accessor implementation is somewhat strict about not allowing you to do anything that would be redundant because otherwise, you know, there are quite a lot of extra things you could be adding everywhere.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  6:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's the same way as marking a property as private. And then the accessors as private as well. Right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah exactly. So, then that will also say: if the property is already private you can't, again say that the accessors also private.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think that's the wise thing, otherwise people go overboard with adding private and final and whatever everywhere anyway right.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:18&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;One could argue that it's really not our business and this is a coding style question, but you know it's better to not leave people, with the option of doing stupid things.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  7:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I saw in the RFC that it is also possible to use references with the get accessor.  Does this complicated implementation and the idea of this RFC, a lot, or just a little?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  7:39&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think the important context to keep in mind here is that we already have magic get set, and the accessors are, like, largely based on their semantics. Magic getters already have this distinction between returning by value and returning by reference. The by reference return value is primarily useful for two cases. One and this is really the important one, is if you're working with arrays, any write operation on an array like setting an element or appending an element, those require that the getter returns by reference, because PHP will actually do the modification on the reference. Because some people asked about that. Why can't we just like get the array using the getter, then make the change and then assign back using the setter. That would theoretically work, but it would be extremely inefficient, and the reason is that this breaks PHP's copy on write mechanism. If the error is returned from the getter, then we have one array inside the property. And we have one copy of the array inside the property, and as the return value. Then we change the return value and the resource is now shared, we actually have to copy the whole array, and then we assign it back. So effectively what we do is we copy the array, we do single element change, and then we copy the array, we do a single element change and then we destroy the old array. That works in theory, but it's so inefficient that we would not want to promote this kind of usage.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  8:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The way around is of course, is having an implicit methods on the class to make this change to the array itself right?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:10&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That would be another option. Problem is that you will need a lot of methods, I mean it's not just a matter of setting a single element or unsetting an element, but you can also set like a deep element where you're not modifying the outermost array but, like, a multi dimensional array. You would actually have to pass through that information somehow as well. I don't think there is a simple solution to that problem beyond the reference based solution that we currently use.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  9:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I saw people arguing about not bothering with references in this new implementation at all, but I think you've now made a good case for keeping them.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  9:42&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Effectively not bothering with references just means not supporting that array use case. Which might be, maybe a reasonable limitation, especially if we like make a distinction and supported for the implicit accessor case where we can, you know, do internal magic to support that and not support it in the explicit accessors case. I mean, people were arguing that this reduces the complexity of the proposal, but it kind of also increases the complexity because now we are doing something else for the accessors and we're doing for the magic get/set, where we already have this established mechanism. I'm not really convinced by that.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;And I also think it creates inconsistencies in the language itself because it does something different with an implicit or explicit accessor, as well as it being different between the original underscore underscore get magic method as well.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  10:34&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's not a secret that I'm not a big fan of references, and I would certainly love to get rid of them, but it's a hard problem, and this array modification behaviour for magic get or for get accessors is certainly a large part of that problem, and I just don't have a good solution for it.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  10:52&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't either. The RFC also goes into great detail about inheritance and variance. Would you have a few words on that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  11:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think mostly inheritance works like inheritance does for methods, at least that's how it's supposed to work. Of course there are some interactions, because you can for example mix real properties and accessor properties. In which case, if you have parent accessor property, you can always replace it with a normal simple property, because normal properties they support all operations that accessor properties do. What you can't do is the other way around. If you have a parent normal property, then you can't replace that with an accessor property. And reason is that it does have some limitations. Not a lot, but there are some limitations. One of them is related to references, I mean, we're already talking about this topic. What the by reference get allows is taking a reference to the property, so you can do something like a reference equals the property. What you can't do is the other way around the property reference equals something else. So you can't assign a new reference into the property, that just doesn't work on a pretty fundamental level, because it would require an additional set handler for set by reference. As we don't particularly love references, adding a new mechanism to support that is not a very popular choice.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  12:20&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Variance wise, I guess, the same rules apply as for normal properties and property types?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  12:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Approximately. Properties are apparently invariant, so you can't change the type or I mean you can change it but it has to be an equivalent type. If you have a read only property, with only a getter, then the implementation makes the type covariant, which means you can use a smaller type in the child class. This is similar to how if you have a getter method, you could also give it a smaller type in the child class. The converse case, if you have a property that can only be set, then the type is contravariant, you can have larger type in the child class, though I should say that properties that can only be set are somewhat odd and really only supported for the sake of completeness, so maybe it might be worthwhile to drop the type specific behaviour there, because a set only property should already be really rare, and then set property with a contravariant inheritance that's like a edge case of an edge case.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Would it even make sense to support set only properties?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  13:27&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Not sure. So for the C#, implementation, I think they don't support this and there is a StackOverflow question about that, and people try to convince their, that they should support this, that the are really use cases. Currently the imagined use cases are along the lines of injecting values into a class, so using setter injection, just that now it's property based setter injection. Okay, I'll be honest I think it doesn't make sense.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  13:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;To be fair, I don't think either. It would reduce the length of the RFC a little bit.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  14:00&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;A little bit, yes.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  14:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Can you say a few words about abstracts, traits, private accessors shadowing and things like that. So a lot of complicated words, maybe you, you can distil that into something slightly simpler.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  14:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Well I think actually abstract properties are worth mentioning. In particular, the fact that you can now specify properties inside interfaces. If you have public properties, then it makes sense to have them really on the same level as public methods, so they are part of the API contract, and as such should also be supported in interfaces. Typically what the RFC allows is, you can't specify a simple property in the interface, but you can specify an accessor property, which tells you which operations have to be supported. So you can't have a property declaration that says, it just has a get accessor, or it has get and set. The implementation of course can always implement more, so if the interface requires get, then you can implement both get and set, but it has to implement at least get, either through an accessor offer another property. I think in most cases implementation will just be a normal property.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Because a normal property would implement an implicit get already anyway?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  15:07&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:08&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How do property accessors tie in, or integrate with constructor property promotion?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  15:13&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;They are supported and promotion with the limitation that it's only implicit accessors. If you use constructor promotion, then you can specify your read only property in there, or property that is Public Read/ private write. You cannot specify a property with complex behaviour in there. This is mainly because it would mean that you embed large code blocks into the constructor signature, which is I think, pushing the limits of shorthand syntax, a bit. Like there is nothing fundamental that will prevent it, it's more a question of style.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  15:50&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC talks a little bit about how, or rather what happens if you use foreach, var_dump, or an array cast on properties with explicit accessor. What are the restrictions here? Is something chasing from normal standard properties like we currently have.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  16:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I don't think so. So here is once again the case where we have this distinction between the implicit accessors, which are really just normal properties with limitations. So those show up in var_dump and array cast, foreach, as usual. And we have explicit accessors, which are really virtual properties, so they don't have any storage themselves. Any storage to use, you have to manage separately somehow. So, these don't show up in var_dump, foreach, and so on. Both these actual computed properties, they don't show up because that would require us to actually call all the accessors if you do foreach and that seems rather dubious to me.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  16:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How this will work for internal API's that some extensions use to access, like a list of all the properties, for say, for a debugger.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  16:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It'll work the same way as var_dump. I mean, in the end it's all, well it's not quite based on the same API's, but still, the answer is the same. You only get those properties that have some kind of backing storage, and those are only the ones that are either normal properties, or the ones with implicit accessors.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:09&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That means I need to go find out a way how to be able to read the ones with explicit accessors.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  17:14&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, if you want to. I don't think that the debugger should read those by default, because that means that doing a dump, will have side effects, which is not ideal, but maybe you want to have an option to show them.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:26&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's something for me to think about, because I'm pretty sure people are going to want to see the contents of these properties, even in a debugger, even though that could mean that are side effects, which I'm not keen on.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  17:36&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I guess that's one of the, I would say advantages of using this over just magic get/set, because actually know which properties you're supposed to look at, with for magic get/set you just don't know at all.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  17:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;The RFC talks a little bit about the performance impacts and although I saw the numbers I didn't actually read them, when preparing for this recording. What are the performance impacts for implicit accessors as well as explicit ones?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  18:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Impact is basically if you use implicit accessors that has similar performance to plain properties, performance is a bit worse. The reason is essentially that we have some limitations on caching. So we can't just cache it as if it were a normal property, because it could have asymmetric visibility. And we reuse the same cache slots for reads and writes. I've been thinking about maybe splitting that up but at least for now there is a small additional performance impact of using implicit accessors, but it's not really significant. On the other side if you use explicit accessors. Those are expensive, they are not quite as expensive as using magic get/set, but they are more expensive than using normal method calls. Reason is basically their normal method calls, they are very optimized, and they do not have to re enter the virtual machine, so we just stay in the same virtual machine loop, and we just switch to different stack frames. For magic get/set we actually have to like recursively call the virtual machine, because we don't have a good point to re enter it, at least based on our current API's. And we also have to deal with some additional stuff, particularly the fact that magic get/set and property accessor as both, they have recursion guards. Normally if you recurse methods in PHP, we don't do any checks about that. Xdebug does, but PHP itself doesn't, so you can infinitely recurse and PHP is fine. The only thing that happens is that at some point you'll run out of memory.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  19:37&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Or when extensions are loaded such as Xdebug, you'll actually still get a stack overflow.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  19:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;So that's something we should still be addressing, at least the baseline behaviour that you can get to that memory limit error. For properties will set have recursion guards, which say that if you recursively access a property in magic get/set, that it will not call magic get/set again and instead, access the property as if they didn't exist.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:01&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Instead of throwing in an error?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  20:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah. For property accessors I'm actually throwing an error on recursion, and the reason for that is if we didn't throw an error, then this would end up accessing dynamic property of the same name as the accessor, which would technically work, but it's very likely not what the programmer actually intended. So it's going to be really inefficient because you actually have to allocate space for the dynamic properties and access for those. So if you wanted to have some kind of backing storage for the property, then you should just explicitly declare it and access that, rather than accessing something with the same name and implicitly creating a dynamic property.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:41&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, that sounds all very complicated.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  20:44&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's cleaner to just make it an error and let the programmer fix it, instead of PHP try to fix it for you.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  20:51&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Are there any BC considerations about the introduction of property accessors?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  20:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Not strictly, but I'm sure that it's going to break, various assumptions for people, or at least in the sense that, right now, most assumptions should already be broken through magic get/set. I mean you can always have this kind of magic behaviour. If we have accessors this is probably going to be a lot more common, and people will have to deal with things like properties being publicly readable, but privately writable much as because someone very rarely manually implements that behaviour, but because the language though has native support for it and it's going to be common.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  21:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;We spoke a little bit about all the different sticking points in his RFC, for example with references, but there's one other thing and I think it's an argument you make somewhere on the bottom of the RFC, that there is a separation between implicit and explicit property accessors. I'm wondering whether it would make sense to consider adding whether the implicit part of this RFC first and then maybe later look at adding explicit property accessors.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  21:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's really the main sticking point, and also my own problem with the RFC. I mean, you mentioned at the very start, that this is a very long RFC and still a little bit incomplete so it's going to be longer. It's a fairly complex feature that has complex interactions with other features in PHP. The implementation is actually, maybe less complex, then you think, given the RFC length. The main concern I have is that, at least for me personally the most useful part of the RFC, are the read only properties. The read only properties and the like Public Read, Private Write properties. I think these two cover like 90% of the use cases, especially because if you have a property that is only publicly readable, then you don't really have to be concerned about this case where you have to, later on, add additional validation. I mean after all the property is read only, or you control all the sets because they're private. There is no danger of introducing an API break, because you have to add additional validation. I think like the largest part of the use case of the whole accessors proposal will be covered by these two things, Or maybe even just one of these two things, that's a bit of a philosophical question. There are some people who think we should have just public read / private write and no proper read only properties, because that like looks the same from the user perspective, but still gives you more flexibility. I think that's like the most important use case, and we could implement that part with a lot less language complexity. So the question is really does it make sense to have this full accessor proposal, if we could get the most useful part as a separate simpler feature, and, well, I heard differing opinions on that one. I was actually pretty surprised that their reception of the on like a full accessors proposal was fairly positive. I kind of expected more pushback, especially as, this is the second proposal on the topic, we had earlier one with, like, similar syntax even though different details, and that one did fail.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:02&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;How long ago was that?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  24:03&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Oh that was quite a while actually, at least more than five years.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:06&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I think that the mindset of developers has changed in the last five to 10 years, like introducing this 10 years ago would never happened, or even typed properties, right. It would never have happened.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  24:17&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;That's true.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:19&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Do you have any idea when you're going to put us up for a vote? Because, of course, PHP 8.1 feature freezes coming up in not too far away from now.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  24:28&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Yeah, I'm not sure about that. I'm still considering if I want to explore the simpler alternatives, first. There was already a proposal. Another rejected proposal for Read Only properties, probably was called write once properties at the time. But yeah, I kind of do think that it might make sense to try something like that, again, before going to the full accessors proposal or instead.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:54&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Do you have anything else to add?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  24:56&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;What are your thoughts on this proposal, and the question at the end?&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  24:59&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;I quite like it, but I also think that it might make sense to split it up. I'm always quite a fan of splitting things up in smaller bits, if that's possible too, and still provide quite a lot of use out of it. And that's why I was asking whether it makes sense to split it up into the implicit part and the explicit part of it, especially because it makes the implementation and the logic around it quite a bit easier for people to understand as well.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  25:24&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;It's maybe worth mentioning that Swift also has a similar accessor model but it is more like a composition of various different features like read only properties, properties with asymmetric visibility, and then finally properties with like fully controlled, get and set behaviour rather than this C# model where everything is modelled using accessors with appropriate modifiers. So there is certainly precedent in other languages of separating these things.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  25:55&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Something to ponder about, and I'm sure we'll get to a conclusion at some point. Hopefully some of it before PHP eight one goes and feature freeze, of course. We've been chatting for quite a while now, I think we should call it the end for this RFC. Thank you for taking the time today to talk about property accessors.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Nikita Popov  26:11&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thanks for having me, Derick.&lt;/p&gt;
          &lt;/dd&gt;
          &lt;dt&gt;Derick Rethans  26:12&lt;/dt&gt;
          &lt;dd&gt;
            &lt;p&gt;Thank you for listening to this installment of PHP internals news, a podcast, dedicated to demystifying the development of the PHP language. I maintain a Patreon account for supporters of this podcast as well as the Xdebug debugging tool. You can sign up for Patreon at &lt;a href="https://drck.me/patreon"&gt;https://drck.me/patreon&lt;/a&gt;. If you have comments or suggestions, feel free to email them to &lt;a href="mailto:derick@phpinternals.news"&gt;derick@phpinternals.news&lt;/a&gt;. Thank you for listening and I'll see you next time.&lt;/p&gt;
          &lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="show_notes"/&gt;Show Notes&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;p&gt;RFC: &lt;a href="https://wiki.php.net/rfc/property_accessors"&gt;Property Accessors&lt;/a&gt;&lt;/p&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="articleSubSection"&gt;
        &lt;h2&gt;&lt;a name="credits"/&gt;Credits&lt;/h2&gt;
        &lt;div class="credits"&gt;
          &lt;a href="https://incompetech.com/music/royalty-free/music.html"&gt;
            &lt;p&gt; Music: Chipper Doodle v2 &amp;#x2014; Kevin MacLeod (incompetech.com) &amp;#x2014; Creative Commons: By Attribution 3.0&lt;/p&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="patreon"&gt;
          &lt;a href="https://www.patreon.com/bePatron?u=7864328"&gt;
            &lt;img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!"/&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <author>derick@derickrethans.nl (Derick Rethans)</author>
      <enclosure url="https://derickrethans.nl/media/pin-086.mp3" length="0" type="audio/x-mp3"/>
      <guid isPermaLink="true">https://derickrethans.nl/phpinternalsnews-86.html</guid>
      <pubDate>Thu, 27 May 2021 08:14:00 +0000</pubDate>
      <itunes:explicit>no</itunes:explicit>
    </item>
  </channel>
</rss>
