A robust, powerful, easy to use attribute parser for PHP – Larry Garfield

A robust, powerful, easy to use attribute parser for PHP

After sitting on it for a while, I am pleased to release a PHP library for robust, powerful attribute handling in PHP 8.1: Crell/AttributeUtils. It’s a robust, centralized tool for slicing, dicing, and reverse engineering classes in PHP using attributes.

The basics

The basic model of Attribute Utils is to analyze a class “with respect to” some attribute. That attribute may be defined on the class, or not. (Both options have meaning.) That attribute may be associated with attributes on properties or methods, which are all scanned together to produce a picture of a class.

Continue reading this post on Hive.

Larry
21 April 2022 – 4:56pm

DDD entities and ORM entities – Matthias Noback

I was tweeting something about having separate “DDD” and “ORM” entities in a project in a project, and that I don’t understand this. There were some great comments and questions, thanks a lot for that! To be honest, I understand more about it now. In this article I’ll try to provide some more information about this.

I’m glad many developers want to use input from the book “Domain-Driven Design” by Eric Evans to improve their domain model. I recommend reading this book and getting your information from the source, because unfortunately the internet, tweets, e-books, including my own books, aren’t able to reflect a full, nor a correct view of everything there is to find out about this topic. All too often DDD is completely misinterpreted to be “an elitist, dogmatic approach to programming, where we use DTOs, layers, and CQRS”…

I think some programmers, myself included, want to escape from the framework-coupled, hype-inspired mess that web application development often seems to be. Unfortunately, while trying to move in the opposite direction, they end up with a lot of code that is written for the sake of decoupling. Or maybe it happens because they want to try something new and not-boring, something that can’t be generated from the command-line with make:entity.

Back in the days when Symfony 2 adopted annotations for routing, and Doctrine ORM did the same for its mapping configuration, I was one of the first to be against that, pointing out that it’s “framework coupling”. I mean, “Are you coupled to the framework?!”

Ever since I’ve been thinking, experimenting, and writing a lot about this topic (e.g. my book about application architecture, and an older article about ORMless). In the end I think our applications need framework coupling in certain areas, and in other areas, like the domain model, they are better off being decoupled.

But full decoupling is usually not the best choice. Rather, 80% decoupling is fine 😉 As an example, it seems that some would like to have DDD entities that are fully decoupled from the ORM. They interpret this to mean that you can’t have ORM annotations in your entity, or that you can’t use specialized collection classes like Doctrine ORM forces you to have. This coupling is by no means dangerous, and certainly doesn’t get in the way, as long as:

  • We can instantiate and modify these entities without a runtime dependency on the database.
  • We can retrieve data from these entities without a runtime dependency on the database.

Once this is the case, you can even test their behavior in a unit test, because these are the only requirements for that. It does mean that most entities-in-the-wild aren’t good entities, because calling methods on them is most likely to trigger database queries (e.g. lazy-loading for child entities or referenced entities). If you use an Active Record implementation like Eloquent, many more methods will trigger database queries.

And this is where DDD comes in, with its aggregate design rules. I often refer to an excellent series of articles on this topic, by Vaughn Vernon. In summary:

  • An aggregate should guarantee its own consistency, establishing relevant domain invariants (i.e. it should prevent itself from being in an invalid or incomplete state).
  • Reference other aggregates by their ID (i.e. don’t pass related entities as objects, or load them lazily).
  • Aggregates should be small (i.e. don’t let it manage child entities or related entities).

We can learn a lot from these DDD patterns to make our models better, and we can in most cases accomplish this while using our current ORM and its entities or model objects. We just upgrade these existing objects with insights from the DDD book; adding intention-revealing methods, making state changes in meaningful chunks instead of on a per-field basis, throwing exceptions whenever a consistent state is in danger, etc. There may be some things we have to do to please the ORM, but nothing that messes up much with our domain model. A good rule of thumb is to focus on the public methods of the entity, and ignore what goes on behind the scenes (good old encapsulation).

There is one situation where upgrading existing ORM entities to DDD entities isn’t going to work: when you want to evolve the design of your aggregates, without also evolving the database schema. I don’t have experience with this. Whenever

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

PHP Tricks: Multi-value match() – Larry Garfield

PHP Tricks: Multi-value match()

