test.ical.ly | getting the web by the balls

May/10

12

Why are interfaces widely ignored in the PHP world and what use do they have when working with symfony?

interfaceEvery once in a while I stumble upon interfaces or somebody mentions them to me. Whenever this happens I realise that the use of Interfaces as an OOP key feature in PHP is next to none at all. But why is that?

Try to google for “php interfaces” and you will get mostly three different kind of results.

  1. Links to the OO/interface section of the  PHP manual
  2. Links to website explaining how to use interfaces for dummies
  3. Links to discussions about the difference between interfaces and abstract classes

What you will rarely see is a link to an interface used in some project. Also if you grep the core of symfony you will find 9 Interfaces for Doctrine, 14 for phing, 11 for Propel and 44 for swiftmailer. symfony itself defines 4 interfaces only.

And symfony is no exception. While interfaces a very common in languages like Java they are almost not present throughout many PHP projects. But why?

What are interfaces?

The best description I could find so far is: An interface is a contract.

  • An interface defines public methods that a class needs to implement
  • An interface does not contain any code
  • A class can implement multiple interfaces
  • Interfaces can be used for type hinting

Basically if you see a class implementing an interface you know how to use it no matter how the implementation within the class is achieved.

What are abstract classes?

  • An abstract class can implement methods (code)
  • An abstract class can define abstract methods (no code)
  • An abstract class can not be instantiated
  • Classes can only inherit from one abstract class

And the difference is now what?

Abstract classes and interfaces are in some ways similar but they do each have their unique use cases.

The simplest rule is:

  • If you write an abstract class containing only abstract methods you use an abstract class as an interface.

On many sites discussion the differences you will find that the fact that many interfaces can be implemented but only one abstract class can be inherited from is the main distinction.

In my humble opinion that is not the case. I even think that classes implementing many interfaces are likely (not always) to be badly designed as many interfaces probably means many concerns within one class.

The main difference is that abstract classes already provide implementations of methods and interfaces do not.

This implies that there is a different concept behind both constructs.

Methods inherited from abstract classes imply that the shared implementation is common to all descending classes.

Methods defined in an interface imply that their implementation needs to be dedicated to the implementing class.

A simple example for an interface is sfLoggerInterface.

interface sfLoggerInterface
{
  /**
   * Logs a message.
   *
   * @param string $message   Message
   * @param string $priority  Message priority
   */
  public function log($message, $priority = null);
}

It defines only a single method log() and if you think about it you will realise that though the job if this method is the same no matter what the implementation is the details will be very different whether you log to a file, a database, syslog or somewhere else.

A simple example for an abstract class does not exist as abstract classes should always contain code. But a simple enough example is sfCache.

In sfCache you will find implementations of methods that are thought to be common throughout all cache classes. The effect of this is of course to avoid duplicate code.

It also defines a few abstract methods where the implementation will be uncommon.

Now you could argue to strip sfCache from all abstract methods and move them to an interface. But other than to server your academic motivation what benefit would it have? It would only create a new file that does not make sense on its own and so would increase the overall complexity.

See what the Java tutorials say about this.

Unlike interfaces, abstract classes can contain fields that are not static and final, and they can contain implemented methods. Such abstract classes are similar to interfaces, except that they provide a partial implementation, leaving it to subclasses to complete the implementation. If an abstract class contains only abstract method declarations, it should be declared as an interface instead.

Multiple interfaces can be implemented by classes anywhere in the class hierarchy, whether or not they are related to one another in any way. Think of Comparable or Cloneable, for example.

By comparison, abstract classes are most commonly subclassed to share pieces of implementation. A single abstract class is subclassed by similar classes that have a lot in common (the implemented parts of the abstract class), but also have some differences (the abstract methods).

(taken from java.sun.com)

As a rule of thumb you could define the following:

  • Use abstract classes to share function
  • Use interfaces to share usage

I guess one of the reasons why interfaces are not used very often by PHP developers is that in PHP you often start to code right away and you would start thinking sharing code later on when you have something to share. This way around you rarely consider contracts as the usage is already developed and negotiated. This can be considered bad practice of course and probably should be but it is my only explanation for the lack of interfaces out there.

How to handle interfaces if working with a framework?

Of course the use of interfaces and abstract classes when working within a framework are no different to the above. There are however things you should consider about when to use them.

Many developers especially in the Java world are used to design interfaces before the implementation. They build the contracts first and determine how the interaction of classes works before starting to code.

However in frameworks such as symfony a good deal of the coding is done via scaffolding and code generation. There is no point to define interfaces for generated code!

Take models for example no matter if generated by Propel or Doctrine, there is no need to write an interface defining all the getters and setters and such because the classes are not implemented against this interface. They are generated against their schema. The schema defines the interface.

