Доступ к публичному объекту в объектно-ориентированном php с помощью конструкции - PullRequest
0 голосов
/ 27 апреля 2018

UPDATE:

Я пытаюсь понять кое-что об объектно-ориентированном 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 возвращает ноль, а $ this-> clean_key возвращает строку, подобную этой:

array(0) {
}

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Я вижу несколько проблем с этим

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
  • Second $this->access_key не упоминается как свойство, но оно перечислено как метод, и вы не можете установить метод равным чему-либо. У вас могут быть свойства с тем же именем, что и у метода, но, по моему мнению, это плохая практика, поскольку это может привести к путанице.

Я не знаю, являются ли это просто опечатками в вопросе, но я должен был упомянуть их.

Насколько это возможно

Проблема в том, что, если я пытаюсь получить доступ к массиву из любого другого экземпляра

Это ожидаемое поведение, поскольку область действия (нестатического) свойства живет только в экземпляре созданного вами класса.

Вы можете сделать это свойство статичным, и оно будет доступно из любого экземпляра в пределах одного и того же запроса (экземпляр PHP). Однако, когда вам нужно динамически устанавливать статические объекты, обычно это не лучший способ, потому что вы должны будете убедиться, что он был установлен, прежде чем использовать его, и он может быть изменен другим экземпляром и привести к неожиданным результатам в текущем экземпляре.

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

И чтобы получить доступ к нему внутри другого метода класса, вы должны использовать либо self::$clean_key, либо static::$clean_key, обычно self будет работать нормально, если вы не создаете дочерние классы, присущие этому классу, тогда вам может понадобиться поздняя статическая привязка aka 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, один раз с static при вызове с self, он связан рано, и класс 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 вещам иметь больше смысла.

  • общедоступный = доступный вне класса и для всех детей, которые расширяют класс
  • protected = доступно только внутри класса и всем детям, которые расширяют класс
  • личное = доступно только в классе
0 голосов
/ 27 апреля 2018

У метода 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!"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...