Author: Manuel Lemos
Posted on: 2013-03-21
Categories: PHP community, PHP opinions
Read this article to learn about many creative solutions that several PHP developers implemented to overcome some of the PHP limitations.
Evolving PHP without Waiting for New Versions
A Tribute to Extremely Talented PHP Developers
Features that PHP does not have yet
Features that PHP already has
Get Distinguished for Your Own PHP Classes
Evolving PHP without Waiting for New Versions
The PHP development process is still a bit frustrating. Many developers hoped that PHP had certain features but those are still missing due to several reasons.
One way to see those features happen is to write code to implement the features and then submit the code to the PHP core. However that is not a guaranteed process. Even if you provide the necessary code, other developers may object to the addition of those features and the effort is wasted.
It is true that the process has improved a bit in the latest years. There is now a RFC (Request For Comments) process that allows developers to propose features and have the community evaluate the proposals without wasting time implementing code in advance for features that will not be accepted anyway.
Still it is often a frustrating process. There are too many politics in front and behind the scenes. The voting process does not require voters to justify why they boycott certain proposals. So the proponent will often be lost without knowing what he needs to do to improve the proposal to make it acceptable.
Not to mention that certain proposals are boycotted just because people do not like each other for some undisclosed reason. That is a matter totally unrelated with the technical merits of the proposal. Very ugly, but that is the way it is.
Anyway, many developers do not want to bother with all that and wait for a future PHP versions that include the features they wanted. They just thought about the problems and figured solutions that can be implemented with the current PHP versions. Simply brilliant!
A Tribute to Extremely Talented PHP Developers
PHP is a very popular language thanks to the Web. We all know that.
Once in a while we see fans of other languages campaigning against PHP with the hope to attract more developers to those other languages. It is a dirty trick but it happens a lot.
The fact is that despite its limitations and inconsistencies, PHP is not a bad language at all. If PHP was so bad, it would not have attracted so many talented PHP developers that can think outside the box and bring surprising solutions that overcome some of those limitations. Most of those solutions use pure PHP code that runs with the current PHP versions.
The PHP Classes site was created to give exposure to any PHP developer that wants to share his work in form of useful PHP Classes. I am glad that so many talented PHP developers have chosen this site to expose to the world classes that overcome PHP limitations.
This article is meant to pay tribute to all those PHP developers that created extraordinary classes which exceed the capabilities of the features provided built-in the language. Let me tell you more about those extraordinary classes and their authors.
Features that PHP does not have yet
The PHPClasses site was created in 1999. Since than PHP has evolved a lot. Many of the features not available in the past, are already available in the present PHP versions.
I am going to start with classes that implement features that PHP does not have built-in or are not available in the main PHP distribution yet.
1. Aspect Oriented Programming
Aspect Oriented Programming (AOP) is a way to implement new aspects to a component without changing its original code.
Guilherme Blanco from Brazil provided a different approach to provide a more transparent PHP AOP implementation. It applies aspects by parsing the PHP code and inserting aspect code in the marked pointcuts. It does that using an alternative require command.
There is a PHP AOP extension in the PECL repository now, but it never made the main PHP distribution.
Annotations are additional pieces of information that can be inserted in the code to let developers define information that may be useful for external tools, like for instance Object-Relational mappers.
There have been several RFC proposals to add annotations support in PHP. However they were either rejected or forgotten.
Evaldo Barbosa from Brazil created a pure PHP implementation to provide annotations support to PHP. It extends PHP reflection class to parse PHP class code and extract annotation values from comments in the code.
3. Extended class meta-data beyond reflection
Artur Graniszewski from Poland also extended the capabilities of PHP reflection with the package Advanced Sourcecode Reflection in PHP.
Basically it can extract additional details from the class, like the source code of functions, line and column numbers of the declarations, etc..
This means that objects are defined dynamically. Variables and functions can be added to all objects of a "class" using the prototype definition.
The Class Prototype package of Marco Marchi˛ from Italy aims to achieve a similar purpose in PHP. It can add variables to all objects of a class. It affects both objects of the class that were already created or will be created in the future.
5. Dynamically extend class with plugins
Plugin based systems are very common. They allow extending components using add-on components that provide additional functionality.
If you want to extend class that does not have the support to load and integrate the functionality of plugins, you may need to change it.
David Bittencourt from Brazil implemented a better alternative with the phpPlugin package. It generates code for a subclass that incorporates code from one or more plug-ins. This way the original class does not need to be changed.
Pashkov Denis Igorevich from Ukraine implemented a different approach with a class named Dynamic Methods. It relies on the __call magic function to dynamically load any plug-ins when a missing function is called.
6. Friend or package access classes
In Java, packages are usually groups of classes that work closely together. These are similar to C++ friend classes. These classes may have special permissions to access each other functions or variables that external classes may not have.
Rubens Takaguti Ribeiro of Brazil implemented a Friend class that emulates this behavior in PHP. It requires that the caller code invokes a function with a friend_ prefix in the name, so Rubens' base class directs the call to protected or private functions that could not be called from external classes.
PHP implements namespaces that in part replicate the Java packages features in terms of defining names. However, there seems to be no way to treat classes within the same namespace as friends.
7. Class generics (templates)
8. Turn errors into exceptions
PHP 5 introduced exceptions as a way handle run time errors. Before that PHP already supported triggered errors and warnings. That made made applications eventually have to deal with two kinds of errors: thrown exceptions and triggered errors.
9. Introspection of private functions and variables
The use of protected and private functions and variables raised a problem for developers that want to implement tests for those types of class members. External code cannot access protected and private members.
Mathias Krieck from Germany implemented the Super Proxy class to workaround this restriction. It uses reflection to create a copy of the class to be tested, removing the private and protected constraints from the functions and variables.
A somewhat similar problem occurs when magic functions __set and __get where implemented. They allowed changing the way the values of variables are stored and retrieved. This made it hard for IDE and documentation extraction tools to figure which variables are implemented by the classes.
Artur Graniszewski from Poland provided a workaround class named C# getters and setters in PHP. It allows to declare fake variables just for the purposed of aiding IDE and documentation extraction tools figure what are the real class variables and any associated meta-information.
10. Alternative auto-loading of classes
PHP 5 introduced auto-loading of classes on demand but it just takes care of loading of the class files according to certain rules defined in the auto-loader function code.
TB from Romania went further and developed a Manager class that implements an alternative for loading classes that also takes care of initializing the objects besides calling the constructor function.
11. Running multiple scripts in parallel
Some tasks require the execution of multiple tasks that would run faster if they were executed in parallel.
Languages like Java come with libraries for creating threads to execute multiple code segments in parallel. The fact that those libraries come with Java installations make some people believe they are part of the language.
PHP has extensions to create parallel processes or threads but since those extensions are not part of the main PHP distribution, some people believe that PHP does not support code in parallel.
Anyway, there are several ways to run multiple PHP code segments in parallel using the main PHP distribution.
Luca Mariano from Italy was the first to submit a class named Thread that uses the PCNTL extension to create and manage multiple processes that run PHP code. This extension only works on Linux or other Unix-systems. It works only with PHP CLI/CGI versions and it is not enabled by default in the main PHP distribution.
A more feasible solution was implemented first by Alex B. Snet from Russia with the Threading class. It uses the PHP CLI program to start PHP scripts running in parallel. Despite the PHP CLI program also exists on Windows, the class uses a feature of Unix-like system shells to start programs in parallel, so it does not work on Windows.
Akash from India implemented the PHP parallel programming class that works both on Unix-like and Windows systems. It relies on an external C++ program to create parallel processes in each system. It provides the C++ source code for compiling that external program in Unix and Windows.
A more portable approach was implemented first by Alex Lau from Hong-Kong in the Multi-thread Simulation class. It takes advantage of the fact that a Web server can execute multiple scripts in parallel. So the class sends HTTP requests to the same Web server to make multiple PHP scripts run in parallel.
Mohammed Yousef from Egypt has written the PHP Threader class that also takes advantage of the fact that a Web server can run multiple scripts in parallel, except that it uses AJAX requests sent from the browser to start the scripts.
12. Named parameters
Named parameters allow code that calls functions to specify only some of the function parameters. The parameters could also be specified by any order.
This is a frequently requested feature that was never implemented in PHP. There is even an RFC proposal that refers a developers meeting that took place in 2005 on which they decided against implementing this feature.
This rejection never stopped PHP developers from keeping to wish that feature was available in PHP like in other languages. That is the case of Stefan Jibrail Froelich from Ghana that wrote a class that emulates Named Parameters.
It parses a string with the parameters names and values. It is not very feasible because parsing slows down the executing of the function, but at least it addresses the wish of many PHP developers that desire this feature.
13. Running unaudited PHP code in a sandbox
Sometimes it may be interesting to show running examples of PHP code provided by third parties. However you may run into security risks if the code is not audited. The code may do something harmful and compromise the whole environment.
Paul Fryer from the United Kingdom provided an interesting PHP Sandbox solution to address this problem. It can run arbitrary code using the PHP CLI version. It changes the file system root to prevent that the code has access to sensitive files.
14. Class composition
An API often provides the combination of functionality of different components. Ingvar Reverser from Ukraine was the first to simplify the composition of classes using functionality of multiple other classes with the Quick API class.
15. Deferred execution of long tasks
Some times applications need to execute tasks that take too long to complete. In that case it would be better to send those tasks to a queue, so they can be executed later without making the user wait.
Solutions like Gearman or others based on message queues can address this problem, but those solutions are not available on all environments you may need to run PHP.
Thomas Bj÷rk from Sweden implemented an elegant solution with the Loco class. It allows applications to call functions of classes to execute long tasks, but instead of executing them, the class records the function parameters and send them to a queue, so they it be executed later.
16. Satisfy needless dependencies with dummy interfaces
Sometimes you need to use a third-party package that implements many interfaces. However, you just need the functionality of small part of that package, so you would not need to include the whole package if it did not require the definition of all the referenced interfaces.
Oliver Anan from Germany provided a workaround for that situations with the Virtual Interface Generator class. It generates dummy code for interfaces you do not need, so you can include them to satisfy dependencies without loading the original interface code.
17. Comparable interface
Comparing values is useful for sorting a list of values. In PHP you can compare scalar values or even arrays and objects. However the rules by which objects are compared are defined built-in the language and you cannot override those rules.
A more flexible solution would be to have a Comparable interface, so each class would define how their objects should be compared. There was even a RFC proposal for that.
18. Iterable interface
In PHP you can use built-in functions to traverse arrays with also objects that implement the ArrayAccess.
Stanislav Shramko from Russia went further and implemented a class named Func Utility that can also traverse strings and objects that implement the Iterator interface to provide some of those array traversing functions.
Features that PHP already has
As PHP evolved, some of the features wished by developers in the past were already implemented in newer PHP versions. Still it is notable the effort of developers that tried to provide those features in past PHP versions. Here follow some of those efforts.
19. Executing code automatically when exiting a function
Sometimes applications need to execute cleanup code when exiting a function regardless of how it returned from that function.
PHP 5.5 introduced the finally construct that allows you to define code that will be always executed when exiting a section defined by try and catch constructs. So the finally construct could be used for that purpose.
If you create an object of the class within a function and assign it to a local variable, that object will be disposed automatically when the function exits. This way the registered cleanup code will be executed when the function returns.
20. Class destructors
PHP 5 introduced class destructor functions. Since that functionality was not available in PHP 4, Bryan Smith from Canada developed an alternative solution to implement destructors in PHP 4 by using PHP shutdown functions to execute object destructor code.
PHP only got namespace support in version 5.3. A long time before that Martin Alterisio from Argentina implemented a Namespace emulation solution that worked in earlier PHP 5 versions. It parses the PHP code with namespace definitions and generated alternative code that would emulate those definitions in older PHP versions.
Carlo Tasca from the United Kingdom also implemented a different class named packagex that would implement a feature similar to the Java import command. It can load many classes at once using namespace wildcards.
PHP 5 introduced the magic functions like for instance __call that allows the implementation of overloading of class functions.
Ralf Mike Pretzlaw from Germany built on this possibility to Overload a class by allowing that the same class function name be called with a different number and types of parameters and have it implemented internally in the class by different functions depending on the parameters being used in the call.
PHP 5.3 introduced closures which are functions without a name that can be called from anywhere.
24. Function parameter type checking
Passing parameters of the wrong types to functions is a symptom of code that has bugs. Strong typed languages do not allow that to happen. PHP 5 introduced type hinting to address this problem without affecting the flexibility of a weak typed language.
Dmitry Sheiko from Belarus created the PHP Typification Class to implement explicit type checking at runtime. It worked even in PHP versions before PHP 5. It added some overhead to the function execution but it addressed the problem of type checking.
Initially PHP 5 only supported type hinting for objects, so it could not check non-object types. Martin Alterisio from Argentina provided an alternative Type Hint class that could check the types of non-object parameters using a custom PHP error handler.
25. Mixing the functionality of different classes
Sometimes you need to compose objects that combine the functionality of different classes. That could be achieved with interfaces or multiple inheritance but that would lead to complexity problems.
PHP 5.4 introduced traits to compose the functionality of classes from small snippets of code that can be combined without increasing the complexity of the code too much.
David Boskovic from Canada implemented a solution that can combine code of different classes using mixins. It generates code for new classes as result of the combination, so it works with older PHP versions.
26. Serializing objects that reference each other
Objects can have variables that reference other objects. This allows the possibility to establish loops of objects that reference each other. This prevented the PHP serialization functions to properly serialize and unserialize objects that reference each other in a loop.
Get Distinguished for Your Own PHP Classes
As you may have read, this article presented the outstanding work of many developers that provided surprising solutions to problems that affect many PHP developers.
Since practically all of those solutions were innovative, they were nominated to the PHP Programming Innovation Award. This means that they earned prizes and recognition apart from the mention in this article.
Other than that, many of them were also mentioned in the Lately in PHP podcast that we record once a month. In the podcast there is a section specifically to comment some of the most innovative packages nominated in the previous month.
All these initiatives are meant to provide recognition to the nominees and encourage more developers to come up and publish more innovative packages.
I am glad that it worked so well for all these years. If you also have innovative packages to submit, please go ahead and do it so we can talk about your work too. Many hundreds of PHP developers earned recognition for this. You can earn deserved recognition too.
Just because PHP has known limitations, it does not mean it is not possible to implement clever workarounds that address those problems.
I am well aware that sometimes PHP developers do not get the respect that they deserve. Some people feel that other languages are superior, and so they look down to PHP developers.
I hope that this article has shown that the PHP community is very fortunate to have so many talented developers that could even come with components that overcome the limitations of the language.
So, every time that you see anybody trying to put down the PHP language and its community, feel free to point them to this article. I am sure many of them will change their minds.This is just my opinion. If you agree or maybe you disagree and have other points of view, feel free to post a comment here to tell what you think.
You need to be a registered user or login to post a comment
Login Immediately with your account on: