dprlv04662 2018-04-27 19:12
浏览 44
已采纳

使用构造访问面向对象的php中的公共对象

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) {
}
  • 写回答

2条回答 默认 最新

  • dqd2800 2018-04-27 19:33
    关注

    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 S.O.L.I.D. 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
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥30 自适应 LMS 算法实现 FIR 最佳维纳滤波器matlab方案
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥15 Python3.5 相关代码写作
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动