Derick RethansPHP Internals News: Episode 47: Attributes v2 (2.4.2020, 08:10 UTC)

PHP Internals News: Episode 47: Attributes v2

In this episode of "PHP Internals News" I chat with Benjamin Eberlei (Twitter, GitHub, Website) about an RFC that he wrote, that would add Attributes to PHP.

The RSS feed for this podcast is, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website:


Derick Rethans 0:16

Hi, I'm Derick. And this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language. This is Episode 47. Today I'm talking with Benjamin Eberlei about the attributes version 2 RFC. Hello, Benjamin, would you please introduce yourself?

Benjamin Eberlei 0:34

Hello, I'm Benjamin. I started contributing to PHP in more detail last year with my RFC on the extension to DOM. And I felt that the attributes thing was the next great or bigger thing that I should tackle because I would really like to work on this and I've been working on this sort of scope for a long time.

Derick Rethans 0:58

Although RFC startled attribute version two. There was actually never an attribute version one. What's happening there?

Benjamin Eberlei 1:05

There was an attributes version one.

Derick Rethans 1:07

No, it was called annotations?

Benjamin Eberlei 1:08

No, it was called attributes. There were two RFCs. One was called annotations, I think it was from 2012 or 2013. And then in 2016, Dmitri had an RFC that was called the attributes, original attributes RFC.

Derick Rethans 1:25

So this is the version two. What is the difference between attributes and annotations?

Benjamin Eberlei 1:30

It's just a naming. So essentially, different languages have this feature, which we probably explain in a bit. But different languages have this. And in Java, it's called annotations. In languages that are maybe more closer home to PHP, so C#, C++, Rust, and Hack. It's called attributes. And then Python and JavaScript also have it, that works a bit differently. And it's called decorators there.

Derick Rethans 1:58

What are these attributes or annotations to begin with?

Benjamin Eberlei 2:01

They are a way to declare structured metadata on declarations of the language. So in PHP or in my RFC, this would be classes, class properties, class constants and regular functions. You could declare additional metadata there that sort of tags those declarations with specific additional machine readable information.

Derick Rethans 2:27

This is something that other languages have. And surely people that use PHP will have done something similar already anyway?

Benjamin Eberlei 2:35

PHP has this concept of doc block comments, which you can access through an API at runtime. They were originally I guess, added as part or of like sort of to support the PHP doc project which existed at that point to declare types on functions and everything. So this goes way back to the time when PHP didn't have type hints and everything had to be documented everywhere so that you at least have roughly have an idea of what types would flow in and out of functions.

Derick Rethans 3:07

Why is that now no longer good enough?

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

platform.shThe suddenly online conference: an Indy Cloud Conf case study (2.4.2020, 00:00 UTC)
With the global COVID19 pandemic threatening the globe, dozens of conferences have had to either cancel or switch from in-person to online events on short notice. That’s no easy task under the best of circumstances and is, not surprisingly, posing challenges for many. Last week I keynoted Indy Cloud Conf a small regional conference on cloud, IoT, and machine learning stuff ostensibly in Indianapolis, Indiana. Of course, it wasn’t in Indianapolis anymore but “on the Interwebs,” and I’m pleased to report that the organizers did a great job of shifting gears so quickly.
Derick RethansPHP Internals News: Episode 46: str_contains() (26.3.2020, 09:09 UTC)

PHP Internals News: Episode 46: str_contains()

In this episode of "PHP Internals News" I chat with Philipp Tanlak (GitHub, Xing) about his str_contains() RFC.

The RSS feed for this podcast is, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website:


Derick Rethans 0:16

Hi, I'm Derick. And this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language. This is Episode 46. Today I'm talking with Phillipp Tanlak, about an RFC that he's made titled str_contains. Phillipp, would you please introduce yourself.

Philipp Tanlak 0:35

Hey, Derick. My name is Philipp. I'm 25 years old and I live in Germany. I work for an IT service company, which does mainly development and maintenance of IT projects. We specialise in the maintenance of e-commerce website and create enterprise applications.

Derick Rethans 0:52

How long have you been using PHP for?

Philipp Tanlak 0:54

I've been using PHP for quite a long time now that might be six years I guess.

Derick Rethans 0:58

What brought to you creating an RFC?

Philipp Tanlak 1:02

The main reason I've created this RFC was out of necessity and interest, mainly to scratch my own itch.

