简体   繁体   中英

Access to a public object in object oriented php using a construct

UPDATE:

I'm trying to understand something about object-oriented PHP.

Let's say that I define my variable at the very top of my code with other arrays and functions (modifiers) like that:

 class Shipments {

        public $clean_key = [];
}

I'm trying to push an array inside my public array in this way:

class Shipments {

    public function __construct($settings = array())
        {
            $use_access_key = $this->access_key();
            $this->ee       = ee();
            $this->settings = $settings;
            $sql = ee()->db->select('*')->from('exp_extensions')->where('class', __CLASS__)->get();
            foreach ($sql->result() as $row) {
                 array_push($this->clean_key, unserialize($row->settings));
            }
        }

Then I call it in another function in this way:

public function access_key()
{
    echo "<pre>";
    var_dump($this->clean_key);
        die();
    if (isset($clean_key['mode']) && $clean_key['mode'] == "0") {
        if (isset($clean_key['access_key_test'])) {
            $this->access_key = array($clean_key['access_key_test']);

        }
    } elseif (isset($clean_key['mode']) && $clean_key['mode'] == "1") {
        if (isset($clean_key['access_key_production'])) {
            $this->access_key = array($clean_key['access_key_production']);
        }
    }

My array looks like that:

array(2) {
  [0]=>
  array(27) {
    ["access_key_test"]=>
    string(22) "blabla11"
    ["access_key_production"]=>
    string(0) ""
    ["mode"]=>
    string(1) "0"
    ["ExpeditedParcel"]=>
    string(1) "1"
    ["ExpeditedParceldrop"]=>
}

If I dump my array right after my code I obtain what I'm looking for. The problem is that, if I try to access the array from any other instance for some reason, I can't have access to my public array for example:

public function access_key()
    {
        var_dump($this->clean_key);
            die();
}

It Wil return an Undefined variable: clean_key.

I don't understand why. The variable should be global (the array in this case) plus I'm using a __construct so I supposed to have access to the function everywhere in my code.

UPDATE: $clean_key returns null and $this->clean_key returns an arry like that:

array(0) {
}

I see several issues with this

public function access_key()
{

    if (isset($clean_key['mode']) && $clean_key['mode'] == "0") {
        if (isset($clean_key['access_key_test'])) {
            $this->access_key = array($clean_key['access_key_test']);

        }
    } elseif (isset($clean_key['mode']) && $clean_key['mode'] == "1") {
        if (isset($clean_key['access_key_production'])) {
            $this->access_key = array($clean_key['access_key_production']);
        }
    }
}
  • First of all $clean_key is a local variable who's scope only lives within the method, to access the property $clean_key you have to use $this->clean_key
  • Second $this->access_key is not mentioned as a property, but it is listed as a method and you can't set a method to equal something. You can have properties with the same name as a method, but in my Opinion that is a bad practice as it can cause confusion.

I don't know if these are just typos in the question, but I had to mention them.

As far as this goes

The problem is that, if I try to access the array from any other instance

That is the expected behavior, because the scope of a (non-static) property only lives within the instance of the class you created.

You can make this property static and it will be accessible from any instance within the same Request ( PHP Instance). However, when you have to dynamically set things static is usually not the best way to go, because you will have to make sure it was set before you use it and it could be changed by another instance and produce unexpected results in the current instance.

class Shipments {
    public static $clean_key = [];
}

And to access it inside another method of the class you have to use either self::$clean_key or static::$clean_key , generally self will work fine unless you are creating children classes that inherent from this class, then you might need late static binding aka static .

Here is a quick example to show the difference between the two:

class p{
     public function test(){
          return "test";
     }

     public function foo(){
         echo "Self: ".self::test() . PHP_EOL;
         echo "Static: ".static::test() . PHP_EOL;

     }
}

class c extends p{
     public function test(){
          return "new";
     }
}

$C = new c();
$C->foo();

Outputs

Self: test
Static: new 

Test it online

http://sandbox.onlinephpfunctions.com/code/268e95a28663f4e8d6172cb513a8b3cf1ad5d929

As you can see the same method is called, one time with self one time with static when calling with self, it's bound early and the class p only knows about it's own methods. When bound late it knows about the class c and it's methods. The c class extends the p class and replaces one of the methods that have an impact on the output. So without the call using late static binding we may get unexpected results from the parent class, because one would expect the method to get overwritten by the child class. This is why I said it mainly has an impact when extending the class.

Hope that helps as it can be a very confusing concept.

A note about public properties (disclaimer this is my opinion)

I avoid using public properties of a class as it isn't very SOLID . Essentially what can happen is you can change the name of a property or remove it etc. And now because it's accessible externally you would have to search through all your code to refactor for that change. Accessing methods outside the class are cleaner because their internal implementation isn't (nor should it be) important to the outside code. You could refactor the guts of a method and as long as the arguments and return values don't change to much you wouldn't have to touch any other code outside the class.

So instead of doing something like this:

class foo{
    public $bar;
}

$foo = new foo();
echo $foo->bar;

I prefer doing it this way:

class foo{
    protected $bar;
}

$foo = new foo();
echo $foo->getBar();

See because internally in the class we can redefine getBar all we want, but if we make any change to $foo->bar it breaks.

Now in some cases this is perfectly fine, such as a class that acts as data storage etc.. it's just something to be aware of, and whey it's generally discouraged. It also helps the public, protected, private stuff make a bit more sense.

  • public = accessible outside the class and in all children that extend the class
  • protected = accessible only within the class and any children that extend the class
  • private = accessible only in the class

There is no reason for the access_key() method to tell you that the clean_key variable is undefined. See below:

<?php
class a{
    public $clean_key = [];

    public function __construct($settings)
    {
        echo "before push:<br>\r\n";
        var_dump($this->clean_key);

        array_push($this->clean_key, $settings);

        echo "after push:<br>\r\n";
        var_dump($this->clean_key);
    }

    public function access_key()
    {
        echo "access_key() method:\r\n";
        var_dump($this->clean_key);
    }
}

$a = new a('hey!');

$a->access_key();

produces:

before push:<br>
array(0) {
}

after push:<br>
array(1) {
  [0]=>
  string(4) "hey!"
}

access_key() method:
array(1) {
  [0]=>
  string(4) "hey!"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM