2010-10-15 21 views
8

Tengo esta API que requiere que tenga una clave de matriz específica para enviar. Como esa matriz debe usarse en TODOS los métodos de clase, estaba pensando en ponerla como propiedad de clase.¿Matriz como propiedad de la clase?

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

Más adelante, en los métodos de esta clase, voy a utilizar a continuación:

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

(Donde "acción" es la clave que hay que enviar a este API);

¿Esto está bien? No he visto suficiente OOP delante de mis ojos, es por eso que estoy preguntando esto.

a lo solicitado, es aquí más información sobre el 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; 
     } 
    } 
} 

Muchas gracias, MEM

+0

Bueno, no sé exactamente por qué necesita esta clave de matriz para existir, pero seguro, se ve perfectamente bien para mí – Hannes

+0

No hay suficiente información para decir si la propiedad '$ _myArray' es lo correcto. ¿Los datos almacenados en él deben persistir a través de llamadas al método 'something'? Cuéntanos más sobre la API que estás usando. – outis

+0

@outis - No estoy seguro acerca de la parte persistente. Esa propiedad se usa en todos los métodos, pero los valores de esa propiedad, hasta ahora al menos, no parecen pasar (el mismo valor) de un método a otro. (¿era esto lo que preguntas?) – MEM

Respuesta

7

Teoría

primer lugar, un poco de historia. Los objetos se componen de "estado" (fields-in PHP, estos usualmente se llaman "propiedades", pero voy a usar ese término de otra manera) y "behavior" (métodos). El estado es una parte importante de encapsulation: permite que los datos persistan mientras exista un objeto y permite que los datos sean visibles en múltiples funciones. Utiliza campos de objeto cuando necesita datos para tener estos dos atributos. Estos atributos son ejemplos de dos propiedades muy importantes: accesibilidad (similar a variable scope) y duración de almacenamiento. Las discusiones generalmente cubren el alcance y la duración de las variables (que asocian los nombres a los datos), pero aquí nos centraremos en los datos.

La accesibilidad determina cuándo y dónde se puede acceder a los datos, bueno, accediendo por código. Otros tipos de accesibilidad incluyen local (donde los datos son solo accesibles dentro de una sola función) y global (donde los datos son accesibles para todos los códigos en una unidad de código en cada llamada a función). Al igual que los datos globales, el estado es accesible para múltiples funciones, pero a diferencia de los datos globales, el mismo método accederá a diferentes datos cuando se invoque a diferentes objetos. Un ejemplo de un lenguaje hecho de que tanto confunde las variables & datos:

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 

Periodo de almacenamiento determina el tiempo que existen los datos (cuando se crea y se destruye). Los tipos de duración incluyen automatic (donde los datos existen hasta que la función que lo creó sale), static (los datos existen durante la vida del proceso) y dynamic (los datos se crean explícitamente y son destruidos o destruidos explícitamente por un recolector de basura cuando no más accesible). El estado comparte la duración con su objeto: si el objeto es automático, el estado es automático; si es dinámico, el estado es dinámico.

El estado no es la única forma de tener acceso a datos entre las llamadas a métodos. También puede pasar los datos como argumentos a los métodos, en cuyo caso los datos tienen una duración local. La diferencia entre el y es que para el estado, "entre" incluye los tiempos cuando no se está llamando a ningún método (es decir, en el call stack), mientras que el segundo no. El uso de estado o argumentos depende del tipo de duración que se requiera. Con los métodos públicos, tener demasiados argumentos reduce la legibilidad y puede causar errores (con una función de alto arity, es más fácil hacer un pedido incorrecto u olvidar por completo un argumento). Como una consideración secundaria, el estado puede ayudar a reducir la cantidad de argumentos.

Aplicación

De lo que has demostrado hasta el momento, los datos que está preguntando por no necesita ser accesible entre los métodos y no tiene por qué existir fuera de cada invocación de método. Los campos de publicación sobre los que pregunta son básicamente argumentos para un remote procedure call (RPC); Si permitiera construir estos argumentos invocando métodos, entonces tendría sentido almacenar los datos como estado del objeto. Tal como está, el almacenamiento de los campos de publicación como estado es válido, pero no como la mejor práctica. Tampoco es necesariamente la peor práctica. En el mejor de los casos, estás abarrotando el objeto y desperdiciando memoria manteniendo los datos a su alrededor cuando no están dentro de un método que usa la API. En el peor de los casos, estableces argumentos en un método que luego se pasan en el RPC cuando se invoca otro método.

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 

Esto es mucho algo que desea evitar. Se puede hacer fácilmente estableciendo la matriz de campos de publicación en una matriz vacía, pero en ese punto también podría usar una variable local en lugar de un campo.

Cuestiones relacionadas