PHP, Groovy and language evolution

I’ve been using PHP since early 1996, back in the PHP/FI days.  I’ve used it steadily over the years, sometimes full time and sometimes part time, but that’s been pretty much a primary language for me for 12 years now.  During that time I’ve seen a lot of language changes, some for better and some not so much.

I remember when PHP5 first came out having ‘discussions’ with a number of people who insisted that PHP5 was way better than 4.  I still couldn’t see too many things that PHP5 made possible that were not possible in PHP4.  Streams made some data processing nicer, and interfaces made it easier to code which was a bit more self-explanatory.  Basically, intentions were made clearer with things like “public protected private” (PPP), but I have not yet seen any web project get done faster or dare I say even much *better* due to those sorts of things.

PPP stuff can make sense if you’re going to be distributing code to others.  For example, if you have sensitive properties that might break your code if futzed with.  However, the majority of code written is inhouse, and to be used by people who have access to the code and can make changes to visibility properties anyway.  Your code won’t break if I change your ‘private’ or ‘protected’ to ‘public.  But keeping some of your properties as ‘private’ can make life more difficult for people who have to live with your code later (AKA me!).  I had Smarty break on me because I dared to put {$comment->postedDate} in a template, instead of {$comment->getPostedDate()}.

Smarty breaking basically means white screens, so after a few minutes of tracking down the error, I found out the original author had made all the properties private and made get/set methods for them.  This was not code meant for others, nor documented in any other way.  IDEs certainly can’t deal with these sorts of things very well, and there’s no way an IDE will ever be able to give me ‘code complete’ in a Smarty template for potentially random variables passed in.

During all this, I couldn’t help but think the original developer probably thought they were “doing the right thing” or being “object oriented” by taking the “private and use get/set methods” approach.

I’m not all doom and gloom, or 100% negative on PHP5.  Native JSON and better XML support (DOM and SOAP, for instance) *are* examples of things I saw as genuine improvements in the language.    Those sorts of improvements remain true to PHP’s original foundation of being a language focused on the web space.  Striving for more “OOness” in PHP feels like it’s trying to become more of a general purpose language like Java, but going about it rather clumsily.

This isn’t specifically saying PPP is necessarily bad, but that PHP could have addressed the issue in a fashion more suitable to dynamic languages.  Keep reading for an example.

Over the last year or so I’ve been spending more time in the Groovy/Grails world as well as PHP.  I’m not a Java person by trade, and more than a few people have asked ‘coming from PHP, why not go right to Ruby for dynamic stuff?’.  There’s a few reasons for my interest in Groovy.  First off, I had great intros to the technologies by Jason Rudolph and Scott Davis at our local Java user group last year which definitely sparked some interest then and there.  Additionally, GORM and Grail’s ‘domain first’ approach to application development feel more natural to me than other technologies.  I’m by no means a master of these technologies, but I’m learning more as I go along.

Groovy is a dynamic language built with inspiration from Smalltalk, Ruby, LISP and other languages.  It compiles down to Java code, and co-exists with Java beautifully.  It seems to exist largly by and for Java developers trying to achieve more rapid development without sacrificing their Java investment.

One of the key things that Groovy does is ignore PPP notations.   By default you do not need to indicate any visibility for class properties – simply give a type.

class foo {

String name

Date createDate

}

etc.  By default, all properties are private, but respond to dynamically created get and set methods.  In the example above, getName() and getCreateDate() would automatically be generated in to Java byte code for you (as well as setName and setCreateDate()).  You can override these if need be, but the defaults are pretty sane.  Rather than forcing the developer to write (or an IDE to generate) get/set methods for every property, the compiler handles access control under the hood with consistent default behaviour.

PHP could pretty easily implement something like this, and it would be a great productivity boost for people that need to refactor code to implement new features.  Rather than having to go through existing code and change *every* instance of $foo->bar to $foo->getBar(), just write your own getBar() method in the main class, which would override the default behaviour.  Same thing could be done for setting values too.