Now of course you will add custom methods to the generated classes but will you really implement an interface on more than one class? If not what’s the point? And if isn’t the implementation of it the same for all classes?

In most cases I assume that you want to define a common behaviour for you models. You want them to share some methods and attributes. Now in Doctrine you should probably create a behaviour for this and specify it in the schema of your models. The code in the case would not be implemented (duplicated) nor would it be inherited instead it would be delegated. I’m not sure but there is probably a similar feature in Propel.

And always ask yourself if you really do share the usage across all classes that should implement your interface. Will you ever pass objects to a method that have a common interface but no common implementation (parent class) ?

There will be situations where all this is appropriate no doubt about it. But for the best part of your work you will deal with models, controllers and templates and the interaction is defined already by the framework..

· · · ·



  • Pingback: Tweets that mention • Why are interfaces widely ignored in the PHP world and what use do they have when working with symfony? | test.ical.ly -- Topsy.com

  • Gnarf

    PHP Interfaces are quite useless to define contracts because PHP is a loosely typed language. How dumb would be a contract where you cannot ensure what you’ll obtain contracting with the API.

    And don’t get me started on using phpdoc for that. Already saw things like @return null|boolean|int…

    PHP is not Java.

  • http://christof.damian.net/ Christof

    A lot of the current frameworks are also very tightly coupled. Sometimes all of the classes inherit from the same root class. This happens when you use abstract classes as interfaces.

    As we are moving to the second generation of frameworks (Symfony 2, Doctrine 2, ZF something) we will see a lot more interfaces being used to decouple the classes and make it possible to use and test the components independently.

    But @Gnarf is right too, without the use of type hinting and tightening of what your methods are expecting, interfaces and abstract classes are useless.

  • http://giorgiosironi.blogspot.com Giorgio Sironi

    We’re not so in a bad situation:

    @Gnarf: with the current implementation we have type hinting on parameters but not on return types. But in dynamic languages tests are the mean to assert these things, not compile-time checks. Due to the nature of the language, a check on the return value could only be done at runtime, so if you have a test that runs it you’re fine.

  • http://giorgiosironi.blogspot.com Giorgio Sironi

    Zend Framework 1.x trunk:
    [08:51:05][giorgio@Marty:~/svn/trunk]$ grep -r ‘^interface’ . | grep -v \.svn | wc
    187 408 20282
    187 interfaces…

  • http://www.leftontheweb.com/ skoop

    The thing is: in PHP there are very little standards. In Java (and some other languages) there are API standards that are upheld even throughout different projects offering the same functionality. The idea of this is that you could easily exchange one for the other. PHP frameworks, both full-stack and component frameworks, seem to be aiming to just be usable by itself. They don’t work on interoperability too much.

    This is changing. The new Framework Interoperability Group that is working on standards will hopefully work on things like this more and more. Their first focus is naming/autoloading, but hopefully after that they will also work on API standards, especially for the easy things like logging, caching etc, because those implementations are pretty common throughout every framework.

    Having said that, I think that if you look in codebases of bigger companies using PHP, you will (or at least should) encounter more interfaces, for the simple reason that they will guide developers new to certain APIs.

    I do agree, interfaces should be used more in the PHP world.

    I disagree with Gnarf that using contracts in PHP code is useless because of it’s loose typing: For *good* developers this should not matter. PHPDoc will help for sure, and also typehinting using interfacenames instead of classnames will help with ensuring a common API set is implemented for passed parameters.

  • http://ju-and-ulf-in-australia.ulf-kirsten.com/ Ulf

    I strongly believe that interface do make sense even in a loosely typed language like php. They define not only contracts between classes within one application they can also define contracts between two applications. Or they define what a class should be able to do. The ZF does make a heavy use of interfaces and they do make sense most of the time. I either use the concrete implementation of their interface or I wrote my own Adapter /WhatEver.

    @Gnarf
    Surely a method can return a boolean, int, double, Object and so one at the same time but it should not. I can also programm in PHP and note use objects at all or just write spaghetti-code. It is possible to do so, does not mean to do it that way – especially within PHP.

  • puch

    I don’t agree with the opinion that an Interface is useless in a loosy-typed language.
    It’s a good practice anyway to define contracts, because contracts are not always “language restrictions” but “conceptual agreements” to garantee the compatibility between pieces of sw.

    And I’m pretty sure that in the future is going to be useful: For instance, there will be tools to check type integrity before running applications. And you can always use Interfaces for “typed arguments” in methods. And you can already use interfaces and check them in your unit and functional tests.

    And, by the way, Symfony use interfaces, in fact, multiple interfacing (that, for me, it’s a good practice):

    “sfDoctrineManager” implements Iterator and Countable

  • http://test.ical.ly Christian

    @puch Let me clarify. I am not at all arguing against the use of interfaces. I was merely stating that they are not widely used in PHP. And I also pointed out that in my opinion interfaces for generated code are a waste of time.
    For everything that you are going to implement on your own and that you are going to need multiple implementations of interfaces make a lot sense.

  • http://munimkazia.com Munim

    I just don’t need the point of using interfaces anywhere.. as do most php developers. That is why they are so rarely used.

  • Les

    Interfaces are ignored because they are misunderstood in regards to PHP.

    Professionals use interfaces – they always take advantage of a language – so my opinion is that it is only those non professionals who fail to see the advantages.

    PHP is an easy language to pick up and learn and because of this so many non professionals – amateurs in other words (“would be developers”) – have no understanding and/or education regarding computer science – even on the most basic levels.

    The problem isn’t the language – but the people who are to ignorant – or stupid – to fully understand a technology.

  • Artem Nezvigin

    @Munim

    Here’s an example of when to use an interface. Let’s say you need to build a File Store. The sole purpose of the file store is… to store files :) When a user uploads an avatar, you want to store that. When a user attaches files to some record, you want to store files there.

    How would you create this? Here’s how you should (namespaces not included).

    Create an interface called FileStore_Service_Interface that forces implementation of the following method: get(), put(), pull(), delete()

    get($filePath) – Should return a URL to the file.
    put($filePath, $fileContents) – Should save the file into the filestore.
    pull($filePath) – Should return the file contents for the file.
    delete($filePath) – Deletes the file from the file store.

    As long as the a class implements the above interface, you can add CDN support to your application by simply flipping a switch.

    FileStore_Service_Local is the local file store class, it implements FileStore_Service_interface. You implement get(), put(), pull() and delete() to work the local file system and to create/read/delete files from a directory you set in configuration (ie: /path/to/your/app/public/files)

    FileStore_Service_Amazon is something you could implement later. It implements the same interface so none of your business logic will change. All that will change is files are now stored in the Amazon CDN instead of the local file store.

    So why not just create an abstract class? Because you may actually need an abstract class to implement some base functionality. For example, FileStore_Service_Amazon may use REST+HTTP to communicate with Amazon. You may implement another CDN that also uses REST+HTTP, so that’s where the abstract class comes in.

    FileStore_Service_Amazon extends FileStore_Service_HttpAbstract implements FileStore_Service_Interface

    And there you have it. They key is understanding that when you use an abstract class instead of an interface you are *defining implementation*, which is dangerous.

    The reason why PHP developers don’t use interfaces is that the projects they work on are small enough that it doesn’t matter. Going back 1 year later and modifying existing code is easier that building for flexibility on day 1. This does not hold true for larger web applications, however.

    This is why you typically see interfaces in large frameworks (like Zend Framework) and large web applications. Both of these heavily benefit from the flexibility up front.

  • http://test.ical.ly Christian

    @Artem Thank you, I’ve got nothing to add! :)

  • Pingback: Max’ Lesestoff zum Wochenende | PHP hates me - Der PHP Blog

  • Pingback: PHP: When to use an Interface

  • Pingback: Interfaces Make Testing Easier | BrandonSavage.net

  • Gnarf

    So let’s have a look at a basic Doctrine call, say

    /**
    * @return Doctrine_Collection|null
    */
    public function getPosts() {
    return $this->createQuery(‘p’)->where(‘p.is_published = 1′)->execute();
    }

    This will return a Doctrine_Collection or a null. PHP is full of that, because it’s loosely typed. If I had an interface specifying a getPosts() method (yeah that would be dumb), I just can ensure that some instance is able to get posts, but not if I will have a null or a collection of posts. so if I do:

    $array = Doctrine::getTable(‘Post’)->getPosts()->toArray()

    I will have a “fatal error” because I’m calling a ->toArray() method from a null. The good practice would be to use exception for that, but it’s even worse than interface in php: nonetheless people are rarely using them, but they’re using them mostly the very wrong way.

    So if even the best and/or most popular libs around are using this “feature” of php, interfaces make no sense. If you want to use interfaces, do Java. If you want to use the php language for what it provides, use it but don’t bother with trying to redo Java with it. Waste of time, and efficiency.

    Cheers

  • http://highgearmedia.com David Harkness

    @Gnarf – I don’t understand your point. Whether Doctrine_Collection is a class or interface matters not. If getPosts() can return null you must check the return value for null before making method calls on it.

    I myself find interfaces very useful when building systems that are designed to be extended. For example I recently built a spam detection module for our site using a naive Bayesian filter. The first algorithm I wrote to calculate the spamicity of a word was a mishmash of if checks for configuration parameters (min/max value, weight, default spamicity, whitespace characters, maximum word length, stop words, etc). As I added more features the code became needlessly complicated.

    I refactored it into several pieces (word extractor, filter, and calculator), and one was the WordCalculator interface with a single method “float calculate(string $word, int $spamCount, int $hamCount)”. To this I added an abstract class that allowed one WordCalculator to decorate (wrap) another. This allowed me to write one implementation for each feature: weighting, final spamicity allowed range, etc. Not only was it easier to understand the final system, but it was far easier to test it.

    When you work with patterns you’ll find that interfaces can be most useful. Obviously, generating code is not writing code to an interface so there’s no point there. If you don’t gain anything I see no reason to pay the cost of writing a separate interface. That your interface would change with the every schema change is a sure sign that there’s no real interface to be had anyway, no pre-designed behavior that you can implement multiple times.

    @Les – I hardly see the point of your invective comment. Claiming someone is ignorant or stupid simply because they don’t follow your preferred engineering methods doesn’t further the discussion, nor will it inspire them to seek more knowledge. I claim one can hardly be ignorant if they’ve taught themselves enough to build working software.

  • http://test.ical.ly Christian

    @David thanks for the example!

  • Pingback: Revue de presse Industrialisation PHP de la semaine 23 (2010) | Industrialisation PHP

  • http://chr.ishenry.com Chris Henry

    I think a lot of developers wound up working with PHP to avoid having to satisfy strict requirements. It can be quite liberating to not have write code just to satisfy a set of draconian requirements. Many, if not most, PHP projects wind up staying small enough that there is no need to assert a common set of functions that must exist.

    The projects named here that do use interfaces certainly make good use of them. I use Phing, have written extensions for it, and can see the need for it. However, I think the vast majority of PHP developers have no real need to ever write an interface.

  • g

    i fell little bit confused guys!

  • http://test.ical.ly Christian

    @g what about? maybe we can shed some light on it?

  • Dino

    In the java world, interfaces give you more flexibility in regards to polymorphism. It allows you to pass different objects from different hierarchies into a method.

    For example, if you had a frog which is an amphibian, and a dog which is a mammal, and you had a method called leap() that accepted a frog or a dog, how would you do it? It wouldn’t make sense to put the dog in the amphibian family nor would it make sense to put
    the frog in the mammal family and declare your method as leap(amphibian) or leap (mammal) respectively.

    Answer: You would have the frog and the dog implement the same interface Leapable and define your method as leap(Leapable) while still keeping both frog and dog in its rightful family. That’s just one of the tenets of OOP.

    However, since PHP is a loosely typed language, it doesn’t leverage interfaces to its full potential.

  • Pingback: • This was 2010 – test.ical.ly continues in 2011! | test.ical.ly

  • Riaan

    I don’t see programmers not using, knowing about or understanding certain parts of whatever language they work with, as ignorant. I suppose it is valid for some to say that they (including myself) are in a way ignorant, I just don’t feel ignorant and I am very very sure that there are some of us out there, in the world, that have used their language of choice in a manner which not even the creators of that language had ever expected their creation to be used in. Surely that doesn’t make them ( the fathers of the languages ) ignorant, does it?

    Anyhow, I had also never known about interfaces in php, or any other language for that matter, I have only ever really worked with php, until I had discovered it earlier while reading through the php.net on-line documentation. After reading this article and comments I’ve got a basic understanding of the idea of interfaces and I might be able to do with them, they make sense in as good a way as my mind can process at the moment and although I can’t see me going through the effort of using them in the type of projects that I’m usually occupied with, I also have a funny suspicion that I’ll give it serious consideration in the future.

    I don’t think you should, or it is even possible that you can, use all aspects of whatever language you program in in all the projects that you do, that would be rather silly, however I do think that it is generally a good idea to try and understand as much of the language as is possible so that when you do need some of the “unused” parts of it you will atleast know that you need it. So while being somewhat “ignorant,” as some calls it, is not that bad a thing I try to always look for things that I do not know and learn them but. In the same breath don’t just use something if it doesn’t fit into what you are doing, just for the sake of using it.

  • Pingback: Interface vs. Abstract class en PHP – castellano « Alessio Mavica

  • sander

    ty
    have been asking myself the same question for about year now. class should be somewhat mathematically described collection of functions and arguments. interface should be INTERFACE to use that class. but in php it’s not. as an c#(MS c++ and java) developer I see point of interfaces but in php i don’t. really, it seems that interface are there to satisfy software designer needs to write universal class diagrams? Not beeing sarcastic – standards of software coding are fine  opposite to standards of software development .    
    Still… seems that  in most cases a simple instance(singelton or not) is all it takes to write fully reusable code.

<<

>>

Theme Design by devolux.nh2.me