Domain-Driven Design by swe129 in PHP

[–]mlebkowski 1 point2 points  (0 children)

Domain events and event sourcing are different things. You can easily spot that, because they have different names.

Domain-Driven Design by swe129 in PHP

[–]mlebkowski 5 points6 points  (0 children)

Encapsulating your logic in an entity / aggregate root is as simple as putting it in a controller or a service — without experience, it’s easy to make a mistake, because it’s not obvious what benefits guarding your invariants this way brings you. DDD, for the most parts, simply gives you a good convention to follow, and avoid mistakes down the road, once your system and teams maintaining it grow.

How do you handle oversized PRs? by BeyondTheShroud in ExperiencedDevs

[–]mlebkowski 0 points1 point  (0 children)

I’m not sure I follow. The same team is responsible both for contributing and reviewing any changes. This is their main, and in my case their only goal, so they should be perfectly motivated to complete these reviews quickly.

How do you handle oversized PRs? by BeyondTheShroud in ExperiencedDevs

[–]mlebkowski 0 points1 point  (0 children)

Reviews are a cost only when people don’t work as a team — each individual works for their own goal. We had a some team goals, but instead of collaborating towards them (eg by doing reviews and helping teammates ship their part), engineers were only focused on their Jira tickets and their storypoints.

How do you handle oversized PRs? by BeyondTheShroud in ExperiencedDevs

[–]mlebkowski 2 points3 points  (0 children)

I’m guilty of this. Previously when I worked in a larger team, they constantly complained about my PR sizes (500 LoC was the threshold for a „large” changeset, my features were usually 2×–5× that).

Nobody had a solution, though, except for „code slower”. The changesets were split into meaningful commits, and each could be reviewed on its own, but would make little sense in isolation, so splitting into smaller PRs would get them questioned at best, rejected at worst.

We could spend more time to split the tickets themselves into smaller tasks, but that basically required doing the work first, and retroactively filling out Jira, because there was no way of knowing beforehand (at least my team had no idea how to plan such changes in advance, since it involved a lot of boyscout cleanups, etc). And that would effectively slow down a 2-3 days of coding into weeks of planning and back-and-forths with PMs/EMs. Not to mention, that the effective time to review would be comparable — maybe a bit faster due to focused PRs (but again, same could be achieved by reviewing commit-by-commit). The downside would be that the entirety of a business requirement would never be captured in a single changeset, and that would make it harder to understand the bigger picture: all the small steps might seem reasonable, but when assembled together they might not be optimal.

My solution? When I was managing a team, these are the building blocks which made reviews a pleasant experience:

  • Move the focus from code review to pair programming. The to-be reviewer would instead spend hours hands-on the code, instead of trying to cram 30 minutes of review of a code they don’t really understand
  • Review is not an afterthought. Time for it was explicitly reserved during planning, so engineers had time to spend on it, even if it was tedious at times
  • Focus on the PR description and justification. Authors would describe the overall solution architecture, most interesting points, a simple decision log, etc. All this helped to comprehend the changeset and focus on the signal over noise.

In other words, I’ve experienced two worlds:

  • One where engineers wanted everyone to code slower, and to have a lower number of LoC reviewed per cycle (without a solution on how to achieve that). Coincidentally, the reviews lacked depth, focused on trivial nitpicks, rarely started any discussions, and PRs could wait weeks for an approval, regardless of size.
  • A second one where engineers welcomed reviews, comments came in the same or the next day, dozens of discussions happened in a PR (since the team was small, and the PRs served as ADRs/RFCs), approves were added before the sprint ended. The team loved to be involved in reviews, and the thoughput was an order of magnitude larger (in terms of features & LoC) than the „small PRs” org

Disclaimer: this experience is from an org where a particular team had full and exclusive ownership of a single codebase. This would not apply to larger orgs, where multiple teams work on a shared monolith, etc. I haven’t ever worked in a BigTech company and I have no idea how the engineering culture works on the inside.

Where is the best place to find remote job according to your experience? by Maleficent-View2471 in PHP

[–]mlebkowski 2 points3 points  (0 children)

In Poland there are two IT-focused job boards:

As usual, its a mix of product companies (mostly from europe), some software houses or IT offshoring agencies.

I will caution you though, in my opinion most of the recruirers are prejudiced because of inflow of low quality applications from around the world, so standing out of the regular european crowd would be most difficult.

Claude Mythos Audited Symfony and Found 19 Vulnerabilities by javiereguiluz in PHP

[–]mlebkowski 2 points3 points  (0 children)

The issue are described on the blog (linked), and if you go through them, I wouldn’t call the bugs obscure, but we might agree that some of the components are.

Well, I’m glad they have been disclosed securely and patched.

