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

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

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

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

$yMessage = new YiiMailMessage();

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

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

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

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

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

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

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

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

Don’t test constructors – Matthias Noback

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

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

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

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

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

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

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

Common constructor problems will be caught by your static analyzer

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

Exposing state breaks encapsulation

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

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

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

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

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

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

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

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

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

Replace the constructor unit test with some higher-level test

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

Given the user registers themself as "Matthias

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

15 years of blogging – Evert Pot

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

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

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

This is how it looked between 2006 and 2010:

My blog between 2006 and 2010

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

Habari Blog from 2011

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

Some stats

Habari Blog from ga

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

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

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

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

Thanks!

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

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

PHP Internals News: Episode 86: Property Accessors

In this episode of “PHP Internals News” I chat with Nikita Popov (Twitter, GitHub, Website) about the “Property Accessors” RFC.

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

Transcript

Derick Rethans 0:14

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

Nikita Popov 0:32

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

Derick Rethans 0:39

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

Nikita Popov 0:46

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

Derick Rethans 2:09

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

Nikita Popov 2:18

Exactly.

Derick Rethans 2:19

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

Nikita Popov 2:24

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

Derick Rethans 3:10

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

Nikita Popov 3:14

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

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

PHP Internals News: Episode 85: Add IntlDatePatternGenerator

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

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

Transcript

Derick Rethans 0:14

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

Mel Dafert 0:35

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

Derick Rethans 0:46

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

Mel Dafert 0:50

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

Derick Rethans 1:02

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

Mel Dafert 1:14

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

Derick Rethans 1:47

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

Mel Dafert 1:57

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

Derick Rethans 2:25

Had you ever seen a PHP source code before?

Mel Dafert 2:28

I don’t think so. No.

Derick Rethans 2:29

But you are familiar with C a little bit?

Mel Dafert 2:32

On a very basic level, yes.

Derick Rethans 2:34

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

Mel Dafert 2:39

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

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

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

Book cover

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

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

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

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

Book automation

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

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

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

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

PHP Internals News: Episode 84: Introducing the PHP 8.1 Release Managers – Derick Rethans

PHP Internals News: Episode 84: Introducing the PHP 8.1 Release Managers

In this episode of “PHP Internals News” I converse with Ben Ramsey (Website, Twitter, GitHub) and Patrick Allaert (GitHub, Twitter, StackOverflow, LinkedIn) about their new role as PHP 8.1 Release Managers, together with Joe Watkins.

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

Transcript

Derick Rethans 0:14

Hi, I’m Derick, welcome to PHP internals news, a podcast, dedicated to explaining the latest developments in the PHP language. This is episode 84. Today I’m talking with the recently elected PHP 8.1 RMs, Ben Ramsey and Patrick Allaert. Ben, would you please introduce yourself.

Ben Ramsey 0:34

Thanks Derick for having me on the show. Hi everyone, as Derick said I’m Ben Ramsey, you might know me from the Ramsey UUID composer package. I’ve been programming in PHP for about 20 years, and active in the PHP community for almost as long. I started out blogging, then writing for magazines and books, then speaking at conferences, and then contributing to open source projects. I’ve also organized a couple of PHP user groups over the years, and I’ve contributed to PHP source and Docs and a few small ways over the years, but my first contributions to the project were actually to the PHP GTK project.

Derick Rethans 1:14

Oh, that’s a blast from the past. You know what, I actually still run daily a PHP GTK application.

Ben Ramsey 1:21

Oh, that’s interesting. What does it do?

Derick Rethans 1:23

It’s Twitter client.

Ben Ramsey 1:24

Did you write it.

Derick Rethans 1:26

I did write it. Basically I use it to have a local copy of all my tweets and everything that I’ve received as well, which can be really handy sometimes to figuring out, because I can easily search over it with SQL it’s kind of handy to do.

Ben Ramsey 1:41

It’s really cool.

Derick Rethans 1:42

Yep, it’s, it’s still runs PHP 5.2 maybe, I don’t know, five three because it’s haven’t really been updated since then.

Ben Ramsey 1:49

Every now and then there will be some effort to try to revive it and get it updated for PHP seven and eight, but I don’t know where that goes.

Derick Rethans 1:59

I don’t know where that’s gone either. In this case, for PHP eight home there are three RM, there’s Joe Watkins who has done it before, Ben, you’ve just introduced yourself, but we also have Patrick Allaert, Patrick, could you also please introduce yourself.

Patrick Allaert 2:13

Hi Derick, thank you for the invitation for the podcast, my name is Patrick Allaert. I am a Belgian freelancer, living in Brussels, and I spent half of my professional time as a IT architect and/or a PHP developer, and the other half, I am maintaining the PHP extension of Blackfire, a performance monitoring solution, initiated by Fabien Potencier.

Derick Rethans 2:39

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

One year of functional PHP; now in Russian! – larry@garfieldtech.com

One year of functional PHP; now in Russian!