Thinking about this closer, I’m seeing Java developers *migrating away* from PPP in an effort to be more (dare I say?) agile.  Perhaps agile isn’t the right word – productive is probably more accurate.  Groovy also does away with the static typing requirement – just declare something as ‘def’ and run with it.

Said another way, people who’ve had some of the constructs (“high ceremony” as Stu from Relevance might say) for years are actively looking to get rid of them and move to something more productive.

Contrast this with where many PHP developers’ heads are at, with wanting more type hinting in their method signatures, embracing PPP all over the place, and trying to adopt what they see as ‘best practices’ from other languages.  At the same time, developers from other languages are having second thoughts about the necessity of some of their dogma, and are looking at dynamic languages like Ruby for inspiration.   Sadly, most don’t look to PHP for inspiration, but I think working in PHP, and thinking dynamically, can be a great advantage if dealt with properly.

Is this just a case of ‘the grass is always greener on the other side’?  What do you think?


I'm currently working on a book for web freelancers, covering everything you need to know to get started or just get better. Want to stay updated? Sign up for my mailing list to get updates when the book is ready to be released!

Web Developer Freelancing Handbook

Share and Enjoy:
  • del.icio.us
  • DZone
  • Facebook
  • Reddit
  • StumbleUpon
  • Digg
  • Simpy
  • Technorati

Tags: , , , , , , , , , , , , ,

