5 things that PHP envies Java for
PHP and Java have somewhat different models of execution, contrapposing shared-nothing processes to resident JVMs. But they have also many similarities, like their object-oriented model.
I've seen many programmers starting to think that Java is old and verbose, and trying to jump on the bandwagon of scripting languages such as PHP and Ruby. But it's not so simple, as these languages are late to the party in many areas. Here are the 5 things that as a PHP programmer I started envy Java for.
Hibernate
PHP models, the M of the overly famous MVC paradigm, are still tied to the databases they use for persistence. It was common, in the first generation of PHP frameworks and ORMs, to only work with Active Records inside of controllers. Even association entities (classes like UserGroup, or ArticleCategory), which exist only for the purpose of mirroring a database table, were spreaded over PHP applications codebases.
The situation has widely improved now: Doctrine 2, which borrows an Api from Hibernate, is catching up. It hides the association tables and the unnecessary association directions for example, simplifying PHP classes where it counts. Impressively, it is the first PHP ORM that does not force your entities to extend a base class.
But we're still runners-up: for example, Doctrine 2 lacks support for mapping of Value Objects in the current version. Doctrine 2 entities are not really tied to database, but the relational model the mapping produces is just a mirror of the object model.
At least, we have now the abstraction of an in-memory Domain Model to work on. Another example of what we do not envy anymore is the PreparedStatement class. Once upon a time we worked with mysql_query() and SQL composed by concatenation, but now we have PDO. PDO is an equivalent of JDBC, with a common Api for each database vendor.
Generics
PHP envies a bit Java generics, but it works very well anyway as a dynamic language.
Anytime we manipulate an array with PHP, we forgot any type checking on keys and values. It's simply an array: it may have 4 MyClass objects and then the 5 is a string.
Java has generics, but often this type system gets in the way: you may want to pass around simply arrays or a DTO-like data structure in a "generic" layer like the application or presentation one, and you're forced to do casts. Where we would need generics, we just omit strict type checking:
<?php
function printList(array $listOfObjects)
{
foreach ($listOfObjects as $object) {
// $object could be anything, and getName() may not exist on it. It can even be TRUE or 0
echo (string) $object->getName(), "\n";
}
}
It's not really an issue, and in dynamic languages there is usually no type checking anyway. But, every once in a while, $object will be NULL and the script will die emitting a Fatal Error.
Keeping objects in memory between requests
Keeping objects in memory is easy in Java, although both in PHP and Java session variables are serialized, you can keep objects from the database in memory as long as they are out of Servlets, even between HTTP requests (feel free to add a comment on this.)
For example, Roman Borschel (who started Doctrine 2) said he harmlessly keep an EntityManager (Facade of Hibernate) open between requests, only to commit a permanent modification to the database on the last HTTP request. That's a bit out of the stateless paradigm of HTTP, but it is definitely handy when you have an action comsisting of multiple steps and requests.
Java Collection Framework
We need a Set, a List, a Map. I can't tell you how many times I have wrapped an array() in a class.
The associative array, the bread and butter (and glue) of PHP code, is kind of a Map but allows only scalar for keys. The same array construct is also a List when used with numerical keys, but without a contains() method, or any method at all since it is not an object. There is no equivalent of Set built into the language.
Doctrine2, our leader orm, even gets to provide a Collection class by itself in the Doctrine\Common package.
Asynchronous processing
Let's say you want to execute an action, like a heavy UPDATE query on the database, at 14:00 every day. In PHP, we need cron, an external program, to tell us to start that task at the right time. Due to the popularity of shared hosting, where programmer do not have access to the shared crontab, workaround were invented like Poormanscron, which checks at every request if it's the right time to do some work.
Asynchronous processing is simply outside of the picture of PHP, although there are some that use PHP without terminating scripts, like PHP-GTK. But on a website,your PHP script will be executed only if someone calls them, being it a browser or cron.
Conclusions
The resident Java processes are a real advantage in some use cases, although the shared-nothing model is very easy and cheap to run, solving many complications. Some other issues with PHP are due to its late arrival on the object-oriented paradigm.
In the next article, we will look at what Java envies PHP instead. I'm sure some of you will say nothing, but I hope to convince you that on the contrary, PHP is easier to use in many scenarios that runs from development and testing to deployment.






