Vigintas Labakojis
Vigintas Labakojis

Reputation: 1069

php - accessing constant through instantiated class in parent

Some code first...

FlashBagUtil class containing the constants:

class FlashBagUtil
{
    const TYPE_NOTICE  = 'notice';
    const TYPE_WARNING = 'warning';
    const TYPE_ALERT   = 'alert';
    const LANG_EN      = 'en';
    const LANG_RU      = 'ru';
    const LANG_IL      = 'il';
}

Parent class:

class CoreController
{
    public $flashUtil;

    public function __construct()
    {
        $this->flashUtil = new FlashBagUtil;
    }
}

Child class:

class BatchController extends CoreController
{
    public function indexAction()
    {
        // Method 1 - This works fine
        $flash     = $this->flashUtil;
        $flashType = $flash::TYPE_NOTICE;

        // Method 2 - This, obviously, does not
        $flashType = $this->flashUtil::TYPE_NOTICE;

        // Method 3 - Neither does this as $flashUtil is a non-static instantiated object
        $flashType = self::$flashUtil::TYPE_NOTICE;
    }
}

PHP documentation states: A property declared as static cannot be accessed with an instantiated class object (though a static method can).

But I seem to be able to do that with the first method. What am I missing?

+

Is Method 1 the only and cleanest way of accessing static content in this context?

Upvotes: 3

Views: 604

Answers (3)

Vigintas Labakojis
Vigintas Labakojis

Reputation: 1069

Making it an abstract class like suggested won't be much of help here, I think, as there are more things going on in FlashBagUtil class that I've removed for the example code.

My Method 1 works but requires making a copy of the original object which defies the purpose of a common inherited object. So...

In the end I've settled on a standard way to access static content directly by importing the namespace to child class and use $flashType = FlashBagUtil::TYPE_NOTICE as suggested by Ralphael. Would've been nice to access the constants from the object in a one liner, but this keeps static content nicely separated as well.

Full child class:

use TreasureForge\CoreBundle\Util\FlashBagUtil;

class BatchController extends CoreController
{
    public function indexAction()
    {
        $flash = FlashBagUtil::TYPE_NOTICE;
    }
}

Many thanks for your input.

Upvotes: 0

Leo Bedrosian
Leo Bedrosian

Reputation: 3799

You're referencing a class constant, which is different than a class variable (property) and is accessible to instantiated objects. The documentation you're referencing refers to class variables defined with the static keyword (ie. private static $flashUtil;), which may be the source of your confusion if you're accustomed to programming in other more strictly typed OOP languages.

Upvotes: 3

Raphael Müller
Raphael Müller

Reputation: 2200

if you want to use your class as enum, make the enumerationsclass abstract:

abstract FlashBagUtil
{
    const TYPE_NOTICE = 'notice';
    ...
}

and use it in your childclass:

class Controller
{
    private flashType = FlashBagUtil::TYPE_NOTICE;
}

Upvotes: 0

Related Questions