{ 19 comments to read ... please submit one more! }

  1. Though it’s not there by default, PHP 5 did give us a way to accomplish this particular task: __call. It’s next to trivial to write this method into a class such that any call to get*() returns the corresponding property value if it exists, and it can be easily overridden by adding an actual get method for that property. I can agree to a certain extent that it might be nice to see this implicitly compiled into opcodes, though.

  2. I think you missed a little on the improvements PHP5 offers over PHP4:
    1. The static keyword was introduced in PHP5, allowing for static variables which are very useful (also class constants were introduced, helping a lot with avoiding globals).
    2. Autoloading was introduced in PHP5 (__autoload()) which is a big help in larger projects with tons of includes.
    3. The visibility keywords are more than just convenience. They define the implemented interface to your class, allowing you to have tons of small protected methods doing things behind the screens without polluting the class namespace (especially for auto-completing IDE’s).
    4. Several magic methods that ease OO all around. Such as __get(), __set(), __call(), __toString() among others.
    5. Object in PHP5 are passed by reference by default, which was very important for performance and scalibility.
    6. Reflection API
    7. MySQLi, PDO…
    8. And more

  3. I was wondering if I read wrong, and I still might have. In PHP5, you can play a lot of shortcut games with the magic object methods. In the case above, specifically __call(). It’s called when a method on an object does not exist, but external code called it anyway, so it’s a hook to dynamically interpreting virtual methods. Here’s what I typically have (from memory) somewhere where I want virtual getters for example.

    Hopefully the code survives submission…

    class Foo
    {

    protected $barString = 'Bar';

    public function __call($method, array )
    {
    if (preg_match("/^get([[:alpha:]]{2,})/", $method, $matches)) {
    $field = $matches[1];
    $field[0] = strtolower($field[0]);
    if (property_exists($this, $field)) {
    return $this->$field;
    }
    }
    }

    }

    $foo = new Foo;
    echo $foo->getBarString();

  4. Hey guys – good points.

    The ‘magic’ methods are, to me, hacks at best because it’s basically glorified error handling.

    Static variables are nice, granted.

    Autoloading – I’m mixed on this. Again, it sort of feels like error handling to me. When I’m looking at a class, I can’t be sure that things are definitely imported or not. I’ve had classes be in my Zend project, so IDE magic worked, but the same classes were not in the include_path, so things errored out. Explicit requiring feels more solid, but that’s just an opinion. For under the hood framework stuff, perhaps it has a place, but for ‘app’ code I prefer my classes to be more explicitly referenced. Maybe I’ll grow out of that? ;)

    Passing by reference by default – didn’t really affect me because I generally passed things by reference anyway even in PHP4. Perhaps there’s some optimizations under the hood that now make it faster in PHP5.

    Re: visibility PPP – if they’re so useful, why are JVM-based languages (Groovy’s the one I know) looking to make them optional? On projects I’ve been on, they’ve caused as many problems as they’ve solved. It’s always someone else who has better “cleaner” or “correct” code, and if only I’d see that code, I’d “see the light”. :)

    Thanks for the code example. That sort of stuff would be best baked in to the language, imo, rather than having to be implemented in userspace.

  5. I’ve always wondered what problem visibility is trying to solve. People aren’t any more likely to try to call non-public bits than they are to stick their fingers in an electric socket.

    Of course a class must have a clearly defined interface, and hence there must be some way to label public / not-public clearly, but the old standard using underscores seems like a simpler – and therefore better – alternative. Visibility doesn’t need to be enforced, just documented. The key argument for me is what failing unit test could be made to pass by making a public variable protected (or private)? (No cheating with a “testCannotAccessPrivatePropertyFoo”: unit tests make assertions about public behaviours not implementation details).

    A need for reflection is the only thing I can think of which might make a case for PPP. However, examples of code which needs to know about visibility are probably extremely rare.

    Private is just evil. Why would you want to make life difficult for someone who needs to extend a class in order to tweak the behaviour? You can’t predict in advance what an end user will need to do with your code. Maybe the little piece of logic which you were determined to keep under lock and key is the very thing they need to change. You just don’t know. (And they can still change it anyway: it just means more work).

    Programming is about expressing complex ideas in the simplest way possible. It’s important to eliminate all unnecessary clutter, polishing and honing until code is as clear as possible. Java-esque verbosity seems a bit pointless in php. Thankfully, it’s not compulsory.

  6. Well said Noel.

    The PPP stuff is useful to a compiler to catch some ‘violations’ before execution. In PHP we don’t have that step. Getting fatal errors for accessing something accidentally (dynamic property access) is difficult to deal with.

    Would some form of read-only and/or read-write property notations make sense as a PHP evolution?

  7. Michael Gauthier

    What ever happened to separation of interface from implementation? I think that is the important part of what PPP enables. With getter/setter methods, the implementation can change and the interface can remain the same. When you just access things through public properties, the interface is the implementation and you can’t improve the implementation without causing BC breaks.

    I think C# has a nice balance here with their notion of properties. They enable a interface similar to public properties but still allow separation of interface and implementation. That’s currently not possible in PHP without using getter/setter methods like Java.

    As for autoloading, I’ve contributed to a rather large package that uses explicit require statements throughout the code. It works well in our systems where we have defined the application environment, but other people are finding it difficult to use the package in separate environments (Symfony, Cake, etc) because their projects are structured differently. For this reason, the next major version of our package will use autoloading to enable greater portability.

  8. @michael – so in your next version, you’ll have to tell people to add paths to your libraries in to their include paths? Or give them the code to place in to their __autoload code that won’t break whatever autoloads they may already be doing as well as enable your code? Seems that the docs for how to integrate the code in to other systems could use some polishing, rather than relying on error handling (autoload). I’ve got a bad feeling that someone in a future version of PHP5 or PHP6 will decide they need autoloading to work differently, make that commit, and lots of sites will be forced to upgrade and break, or stay behind while that gets sorted out. It may sound paranoid, but given the history of PHP and the QA around the development process, that’s not a completely unlikely scenario.

  9. @michael – also, fwiw, I agree on the C# thing and had meant to add that to the original post. C#’s way, as well as Groovy’s, should be models for how PHP deals with PPP, not the original Java inspired way. Migrating to a Groovy-fied approach would allow backwards compatibility, but free people to lose the PPP ceremony and concentrate more on ‘real’ code.

  10. I look at PPP the same way I look at triggers within databases. If I have properties that need to be coordinated with other values stored in the object (alteration of one will change a stored tally or a complex calculation), then PPP lets me enforce the updating of dependent values immediately upon setting instead of having to initialize recalculation of the values before I call any of the values. Without private/protected, a bad value might sneak in from the outside world anywhere within the code. With enforced setters, it means that the calculated values within the object are always accurate instead of waiting to be updated/recalculated whenever any of them is called.

  11. Re: PPP, i think it depends whether you are talking about a simple “bean” class (in which case yeah, it’s probably overkill) vs. something more complicated. The people who complain about private variables are often the same ones who gripe about libraries that don’t work “as advertised”.

    I think PHP5 could do a lot worse than to emulate Java. Back in 2002 or whatever when they started working on PHP5, Java was the clear leader in OO, and PHP was getting slammed for its lack of OO support. You didn’t mention Exceptions, BTW, which IMO are a huge deal. However, they still really dropped the ball with PHP5 by not adding namespaces or unicode.

    Having said all this, I really don’t think the biggest problems in our industry have anything whatsoever to do with programming languages. Stupidity, greed, laziness, hubris… these are the real demons we have to fight.

    Thanks for the excellent post!

  12. Agreed that language isn’t necessarily the most important thing. Exceptions – ball was dropped here by exceptions being used inconsistently. Some functions return false, some throw exceptions, etc. Yes, there’s backwards compatibility to consider, but exception handling still feels very inconsistent.

  13. __autoload only reduces the flexibility PHP brings to the table when trying to merge two libraries.

    You only get ONE (1) __autoload function for any request.

    Your __autoload encapsulates your package’s notion of how to include classes… trying to merge in someone else’s ideas about how to include classes requires changing the function. This change now clashes with upgrades in either system.

    If you are trying to write a “re-usable” library, do not use __autoload, do not use set_include_path… simply define a constant such as

    define (MY_LIB, dirname(__FILE__))

    and require_once MY_LIB.’/foo.php’;

    If end users want to move pieces of your library all around, let them… it will break… but merging two __autoload behaviors will also break one of them.

  14. PHP 5.1.2 introduced spli_autoload

    http://dk2.php.net/manual/en/function.spl-autoload.php

    that lets you use multiple ‘entry’ points for a class-not-found exception

  15. spl-autoload seems like the “error handling for the error handling”, but lot better them not having it… and i use it a lot.

    and I think read-only / read-write access is the best way, really. PHP has it already on DOM* classes somehow. Something like chmod would make it nice ;)

  16. I think Python! :) Groovy is definitely cool, but it’s the stack in Java that’s such a problem for me, not the language itself. Not that Python is immune from stack decision paralysis, but I think it’s a simpler choice.

    For big projects, uniform error handling and packages are pretty important. PHP may soon have some half-baked namespace support, but the fact that a PHP fatal error is still going to be a blank white page (display_errors=Off of course) and a “200 OK” is completely unacceptable for multi-tier / distributed applications. It’s just a crappy language with a lot of following. It’s nice to have the flexibility to ignore the following — which I grant that not all jobs really allow. (e.g. people who need apps to run anywhere will probably stick with PHP for awhile)

    Hans

  17. hi :

    I have read your comment about ppp.

    I think those keywords has something to do with information hiding. but most people wrongly understanding about “information hiding”. so they think , just add private or protected keyword before a variable or function will protcted they software internal state will not be wrongly altered by external party.

    but actully ,”information hidding” means hidding your design decision, not just put a private keyword before a variable and use getter and setter to fetch/alter those variables.

    getter and setter is a bad design decision, better to avoid it.

    I think ppp is a greate improvement for php, that force you to considering about design of your application. and force external party stick to your design decision, but some time those design decision may cause problem or make external party not happy.

  18. Agustín Fernández

    The great advantage of using private (no so much protected) is that when you refactor the code you don’t need to check if it’s being used or not. You just know. I think that that’s very important, specially in php, where you don’t have any IDE to help you locate the uses. Other options like python’s obfuscated “private” methods or having the convention of always using an underscore to indicate privateness are of course ok, but it’s nice to be sure.

{ 1 Pingbacks/Trackbacks }

  1. O que é programação? | CrisDev - Cristian Medeiros

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">



0.25716280937195