使用构造

时间:2018-04-27 19:12:31

标签: php arrays oop object constructor

更新:

我正在尝试理解面向对象的PHP。

假设我在我的代码的最顶部用其他数组和函数(修饰符)定义我的变量:

 class Shipments {

        public $clean_key = [];
}

我正试图以这种方式在我的公共数组中推送一个数组:

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));
            }
        }

然后我用这种方式在另一个函数中调用它:

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']);
        }
    }

我的数组看起来像这样:

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"]=>
}

如果我在我的代码之后立即转储我的数组,我就会得到我正在寻找的东西。问题是,如果我出于某种原因尝试从任何其他实例访问该数组,我无法访问我的公共数组,例如:

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

它返回一个未定义的变量:clean_key。

我不明白为什么。变量应该是全局的(在这种情况下是数组)加上我使用__construct所以我应该可以在我的代码中到处访问函数。

更新:$ clean_key返回null,$ this-&gt; clean_key返回类似的arry:

array(0) {
}

2 个答案:

答案 0 :(得分:1)

我看到了这个

的几个问题
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']);
        }
    }
}
  • 首先$clean_key是一个局部变量,其范围仅存在于方法中,以访问您必须使用的$clean_key属性$this->clean_key
  • 第二个$this->access_key未被提及作为属性,但它被列为一种方法,您无法将方法设置为相等。您可以拥有与方法同名的属性,但在我的意见中这是一个不好的做法,因为它可能会导致混淆。

我不知道这些是否只是问题中的拼写错误,但我不得不提及它们。

就此而言

  

问题是,如果我尝试从任何其他实例访问该数组

这是预期的行为,因为(非静态)属性的范围仅存在于您创建的类的实例中。

您可以将此属性设置为静态,并且可以从同一个请求(PHP实例)中的任何实例访问它。但是,当您必须动态设置静态通常不是最好的方法时,因为您必须确保在使用它之前设置它,并且它可能被另一个实例更改并在当前实例中产生意外结果。

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

要在类的另一个方法中访问它,你必须使用self::$clean_keystatic::$clean_key,通常self会正常工作,除非你创建这个类固有的子类,然后你可能会需要late static binding又名static

这是一个快速示例,显示两者之间的区别:

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();

输出

Self: test
Static: new 

在线测试

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

正如您所看到的那样,在使用self进行调用时,self一次static调用同一方法,它只提前绑定,仅限p类了解它自己的方法。当它迟到时,它知道类c及其方法。 c类扩展了p类,并替换了对输出有影响的方法之一。因此,如果没有使用后期静态绑定的调用,我们可能会从父类中获得意外结果,因为人们会期望该方法被子类覆盖。这就是为什么我说它在扩展课程时主要有影响。

希望有所帮助,因为它可能是一个非常令人困惑的概念。

关于公共财产的说明(免责声明,这是我的意见)

我避免使用类的公共属性,因为它不是S.O.L.I.D。基本上可能发生的事情是你可以更改属性的名称或删除它等等。现在因为它可以在外部访问,你必须搜索所有代码来重构这个变化。访问类外的方法更清晰,因为它们的内部实现对外部代码不重要(也不应该)。您可以重构一个方法的内容,只要参数和返回值不会改变太多,您就不必触及类外的任何其他代码。

所以不要做这样的事情:

class foo{
    public $bar;
}

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

我更喜欢这样做:

class foo{
    protected $bar;
}

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

请参阅因为课程内部我们可以重新定义getBar我们想要的所有内容,但如果我们对$foo->bar进行任何更改,则会中断。

现在在某些情况下,这是非常好的,例如一个充当数据存储等的类。它只是需要注意的东西,而且它通常是气馁的。它还有助于public, protected, private的内容更有意义。

  • public =在课堂外以及所有扩展课程的孩子中都可以访问
  • protected =仅在课程和任何扩展课程的孩子中可以访问
  • private =只能在班级中访问

答案 1 :(得分:0)

access_key()方法没有理由告诉您clean_key变量未定义。见下文:

<?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();

产生

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

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

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