subscribe

Why PHP-FIG matters

The PHP-FIG is currently going through some growing pains. I recently resigned as a voting rep, and after some juvenile controversy Lavarel, Doctrine and Propel have as well.

Since its inception 8 years ago, the groups greatest problem has been to properly organize itself. From having followed the mailing lists for that time, I believe that the amount of emails entailing “the process, bylaws, voting and general bureaucracy” outnumber the actually productive technical discussions by maybe something like 4 to 1. This is a lot of wasted time, for a lot of people, and while (some) good documents have come from it, it is an incredibly inefficient process.

Now as a sort of knee-jerk reaction to these issues, PHP-CDS was setup with a much simpler process. Anyone can submit a PSR document there, first come first serve, disrespectfully in the psr composer vendor name. While it’s a nice protest, this will of course go nowhere. But the initiative makes a few good points: Ultimately the key to the success of PHP-FIG will be a more open group, a much lower barrier to entry and the ability to more rapidly release PSR’s; allowing them to fail quicker so better versions can rise from their ashes.

If you want a great example of why this is needed, look no further than PSR-6 a.k.a. the “Caching” interface. This is an effort I originally started somewhere in 2011. It took 5 years to complete (I gave up after 2). Originally a simple key-value store that mimicked interfaces from memcache and apc 1:1, it has become a textbook example of “design by committee” and aims to solve a wide range of problems such as being able to store and retrieve NULL from a cache (yes, this was a major design consideration, and a big influencer for the resulting API. See the meta document).

Now I don’t think we need to try to aim to create an organization that prevents people from making bad decisions. Instead the organization we need is one that allows someone to make that mistake in the timespan of about 5 months instead of 5 years, so room can be created for a new PSR that solves the 80% problem in a less ridiculous way.

Some good stuff is happening though. A few people are working on a thankless effort to restructure the organization dubbed “FIG 3.0”. (thanks Larry Garfield and Michael Cullum). Contrary what you might read in the first half of my post, I don’t actually believe that total anarchy is the solution. Process is needed, but it needs to be good process, and you need humble people to shepard it. As long as the role comes with a certain amount of prestige, it will attract the wrong people. This has happened with the group of voting representatives. Some voters have joined and then put in zero effort, while others have devised elaborate schemes to get admitted as one.

I think PHP-FIG needs to immediately create a separate mailing list, specifically for organizational / process matters. Let its moderators rule with an iron hand and delete posts and suspend mailing list users that go off topic on either the organization or general mailing list.

Perhaps even go to a model where every post gets moderated in the short-term.

Why it matters

But why does this all matter in the first place? Take caching for example. A lot of different frameworks provide some facility to do this.

But there’s also a lot of framework-independent libraries that can take advantage of this.

Libraries today generally have a few options to solve this:

  1. Build in a caching library in the library.
  2. Depend on a specific external caching library.
  3. Only work with one framework (by expecting for example a Symfony cache).
  4. Provide adapters for different frameworks.

All of these solutions have drawbacks, and all of these solutions are happening in the wild. A (sane) PSR-Cache can solve this.

We are creating a TON of redundant code, each framework and ecosystem gets its own implementation of everything, and the few packages that are used across frameworks get framework-specific bundle packages.

I think it requires a bit of change in thinking to make successful interfaces though. The problem that haunts PSR-Cache, but also the earlier PSR-3 Logging interface and PSR-7 (HTTP), is that they all aim to be the framework directly exposed to the user, instead just the plumbing.

This is the most obvious from the logging interface. The logging interface really only facilitates one operation, logging something:

public function log($level, $message, array $context = array());

This would actually have been enough, but we got 8 additional methods that make it easier to to call this (already fairly simple) method:


public function emergency($message, array $context = array());
public function alert($message, array $context = array());
public function critical($message, array $context = array());
public function error($message, array $context = array());
public function warning($message, array $context = array());
public function notice($message, array $context = array());
public function info($message, array $context = array());
public function debug($message, array $context = array());

While I think it’s fine for something like monolog to provide this interface to its end-users, this goal should not have been conflated with the PSR.

Removing those functions would have cost us very little. It’s up to library developers to make the plumbing look nice.

Instead, the Monolog API pretty much is PSR-3, like the Stash user-facing API is PSR-6 and Zend Diactoros is PSR-7.

By conflating the goal of simple library to library interop to becoming the end-user API, each of these standards have become very opiniated which is good for the people running those projects, or people who hold that opinion, but it leaves little space for other opinions. There’s also a risk that these PSRs will go out of fashion when their respective ‘host projects’ do.

