December Code

PHP traits and interfaces interview questions, with answers

PHP has single inheritance, so a class extends at most one parent. Interfaces and traits fill the gap in two different ways: an interface is a contract a class promises to fulfil, and a trait is a bundle of methods copied into a class. Interviewers ask when to use each, how they differ from abstract classes, and how PHP resolves the method a class ends up with.

The answers below cover interfaces, abstract classes, traits, multiple interfaces, abstract trait methods, built-in interfaces and introspection, with code run on PHP 8.5. Then take the free PHP diagnostic — ten questions across every PHP topic in the bank — to see which of these you can explain but not yet predict.

The questions, with answers

  1. 1.What is an interface in PHP?

    In short: An interface lists public methods, and constants, that a class promises to provide; a class declares implements Interface and must define them all.

    An interface is a contract: it declares method signatures without bodies, and any class that implements it must define every one of them with compatible signatures, or the class fails to load. Code can then accept any object that implements the interface, such as a Shape, without caring which class it is, which is how PHP achieves polymorphism across unrelated classes. Interfaces can extend other interfaces and declare constants. Since PHP 8.4 they can also declare properties that implementing classes must provide.

    interface Shape {
        public function area();
    }
    class Sq implements Shape {
        function __construct(
            private float $s,
        ) {}
        public function area() {
            return $this->s ** 2;
        }
    }
    echo (new Sq(3))->area();
    // 9
  2. 2.What is the difference between an abstract class and an interface in PHP?

    In short: An abstract class can hold state and implemented methods alongside abstract ones, but a class extends only one; a class can implement many interfaces.

    An abstract class is a partial class: it can have properties, a constructor, fully implemented methods and abstract methods that subclasses must define, and it cannot be instantiated itself. Animal below implements hi in terms of the abstract cry, leaving each subclass to supply its sound. A class can extend only one abstract class. An interface has no state and, apart from constants, no implementation, but a class can implement any number of them. Use an abstract class to share code among closely related classes, and an interface to describe a capability that unrelated classes can have.

    abstract class Animal {
        abstract function cry();
        public function hi() {
            return "I say " .
                $this->cry();
        }
    }
    class Cat extends Animal {
        function cry() {
            return "meow";
        }
    }
    echo (new Cat)->hi();
    // I say meow
  3. 3.What are traits in PHP?

    In short: A trait is a reusable group of methods and properties that the use keyword copies into a class, giving code reuse without inheritance.

    Because a class can extend only one parent, PHP 5.4 added traits for sharing code horizontally. A trait declares methods and properties, and use TraitName inside a class copies them in, as if they had been written there; Order below gains stamp. Inside a trait method, $this is the using object, and static::class names the class that used it. A class can use several traits, and conflicts between them are resolved explicitly. Methods declared in the class override the trait's, and the trait's override methods inherited from a parent class.

    trait Stamps {
        public function stamp() {
            return static::class;
        }
    }
    class Order {
        use Stamps;
    }
    echo (new Order)->stamp();
    // Order
  4. 4.Can a PHP class implement more than one interface?

    In short: Yes: list them after implements, separated by commas; the class must then define every method of every interface.

    Single inheritance applies to classes, not interfaces: class File implements Readable, Writable promises both contracts, and the object passes an instanceof check for each. This is how PHP models objects with several independent capabilities, such as a class that is both Countable and IteratorAggregate. If two interfaces declare the same method, the signatures must be compatible, and one implementation satisfies both. An interface can also extend several other interfaces, combining them into a larger contract.

    interface Readable {}
    interface Writable {}
    class File implements
        Readable, Writable {}
    $f = new File();
    $ok = $f instanceof Writable;
    var_dump($ok);
    // bool(true)
  5. 5.Can a PHP trait declare abstract methods?

    In short: Yes: a trait can declare abstract methods that the using class must implement, which lets the trait's own methods rely on them.

    A trait often needs something from the class that uses it, such as a name or a repository. Declaring it as an abstract method, abstract function name(), makes that requirement explicit: the class must implement name, or it fails to load, and the trait's hi can call $this->name() safely. Traits can also have static methods and properties, and since PHP 8.2 constants. Since PHP 8.0 the using class's implementation must match the abstract signature exactly, which catches mistakes early.

    trait Greets {
        abstract function name();
        function hi() {
            $n = $this->name();
            return "hi $n";
        }
    }
    class Guest {
        use Greets;
        function name() {
            return "Ravi";
        }
    }
    echo (new Guest)->hi();
    // hi Ravi
  6. 6.What are PHP's built-in interfaces such as Countable and ArrayAccess?

    In short: Implementing interfaces such as Countable, ArrayAccess, IteratorAggregate or Stringable lets an object work with count(), [] access, foreach or string conversion.

    PHP defines interfaces that hook objects into language features. A class implementing Countable can be passed to count(), as Bag is below. ArrayAccess lets an object be read and written with square brackets, IteratorAggregate and Iterator let foreach loop over it, JsonSerializable controls json_encode output, and Stringable is implemented automatically by any class with __toString. Implementing them makes custom collections feel like built-in arrays. Each method must declare the return type the interface specifies, such as count(): int.

    class Bag implements
        Countable {
        private $a = [1, 2];
        function count(): int {
            return count($this->a);
        }
    }
    echo count(new Bag());
    // 2
  7. 7.How do you find out which interfaces and traits a PHP class uses?

    In short: class_implements returns the interfaces a class implements and class_uses the traits it uses; Reflection gives more detail.

    class_implements($classOrObject) returns an array of every interface a class implements, including those inherited from its parents. class_uses returns the traits used directly by that class, not those of its parents or of other traits, so a full list needs a loop over class_parents as well. For anything more, the Reflection API, through ReflectionClass, exposes interfaces, traits, methods, attributes and types. Frameworks use these to find classes that implement a contract, and tests use them to check that a class meets one.

    trait T {}
    interface I {}
    class C implements I {
        use T;
    }
    $i = class_implements("C");
    $t = class_uses("C");
    echo implode(",", $i), " ";
    echo implode(",", $t);
    // I T

How the diagnostic asks it

One question from the PHP bank, exactly as a sitting would show it. The bank has 3 on interfaces & traits and 30 across PHP.

Interfaces & Traits · mediumPHP-019

What does this PHP code print?

class Base {
    public function hi() { return "base"; }
}
trait Loud {
    public function hi() { return "trait"; }
}
class Kid extends Base {
    use Loud;
}
class Own extends Base {
    use Loud;
    public function hi() { return "own"; }
}
echo (new Kid)->hi(), " ", (new Own)->hi();
  1. 1base own
  2. 2trait trait
  3. 3trait owncorrect
  4. 4base base

PHP resolves a method name in a fixed order: a method declared in the class itself wins over one from a trait it uses, and a trait method wins over one inherited from the parent class. Kid uses Loud and declares no hi, so the trait's version overrides Base's: trait. Own declares its own hi, which overrides the trait's: own. base own assumes inheritance beats traits. trait trait assumes the trait beats the class's own method. base base ignores the trait entirely. Traits are copied into the class, which is why they sit between the class and its parent.

Measure it

Reading answers tells you what’s true. A diagnostic tells you what you get wrong.

10 PHP questions across its topics, easy to hard, about fifteen minutes. You get a readiness figure with the arithmetic shown, the topics you missed named, and a practice set sized for today. Free: 1 diagnostic a month and 15 problems a day. No card.

What the readiness test measures · how the score is computed

By Harshit · updated