Blog calendar
— or —
... and more
Blog tags
12 Feb 2009 08:53
For several years now I have been using PHP for building several projects and web applications, including Wikidot. I dare say I know PHP very well, I was also one of the few first people in Poland to get the Zend Certified Engineer certification (which nicely sits next to my Sun Certified Java Programmer cert).
PHP is extremely popular. Zend is putting a lot of money and effort to move PHP from the commodity market into enterprise and… it seems to work. PHP has very nice learning curve, although to produce good code in PHP it takes as long time and effort as in other languages. PHP is easy to deploy, runs well on commodity hardware…
But PHP sucks. And it really sucks badly for certain tasks, which we from time to time find out. So here is a short list, which by no means is complete, but compiles my thoughts of the language I have been using for the last 5 years:
Functional + Object-Oriented
PHP started as a purely functional language. The initial easiness was tempting for many web developers, therefore PHP exploded in popularity. The problem is that Zend wanted it to be a object-oriented. They tried twice. PHP 4 was the first attempt and it was bad. Terrible language constructs, mixing functional and OO features in a very complicated and unclear way.
In PHP 5 the OO part was mostly redesigned and right now PHP 5 follows the Java-style - it has Interfaces, Classes, proper constructors, inheritance… Even syntax follows the one of Java.
The pity is that PHP is still a functional language mixed with OOP. Come on, why is Array not a real object? Or a String? Why do we still need to use complicated built-in functions to manipulate them?
Quality of the open source code
Quality of the open source projects varies tremendously. Because PHP does not enforce you to use good programming style, developers tend to use a lot of shortcuts, homebrewed solutions and a lot of hacks. Most of the available code is PHP4-compatible, which means it uses different OO approach than PHP5.
What is worse, libraries often pollute global namespace with their own variables (and constants) and functions which is a potential source of conflicts.
Most importantly, when you are trying to use
error_reporting(E_ALL|E_STRICT);
which will be default in PHP6, you will quickly find that most of the open-source libraries produce TONS of warnings and notices.
What I have learned so far and is a general rule of thumb:
- Avoid PHP4-compatible libraries
- Look very carefully at PEAR stuff, it might be broken, see all pending bugs, see if it is maintained
- Test any library with the strict error reporting
Duality of errors/warnings + exceptions.
PHP5 uses Java-like Exception classes with try{} catch{} clauses. But it also uses legacy errors warnings, with all their handlers etc. This really does not play nice together. Especially if any of your external libraries tries to handle such errors by itself.
What you should do in a perfect world is to map all the errors and warnings into Exceptions, like we do. (Except for Fatal errors that cannot be handled by an application). But then, you can be really unpleasantly surprised when you use the above error_reporting(E_ALL|E_STRICT).
More like Java
As I am trying to point out, PHP tries to resemble Java. This is both good and bad.
Good:
- Introduces clear language structures that we all know, classes, interfaces, exceptions etc.
- Easy to design application by people experienced in Java
- Yes, you can make your application behave like in Java with a set of custom error mappings, directory structures, autoloaders, pseudo-packages etc. But it is hacking.
Bad:
- Several other conventions still apply: functions, warnings/errors, PHP4-like OO
- Very different underlying architecture from Java (share-nothing)
- Still an interpreted language
- It is not Java
OO features in Standard Library
Did you hear about the Standard PHP Library? Probably not. Me neither before I had to use iterator interfaces to create a well-behaving array-like objects or use chained class autoloaders.
- Why is this called a standard library?
- It only covers a small tiny portion of the language.
- Documentation is almost non-existant, looks like reserver for advanced programmers.
Zend Framework
Zend Framework is an attempt by Zend itself to create THE way of using PHP. It is a really good project and we are using parts of it extensively. It is PHP5+ only, encourages good programming practices (including testing), have a nice set of classes. It somehow tries to fix the lowish quality of PEAR packages. But:
- It is late. Too late.
- Most parts on the Zend Framework should be coded in fast C modules, not in PHP itself. Try the performance of date/time/calendar operations and you will see what I mean.
- ZF tries to fix broken features and add new ones to PHP, but they are often sub-optimal.
Share nothing
The point I made about writing large constructs in PHP itself is very important. PHP is a "share-nothing" type of solution, every web request is handled separately and after it the PHP engine is reset into the default state. All the classes need to be re-loaded and initialized with every single web request! The larger your codebase libraries are, the less performance you get.
The share-nothing architecture has some benefits: you do not need to care about freeing system resources, returning db connections to the pool etc. PHP does it for you, because once the request is processed, all resources are properly closed and released.
Garbage collection
PHP does not resolve circular references when performing its simple reference counting and copy-on-write garbage collection. Several times I had to rewrite the code because the garbage collector was unable to properly release memory from database model objects.
Web-only
Poor garbage collection also prevents any long-running programs to be written in PHP. Every program I have written in PHP that was running longer than a few days ended up by using all its available memory and crashing eventually.
In fact PHP has been designed only to handle web requests. ONLY. It is quite good at it, but at nothing else. You will not write a FUSE project with PHP,daemon, mail server, irc server, ANYTHING persistent.
PHP is not a standalone platform. Many projects combine PHP with Java, so that PHP handles web + logics and Java fits where persistance is required.
There are a lot of other problems I see with PHP: missing namespace support, no real unicode (try strlen('ąśćŁ'), debugging etc.
I am really looking forward to PHP alternatives. Java is IMHO out-of-question, but Python and Ruby are tempting solutions that eventually I might migrate to.
rating: 0, tags: dev php programming
I wanted to write such a blog post too.
I would say one more thing about exceptions and errors.
Fatal Errors cannot be mapped to Exceptions, but can be made quiet, which totally sucks if SOME of code call a function (using @) that produce a Fatal Error. This way you have something like exit() in the middle of code with absolutely NO output and NO Exception raised.
This SUCKS as hell.
Piotr Gabryjeluk
visit my blog
I have done 4 years of PHP programming when it was still at version 3, I just gave up PHP for Python, seeing the OO aspect as well as the better understandability of the code.
Exactly. Am I am myself tired of waiting for long-promised namespaces in PHP 5.3.
Python is great. In fact for me the only problem with Python is that there is Ruby, which is imho more elegant. And they both try to target exactly the same area, are VERY similar to each other.
Python has more mature libraries (some of), Ruby is more web-oriented… They are both great and truly OO.
Michał Frąckowiak @ Wikidot Inc.
Visit my blog at michalf.me
I just want to point out here that chances are it's not Ruby that's "more web-oriented", but a framework you're looking at that is Ruby backed(probably Rails).
Learn the difference between Ruby and Rails.
Saying Ruby is web oriented is as stupid as saying PHP is a functional language.
Even mb_strlen does not work really cool (and you need mbstring PHP extension):
It's worth noting, that PHP extensions are mostly written in C. And they have to "loaded" to PHP server-side. Most Python libraries are written in Python, so if not installed system-wide you just copy a bunch of files into your project and that's it: you're using some library.
(In Python 3, there is nice thing of loading C version of Python modules if available with fallback to Python one. This means, you can use Python version of libraries and when you need more power, you even don't need to change import module to import cModule in your code. All you need to do is install a C-version of a module. This is nice as well :).
Piotr Gabryjeluk
visit my blog
PHP is NOT Functional. It's a procedural language. Functional languages inlcude LISP… or XSLT or anything on the kind.
But obviously I know what you mean. PHP sucks. Go python :) Go django :)
The mark of of a PHP programmer is ignorance. Learn a little about the functional paradigm(hint: php is not functional, it is procedural) and you might take a few steps towards being a real programmer.