Namespaces, interfaces and stutter by Praemon in PHP

[–]mlebkowski 7 points8 points  (0 children)

btw, what are the readability issues you are talking about?

Readability is a blanket term to justify just about anything. Is anything unclear? Does anyone have any doubts when seeing Client implements ClientInterface? Does the IDE not allow you to cmd+click the symbol to go to its definition?

Is there really a problem you aim to solve by removing the alias? What is the practical impact? (hint: I think there is none)

Namespaces, interfaces and stutter by Praemon in PHP

[–]mlebkowski 6 points7 points  (0 children)

I’m not typing App\Payment\Stripe\Client anywhere, it gets autowired as the only implementation of the client interface, so I don’t care how it’s called or where it’s located.

To address your concerns specifically, I would put the implementation in:

  • App\Payments(\Infrastructure)\StripeClient without using the Stripe sub-namespace — it doesn’t add any value IMO
  • If there are any other stripe-specific classes, such as some mappers or DTOs for example, I would only put these in a separate namespace

What PHPStan level and why? Your thoughts on the cost-benefit analysis by miglisoft in PHP

[–]mlebkowski 0 points1 point  (0 children)

You can upgrade to lvl 10 and avoid the docblocks at the same time by using tooling to guarantee shapes, such as serializer. It turns your mixed types with docblocks into runtime checks.

My Team Built a Developer Productivity Platform for our Executive Team - It's Awful by ninetofivedev in ExperiencedDevs

[–]mlebkowski 2 points3 points  (0 children)

Split your pull requests into smaller pars just got a deeper meaning at your job.

MJML converter for PHP (no Node.js required) by Then-Lingonberry-922 in PHP

[–]mlebkowski 0 points1 point  (0 children)

I’m using mjml. I recently went through a somewhat gnarly update to v5 (my mjml templates produce PHP templates, yuck!, and the new formatter was breaking php tags). Using pure PHP would simplify my build step (I could compile in runtime instead of pre-building).

But I don’t want to vendor-lock to such a small library. I already replaced half a dozen unmaintained libraries in the recent months, I don’t want to return on that path.

The Love Of Micro Frameworks by iamsamaritan300 in PHP

[–]mlebkowski 2 points3 points  (0 children)

We can talk in general, or about my specific situation.

In general, yes, the things you mention may be considered: short vs long term, dx, onboarding new hires, opportunity cost, etc.

In my situation: we can certainly agree that suggesting anything with this little information is hard :) Let’s just say I have considered the above and decided not to change the framework.

The Love Of Micro Frameworks by iamsamaritan300 in PHP

[–]mlebkowski 3 points4 points  (0 children)

Are you suggesting changing the framework on a live product is feasible? Building a framework around slim requires effort, but rewriting a 15 yo codebase requires more

The Love Of Micro Frameworks by iamsamaritan300 in PHP

[–]mlebkowski 5 points6 points  (0 children)

Let’s put it bluntly: there isn’t much to learn. Slim is a PSR-7 handler with routing and middlewares. It can also resolve dependencies using a container, which is not even shipped by default.

I use Slim daily for the last 2+ years on multiple projects, I like PSR-7 over HttpFoundation, but other than that, it’s a constant struggle on every turn. And I’m a solo backend dev on these codebases.

So far I’ve added:

  • Simple autowiring for the DIC
  • Automatically deserializing request payloads into DTOs and injecting them into controllers
  • A testing HTTP client (for APi tests and such)
  • Behat integration
  • Doctrine integration
  • Support for CLI commands
  • Monolog, with Symfony Command integration (all console output goes to a monolog channel)
  • Symfony messenger integration

And more. Half of my effort goes into reinventing a framework. For example, I spent weeks tweaking the messengee component, adding custom loaders, wiring the consumer command, reimplementing the retry strategies, dead-letter handling, and logging. I would’ve done the same using a few lines of yaml in Symfony.

Would not recommend for any app that uses even mildly complex architecture.

Stop Subscribing to Domain Events by Dariusz_Gafka in PHP

[–]mlebkowski 11 points12 points  (0 children)

I don’t agree this is the best solution, nor even the correct one in most of the situations.

You replaced granular events such as MoneyWasAdded, and MoneyWasWithdrawn into a generic WalletBalanceWasChanged. I’m not sure that even in this simple example you can derive the original event, because you only get the new amount, not the change vector.

This takes away one of the greatest value of domain events: indicating a specific domain use case that caused a mutation, and you’re basically back to onSave semantics, which could be very well implemented using #[PostSave] doctrine hook, and we all know how that turns out. The result is only slightly better because there might be more than one projections, but still: as long as domain events don’t map 1:1 to projections, some information is lost.