Last time, I talked about fun uses of the match() expression in PHP, using unconventional types of expressions on the right-arm branch. This time, I want to expand that discussion to include fun tricks on the left-side of the `=>`, and how you can easily match by multiple values at the same time.

I’m going to assume you have read the previous installment about how match() works and what an “expression” means. Also, I don’t claim to be the original source of these tricks. I’m just documenting them because they’re cool. Let’s dive in.

Continue reading this post on Hive.

Larry
19 April 2022 – 11:41am

PHP Tricks: Uncommon match() expressions – Larry Garfield

PHP Tricks: Uncommon match() expressions

Submitted by Larry on 15 April 2022 – 1:15pm

Recently, I’ve been helping a new developer out in a chat room. He’s still learning PHP and working through tutorials, with lots of questions along the way. Earlier this week, by accident, he stumbled across a use of match() statements I’d not considered before. While technically not right for his use case, it did suggest another, potentially valid use for match() I’d not seen. Let’s add it to the list of cool things you can do with match().

Continue reading this post on Hive.

Write tests – even for your pet projects – Brandon Savage

I had an interesting discussion recently whereby I asserted that changing the constructor signature of a class should necessarily break some of your tests, if your tests are adequate in their coverage. This tweet generated considerable discussion, and one of the takeaways was a discussion about whether or not writing tests for personal pet projects […]

The post Write tests – even for your pet projects appeared first on BrandonSavage.net.

Xdebug Update: March 2022 – Derick Rethans

Xdebug Update: March 2022

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.

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 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 a subscription.

In March, I spend 39 hours on Xdebug, with 25 hours funded.

Development

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.

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.

I spend a considerable amount of time cataloguing 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 Xdebug Course that I have mentioned before.

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 Google Doc.

In the more complicated set-ups, perhaps it would be easier to use Xdebug Cloud as it has none of these networking complications.

New Jigsaw-based Site – Jordi Boggiano

My blog was always based on some home-grown CMS I built during my studies in.. checks CV 2007-2008.

This was mostly fine but it had no markdown support and it was one more server to manage. I would like to try and write some more content here again so I figured I should get this sorted out as a first step, because writing text in plain html is kind of a pain.

So here we are, here’s my new website! It’s built with Jigsaw and hosted with GitHub pages for convenience.

And because it’s 2022 and I wanted to play a bit with Tailwind, there’s a dark mode too of course .

Stay tuned for more content coming soon!

Memory Malfeasance – Derick Rethans

Memory Malfeasance

A while ago I started getting weird crashes on my desktop machine — 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.

At first I thought there was some memory corruption in a system library, but neither valgrind or GDB would show any issues — 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.

I suspected the worst: Broken memory.

In the past I had used tools like memtest86, and memtest86+ — both available as packages on my Debian system. There are some complications 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 memtest86+ was supposed to fix this, but that did not work either for me.

I decided to live with it for a while, but after another total loss of tabs (oh dear!), I stumbled upon a different tool: PCMemTest. This did boot, but their documentation page says “The UHCI USB controller is not yet supported”, which is needed for USB keyboards.

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:

PCMemTest showing broken memory

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.

Then I read that the kernel itself also has a memory test tool built in: the memtest kernel parameter.

To include the memory test when the system boots, update the GRUB_CMDLINE_LINUX_DEFAULT line in /etc/default/grub to:

GRUB_CMDLINE_LINUX_DEFAULT="quiet pcie_aspm=off memtest=4" 

And then run update-grub.

Now when the system starts, the kernel will run a memory test and automatically exclude any memory that it finds not working.

On my system this looks in the dmesg output like:

[ 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
…
[ 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.
…
[ 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
…
[ 0.000000] 0x000000072980d000 - 0x000000107f300000 pattern 0000000000000000 

The line bad mem addr 0x000000016dbc8450 - 0x000000016dbc8458 reserved is saying that the kernel excluded that section of memory because it found it to be broken.

Since I booted my system 16 days ago, I have no longer seen any unexplained crashes. Yay!

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.

Breaking RSS Links – Jordi Boggiano

Sorry for the spam but I’m about to break links on the internet and I feel bad.

I am finally ready to migrate away from my home-grown-CMS-built-in-2007 to a static site generator, and while I can keep most things running the feed URLs will just have to go.

If you happen to be still be using RSS (high five fellow old person), and also subscribed to this blog, please update your subscription URL to: https://seld.be/feed.atom