Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Force a class to declare a property

Tags:

php

I have a set of classes which extend an abstract class. The abstract class contains methods that make use of late static bindings to get information which is defined in the child classes. So for example, the abstract class might have a method containing the line:

$var = static::$childVar . ' some text';

In this way, it is possible at runtime for the method defined in the abstract class to generate different strings based on the value of a variable defined in the child classes.

What I want to do is to have some mechanism that forces the child classes to declare this variable, eliminating the possibility of the method being called if the variable is not set.

Using interfaces, it is possible to require a class to define methods (and constants, which unfortunately cannot have their visibility modified using public/protected/private). So if a class implements an interface, but does not define all the methods specified in the interface, an error is generated. However, there is no way to use an interface to require a class to define a property.

I have seen some material which suggests using getter methods in the interface (e.g. getChildVar()) to implicitly require variable declaration, but this is not suitable for me as I don't want the variables to be accessible outside the class (they have protected visibility).

Similarly, constants will not work, because they do not support the protected visibility modifier.

I know I could always use an isset() statement to check for this in the method (or even in the constructor) of the abstract class, but this seems inelegant compared to the use of interfaces for ensuring methods are defined. I am wondering if there is some standard way of doing this without hardcoding the requirements in my abstract class.

Incidentally, if anyone knows why you can't declare variables inside interfaces, I'd be interested to know what the reasoning is. It seems like a major oversight to me.

Any help will be much appreciated.

like image 801
C106 Avatar asked Jan 17 '12 04:01

C106


People also ask

How define a class property in PHP?

Classes can have variables within it. Those variables are called properties. A property is a normal PHP variable which is in any data type (integer, string, array, object, etc). In classes, before declaring a variable, we should add the visibility keyword to define where the variable is available.

Which keyword makes it possible to use class members methods and properties without having a new instance of the class?

The static keyword defines a static method or property for a class. Static members (properties and methods) are called without instantiating their class and cannot be called through a class instance.

How do you declare and access properties of a class?

Note: A property declared without a Visibility modifier will be declared as public . Within class methods non-static properties may be accessed by using -> (Object Operator): $this->property (where property is the name of the property). Static properties are accessed by using the :: (Double Colon): self::$property .

How do you declare a variable inside a class in PHP?

The var keyword in PHP is used to declare a property or variable of class which is public by default. The var keyword is same as public when declaring variables or property of a class.


1 Answers

You can't enforce variables in an interface because an interface is a public representation of how to use your class. If I'm another developer jumping on board with your project, I want to be able to look at the interface and know all the methods I can assume are implemented in classes that, well, implement that interface. This isn't all that relevant for private or protected properties, or really any specific property for that matter. Getters/setters are the standard for that sort of thing.

The oversight right now is that you can't have a magic method for trying to access an undefined static property. That would be the ideal solution for you here.

If the static property is declared at runtime, why not enforce a setChildVar() method, or put a parent-class method that gets the late-static-bound property and throws an error if it isn't set? You could even implement a "driver" pattern to accomplish this:

<?php

class MyParentClass {

    public function __get($key)
    {
        if ( !isset(static::$$key))
        {
            throw new Exception('Child class '.get_called_class().' failed to define static '.$key.' property');
        }

        return static::$$key;
    }

    public function getText()
    {
        return $this->childVar . ' some text';
    }

}

class MyChildClass extends MyParentClass {

    protected static $childVar = 'some value:';

}

$a = new MyChildClass;
echo $a->getText(); // some value: some text
like image 58
landons Avatar answered Sep 30 '22 15:09

landons