The folks that sign up to taking an “event sourcing” / functional approach to PHP have largely dictated the design of PSR-7. This is why we’re left with a set of objects that are pretty odd to pretty much anyone who first sees them.

The larger problem is that PSR-7 was never designed to cater the use-case where an existing PHP framework interacts with a framework-agnostic plugin. In the world of PSR-7, we all first need to convert to the church of event sourcing. There is one de facto implementation, and while there is traction, the traction largely exists within libraries that subscribe to the idea of this particular approach to Middleware and they seem mostly new utilities, not existing feature bundles that are becoming framework agnostic. We pretty much need new major versions of the major frameworks first, and then PSR-7 to become a first-class citizen. Had PSR-7 been a simple mutable interface, every framework could have created a simple proxy pattern between PSR-7 and the underlying request/response objects they already had.

However I actually believe that PHP-FIG should facilitate the eventsourcing school of thought and should help them interop, but by optimizing the process and making it much easier to publish PSR documents (even if they are competing with earlier ones) it will be in a much better position to achieve the goal to let libraries and frameworks interop better.

This is because a successful PSR is one that allows at least 3 projects to better interop. If we make it a requirement to reach total concensus the pressure is way too high for everyone involved to make that PSR perfect. Since “perfect” is different for everyone, the most persistent debater wins, and ultimately for PSR 3, 6 and 7 that has been the author of the document. That’s why PSR-3, PSR-6 and PSR-7 might as well be called Monolog, Stash and Diactoros.

If you only get a chance once every 5 years to build the right interface, you’re gonna care about getting it right. Nobody is to blame for that, but if we were a bit more flexible, we may have had a simple key-value store 4 years ago. 3 years ago we may have gotten a multikey extension, and last year the author of Stash may have published a third PSR that might have worked better for Stash’s end users, one which may not have suffered as much from having too many cooks in the kitchen.

Conclusion

Well, this turned into quite a rant. My ultimate goal with this post is to try and better vocalize the vague criticism I’ve seen about the PHP-FIG. I notice a lot of people ‘feel’ this way but have not been inside the sausage factory for long enough to figure out why all the recent PSR’s leave such an odd after-taste.

Not sure if I’ve succeeded with that or if I’m just stirring the pot. Regardless, I believe PHP needs PHP-FIG, and I would be excited to get involved again in a strict technical capacity once Larry and others are done with the open heart surgery.

Web mentions