Comments
Stefan Koopmanschap replied on Thu, 2011/01/20 - 9:28am
I don't fully agree with your statement. PHP does not need to envy Java for some things. It just works differently, and that's fine.
Generics, for instance: if you're a good developer, you still typecheck what you're calling the method on. If you don't, that's asking for problems. Sure, that's different from how it works in Java, but I don't necessarily think it's a bad thing. It just means you have to be a good developer to do things well.
Java Collection Framework: OK, so PHP does not have that. Arrays are powerful in PHP. And if a library or application needs more (like Doctrine), they can provide it themselves. I don't see a reason to envy Java for having that.
Asynchronous Processing: Isn't that why Gearman, RabbitMQ et al are available? There is no need to do that in PHP. You can outsource that to a different process which can do any background processing. poormanscron is probably the worst solution for that.
You mention the popularity of shared hosts, but how many shared hosts support running Java on the serverside at all? Hardly any.
I usually enjoy your articles, but I think this is fairly poor in supporting the statements you make.
Manuel Jordan replied on Thu, 2011/01/20 - 9:56am
Gaylord Aulke replied on Thu, 2011/01/20 - 10:01am
Mark Unknown replied on Thu, 2011/01/20 - 10:14am
Let PHP be PHP. If you need the things you mentioned, use Java or something like it. Or like Stefan said, pass that work to another platform. I am sure there is use for PHP other than places where you need cheap hosting. But i have not seen it (for the things I do). The Java platform is much more than Java the language.
From my experience with cheap application hosting - you get what you pay for. But as always (ok not EVERYTHING), there are exceptions to the rules and sometimes you gotta pick the lessor of 2 evils.
Mario Tenc replied on Thu, 2011/01/20 - 10:36am
Well, I don't think so. That's all buona fine Java technologies, but PHP developers do not envy Java for that. And this is because hardly anyone knows them, and the use cases in midsize web applications are few.
What I see recently however, is superficial Java syntax duplication. PHP is unlike Java in that it is a hybrid language. Yet developers mimick cursorily Java idioms, foremost object happienes and shoehorning strict typing onto PHP. High-level features do not enter the picture in most development settings.
Christopher All... replied on Thu, 2011/01/20 - 10:42am
Doctrine is great for this, but also look at the Zend implementation. It isn't terribly different. Now, it takes a good deal more to create something to properly implement save, but the POJO objects can't save themselves either. Frankly, in that category, I think that the Django approach is actually the best. (something like model = Model(key="foo"); model.foo = "bar"; model.save();). I don't really want to have external classes that I need to set up and to get Hibernate working properly, I really should set up at least two and an interface (plus a map, either through annotations or through xml).
PHP generics:
Look up the SPL libraries, specifically the Iterator interface. It is TRIVIAL to make something which mimics generics and still functions as an array. Heck, in certain circumstances it is even faster to use Iterators (and it is more type-safe) than it is to use the base array.
Persistent objects:
My understanding is that PHP is better at serializing and deserializing than Java is and if you have a simple object, then it really isn't that costly to reinitialize it on the new request.
Java Collection Framework:
This premise is fundamentally false. Look up SplObjectStorage.
Asynchronous processing:
This is, I think, one of your better arguments, but it invalidates your other arguments. Most hosting companies which will allow you to control a Tomcat instance will also allow you to piggy-back crons or, like Hostgator, for instance, they will let you set up your own crons. But, if you're just doing maintenance, then you could easily implement a command line PHP script that uses sleep to handle something cron-like. It is arguably bloat to have the same application which is serving up web pages controlling the cron jobs anyway.
Frankly, I think that Java could learn a thing or two from the scripting languages, but that is a separate issue.
Rob Olmos replied on Thu, 2011/01/20 - 2:58pm
Gonzalo Ayuso replied on Thu, 2011/01/20 - 5:45pm
arjan tijms replied on Fri, 2011/01/21 - 8:08am
> You mention the popularity of shared hosts, but how many shared hosts support running Java on the serverside at all? Hardly any.
Google Application Engine? It's free too...
Giorgio Sironi replied on Sun, 2011/01/23 - 5:14am
in response to:
Stefan Koopmanschap
Giorgio Sironi replied on Sun, 2011/01/23 - 5:24am
in response to:
Gaylord Aulke
Giorgio Sironi replied on Sun, 2011/01/23 - 5:35am
in response to:
Rob Olmos
Josh Marotti replied on Mon, 2011/01/24 - 5:03pm