Derick Rethans 1:08

That is how most things make it into PHP in the end isn't it?

Philipp Tanlak 1:11

Yeah, I guess.

Derick Rethans 1:12

The RFC is titled str_contains, that tells me something that is about strings and containing things. How do we currently find a string in a string?

Philipp Tanlak 1:22

The current approach to find the string in a string is to use the strpos() function or the strstr() function. But on Reddit, I found someone also use preg_match which I find kind of interesting.

Derick Rethans 1:35

There are multiple amount of different methods in use, what are the general problems with these approaches that people have made?

Philipp Tanlak 1:41

So the current approach which I find is not very intuitive, and mainly because of the return values of these functions. For example, the strpos() returns either the position where the string is found, or a false value if the string is not found, but there has to be a check with a !== operation, and the strstr() function just returns a string. So you have to convert that to a boolean to check if the string is found or not.

Derick Rethans 2:11

Because with strpos(), if you wouldn't use the === or !== operator. Of course, if it would find it at the first position of the string, it'd be zero position, and it would return false, even though it's sfound it.

Philipp Tanlak 2:26


Derick Rethans 2:27

So there's a few different problems with these things. Also, I don't think it's particularly vary intuitive to do because you sort of need to come up with like a whole construct to see whether it's part of a string.

Philipp Tanlak 2:37

Correct. I don't think it's intuitive for a beginner. So if someone is learning PHP for

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

platform.shThe container is a lie! (24.3.2020, 00:00 UTC)
(This article was originally published in php[architect] magazine, in two installments.) As a general rule, lying to people is a bad idea. People don’t like dishonesty. It’s insulting to lie to a person and tends to destroy relationships both personal and professional. But computer software isn’t people (thank goodness). Virtually all software today is based on lies, very well-organized and effective lies. Lies make modern computer systems possible. The latest generation of software deception is “containers.
Matthias NobackFunctional tests, and speeding up the schema creation (23.3.2020, 15:53 UTC)

When Symfony2 was created I first learned about the functional test, which is an interesting type of test where everything about your application is as real as possible. Just like with an integration or end-to-end test. One big difference: the test runner exercises the application's front controller programmatically, instead of through a web server. This means that the input for the test is a Request object, not an actual HTTP message.

Drawbacks of functional tests

This approach has several drawbacks, like:

  1. Faking a Request object means you don't know if the code also works in a production environment, when an actual HTTP request will be provided as input.
  2. Inspecting a Response object instead of a real HTTP response message comes with the same risk, but my guess is that it's a less severe risk.
  3. Since you have access to the application's service container you may be tempted to open the black box and replace all kinds of services, or otherwise influence them. I recommend doing no such thing.
  4. You are likely to end up testing all kinds of domain-related behaviors through thick layers of unrelated code. This obscures the view on the real issues and makes it hard to figure out what's wrong, if anything pops up. Combining this with drawback 3 you often find yourself rummaging around in all the stuff that's on the inside of your application, lengthening the feedback loop between building something and finding out if it works. Because these tests end up being white-box tests after all, you also end up with many cracks; it will be easy for anything to fall through them and you'll only find out if that happened when the code is already running in production.

Another issue I see with functional tests is that the assertions that are made are often something like: "I see in database". This too is like opening the box and looking inside. I'd like to follow this reasoning instead: if, as a user of the system, I expect a request to produce some kind of effect, then I should be able to notice this effect as a user. And as a user I can't look directly inside the database. There must be some other aspect of the system that was changed when I made that request. E.g. after registration I can now log in, or the product I added to my basket actually shows up on the "my shopping basket" page.

In some rare cases the desired effect can't be observed by a user. For instance, when you expect a certain message to be published to a queue. Well, maybe a functional test isn't the right place for such a check after all, and you can prove that the message will be published using a combination of other, smaller tests. But if you still want to do it, you'd have to do a quick peek into the box after all. Sometimes that's just how it is. But always look for ways to prevent this, and let your application remain the black box that you poke at with HTTP requests only, making only assertions about the response you receive.

Having discussed many of the downsides now, let's not forget the good parts: we don't have to deal with a web server or run all those slow browser tests without getting a "90% okay" approval from our tests. We can accept the "risk" and work with functional tests instead of true end-to-end tests which force the test to send an actual HTTP request to an actual web server and wait for an actual HTTP response. We can benefit from some options for peeking-in-the-box. If we can keep the number of times we do this to the absolute minimum, we will end up with high-quality tests that don't fail for just any random reason, like concurrency issues.

