【问题标题】:Array as class property?数组作为类属性?
【发布时间】:2011-04-25 21:44:49
【问题描述】:

我有这个 API,需要我有一个特定的数组键才能发送。 由于该数组需要在所有类方法上使用,我正在考虑将其作为类属性。

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

稍后,关于这个类的方法,我将使用:

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

(其中“action”是需要发送到此 API 的密钥);

这样好吗?我没有在我眼前看到足够的 OOP,这就是我问这个的原因。

根据要求,这里是有关 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;
        } 
    }
}

非常感谢, 内存

【问题讨论】:

  • 嗯,我不知道你为什么需要这个数组键存在,但可以肯定的是,对我来说看起来非常好
  • 没有足够的信息来说明$_myArray 属性是否正确。存储在其中的数据是否需要在something 方法调用中持续存在?告诉我们有关您正在使用的 API 的更多信息。
  • @outis - 不确定持久部分。该属性用于所有方法,但该属性的值,至少到现在为止,似乎没有从一个方法传递(相同的值)到另一个方法。 (这是你要求的吗?)
  • 我认为这回答了我的问题。如果在一个方法调用中存储在数组中的任何数据在另一个调用中使用,则数据将需要持久化。另一方面,如果您可以在每个方法结束时清空数组并且程序仍然可以正确执行,则数据不需要持久化。你是说后者成立吗?
  • @outis - 它不会持续存在。 :( 所以我做得不好? - 我会告诉更多关于 API 的信息

标签: php arrays class properties


【解决方案1】:

理论

首先,一些背景知识。对象由“状态”(字段——在 PHP 中,这些通常称为“属性”,但我将以另一种方式使用该术语)和“行为”(方法)组成。状态是encapsulation 的重要组成部分:它允许数据在对象存在时一直存在,并让数据在多个函数中可见。当您需要数据具有这两个属性时,您可以使用对象字段。这些属性是两个非常重要的属性的示例:可访问性(类似于variable scope)和存储持续时间。讨论通常涉及变量(将名称与数据相关联)的范围和持续时间,但这里我们将重点关注数据。

可访问性决定了何时何地可以通过代码访问数据。其他类型的可访问性包括本地(其中数据只能在单个函数中访问)和全局(在每个函数调用中代码单元中的所有代码都可以访问数据)。和全局数据一样,状态可以被多个函数访问,但与全局数据不同的是,同一个方法在不同对象上调用时会访问不同的数据。一个在某种程度上混淆变量和数据的虚构语言示例:

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

存储持续时间决定了数据存在的时间(创建和销毁的时间)。持续时间的类型包括automatic(数据存在直到创建它的函数退出)、static(数据在进程的生命周期内存在)和dynamic(数据被显式创建并显式销毁或销毁当不再可访问时由垃圾收集器处理)。状态与其对象共享持续时间:如果对象是自动的,则状态是自动的;如果是动态的,则状态是动态的。

状态并不是在方法调用之间访问数据的唯一方法。您还可以将数据作为参数传递给方法,在这种情况下,数据具有本地持续时间。 to 之间的区别在于,对于 state,“between”包括没有调用任何方法的时间(即在 call stack 上),而后者没有。是否使用状态或参数取决于所需的持续时间类型。使用公共方法时,参数过多会降低可读性并可能导致错误(使用高 arity 的函数,更容易弄错顺序,或者完全忘记参数)。作为次要考虑,状态可以帮助减少参数的数量。

应用

从您目前所展示的内容来看,您所询问的数据不需要在方法之间可访问,也不需要存在于每个方法调用之外。您询问的帖子字段基本上是remote procedure call (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 数组设置为空数组来轻松完成,但此时您最好使用局部变量而不是字段。

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 2013-05-25
    • 2011-07-17
    • 1970-01-01
    • 2023-03-13
    • 2012-09-14
    相关资源
    最近更新 更多