59

In PHP, can I specify an interface to have fields, or are PHP interfaces limited to functions?

<?php
interface IFoo
{
    public $field;
    public function DoSomething();
    public function DoSomethingElse();
}
?>

If not, I realize I can expose a getter as a function in the interface:

public GetField();
2
  • Warning: if you get a down vote for asking this don't be suprised - check the OOP section of the PHP manual. Commented Feb 12, 2010 at 11:55
  • 4
    Yeah, a quick scan of the manual showed them only using functions in interfaces. May have just skipped over that part. In either event, I just wanted to be sure. Commented Feb 12, 2010 at 12:16

5 Answers 5

63

You cannot specify members before PHP 8.4.0. You'd have to indicate their presence through getters and setters, just like you did. However, you can specify constants:

interface IFoo
{
    const foo = 'bar';    
    public function DoSomething();
}

As of PHP 8.4.0, interfaces may also declare properties. If they do, the declaration must specify if the property is to be readable, writeable, or both. The interface declaration applies only to public read and write access:

interface I
{
    // An implementing class MUST have a publicly-readable property,
    // but whether or not it's publicly settable is unrestricted.
    public string $readable { get; }

    // An implementing class MUST have a publicly-writeable property,
    // but whether or not it's publicly readable is unrestricted.
    public string $writeable { set; }

    // An implementing class MUST have a property that is both publicly
    // readable and publicly writeable.
    public string $both { get; set; }
}

See http://www.php.net/manual/en/language.oop5.interfaces.php for more details

Sign up to request clarification or add additional context in comments.

1 Comment

28

Late answer, but to get the functionality wanted here, you might want to consider an abstract class containing your fields. The abstract class would look like this:

abstract class Foo
{
    public $member;
}

While you could still have the interface:

interface IFoo
{
    public function someFunction();
}

Then you have your child class like this:

class bar extends Foo implements IFoo
{
    public function __construct($memberValue = "")
    {
        // Set the value of the member from the abstract class
        $this->member = $memberValue;
    }

    public function someFunction()
    {
        // Echo the member from the abstract class
        echo $this->member;
    }
}

There's an alternative solution for those still curious and interested. :)

6 Comments

I'm curious and interested. How to guarantee member's presence? :)
Class Foo should implement interface 'IFoo', it is abstract and it would clearly show Foo purpose: to simplyfy interface implementation.
Agreed, @PeterM. The abstract class might as well implement the interface instead of the final class. Depending on whether you always want to be forced to implement someFunction().
As an update from the future; further segmenting the implementation into traits -- such that the abstract class implements the interface purely using traits and is otherwise empty -- allows you to prune child classes.
I believe this is the only correct answer for such question. Because Interface is not basically designed to do what is asked for. Here there is a more simple example for better understandings: php.net/manual/en/language.oop5.abstract.php#95404
|
23

Use getter setter. But this might be tedious to implement many getters and setters in many classes, and it clutter class code. And you repeat yourself!

As of PHP 5.4 you can use traits to provide fields and methods to classes, ie:

interface IFoo
{
    public function DoSomething();
    public function DoSomethingElse();
    public function setField($value);
    public function getField();
}

trait WithField
{
    private $_field;
    public function setField($value)
    {
        $this->_field = $value;
    }
    public function getField()
    {
        return $this->field;
    }
}

class Bar implements IFoo
{
    use WithField;

    public function DoSomething()
    {
        echo $this->getField();
    }
    public function DoSomethingElse()
    {
        echo $this->setField('blah');
    }
}

This is specially usefull if you have to inherit from some base class and need to implement some interface.

class CooCoo extends Bird implements IFoo
{
    use WithField;

    public function DoSomething()
    {
        echo $this->getField();
    }
    public function DoSomethingElse()
    {
        echo $this->setField('blah');
    }
}

2 Comments

But with abstract class you can inherit only from this class. With traits and interfaces you have sort of multi inheritance. Ill add it to answer.
15

Interfaces are only designed to support methods.

This is because interfaces exist to provide a public API that can then be accessed by other objects.

Publicly accessible properties would actually violate encapsulation of data within the class that implements the interface.

Comments

6

You cannot specify properties in an interface : only methods are allowed (and make sense, as the goal of an interface is to specify an API)


In PHP, trying to define properties in an interface should raise a Fatal Error : this portion of code :

interface A {
  public $test;
}

Will give you :

Fatal error: Interfaces may not include member variables in...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.