Bringing the database in the right state

One thing that turns out to be quite hard when writing functional tests is getting the database in the correct state for running the tests. In fact, we have to get it in the right state before each test, so that tests can't influence each other when they use the same database tables. Ideally I'd always use the actual steps that a user would take to get that data into the database, instead of loading data directly into the database using some kind of fixture generation tool. But for some data, this is just impossible. That data needs to be there from the start. Sometimes it's because how the application has been designed; or maybe nobody realized there was a problem until they started writing tests (we call it a "legacy application" then ;)). Sometimes it's a hint that this data-that-is-always-there should not be in the database but in the code instead, since the code is by definition always-there. See also About fixtures.

Before running a functional test you have to get the database into the correct s

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

Fabien PotencierWeek 1 (20.3.2020, 23:00 UTC)

This is my first "lockdown" week-end after a week of confinement. I'm not alone. Most of us are confined now. Most of the world is confined or will be very soon.

I won't go outside this week-end and that's fine.

I'm lucky. I share my life with my wife and my two sons in my apartment in Lille, France. Hopefully, we're not infected. Not yet. We're now following the rules very strictly. To protect us, but more importantly, to protect everyone else. Let's not be selfish.

In January and February, the weather was bad. It rained every single day. Or it seemed so. Since the beginning of the week, sun made a big come back. The sun taunts me. If you know me a little, you know that I would really like to go outside. Buy a book in my local bookstore, buy some groceries, find some new cheese to taste, bike to the butcher, jog in the biggest public park of the city. I would love to do all of these activities today. Like every "regular" Saturday. But for the next few weeks, my world will look different. I need to adapt. And that's fine. I can certainly wait.

I'm lucky. I can work from home. My sons are 12 and 15, so they can do their homework on their own. Wonderful kids. They know how to spend their time. They read books, they watch some episodes of their favorite series on TV. They draw and they are talented. Don't ask me to draw anything.

I'm lucky. I'm the CEO of two great companies. Symfony and Blackfire. Remote first companies. All employees are working remotely, from home. They live everywhere in the world. I'm proud of them. They are confined like everyone else. Some have kids at home. Some are anxious. We are all reading the news, trying to understand what's going on; trying to imagine the impact of this "tornado". We are also trying to keep working. As "usual". Let's be honest, maybe less than usual. That's fine. The business is impacted. Some customers have already canceled their subscription. Very little new customers this week. That makes sense. At Symfony, we're canceling or postponing all our worldwide conferences. At Blackfire, our marketing is mostly about sponsoring conferences. All our eggs in the same basket. How ironic. Everyone is on board to imagine our future. We have many ideas to reinvent ourselves. I'm blessed.

I'm lucky. I'm young-ish and I'm in good health. I want to help but I'm not a doctor. I'm trying to support my family and my employees the best I can. There is blood shortage in France, and in some other countries. I will donate my blood next week.

This is the week-end. I won't go outside. I will probably read fiction books and code. I will cook for sure. As usual. But I will also take some time to dream. For a change. Or perhaps thinking about what's next.

Be strong, stay safe.

Evert PotCommon no-cors misconceptions (19.3.2020, 16:45 UTC)

Between tasks I spend a fair time on Stack Overflow, which is (truth be told) a love/hate relationship.

There’s a few recurring questions that I feel deserve a longer explanation. Last time, I wrote about how to use MySQL in Node.js, but today I wanted to write about the fetch no-cors setting.

What is CORS?

Browsers have a ‘sandbox’. This sandbox prevents a script on some domain to do things on other domains.

For example, if a script runs on, it is not allowed to do a PUT request on It also can’t embed an <iframe> from domain2 and read its contents.

A script making a request to a different domain is very useful though, so workarounds were invented. Examples are server-side proxy scripts, using Flash and passing messages via iframe urls (and later on postMessage).

But then CORS came along, which offered a better solution. CORS allows domain2 to say: “domain1 is allowed to make requests”.

The browser sandbox is not specific to exactly the domain. It’s actually the combination of the scheme (http or https), the domain and the port. Those 3 parts combined are called the “origin”.

So, this is the first popular misconception: CORS does not add security, it selectively removes it. CORS is strictly opt-in, so if an origin does not have support for CORS headers, the old behavior stays in effect.

