Home » Php » Naming of interfaces/abstract classes in PHP 5.3 (using namespaces)

Naming of interfaces/abstract classes in PHP 5.3 (using namespaces)

Posted by: admin November 29, 2017 Leave a comment

Questions:

Prior to PHP 5.3 I used to name interfaces/abstract classes like this:

abstract class Framework_Package_Subpackage_Abstract {}
Framework/Package/Subpackage/Abstract.php

interface Framework_Package_Subpackage_Interface {}
Framework/Package/Subpackage/Interface.php

Now with PHP 5.3 and using namespaces I can’t use my convention anymore, because interface and abstract are reserved keywords.

namespace Framework\Package\Subpackage;
abstract class Abstract {}
Framework/Package/Subpackage/Abstract.php

namespace Framework\Package\Subpackage;
interface Interface {}
Framework/Package/Subpackage/Interface.php

So, what should I name my classes/interfaces like?

Answers:

A current coding guide “PSR-2” basically suggests you drop the interface down one directory and combine the name.

eg:

File \Vendor\Foo\Interface.php ===> \Vendor\FooInterface.php.

and the use stament eg:

use \Vendor\Foo\Interface; ===> use\Vendor\FooInterface;

see: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md

Questions:
Answers:

About this question (Abstract and Interface), you might have a look at the post “Migrating OOP Libraries and Frameworks to PHP 5.3” on Matthew Weier O’Phinney’s blog — it’s about Zend Framework, and how they could solve that problem in 2.0.

One of the things they note is :

In other OOP languages, such as
Python, C#, interfaces are denoted by
prefixing the interface with a capital
‘I’; in the example above, we would
then have Zend::View::IView.

So, in your example, you would have something like this, I guess :

namespace Framework\Package\Subpackage;
abstract class ASubpackage {}
Framework/Package/Subpackage/ASubpackage.php

namespace Framework\Package\Subpackage;
interface ISubpackage {}
Framework/Package/Subpackage/ISubpackage.php

What do you think about that ?
(I have not tested this way, but it doesn’t look like a bad idea ? )

Questions:
Answers:

SubpackageAbstract,
SubpackageInterface

Questions:
Answers:

I personally would recommend avoiding any usage of Hungarian Notation, and consider following the Java standard for interface names; that is, they’re named descriptively just like any other class. See this SO question for a discussion of the ins and outs of Hungarian notation.

A good example of using generic, descriptive names indicative of functionality or behavior can be found in PHP’s own SPL, like: “Countable”, “Iterator”, “ArrayObject”.

Questions:
Answers:

Honestly, I believe the Hungarian notation was introduced with C#, because there is not “extends” and “implements” keyword like in Java. So to differentiate the convention became to call it IView. In Java, the interface would be called View alone, and implementations would be called DefaultViewImpl, SmartyViewImpl or something like that. Since, PHP does have extends and implements keywords, it makes sense to use the Java convention.
I have heard the argument that the Hungarian notation does lend it self to making the API elements identifiable just by looking at the class names. In that case I would call it either IView or AbstractView.

Questions:
Answers:

You could also do something like this:

src/Chess/Piece.php

<?php

namespace \Chess;

abstract class Piece implements \Chess\PieceInterface {}

src/Chess/PieceInterface.php:

<?php

namespace \Chess;

interface PieceInterface {}

src/Chess/Piece/Pawn.php:

<?php

namespace \Chess\Piece;

class Pawn extends \Chess\Piece {}

Here’s how I would setup autoloading in composer.json

{
    "autoload": {
        "psr-0": {
            "": "src/"
        }
    }
}

Questions:
Answers:

In my opinion, the best way to solve this, is by simply appending Class to your classnames.

namespace Framework\Package\Subpackage;
abstract class AbstractClass {}
Framework/Package/Subpackage/AbstractClass.php

namespace Framework\Package\Subpackage;
interface InterfaceClass {}
Framework/Package/Subpackage/InterfaceClass.php

note that this is still not perfect (however, works perfectly) but i keeps the code similar to the original idea 😉