# Marco Pivetta

Published articles for Marco Pivetta.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Proper logging in PHP with PSR-3

DevFeed: [Proper logging in PHP with PSR-3](<https://devfeed.tech/articles/proper-logging-in-php-with-psr-3-21144.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/php-logging-with-psr-3/>)

Published: 2026-07-28T00:00:00Z

Content type: article

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [PHP](<https://devfeed.tech/topics/php.md>), [Logging](<https://devfeed.tech/topics/logging.md>), [Exception](<https://devfeed.tech/topics/exception.md>), [log management](<https://devfeed.tech/topics/log-management.md>), [Monitoring](<https://devfeed.tech/topics/monitoring.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [errors](<https://devfeed.tech/tags/errors.md>), [exception](<https://devfeed.tech/tags/exception.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [logging](<https://devfeed.tech/tags/logging.md>), [monitoring](<https://devfeed.tech/tags/monitoring.md>), [php](<https://devfeed.tech/tags/php.md>)

### AI overview

This article explains practical PHP logging with PSR-3. It focuses on passing exceptions through the logger context, allowing the logger to render exception details, defining exception types for business-specific failures, and logging enough information to understand software behavior in production. It also warns that logging and exceptions can impose CPU, memory, and I/O overhead.

### Source excerpt

Who is this article for? This post is for people that do day-by-day busywork coding, and for team leads that want to direct their peers towards better logging practices. Note that this article comes from my regular need to present these exact points to different people, multiple times a year, in multiple teams, in multiple companies. Also, we will not talk about how to configure a PSR-3 logger, but rather how to use one. Handling errors properly Error/exception handling is the main use-case for logging. When logging exceptions, please pass the Throwable instance to the 'exception' context key. try { // logic here } catch (SomeException $failed) { $this->logger->error('Something went wrong', [ 'exception' => $failed, ]); } Avoid cluttering the logger call with data deriving from the exception: it's not the logger call-site's job, and you are just repeating work. I often see unnecessary code like: try { // logic here } catch (SomeException $failed) { $this->logger->error('Something went wrong', [ // first mistake: we forgot 'exception' 'previous' => $failed->getPrevious(), // let the logger do this! 'line' => $failed->getLine(), // already part of the stack trace 'error' => $failed->getMessage(), // also always rendered 'error_type' => $failed::class, // done by the logger, usually ]); } The logger itself must instead be configured (and usually already is configured) to render: the exception ::class the exception message and code (codes are not really relevant any more, in this century) the stack trace previous exceptions additional exception fields Your responsibility is to instead pass context information that the logger can't infer on its own. What if my code fails gracefully, and does not raise an exception? if (is_wrong($something)) { $this->logger->warn('Something went wrong', ['something' => $something]); } For business-specific failures that deserve a type, we can upcast them to a Throwable anyway: if (is_wrong($something)) { $this->logger->warn('Something wen

## Reviving a Static Blog with Nix and Reproducible Builds

DevFeed: [Reviving a Static Blog with Nix and Reproducible Builds](<https://devfeed.tech/articles/reviving-the-blog-21147.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/reviving-the-blog/>)

Published: 2026-02-22T00:00:00Z

Content type: tutorial

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [Nix](<https://devfeed.tech/topics/nix.md>), [reproducible builds](<https://devfeed.tech/topics/reproducible-builds.md>), [Composer](<https://devfeed.tech/topics/composer.md>), [PHP](<https://devfeed.tech/topics/php.md>), [GitHub](<https://devfeed.tech/topics/github.md>), [WordPress](<https://devfeed.tech/topics/wordpress.md>), [pull-requests](<https://devfeed.tech/topics/pull-requests.md>)

Tags: [blog](<https://devfeed.tech/tags/blog.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [github](<https://devfeed.tech/tags/github.md>), [php](<https://devfeed.tech/tags/php.md>), [pull-request](<https://devfeed.tech/tags/pull-request.md>), [reproducible-builds](<https://devfeed.tech/tags/reproducible-builds.md>), [wordpress](<https://devfeed.tech/tags/wordpress.md>)

### AI overview

The author returns to blogging and explains how they stabilized a Sculpin-based static website by using Nix Flakes to pin dependencies and support reproducible builds. The article also covers Composer dependency hashing and deployment to GitHub Pages.

### Source excerpt

I'm back! The last time I blogged was in 2017: a lot has changed since then, and after a decade of ignoring blogging, I will attempt to put some regularity into it again. The times call for it: having a personal space that is really "our own" is extremely important, and it is as important as having something to read that is written by other humans, and not slop. I mainly stopped blogging for two reasons: Wordpress and similar tools are terrible, for rarely changing content. I'd rather not blog, than host a dynamic website just for serving static webpages My static site generation pipeline heavily relied on my workstation's software dependencies, which shifted continuously, breaking the website build at all times. Stabilizing the build Note: This section describes the Nixification of the blog, done in this pull request. You can skip this, if you prefer reading the PR instead. The first thing to do is to get everything under control again. Since a few years back, I started heavily relying on Nix, a lazy functional language that is perfect to achieve reproducible builds and environments. At the time of this writing, this website is built via Sculpin, a static website generator whose dependency upgrades I've neglected for far too long. In order to "freeze" the build in time, I used a Nix Flake to pin all the dependencies down, preventing any further shifts in dependency versions: { inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils, composer2nix, ... }@inputs: flake-utils.lib.eachDefaultSystem ( system: { packages = { # things that will stay extremely stable will go here }; } ); } The above will "pin" dependencies such as composer or php, preventing them from drifting apart, unless a commit moves them. This is also thanks to the built-in flake.lock mechanism of Nix Flakes. Because Composer does not compute content hashes of PHP dependencies, NixOS cannot directly u

## BetterReflection version 2.0.0 released

DevFeed: [BetterReflection version 2.0.0 released](<https://devfeed.tech/articles/betterreflection-version-2-0-0-released-21148.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/roave-better-reflection-v2.0/>)

Published: 2017-09-18T00:00:00Z

Content type: release

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [PHP](<https://devfeed.tech/topics/php.md>), [Library](<https://devfeed.tech/topics/library.md>), [Parser](<https://devfeed.tech/topics/parser.md>), [Security](<https://devfeed.tech/topics/security.md>), [Object-oriented programming (OOP)](<https://devfeed.tech/topics/oop.md>), [Malware](<https://devfeed.tech/topics/malware.md>), [Composer](<https://devfeed.tech/topics/composer.md>)

Tags: [2-0-0](<https://devfeed.tech/tags/2-0-0.md>), [code](<https://devfeed.tech/tags/code.md>), [compilation](<https://devfeed.tech/tags/compilation.md>), [env-file-security](<https://devfeed.tech/tags/env-file-security.md>), [inheritance](<https://devfeed.tech/tags/inheritance.md>), [oop](<https://devfeed.tech/tags/oop.md>), [php](<https://devfeed.tech/tags/php.md>), [procedural](<https://devfeed.tech/tags/procedural.md>), [scope](<https://devfeed.tech/tags/scope.md>), [security](<https://devfeed.tech/tags/security.md>), [use-cases](<https://devfeed.tech/tags/use-cases.md>), [version-2-0-0](<https://devfeed.tech/tags/version-2-0-0.md>)

### AI overview

Roave's BetterReflection 2.0.0 reproduces PHP's reflection API without triggering autoloading. It scans source files, parses PHP code into an AST, and exposes reflection objects for analysis before classes are loaded.

### Source excerpt

Roave's BetterReflection 2.0.0s was released today! I and James Titcumb started working on this project back in 2015, and it is a pleasure to see it reaching maturity. The initial idea was simple: James would implement all my wicked ideas, while I would lay back and get drunk on Drambuie. Yes, that actually happened. Thank you, James, for all the hard work! 🍻 (I did some work too, by the way!) What the heck is BetterReflection? Jokes apart, the project is quite ambitious, and it aims at reproducing the entirety of the PHP reflection API without having any actual autoloading being triggered. When put in use, it looks like this: <?php // src/MyClass.php namespace MyProject; class MyClass { public function something() {} } <?php // example1.php use MyProject\MyClass; use Roave\BetterReflection\BetterReflection; use Roave\BetterReflection\Reflection\ReflectionMethod; require_once __DIR__ . '/vendor/autoload.php'; $myClass = (new BetterReflection()) ->classReflector() ->reflect(MyClass::class); $methodNames = \array_map(function (ReflectionMethod $method) : string { return $method->getName(); }, $myClass->getMethods()); \var_dump($methodNames); // class was not loaded: \var_dump(\sprintf('Class %s loaded: ', MyClass::class)); \var_dump(\class_exists(MyClass::class, false)); As you can see, the difference is just in how you bootstrap the reflection API. Also, we do provide a fully backwards-compatible reflection API that you can use if your code heavily relies on ext-reflection: <?php // example2.php use MyProject\MyClass; use Roave\BetterReflection\BetterReflection; use Roave\BetterReflection\Reflection\Adapter\ReflectionClass; require_once __DIR__ . '/vendor/autoload.php'; $myClass = (new BetterReflection()) ->classReflector() ->reflect(MyClass::class); $reflectionClass = new ReflectionClass($myClass); // You can just use it wherever you had `ReflectionClass`! \var_dump($reflectionClass instanceof \ReflectionClass); \var_dump($reflectionClass->getName()); How does that

## Eliminating Visual Debt

DevFeed: [Eliminating Visual Debt](<https://devfeed.tech/articles/eliminating-visual-debt-21142.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/eliminating-visual-debt/>)

Published: 2017-05-29T00:00:00Z

Content type: opinion

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [PHP](<https://devfeed.tech/topics/php.md>), [Code](<https://devfeed.tech/topics/code.md>), [coding](<https://devfeed.tech/topics/coding.md>), [Polymorphism](<https://devfeed.tech/topics/polymorphism.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [inheritance](<https://devfeed.tech/tags/inheritance.md>), [php](<https://devfeed.tech/tags/php.md>)

### AI overview

The article examines "visual debt" in PHP code and argues for questioning conventional coding practices. It demonstrates progressively removing type declarations, runtime checks, contracts, meaningful names, and inheritance restrictions from an event system, emphasizing reduced visual and engine overhead while discussing the tradeoff with code clarity and declarative guidance.

### Source excerpt

Today we're talking about Visual debt in our code. As an introduction, I suggest to watch this short tutorial about visual debt by @jeffrey_way. The concept is simple: let's take the example from Laracasts and re-visit the steps taken to remove visual debt. interface EventInterface { public function listen(string $name, callable $handler) : void; public function fire(string $name) : bool; } final class Event implements EventInterface { protected $events = []; public function listen(string $name, callable $handler) : void { $this->events[$name][] = $handler; } public function fire(string $name) : bool { if (! array_key_exists($name, $this->events)) { return false; } foreach ($this->events[$name] as $event) { $event(); } return true; } } $event = new Event; $event->listen('subscribed', function () { var_dump('handling it'); }); $event->listen('subscribed', function () { var_dump('handling it again'); }); $event->fire('subscribed'); So far, so good. We have an event that obviously fires itself, a concrete implementation and a few subscribers. Our code works, but it contains a lot of useless artifacts that do not really influence our ability to make it run. These artifacts are also distracting, moving our focus from the runtime to the declarative requirements of the code. Let's start removing the bits that aren't needed by starting from the method parameter and return type declarations: interface EventInterface { public function listen($name, $handler); public function fire($name); } final class Event implements EventInterface { protected $events = []; public function listen($name, $handler) { $this->events[$name][] = $handler; } public function fire($name) { if (! array_key_exists($name, $this->events)) { return false; } foreach ($this->events[$name] as $event) { $event(); } return true; } } Our code is obvious, so the parameters don't need redundant declarations or type checks. Also, we are aware of our own implementation, so the runtime checks are not needed, as the

## YubiKey for SSH, Login, 2FA, GPG and Git Signing

DevFeed: [YubiKey for SSH, Login, 2FA, GPG and Git Signing](<https://devfeed.tech/articles/yubikey-for-ssh-login-2fa-gpg-and-git-signing-21150.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/yubikey-for-ssh-gpg-git-and-local-login/>)

Published: 2017-04-15T00:00:00Z

Content type: tutorial

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [Security](<https://devfeed.tech/topics/security.md>), [OpenSSH](<https://devfeed.tech/topics/openssh.md>), [Authentication](<https://devfeed.tech/topics/authentication.md>), [Cryptography](<https://devfeed.tech/topics/cryptography.md>), [Open Source](<https://devfeed.tech/topics/open-source.md>), [USB](<https://devfeed.tech/topics/usb.md>), [Git](<https://devfeed.tech/topics/git.md>), [Linux](<https://devfeed.tech/topics/linux.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [authentication](<https://devfeed.tech/tags/authentication.md>), [crypto](<https://devfeed.tech/tags/crypto.md>), [cryptography](<https://devfeed.tech/tags/cryptography.md>), [dell](<https://devfeed.tech/tags/dell.md>), [development](<https://devfeed.tech/tags/development.md>), [git](<https://devfeed.tech/tags/git.md>), [linux](<https://devfeed.tech/tags/linux.md>), [nfc](<https://devfeed.tech/tags/nfc.md>), [open-source](<https://devfeed.tech/tags/open-source.md>), [pc](<https://devfeed.tech/tags/pc.md>), [ssh](<https://devfeed.tech/tags/ssh.md>), [tutorial](<https://devfeed.tech/tags/tutorial.md>), [usb](<https://devfeed.tech/tags/usb.md>), [xps](<https://devfeed.tech/tags/xps.md>)

### AI overview

A tutorial on using YubiKey Neo devices to improve developer security through two-factor authentication, PAM login authentication, GPG mail and Git commit signing or encryption, and SSH authentication. It also explains the need for a backup key and introduces NFC-based 2FA setup.

### Source excerpt

I've been using a YubiKey Neo for a bit over two years now, but its usage was limited to 2FA and U2F. Last week, I received my new DELL XPS 15 9560, and since I am maintaining some high impact open source projects, I wanted the setup to be well secured. In addition to that, I caught a bad flu, and that gave me enough excuses to waste time in figuring things out. In this article, I'm going to describe what I did, and how you can reproduce my setup for your own safety as well as the one of people that trust you. Yubi-WHAT? In first place, you should know that I am absolutely not a security expert: all I did was following the online tutorials that I found. I also am not a cryptography expert, and I am constantly dissatisfied with how the crypto community reduces everything into a TLA, making even the simplest things impossible to understand for mere mortals. First, let's clarify what a YubiKey is. That thing is a YubiKey. What does it do? It's basically an USB key filled with crypto features. It also is (currently) impossible to make a physical copy of it, and it is not possible to extract information written to it. It can: Generate HMAC hashes (kinda) Store GPG private keys Act as a keyboard that generates time-based passwords Generate 2FA time-based login codes What do we need? In order to follow this tutorial, you should have at least 2 (two) YubiKey Neo or equivalent devices. This means that you will have to spend approximately USD 100: these things are quite expensive. You absolutely need a backup key, because all these security measures may lock you out of your systems if you lose or damage one. Our kickass setup will allow us to do a series of cool things related to daily development operations: Two Factor Authentication PAM Authentication (logging into your linux/mac PC) GPG mail and GIT commit signing/encrypting SSH Authentication I am not going to describe the procedures in detail, but just link them and describe what we are doing, and why. Setting up NFC 2FA

## On Aggregates and Domain Service interaction

DevFeed: [On Aggregates and Domain Service interaction](<https://devfeed.tech/articles/on-aggregates-and-domain-service-interaction-21143.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/on-aggregates-and-external-context-interactions/>)

Published: 2017-01-25T00:00:00Z

Content type: tutorial

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [Object-relational mapping](<https://devfeed.tech/topics/orm.md>), [Code](<https://devfeed.tech/topics/code.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>), [API](<https://devfeed.tech/topics/api.md>), [App](<https://devfeed.tech/topics/app.md>), [Databases](<https://devfeed.tech/topics/databases.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [code](<https://devfeed.tech/tags/code.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [frontend](<https://devfeed.tech/tags/frontend.md>), [orm](<https://devfeed.tech/tags/orm.md>), [payment](<https://devfeed.tech/tags/payment.md>), [shopping](<https://devfeed.tech/tags/shopping.md>)

### AI overview

This article examines where to place I/O and domain-specific validation when working with aggregates in CQRS, event-sourced architectures, and imperative ORM entity code. Using a shopping-cart payment example, it discusses commands, aggregates, command handlers, guards, dependency injection, and the problem of moving business rules into application-layer handlers.

### Source excerpt

Some time ago, I was asked where I put I/O operations when dealing with aggregates. The context was a CQRS and Event Sourced architecture, but in general, the approach that I prefer also applies to most imperative ORM entity code (assuming a proper data-mapper is involved). Scenario Let's use a practical example: Feature: credit card payment for a shopping cart checkout Scenario: a user must be able to check out a shopping cart Given the user has added some products to their shopping cart When the user checks out the shopping cart with their credit card Then the user was charged for the shopping cart total price Scenario: a user must not be able to check out an empty shopping cart When the user checks out the shopping cart with their credit card Then the user was not charged Scenario: a user cannot check out an already purchased shopping cart Given the user has added some products to their shopping cart And the user has checked out the shopping cart with their credit card When the user checks out the shopping cart with their credit card Then the user was not charged The scenario is quite generic, but you should be able to see what the application is supposed to do. An initial implementation I will take an imperative command + domain-events approach, but we don't need to dig into the patterns behind it, as it is quite simple. We are looking at a command like following: final class CheckOutShoppingCart { public static function from( CreditCardCharge $charge, ShoppingCartId $shoppingCart ) : self { // ... } public function charge() : CreditCardCharge { /* ... */ } public function shoppingCart() : ShoppingCartId { /* ... */ } } If you are unfamiliar with what a command is, it is just the object that our frontend or API throws at our actual application logic. Then there is an aggregate performing the actual domain logic work: final class ShoppingCart { // ... public function checkOut(CapturedCreditCardCharge $charge) : void { $this->charge = $charge; $this->raisedEvents[

## ProxyManager 2.0.0 release and expected 2.x lifetime

DevFeed: [ProxyManager 2.0.0 release and expected 2.x lifetime](<https://devfeed.tech/articles/proxymanager-2-0-0-release-and-expected-2-x-lifetime-21146.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/proxy-manager-2-0-0-release/>)

Published: 2016-01-29T00:00:00Z

Content type: release

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [PHP](<https://devfeed.tech/topics/php.md>), [Code quality](<https://devfeed.tech/topics/code-quality.md>), [test-coverage](<https://devfeed.tech/topics/test-coverage.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [compatibility](<https://devfeed.tech/tags/compatibility.md>), [improvements](<https://devfeed.tech/tags/improvements.md>), [maintenance](<https://devfeed.tech/tags/maintenance.md>), [performance](<https://devfeed.tech/tags/performance.md>), [php](<https://devfeed.tech/tags/php.md>), [quality](<https://devfeed.tech/tags/quality.md>), [release](<https://devfeed.tech/tags/release.md>), [test-coverage](<https://devfeed.tech/tags/test-coverage.md>)

### AI overview

ProxyManager 2.0.0 was released with major improvements, exclusive PHP 7 support, exceptional code quality, complete test coverage, and performance improvements. ProxyManager 1.0.x moved to security-only support, while the 2.x branch became maintenance-only with bug fixes through January 29, 2017, security fixes through January 29, 2018, and no new features. HHVM compatibility was not achieved.

### Source excerpt

ProxyManager 2.0.0 was finally released today! It took a bit more than a year to get here, but major improvements were included in this release, along with exclusive PHP 7 support. Most of the features that we planned to provide were indeed implemented into this release. As a negative note, HHVM compatibility was not achieved, as HHVM is not yet compatible with PHP 7.0.x-compliant code. As of this release, ProxyManager 1.0.x switches to security-only support. Planned maintenance schedule ProxyManager 2.x will be a maintenance-only release: I plan to fix bugs until January 29, 2017 I plan to fix security issues until January 29, 2018 No features are going to be added to ProxyManager 2.x: the current master branch will instead become the development branch for version 3.0.0. Features for ProxyManager 3.0.0 are yet to be planned, but we reached exceptional code quality, complete test coverage and nice performance improvements with 2.0.0: the future is bright! Thank you! And of course, a big "thank you" to all those who contributed to this release! Abdul Malik Ikhsan Alberto Avon Jefersson Nathan John Bafford

## Doctrine ORM Hydration Performance Optimization

DevFeed: [Doctrine ORM Hydration Performance Optimization](<https://devfeed.tech/articles/doctrine-orm-hydration-performance-optimization-21141.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/doctrine-orm-optimization-hydration/>)

Published: 2015-04-13T00:00:00Z

Content type: article

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [Object-relational mapping](<https://devfeed.tech/topics/orm.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [Databases](<https://devfeed.tech/topics/databases.md>), [SQL](<https://devfeed.tech/topics/sql.md>), [PHP](<https://devfeed.tech/topics/php.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [database](<https://devfeed.tech/tags/database.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [orm](<https://devfeed.tech/tags/orm.md>), [performance](<https://devfeed.tech/tags/performance.md>), [performance-optimization](<https://devfeed.tech/tags/performance-optimization.md>), [php](<https://devfeed.tech/tags/php.md>), [sql](<https://devfeed.tech/tags/sql.md>)

### AI overview

This article explains how Doctrine ORM hydrates database results into objects and why hydration becomes more expensive for complex result sets. It examines the cost of mapping rows, handling joined records, skipping empty associations, and de-duplicating repeated records, with attention to CPU and memory usage.

### Source excerpt

PRE-REQUISITE: Please note that this article explains complexity in internal ORM operations with the Big-O notation. Consider reading this article, if you are not familiar with the Big-O syntax. What is hydration? Doctrine ORM, like most ORMs, is performing a process called Hydration when converting database results into objects. This process usually involves reading a record from a database result and then converting the column values into an object's properties. Here is a little pseudo-code snippet that shows what a mapper is actually doing under the hood: <?php $results = []; $reflectionFields = $mappingInformation->reflectionFields(); foreach ($resultSet->fetchRow() as $row) { $object = new $mappedClassName; foreach ($reflectionFields as $column => $reflectionField) { $reflectionField->setValue($object, $row[$column]); } $results[] = $object; } return $results; That's a very basic example, but this gives you an idea of what an ORM is doing for you. As you can see, this is an O(N) operation (assuming a constant number of reflection fields). There are multiple ways to speed up this particular process, but we can only remove constant overhead from it, and not actually reduce it to something more efficient. When is hydration expensive? Hydration starts to become expensive with complex resultsets. Consider the following SQL query: SELECT u.id AS userId, u.username AS userUsername, s.id AS socialAccountId, s.username AS socialAccountUsername, s.type AS socialAccountType FROM user u LEFT JOIN socialAccount s ON s.userId = u.id Assuming that the relation from user to socialAccount is a one-to-many, this query retrieves all the social accounts for all the users in our application A resultset may be as follows: userId userUsername socialAccountId socialAccountUsername socialAccountType 1 ocramius@gmail.com 20 ocramius Facebook 1 ocramius@gmail.com 21 @ocramius Twitter 1 ocramius@gmail.com 22 ocramiusaethril Last.fm 2 grandpa@example.com NULL NULL NULL 3 grandma@example.co

## When to declare classes final

DevFeed: [When to declare classes final](<https://devfeed.tech/articles/when-to-declare-classes-final-21149.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/when-to-declare-classes-final/>)

Published: 2015-01-06T00:00:00Z

Content type: opinion

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [PHP](<https://devfeed.tech/topics/php.md>), [Object-oriented programming (OOP)](<https://devfeed.tech/topics/oop.md>), [Programming](<https://devfeed.tech/topics/programming.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>)

Tags: [articles](<https://devfeed.tech/tags/articles.md>), [doom](<https://devfeed.tech/tags/doom.md>), [examples](<https://devfeed.tech/tags/examples.md>), [inheritance](<https://devfeed.tech/tags/inheritance.md>), [oop](<https://devfeed.tech/tags/oop.md>), [opinion](<https://devfeed.tech/tags/opinion.md>), [php](<https://devfeed.tech/tags/php.md>), [programming](<https://devfeed.tech/tags/programming.md>)

### AI overview

This opinion article argues that PHP classes should generally be declared final, especially when they implement an interface and expose no other public methods. It explains that preventing inheritance can discourage deep inheritance chains, encourage composition, and make developers design clearer public APIs.

### Source excerpt

TL;DR: Make your classes always final, if they implement an interface, and no other public methods are defined In the last month, I had a few discussions about the usage of the final marker on PHP classes. The pattern is recurrent: I ask for a newly introduced class to be declared as final the author of the code is reluctant to this proposal, stating that final limits flexibility I have to explain that flexibility comes from good abstractions, and not from inheritance It is therefore clear that coders need a better explanation of when to use final, and when to avoid it. There are many other articles about the subject, but this is mainly thought as a "quick reference" for those that will ask me the same questions in future. When to use "final": final should be used whenever possible. Why do I have to use final? There are numerous reasons to mark a class as final: I will list and describe those that are most relevant in my opinion. 1. Preventing massive inheritance chain of doom Developers have the bad habit of fixing problems by providing specific subclasses of an existing (not adequate) solution. You probably saw it yourself with examples like following: <?php class Db { /* ... */ } class Core extends Db { /* ... */ } class User extends Core { /* ... */ } class Admin extends User { /* ... */ } class Bot extends Admin { /* ... */ } class BotThatDoesSpecialThings extends Bot { /* ... */ } class PatchedBot extends BotThatDoesSpecialThings { /* ... */ } This is, without any doubts, how you should NOT design your code. The approach described above is usually adopted by developers who confuse OOP with "a way of solving problems via inheritance" ("inheritance-oriented-programming", maybe?). 2. Encouraging composition In general, preventing inheritance in a forceful way (by default) has the nice advantage of making developers think more about composition. There will be less stuffing functionality in existing code via inheritance, which, in my opinion, is a symptom of haste

## ProxyManager 1.0.0 release and expected 1.x lifetime

DevFeed: [ProxyManager 1.0.0 release and expected 1.x lifetime](<https://devfeed.tech/articles/proxymanager-1-0-0-release-and-expected-1-x-lifetime-21145.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/proxy-manager-1-0-0-release/>)

Published: 2014-12-12T00:00:00Z

Content type: release

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [Library](<https://devfeed.tech/topics/library.md>), [PHP](<https://devfeed.tech/topics/php.md>), [Code generation](<https://devfeed.tech/topics/code-generation.md>), [Documentation](<https://devfeed.tech/topics/documentation.md>), [Security](<https://devfeed.tech/topics/security.md>), [Windows](<https://devfeed.tech/topics/windows.md>)

Tags: [2-0-0](<https://devfeed.tech/tags/2-0-0.md>), [code-generation](<https://devfeed.tech/tags/code-generation.md>), [documentation](<https://devfeed.tech/tags/documentation.md>), [github](<https://devfeed.tech/tags/github.md>), [php](<https://devfeed.tech/tags/php.md>), [release](<https://devfeed.tech/tags/release.md>), [security](<https://devfeed.tech/tags/security.md>), [windows](<https://devfeed.tech/tags/windows.md>)

### AI overview

This release article announces ProxyManager 1.0.0, describing improvements to Windows path handling, proxy regeneration, documentation hosting, and code-generation error handling. It also outlines the maintenance policy for the 1.x series and planned goals for ProxyManager 2.0.0, including newer PHP runtime support, property-based lazy-loading ghost objects, RST documentation, improved LSP compliance, Doctrine compatibility, and possible prototypal inheritance support.

### Source excerpt

Today I finally released version 1.0.0 of the ProxyManager Noticeable improvements since 0.5.2: Windows path length limitations are now mitigated Proxy classes are now re-generated when the library version changes Documentation has been moved to github pages (Markdown documentation will be kept in sync) It is not possible to trigger fatal errors via code-generation anymore Planned maintenance schedule ProxyManager 1.x will be a maintenance-release only: I plan to fix bugs until December 11, 2015 I plan to fix security issues until December 11, 2016 No features are going to be added to ProxyManager 1.x: the current master branch will instead become the development branch for version 2.0.0. ProxyManager 2.0.0 targets ProxyManager 2.0.0 has following main aims: Drop PHP 5.3, 5.4 and HHVM 3.3 limitations, aiming only at next-generation PHP runtimes Lazy Loading ghost objects should be property-based, even for private properties Move documentation to RST, eventually using couscous Complete LSP compliance by avoiding overriding constructors in proxies Compatibility with Doctrine\Common\Proxy\AbstractProxyFactory to improve doctrine proxy logic in next generation data mappers Prototypal inheritance in PHP, which was left un-merged for a long time, and will likely be moved to a different library Thank you! It wouldn't be a good 1.0.0 release without thanking all the contributors that helped with the project, by providing patches, bug reports and their useful insights to the project. Here are the most notable ones: blanchonvincent malukenho staabm gws leedavis81 lisachenko Pittiplatsch