Features Missing In PHP

PHP started badly as a programming language but even as it evolved and addressed its design problems it never ran out of detractors. Their criticism has both a subjective (they love other languages) and an objective (they dislike its chaotic ways) basis, but one can safely say that in its current form PHP no longer impairs developers from creating satisfactory software.

Why can't we build something more than satisfactory in this language (and this framework from becoming perfect software applying art of computer programming from top to bottom)? Here is a list of most important shortcomings PHP developers will have to face:

Most of these issues have been solved by Hack Language, a dialect of PHP used by Facebook (using HHVM C++ based interpreter), but in normal PHP (using Zend C-based interpreter) they are all missing.

Inconsistent Error Management

PHP started very badly with this, showing utter disregard of structure from its developers, and it continues to split erors into nonsensical types instead of throwing an exception for each type of error so developers can handle differentially. A movement in latter direction was undergoing at snail's pace in versions 4/5:

Then a leap forward was made in version 7, taking Java as model, introducing error encapsulation through following classes/interfaces:

But as you're developing software using PHP7, you will still find cases when some fatal errors will not be directed to desired exceptions and cause an abrupt script end. To handle such cases you will still be forced to debug old (catastrophic) style using:

ini_set("display_errors", 1);

Such issues may occur while working with Lucinda Framework, as well, and require you to do following temporary changes in index.php until cause is tracked:

new Lucinda\STDERR\FrontController("stderr.xml", ENVIRONMENT, __DIR__, new EmergencyHandler()); ini_set("display_errors", 1);

Inconsistent Data Type Declaration

As an interpreted language PHP doesn't benefit performance wise from variable or method return type declaration: any variable declared in PHP is compiled as zval that's mixed by default. Since PHP is a weakly typed language while C, the language PHP is written into, is strongly typed, Zend interpreter has to guess data type of your declared variable at runtime.

So why is that ever since version 5.0 PHP is starting to look like more strongly typed as time passes? The reason is purely to help developers enforce structural integrity in their code. As with error management, this trend went at snail's pace:

The problem, as in previous chapter, is lack of consistency:

Lucinda Framework takes full advantage of data type declaration, minus cases not supported by language plus rare cases in which argument or return type are objectively mixed, something necessary since PHP doesn't support method overloading.

Lack Of Enums

Strongly typed programming languages such as C++/Java/C# support a special data type that groups families of constants. PHP doesn't support it at all, but its sister Hack language (used by Facebook) does. Example:

enum Permission: string { Read = 'R'; Write = 'W'; Execute = 'E'; Delete = 'D'; }

Then offer developers an ability to inject this special type in methods or use it in variables:

public function isAllowed(Permission $permission): bool { return ($permission == Permission::Execute); }

As mentioned above, in normal PHP this is not possible to achieve. Enum above would have to look like:

interface Permission { const Read = 'R'; const Write = 'W'; const Execute = 'E'; const Delete = 'D'; }

But you won't be able to inject it into methods or use it in variables:

public function isAllowed(string $permission): bool { return ($permission == Permission::Execute); }

Lucinda Framework uses enums extensively (example: ) and suffers in terms of beauty by lacking PHP support for it (using experimental SPL Types was considered a non-option).

Lack Of Overloading

Overloading is a powerful feature of strongly typed programming languages (C++/Java/C#) allowing developers to have multiple methods within same class using same name but different signatures. Example:

class Permission { public function check(string $userID): bool {...} public function check(int $userID, int $roleID): bool {...} }

In PHP this is not available, even though technically it would be possible and goes in line with trend towards stronger typed declarations. What the language offers instead is an emulation that takes advantage of its loose syntax:

class Permission { public function check($userID, int? $roleID = null): bool {...} }

The problem with this approach isn't just that it doesn't look good, but it will force you to do a big IF within method body to identify which case is it. The usual approach to fight chaos is to keep having two methods, only specialize name:

class Permission { public function checkById(string $userID): bool {...} public function checkByIdAndRole(int $userID, int $roleID): bool {...} }

Compared to other problems described above, that's not THAT much of an show stopper but Lucinda Framework would have benefited from it by drastically reducing cases when mixed argument/return type is required.

Lack Of Generics

Generics are yet another powerful feature of strongly typed programming languages (C++/Java/C#), and Hack dialect as well, allowing developers to parameterize their classes. Example in Hack declaration (a parameterized box class):

class Box<T> { protected T $data; public function __construct(T $data) { $this->data = $data; } public function getData(): T { return $this->data; } }

Once that was defined, Hack allows you to parameterize class by desired type on instantiation, which has the effect of replacing "T" above with "int" below:

$box = new Box<int>(12);

No such thing is possible in normal Zend-based PHP, nor is it planned for the future. The most common application of generics are data structures and few developers need to build data structures in PHP, so this isn't THAT much of a show stopper either.

Array Limitations

A much more significant issue somehow related to above is a fundamental array limitation that has never been resolved: a PHP array can only have integer or string keys. This goes against common sense especially considering HashTable implementation underneath supports it already. Other programming languages have no such problem, requiring objects that desire to serve as keys to implement:

Here is how it should have looked like in PHP:

# interfaces that should have been defined in PHP itself interface Comparable { public function compareTo(object $object): int; } interface Hashable { public function hash(): int; } # class defined by developer class MyObject implements Hashable, Comparable { private $field; public function __construct(string $field) { $this->field = $field; } public function getField(): string { return $this->field; } public function compareTo(object $object): int { return strcmp($this->field, $object->getField()); } public function hash(): int { return crc32($this->field); } } # usage example of array with MyObject type key and int values $array = []; $obj1 = new MyObject("hello"); $array[$obj1] = 1; $obj2 = new MyObject("world"); $array[$obj2] = 2;

No such thing is supported in PHP or Hack (if array is used) nor is there any formal request by developers to include it, no matter how natural that requirement is. This once again adds fuel to critics' opinion on the quality of PHP and developers that use it...

×