Comments

  • Navarr Barnier

    I would like to take this comment to respond to your logging interface.

    I am only a mid-level developer, but this is where I'm a little confused. Where should the line be drawn?

    The one log function is great and all that is probably needed for cross-framework log drop-in/drop-out, where the logging mechanism can be pulled it from anywhere, instantiated if it follows the PSR, and "just work" when plugged into the framework.

    But on the other end is when you want the PSR to be helpful to the users, not the frameworks. For example, To decrease the amount of friction between swapping out logging components. If they're not using a framework, or their "framework" doesn't have a built in logging mechanism with which they would swap out the base logger, these ->emergency() commands etc cause additional strain for them to move away from their logger.

    Where should the FIG put it's attention? If it's solely for framework interop, then I guess at the `log`. But if its for additional developer benefit - then `emergency`.

    We could end up instead at an interesting place where you have the FIG responsible for the plumbing and the CDS responsible for the developer-friendly API.

    (And they setup in the psr namespace by default, but there is of course an active discussion about what it SHOULD be)

    • Mark P

      If a developer wanted a nicer interface to work with while still being able to swap out the concrete implementation (Monolog) at a whim, he could create his own wrapper.

      class BetterLogger {
      function __construct(SimplePsrLoggingInterface $logger) { ... }

      function emergency($msg, $context) {
      $this->logger->log(6, $msg, $context);
      }
      }

      $betterLogger = new BetterLogger(new Monolog());

      Then just typehint against BetterLogger instead of SimplePsrLoggingInterface directly. Since BetterLogger is under your control, you can design the API however you like while still allowing the concrete implementation to do the gruntwork, and the PSR interface to handle the plumbing. (And if you don't want to typehint against a class, have BetterLogger implement BetterLoggerInterface).

      Doesn't this solve everyone's needs?

      • Evert

        Evert

        Yes this is the point. Keep in mind that I took the logging example mainly to make the point because it's pretty clear. The impact of making the logger simpler/complexer is low, but the same situation exists in PSR 6 and 7 and the impact/cost of these decisions were much higher.

        • Mark P

          Right. I'm just saying that making the interfaces simpler doesn't hurt anyone. It's fewer methods library authors have to implement, and end developers can wrap the interfaces anyway they see fit.

      • Ryan Winchester

        i spy a magic number! *slaps wrist*

    • Evert

      Evert

      The point of FIG is framework/library interop. If you solely have the 'end user hat' on in this, then you are NOT the target audience.

      Well, you shouldn't have been...except the PSR's were written in a way that you are, and this is a bad thing.

  • Marc J. Schmidt

    > disrespectfully in the psr composer vendor name

    This changed already: https://github.com/php-cds/...

  • beberlei

    I really like your description of plumbing for libraries/Frameworks, that is *exactly* what the FIG should have been about.

    I can share my story of proposing, what in the end sort-of became PSR-. Initially it was about an Http Client and my proposal was something along the lines of:

    $response = $client->request($method, $uri, $payload, $headers);
    $response->getStatusCode(); $response->getBody();

    I gave up defending this after some weeks already, everybody wanted a dedicated Request to solve *all* their problems an we know from the end, Request and Response made it in and Client oesn't even exist anymore, although it was the most important part of the proposal from a plumbing POV.

    Back then (this must have been 2010 or something), could we have agreed on this issue, then we wouldn't have all the HTTP client problems that we are currently seeing everywhere, with third party api libraries using various versions of Guzzle, Buzz et. al. and incompatibilities.

    php-http tried to step in to build a wrapper, but it essentially ended up re-inventing another very complex API all over again, something that cannot be standardized because of the complexity. The tutorial literally starts with an example on asynchronous http, which is not even a 10% use case for most of the developers.

    • Evert

      Evert

      10% is very, very generous. A super sane subset would have actually been just the read-only interfaces. They would have worked for virtually every usecase. For what it's worth I do think it was worth getting to the bottom of figuring out the response correctly. The underlying data model of the headers and uri/request target is _really good_.

  • G

    As I see it, in the first part of your article you write about bureaucracy and then later you become bureaucrat:) Maybe that's the same problem as with the people you complain about.

    Regarding HTTP message PSR, as others you have your opinion too. You seem very exclusive about it, no one could change your mind. I'm sorry to say that but that's wrong attitude for participating in any kind of group. Especially if it's accompanied by a lack of knowledge - the following sentence proves it: "The folks that sign up to taking an “event sourcing” / functional approach
    to PHP have largely dictated the design of PSR-7". It's really not about approach, it's about security, safety, simplicity, etc. I think you don't have a clue about event sourcing, functional approach, value objects, modelling... and yet you scream about it.

    Sorry if my reply sounds offending but as I read your article I felt sorry about poor guy who devoted his time to participate in creating something extraordinary. Not without flaws but better than alternatives.

    • Evert

      Evert

      >As I see it, in the first part of your article you write about
      > bureaucracy and then later you become bureaucrat:) Maybe that's the same
      > problem as with the people you complain about.

      If that's what you take from this, then the only solution against the management problems is no management at all. I do indeed disagree with that notion. So you read that correctly. I think rules and regulations are important, but if we spend the majority of the 8 years discussing them, then the process is broken. That does not imply that the remedy is no process at all...

      > to PHP have largely dictated the design of PSR-7". It's really not
      > about approach, it's about security, safety, simplicity, etc. I think
      > you don't have a clue about event sourcing, functional approach, value
      > objects, modelling... and yet you scream about it.

      I don't take a pro or against stance against that school of thought. If you took from it that I wanted to invalidate the approach, you misread. My point is that this particular approach to application design is used by a small subset of people. Whether you think it's a good thing or not, you can't argue that it's a niche. You also can't argue that it does not match what the vast majority of people are actually doing.

      If you look at some more recent PHP-FIG messages about middleware, you'll actually see that people are still figuring out the design patterns around it and don't fully know yet what does and doesn't work. This is an indication that it's in its infacy and people are learning as they go. Which is fine. I'm not saying one thing is better or worse.

      But of course a more convenient interpretation is that I'm just an idiot who doesn't know what he's talking about. Lets just attack my lack of knowledge of the subject instead of discussing the merits of my point. Thanks anonymous person. Very brave of you.

  • s.molinari

    I am a nobody PHP developer, but I too hope the PHP-FIG can get over the politics and remember its purpose and work towards that purpose much more fervently. Why? Because it is, IMHO, the next evolution to the PHP language and its community. If it works well, the interoperability will be the needed propulsion to push PHP's further success. If it fails, I am afraid PHP will stagnate (even more than it has in the past). I'd like to see a much more promising future for PHP and PHP-FIG plays a major leadership role, by doing its work efficiently. That is a huge responsibility. It is NOT prestige. It takes modesty, caring and giving to come together to support a greater whole as a group. It is an honor and a duty. And as such, it takes diligence and fortitude. And everyone needs to keep the greater purpose in mind....all the time!