PHP issue 

Apparently you can do

declare(ticks=1) {
[ ...code... ]

instead of

[ ...code... ]

but you can't do

declare(strict_types=1) {
[ ...code... ]

instead of

[ ...code... ]

...or at least not in PHP 7.4.

This isn't mentioned or explained in the documentation, as far as I can tell.

It also leaves open the question of how to turn on strict typing globally.

It's annoying the way inheriting traits in doesn't confer parentage.

Like... if trait B uses trait A which has function X() which is re-implemented in B, B can't call parent::X(); you have to alias it in the use statement and call the alias... or else split off the functionality you want them both to have in common into a separate function, and call that from each version of X().

(The latter technique is kind of good, in a way, since it forces you to be more descriptive and compartmental in your functions... but then why not make class inheritance work the same way?)

(albeit minor)

Apparently this is only actually supported for return values? I'm getting a warning trying to override an argument type with a class that descends from the original type...

I wish had an equivalent to dumping the memory address of an object -- some kind of unique identifier. It does have the === operator which lets you determine if two variables point to the same data-space, but sometimes that's not practical to use when debugging.

This doesn't quite qualify as a software gripe... maybe : it would be nice if would let you declare that a function isn't supposed to return anything at all (e.g. NULL as a return type).


  • minimizes confusion with older functions where I just haven't gotten around to giving them a return type
  • catches mistaken attempts to return a value, when you forget that the output is supposed to be conveyed via some other means.

thought: If you use a trait in a class, are you a class-traiter?*

Bonus joke: if the parent classes don't like it, they may make a "final" declaration and cut off your inheritance.

(*This joke is probably obvious and and only 1% of PHP devs working with traits haven't already thought of it -- which is why 1% of PHP devs own 99% of the bad PHP jokes.)

If I were to implement an SMTP server in , would that be chaotic neutral?

How about if I stored the data in MySQL instead of mbox? Or... JSON? 🌩️ ☠️ :kestraglow:

Another Actual Gripe (minor): I wish traits could require an interface from the host class. (That is, a trait could specify that any class which uses it must implement one or more specified interfaces, because it needs that interface's methods in order to function.)

Related gripe mentioned earlier: I wish traits could specify that they satisfy a given interface.

So the syntax to incorporate both of these would be something like this:

trait MyTrait
implements SatisfiedInterface
extends NeededInterface {

(I'm using "extends" mainly to avoid adding another keyword like "requires", but I think it's logically consistent: if a class extends a class that has abstract methods, then it must either be abstract or implement those methods -- and an interface is pretty much identical to an abstract class with only abstract methods, all public.)

(P.S. This is my first toot!)

Another actual (minor) gripe:

A class uses a trait, but wants to override one of the trait's methods by modifying its output, which requires calling the trait's version of the method to get the original output.

If the trait were used by a parent class, you could use parent::method() to call it -- but if the trait is used in the current class, you can't.

I get around this by declaring a dummy parent class which uses the trait, then overriding it in the real class (which descends from the dummy) -- but honestly, I shouldn't have to do that.

While typing this, I remembered there was a syntax for modifying how trait methods are accessed when they're used. I tried that just now, and it worked. This is better than my old solution, but still seems like it should be unnecessary.

Actual complaint about : you can't typecast classes.

That is, you can't treat an object of Class1 as being an object of Class2 (so as to have access to additional/different functions (methods) for handling its data)...

...even if Class2 is a descendant of Class1.

...unless that has changed since the last time I tried it.


The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!