Массив как свойство класса? - PullRequest
9 голосов
/ 15 октября 2010

У меня есть этот API, который требует, чтобы у меня был определенный ключ массива для отправки.Поскольку этот массив нужно использовать во ВСЕХ методах класса, я подумывал о том, чтобы поместить его в качестве свойства класса.

abstract class something {
    protected $_conexion;
    protected $_myArray = array();
}

Позже я расскажу о методах этого класса:

$this->_myArray["action"] = "somestring";

(где «действие» - это ключ, который необходимо отправить этому API);

Это нормально?Я не видел достаточно ООП перед моими глазами, поэтому я спрашиваю об этом.

В соответствии с просьбой, вот больше информации об API:

class Apiconnect {
    const URL = 'https://someurl.com/api.php';
    const USERNAME = 'user';
    const PASSWORD = 'pass';

    /**
     *
     * @param <array> $postFields
     * @return SimpleXMLElement
     * @desc this connects but also sends and retrieves the information returned in XML
     */
    public function Apiconnect($postFields)
    {
        $postFields["username"] = self::USERNAME;
        $postFields["password"] = md5(self::PASSWORD);
        $postFields["responsetype"] = 'xml';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, self::URL);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 100);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
        $data = curl_exec($ch);
        curl_close($ch);

        $data = utf8_encode($data);
        $xml = new SimpleXMLElement($data);

        if($xml->result == "success")
        {
            return $xml;
        }
        else
        {  
            return $xml->message;
        }
    }

}


abstract class ApiSomething
{
    protected $_connection;
    protected $_postFields = array();

    /**
     * @desc - Composition.
     */
    public function __construct()
    {
        require_once("apiconnect.php");

        $this->_connection = new Apiconnect($this->_postFields);
    }

    public function getPaymentMethods()
    {
        //this is the necessary field that needs to be send. Containing the action that the API should perform.
        $this->_postFields["action"] = "dosomething";

        //not sure what to code here;

        if($apiReply->result == "success")
        {
            //works the returned XML
            foreach ($apiReply->paymentmethods->paymentmethod as $method)
            {
                $method['module'][] = $method->module;
                $method['nome'][] = $method->displayname;
            }

            return $method;
        } 
    }
}

Большое спасибо,MEM

1 Ответ

7 голосов
/ 16 октября 2010

Теория

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

Доступность определяет, когда и где данные могут быть доступны посредством кода. Другие типы доступности включают локальный (где данные доступны только в пределах одной функции) и глобальный (где данные доступны для всего кода в единице кода при каждом вызове функции). Как и глобальные данные, состояние доступно для нескольких функций, но в отличие от глобальных данных, один и тот же метод будет обращаться к разным данным при вызове для разных объектов. Пример на выдуманном языке, который несколько смешивает переменные и данные:

i=0
inc() {...}
dec() {...}
class C {
  i=0
  inc() {...}
  dec() {...}
}


a = C()
b = C()

inc() // the global i is visible in both these calls, 
dec() // which access the same data

a.inc() // C::i is visible in both C::inc and C::dec,
b.dec() // but these calls access different data

i    // The global i is accessible here
// C::i not accessible

Срок хранения определяет, как долго существуют данные (когда они создаются и уничтожаются). Типы длительности включают автоматический (где данные существуют до тех пор, пока не завершится созданная ими функция), статический (данные существуют в течение всего жизненного цикла процесса) и динамический (данные создаются явно и либо уничтожаются, либо уничтожаются сборщиком мусора, когда он более недоступен). Состояние делит продолжительность со своим объектом: если объект автоматический, состояние автоматическое; если динамический, состояние является динамическим.

Состояние - не единственный способ получения данных между вызовами методов. Вы также можете передать данные в качестве аргументов в методы, в этом случае данные имеют локальную продолжительность. Разница между to и заключается в том, что для состояния «before» включает в себя случаи, когда метод не вызывается (т.е. в стеке вызовов ), а последний - нет. Использование состояния или аргументов зависит от того, какой тип длительности требуется. При использовании открытых методов слишком большое количество аргументов снижает удобочитаемость и может привести к ошибкам (при функции с высокой arity проще ошибиться в порядке или полностью забыть аргумент). В качестве вторичного соображения состояние может помочь уменьшить количество аргументов.

Применение

Из того, что вы уже показали, данные, о которых вы спрашиваете, не должны быть доступны между методами и не должны существовать вне каждого вызова метода. Поля сообщения, о которых вы спрашиваете, в основном являются аргументами для удаленного вызова процедуры (RPC); Если бы вы позволили создать эти аргументы, вызывая методы, то имело бы смысл сохранить данные как состояние объекта. Как таковое, сохранение полей сообщения как состояния допустимо, но не является наилучшей практикой. Это также не обязательно худшая практика. В лучшем случае вы загромождаете объект и тратите впустую память, сохраняя данные, когда не находитесь внутри метода, использующего API. В худшем случае вы устанавливаете аргументы в одном методе, которые затем передаются в RPC при вызове другого метода.

abstract class ApiSomething {
    public function eatSaltyPork() {
        $this->_postFields["action"] = __FUNCTION__;
        $this->_postFields['spices[]'] = 'salt';
        $result = $this->_connection->Apiconnect($this->_postFields);
        ...
    }
    public function eachCheese() {
        $this->_postFields["action"] = __FUNCTION__;
        $result = $this->_connection->Apiconnect($this->_postFields);
        ...
    }
}


$thing = new ApiSomething();
$thing->eatSaltyPork();
$thing->eatCheese(); // ends up eating salty cheese

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...