Submitted by Larry on 11 May 2021 – 8:14pm

A year ago, I published my first solo book, Thinking Functionally in PHP. The reception has been extremely positive; almost everyone that’s read it (that has bothered to talk to me about it) has found it clear, helpful, and enlightening. Mission accomplished!

To celebrate the one year anniversary of the book’s publication, I am happy to make two announcements.

First, Thinking Functionally in PHP is now available in Russian! The translation is by Alexey Pyltsyn, who is responsible for the Russian translation of the PHP documentation as well as numerous other tech book translations.

Xdebug Update: April 2021 – Derick Rethans

Xdebug Update: April 2021

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

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

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

In April, I worked on Xdebug for about 35 hours, with funding being around 28 hours.

Xdebug 3.1

I have continued to work on the Xdebug 3.1 tasks. I have added an API to that tools can query which modes Xdebug has enabled, no matter how; added compression for profiling file, which both PhpStorm and KCacheGrind/QCacheGrind can read, and I’ve made some changes to how errors are reported if the Xdebug log is active.

To enable Xdebug Cloud to be used in more situations, it is now possible to replace the “session name” that browser extensions use to activate Xdebug with your Cloud ID. By setting the Cloud ID through the browser extension (or with the GET/POST) parameters, you can now share a single development server with multiple developers all using their own IDE through Xdebug Cloud.

Xdebug Videos

I also continued to produce a few more videos on how to use Xdebug.

The first of these is Profiling with Xdebug in Docker, and the second one is Debugging Unit Tests with PhpStorm on Linux. I will continue to release more videos on YouTube, where you can also find other Xdebug videos in the Xdebug 3 play list.

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

Xdebug Cloud

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

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

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

JWT should not be your default for sessions – Evert Pot

Cookies

When designing web applications, (especially the traditional html kind),
you will at one point have to figure out how to log a user in and keep them
logged in between requests.

The core mechanism we use for this are cookies. Cookies are small strings sent
by a server to a client. After a client receives this string, it will repeat
this in subsequent requests. We could store a ‘user id’ in a cookie, and
for any future requests we’ll know what user_id the client was.

Cookie: USER_ID=123

But this is very insecure. The information lives in the browser, which means
users can change USER_ID and be identified as a different user.

Sessions

The traditional way to solve this is what’s known as a ‘session’.
I don’t know what the earliest usage of sessions is, but it’s in every web
framework, and has been since web frameworks are a thing.

Often, sessions and cookies are described as 2 different things, but
they’re really not. A session needs a cookie to work.

Cookie: MY_SESSION_ID=WW91IGdvdCBtZS4gRE0gbWUgb24gdHdpdHRlciBmb3IgYSBmcmVlIGNvb2tpZQ

Instead of a predictable user id, we’re sending the client a completely random
session id that is impossibly hard to guess. The ID has no further meaning, and
doesn’t decode to anything. This is sometimes called an opaque token.

When a client repeats this session id back to the server, the server will look
up the id in (for example) a database, which links it back to the user id.
When a user wants to log out, the session id is removed from the data storage,
which means the cookie is no longer associated with a user.

Where is the session data stored?

Languages like PHP have a storage system for this built in, and will by default
by default store data in the local filesystem. In the Node.js ecosystem, by
default this data will be in ‘memory’ and disappear after the server restarts.

These approaches make sense on developer machines, or when sites were hosted
on long-lived bare-metal servers, but these days a deploy typically means
a completely fresh ‘system’, so this information needs to be stored in a place
that outlives the server. An easy choice is a database, but it’s common for
sites to use systems like Redis and Memcached, which works for tiny sites, but
still works at massive scales.

Encrypted token

Over 10 years ago, I started working a bit more with OAuth v1 and similar
authentication systems, and I wondered if we could just store all the
information in the cookie and cryptographically sign it:

Question about session tokens on Stack Overflow

Despite getting some good answers, I didn’t go through with it as I didn’t
feel confident enough in making this secure, and I felt it required a better
understanding in crypto than I did.

A few years later, we got JWT, and it’s hot shit! JWT itself is a standard for
encrypting/signing JSON objects and it’s used a LOT for authentication.
Instead of an opaque token in a cookie, we actually embed the user_id again,
but we include a signature. The signature can only be generated by the server,
and it’s calculated using a ‘secret’ and the actual data in the cookie.

This means that if the data is tampered with (the user_id was changed), the
signature no longer matches.

So why is this useful? The best answer I have for this, is that it’s not
needed to have a system for session data, like Redis or a database. All the
information is contained in the JWT, it means your infrastructure is in
theory simpler. You’re potentially making fewer calls to a data-store on
a per-request basis.

Drawbacks

Theres are major drawbacks to using JWT.

First, it’s a complicated standard and users are prone to get the settings
wrong. If the settings are wrong, in the worst case it could mean that anyone
can generate valid JWTs and impersonate anyone else. This is not a
beginners-level problem either, last year Auth0 had a bug in one of
their products that had this very problem.

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