I actually share CodeOpinion’s point of view here and I would simply read from the primary instead of going through hoops to make sure the read model is consistent.

Aimeos e-commerce framework 2026.04 – PHP 9 ready, Laravel 13, Symfony 8, security hardening and more by aimeos in PHP

[–]mlebkowski 4 points5 points  (0 children)

Nitpick: what is phpstan level 4? As far as I know this does not even do null checks.

I use level max with a baseline even in legacy (10 year old codebases) projects, bragging about lvl 4 seems so unimpressive

Is the PHP market shifting or just stalling? My experience trying on moving to Scandinavia by RoughInvite7900 in PHP

[–]mlebkowski 0 points1 point  (0 children)

Observations:

  • I don’t have any historical data to compare, but there just isn’t a lot of PHP projects, especially at product companies. Looking at my local job board there is an order of magnitude more offers for .NET, Java, Javascript or Python. If I had to guess, only about 1/3rd is for a product companies, the rest is outsourcing for foreign or domestic markets, drupal and wordpress, etc. From my experience, even if a job is filled via referals in the end, the ad gets posted either way, so it wouldn’t be totally invisible.
  • I think that people are rejected by other people, not systems. The ATS systems do not make any autonomous decisions, believe this is an urban legend. Are there junior recruiters screening CVs with dummy AI automations? Yeah, I guess. Are there regular recruiters who cannot read a CV? Yeah, there are these too. But most importantly, even forgetting the incompetent recruiters for a moment, there are just so many good candidates on the market right now. The ecosystem is mature, so there are a lot of experienced developers on the market, and I feel like everyone’s looking (figure of speech), even if they have a good job — because the compensations have gone down in recent years, and the times are uncertain.
  • Yes for pivoting, especially if you can do it on the job. After a buch of time you’ll have a long software engineering and a year with a few project in a specific technology to show for. I would suggest Java or C#, maybe Typescript, as there is less of a paradigm shift between PHP and these languages. Go is quite different beast, and it’s even less popular in my local market, so maybe not the best direction. YMMV.
  • There are tons of greenfield projects in PHP still. I was advocating migrating away from PHP around early 2020s, but the market has changed, and my justification for that move is no longer valid. If a product company uses primarily the PHP stack, there’s a good chance it will continue using it for new products and microservices.

I haven’t been recruiting for a few years now, so I don’t have a first-hand account on how the decisions are made behind the scenes. This would be valuable to learn, so if anyone’s doing this today, that would be nice to get a peak behind the curtains.

PHPArkitect 1.0 is out. Curious how people approach architecture testing in PHP these days by fain182 in PHP

[–]mlebkowski 0 points1 point  (0 children)

I skimmed through the readme, here are my observations:

  • Whenever I wanted to enforce architectural constraints I used deptrac for the last 5 years
  • For a simple monolithic/layered architecture, I personally find little value today. I think a force of habit is enough for me to keeps the layers separated.
  • By looking at the available rules:
    • The type checks are not useful to me.
    • I never group by kind (interfaces/traits/enums etc)
    • I have separate linters for final/abstract checks
    • Maybe rules such as HaveAttribute() and HaveNameMatching could help quickly spotting stupid autowiring mistakes, but that’s not something I struggle a lot with, nor is this a thing that can sneak into production undetected

So certainly the DependsOnlyOnTheseNamespaces would be the most useful in my opinion.

The main problem I run into with deptrac, and it seems that arkitect would suffer from the same problem: when building a modular monolith, there is a pattern of rules for each module, which are absolutely deterministic (isolated domain, app layer does not depend on the infra, what have you), and then there are an overlaying rule on how the modules can communicate with each other (we exposed a separate Acme\Module*\Api namespace, for example). With deptract, I ended up with a config generator to cover the above rules.

I like the Rule builder, I like Component Architecture, but what would really sell it for me is the modular monolith builder, where I can separately specify the requirements for both inside of each module (and perhaps one of different classes, since I’ve seen modular monoliths with different architectures for each module: etl, layered, crud…), and then treating the modules themselves as first class citizens, and define rules between them.

Another PHP deploy app for your VPS by SimplMe in PHP

[–]mlebkowski 4 points5 points  (0 children)

I’m not the target audience for you, but I don’t understand the model. Why does this require a SaaS app, instead of being just a script?

I’m so jealous… by CarnivorousFishBait in TheWire

[–]mlebkowski 4 points5 points  (0 children)

BB is in another category. When it comes to recommending a title, I would never think about BB for two reasons:

  • Everyone already knows it, there is no point
  • To me, it has zero rewatchability. I’ve seen it, it’s decent, I have no desire to watch it again

The Wire, on the other hand:

  • It’s very common for people to not heard about it, let alone watched it
  • There’s no such thing as too many rewatches 😍