What is no-cors?

If you’re trying to fetch() to another origin, and this origin does not opt into CORS, your request will return a network error and some messaging in the console.

If you don’t control the API you are calling, you might be looking for alternative solutions, and you might run into no-cors:

const result = await fetch('', {
  method: 'POST',
  mode: 'no-cors',
  headers: {
    'Content-Type': 'application/json',
  body: JSON.stringify({ foo: 'bar' }),

If you see the no-cors setting, you might think that you are simply turning off the CORS check, and when trying no-cors it the first thing you might notice is that the request now actually shows up on your network tab!

However, you will quickly run into new problems. no-cors doesn’t just turn off the check. It has greater consequences that make the request ‘safe’.

These are the main effects:

  • Any request header except: Accept,

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

Derick RethansPHP Internals News: Episode 45: Language Evolution Overview Proposal (19.3.2020, 09:08 UTC)

PHP Internals News: Episode 45: Language Evolution Overview Proposal

In this episode of "PHP Internals News" I chat with Nikita Popov (Twitter, GitHub, Website) about the Language Evolution Overview Proposal RFC.

The RSS feed for this podcast is, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website:


Derick Rethans 0:16

Hi, I'm Derick. And this is PHP internals news, a weekly podcast dedicated to demystifying the development of the PHP language. This is Episode 45. Today I'm talking with Nikita Popov yet again about a non technical RFC that he's produced titled language evolution overview. Somewhere last year, there was a big discussion about P++, an alternative ID of how to deal with improving PHP as a language but also still think about how some other people already use PHP and I don't really want to change how they currently use PHP. Like then I didn't really have an episode about that because I'd like to keep politics out of this podcast, or definitely PHP's internals politics. I do think that we realised at that moment that something did have to happen, because there's not really policy about when we can add things, when we can remove things, and so on. So I was quite pleased to see that you have come up with a quite wordy RFC, not talking about anything technical, but more looking forward of were will see PHP in the near or medium future, I would say. What are your thoughts about making this RFC to start with?

Nikita Popov 1:29

As you mentioned we had some pretty, let's say heated discussions last year, concerning especially backwards incompatible changes. So there were a number of very, very contentious RFCs. One of them was the short opentags removal, and another one was the classification of undefined variable warnings. So whether those should throw or not throw, and well basic contention is this that PHP is a by now pretty old language, 25 years old. And we can all admit that it's not the language with the best design. So it has evolved relatively organically with quite a few words, and the famous inconsistencies. And now we have this problem where we would like to resolve some of these long standing issues. Many of them are genuine problems that are introducing bugs in code, that reduce developer productivity. But at the same time, we have a huge amount of legacy code. So there are probably many hundreds of millions of lines of PHP code. And every time we do a backwards compatibility break, that code has to be updated, or more realistically, that code does not get updated and keeps hitting on old PHP version that, at some point also drops out of security support. And now the question is how can we fix the problems that PHP has, while still allowing this legacy code to update their PHP version. The general idea of how to fix this is to make certain backwards compatibility breaks opt in. By default, you just get the old behaviour, but you can specify in some way, exactly how it's done doesn't really matter at this point, that you want to opt into some kind of change or improvement.

Derick Rethans 3:34

As one example being the strict types that have been introduced in PHP that you need to turn on with a switch with a declare switch.

Nikita Popov 3:42

Strict types is really a great example because it has the important characteristic that has done per file. So you can turn on the strict types in one file and not affect any other code, at least in theory. So there are some edge cases, but I think like mostly you can just enable strict types in your library and you don't affect any other library that the project uses. We would like to extend this concept. It should be possible that libraries can update to

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

PHP: Hypertext PreprocessorPHP 7.2.29 Released (19.3.2020, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 7.2.29. This is a security release.All PHP 7.2 users are encouraged to upgrade to this version.For source downloads of PHP 7.2.29 please visit our downloads page, Windows source and binaries can be found on The list of changes is recorded in the ChangeLog.
PHP: Hypertext PreprocessorPHP 7.3.16 Released (19.3.2020, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 7.3.16. This is a security release which also contains several bug fixes.All PHP 7.3 users are encouraged to upgrade to this version.For source downloads of PHP 7.3.16 please visit our downloads page, Windows source and binaries can be found on The list of changes is recorded in the ChangeLog.
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP