2010-10-15 17 views
8

Ho questa API che mi richiede di avere una specifica chiave di array da inviare. Dato che quell'array deve essere usato su TUTTI i metodi di classe, stavo pensando di metterlo come una proprietà di classe.Matrice come proprietà di classe?

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

Più tardi, sui metodi di questa classe, io poi usare:

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

(Dove "azione" è la chiave che deve essere inviato questa API);

Va bene? Non ho visto abbastanza OOP davanti ai miei occhi per questo lo sto chiedendo.

Come richiesto, qui è più informazioni sulle 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; 
     } 
    } 
} 

Grazie mille, MEM

+0

Beh, non so esattamente perché è necessario che questa chiave di array esista, ma sicuramente, mi sembra perfettamente a posto – Hannes

+0

Non ci sono abbastanza informazioni da dire se la proprietà '$ _myArray' è la cosa giusta da fare. I dati memorizzati in esso devono persistere attraverso chiamate di metodo 'qualcosa'? Dicci di più sull'API che stai utilizzando. – outis

+0

@outis - Non sono sicuro della parte persistente. Quella proprietà è usata su tutti i metodi, ma i valori di quella proprietà, almeno fino ad ora, non sembrano passare (lo stesso valore) da un metodo a un altro. (era questo quello che chiedevi?) – MEM

risposta

7

Teoria

primo luogo, un po 'di background. Gli oggetti sono composti da "stato" (campi in PHP, questi sono solitamente chiamati "proprietà", ma userò quel termine in un altro modo) e "comportamento" (metodi). Lo stato è una parte importante di encapsulation: consente ai dati di persistere fintanto che un oggetto esiste e consente la visualizzazione dei dati in più funzioni. Si utilizzano campi oggetto quando sono necessari dati per avere questi due attributi. Questi attributi sono esempi di due proprietà molto importanti: accessibilità (simile a variable scope) e durata di archiviazione. Le discussioni di solito coprono l'ambito e la durata delle variabili (che associano i nomi ai dati), ma qui ci concentreremo sui dati.

L'accessibilità determina quando e dove i dati possono essere, anche, accessibili tramite codice. Altri tipi di accessibilità includono locale (dove i dati sono accessibili solo all'interno di una singola funzione) e globale (dove i dati sono accessibili a tutti i codici di un'unità di codice in ogni chiamata di funzione). Come i dati globali, lo stato è accessibile a più funzioni, ma a differenza dei dati globali, lo stesso metodo accederà a dati diversi quando invocato su oggetti diversi. Un esempio in un linguaggio fatto che confonde un po 'le variabili di dati &:

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 

Durata di stoccaggio determina la durata dei medesimi dati (quando viene creato e distrutto). I tipi di durata includono automatic (dove i dati esistono finché la funzione che lo ha creato non è terminata), static (i dati esistono per la durata del processo) e dynamic (i dati vengono creati esplicitamente e distrutti o distrutti esplicitamente da un garbage collecter quando no più accessibile). Stato condivide la durata con il suo oggetto: se l'oggetto è automatico, lo stato è automatico; se dinamico, lo stato è dinamico.

Lo stato non è l'unico modo per accedere ai dati tra le chiamate di metodo. È anche possibile passare i dati come argomenti ai metodi, nel qual caso i dati hanno una durata locale. La differenza tra il to è quello per lo stato, "between" include le volte in cui non viene chiamato alcun metodo (ad esempio sul call stack), mentre il secondo no. Se utilizzare lo stato o gli argomenti dipende dal tipo di durata richiesta. Con metodi pubblici, avere troppi argomenti riduce la leggibilità e può causare bug (con una funzione di alto arity, è più facile ottenere l'ordine sbagliato o dimenticare completamente un argomento). Come considerazione secondaria, lo stato può aiutare a ridurre il numero di argomenti.

Applicazione

Da quello che hai mostrato finora, i dati che stai chiedendo non ha bisogno di essere accessibile tra i metodi e non ha bisogno di esistere al di fuori di ogni chiamata di metodo. I campi di posta che stai chiedendo sono fondamentalmente argomenti per un remote procedure call (RPC); Se dovessi consentire la creazione di questi argomenti invocando metodi, allora avrebbe senso memorizzare i dati come stato dell'oggetto. Così com'è, la memorizzazione dei campi di posta come stato è valida, ma non la migliore pratica. Inoltre, non è necessariamente la peggiore pratica. Caso migliore, stai ingombrando l'oggetto e sprecando memoria mantenendo i dati in giro quando non all'interno di un metodo che utilizza l'API. Nel peggiore dei casi, si impostano gli argomenti in un metodo che viene poi passato nell'RPC quando viene richiamato un altro metodo.

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 

Questo è qualcosa che si desidera evitare. Potrebbe facilmente essere fatto impostando la matrice dei campi di posta su una matrice vuota, ma a quel punto si potrebbe anche usare una variabile locale piuttosto che un campo.

Problemi correlati