1

I'm still new to OOP and this is probably a simple question, not sure if I'm overthinking this.

Let's say we have a simple class like the following that we can use to instantiate an object that can generate an array:

class gen_arr {

   public $arr = array();

   public function fill_arr() {
     $this->arr["key"] = "value";
   }

}

// instantiate object from gen_arr
$obj = new gen_arr();

Now if you wanted to get the value of the object's array's item, would you generate an array first and then echo the value like:

$arr = $obj->fill_arr();

echo $arr["key"];

Or would you access the object's property directly?

echo $obj->arr["key"]

In the actual code the property is private and there is a method that allows the viewing of the property array, the above is just to simplify the question.

Are there performance considerations and/or just best practices when it comes to this kind of case?

UPDATE:

It's still unclear from the answers if the best way is to generate an array from the property and access that array or just access the property directly (through the getter method)

4
  • What's the point of this class if the property is public anyway? Commented Aug 16, 2017 at 13:16
  • it will be private and there will be a getter method, i'm just showing it as an example. It's still unclear from the answers if the best way is to generate an array from the property and access that array or just access the property directly (through the getter method) Commented Aug 16, 2017 at 17:09
  • Well, what's the purpose? What do you want to achieve? What do you want to prevent? Commented Aug 16, 2017 at 18:31
  • i want to access the data inside the property, i just don't know if I should access it "directly" (through the getter method), or by generating an array from it first Commented Aug 16, 2017 at 23:06

3 Answers 3

2

Since you are filling the array with items only on fill_arr, those items wont be availabl until you call $arr = $obj->fill_arr();.

If you want to directly call the array, then you have to fill this array on the constructor function of this call like this:

class gen_arr {

   public $arr = array();

   function __construct() {
     $this->arr["key"] = "value";
   }

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

Comments

1

First off, the class you shared with us has a range of problems:

  • its sole instance property is public and can be modified by anyone
  • you have some temporal coupling, the method fill_arr() needs to be invoked before accessing the the value makes any sense

Encapsulation

Reduce the visibility of the instance property from public to private, so that the property can only be modified by the object itself, and provide an accessor instead:

class gen_arr
{
    private $arr;

    public function fill_arr() 
    {
        $this->arr["key"] = "value";
    }

    public function arr()
    {
        return $this->arr;
    }
}

Temporal Coupling

Remove the method fill_arr() and instead initialize the property $arr in one of the following options:

  • initialize field lazily when accessed the first time
  • initialize field in the constructor
  • initialize field with a default value
  • initialize field with a value injected via constructor

Initialize field lazily when accessed the first time

Initialize the field when it's accessed the first time:

class gen_arr
{
    private $arr;

    public function arr()
    {
        if (null === $this->arr) {
            $this->arr = [
                'key' => 'value',
            ];
        }

        return $this->arr;
    }
}

Initialize field in the constructor

Assign a value during construction:

class gen_arr
{
    private $arr;

    public function __construct()
    {
        $this->arr = [
            'key' => 'value',
        ];
    }

    public function arr()
    {
        return $this->arr;
    }
}

Initialize field with a default value

Assign a value to the field directly, which works fine if you don't need to do any computation:

class gen_arr
{
    private $arr = [
        'key' => 'value',
    ];

    public function arr()
    {
        return $this->arr;
    }
}

Initialize field with a value injected via constructor

If the values are not hard-coded or otherwise calculated (as in the previous examples), and you need to be able to instantiate objects with different values, inject values via constructor:

class gen_arr
{
    private $arr;

    public function __construct(array $arr)
    {
        $this->arr = $arr;
    }

    public function arr()
    {
        return $this->arr;
    }
}

Accessing and dereferencing values

This seems like this is your actual question, so the answer is - of course - It depends!.

Let's assume we have provided an accessor instead of accessing the otherwise public field directly:

Since PHP 5.4, the following is possible:

$object = new gen_arr();

echo $object->arr()['key'];

If you are still using an older version of PHP, you obviously can't do that and have to do something like this instead:

$object = new gen_arr();

$arr = $object->arr();

echo $arr['key'];

Largely, though, the answer to this question depends on the circumstances, and what you want to achieve. After all, readability is key for maintenance, so it might just make sense for you to introduce an explaining variable.

Note About your example, you could just use an ArrayObject instead:

$arr = new \ArrayObject([
    'key' => 'value',
]);

echo $arr['key']);

For reference, see:

For an example, see:

Comments

1

First fill up the array

$gen_arr = new gen_arr();
$gen_arr->fill_arr();

then get the values with a getter method

$val = $gen_arr->getValue($key);

A getter method would be like this

public function getValue($key) {
    return $this->arr[$key];
}

And certailny make the $arr property private

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.