PHP wish-list

Random list of missing language features in PHP. I do mostly Kotlin nowadays, so this is quite inspired by that language. I think these features could be (somehow) “easily” added into PHP.

No new keyword

It removes unnecessary keyword, allows to easily chain method call.

class Url
{
    function something(): static { return $this; }
}

$author1 = Url();

$author2 = Url()->disable();
// instead of 
// $author2 = (new Url())->something();

This cool feature also allows a nice trick – using function named as the interface to create different implementations depending on the arguments:

interface Driver {}
class MysqlDriver implements Driver {}
class PgsqliDriver implements Driver {}

function Driver(string $dsn): Driver
{
    if (strpos($dsn, "mysqli") !== false) {
        return MysqliDriver($dsn);
    } elseif (strpos($dsn, "pgsql") !== false) {
        return PgsqliDriver($dsn);
    } ...
}

Conflicts would be simply resolved as the function is always preferred if class and function with the same name are present in the scope. Be aware the same named interface wouldn’t cause any troubles. Also, the new keyword would still work and wouldn’t be deprecated.

Extension functions

This is a must for better code design. The class will provide only the minimal API and users could easily and cleanly extends the class. The extension has access only to the public API -> i.e. it is just a syntax sugar.

namespace MyNamespace;

function Connection.inTransaction(callable $cb)
{
    $this->beginTransaction();
    try {
        $result = $cb();
        $this->commitTransaction();
        return $result;
    } catch (Exception $e) {
        $this->rollbackTransaction();
        throw $e;
    }
}

These extension functions would have to be always imported to be “callable”. Defining the same extension function would cause standard error.

The open question is the import syntax. Would be PHP able to resolve the proper function if there would be more functions with the same name extending different classes? This resolution issue is similar to overloading, which is not currently present in PHP.

use function MyNamespace\inTransaction;
// alternatively
use function MyNamespace\Connection.inTransaction;

$connection->inTransaction(...);

Overloading

Since PHP has types in function definitions, it would be great to have overloading. That would greatly help to codebase progression and allow changes without BC breaks. Also static analysis would be able to detect which call is deprecated and which not (in contradiction to taking both types and logging deprecated warning in runtime).

/**
 * @deprecated Use getValue with property object.
 */
function getValue(string $key) {}

function getValue(Property $property) {}

Immutability helpers (data class & readonly)

Immutable classes are quite powerful but it’s quite difficult to design them in current PHP. Mostly because we need “modifying” methods to allow change any property (i.e. these methods would be able reflect property additions/removals). With named args in PHP 8.0 it is possible to write them by hand, but some auto-generated method would be quite nice. A data class modifier which would do this for me. Also, read-only modifier is needed to make the class really immutable.

data class User
{
    public __construct(
        public readonly string $name,
        public readonly int $age,
    ) {}
}

$user = User(name: "John", age: 3)->copy(name: "Anie");
// === User(name: "Anie", age: 3)

Anything else?

Of course, I would gladly see generics, and other stuff. But these are quite difficult topics to get them right and correctly incorporated into lang. So just these would be really nice.

Leave a Comment