2013-07-24 13 views
10

Ho iniziato a scrivere una classe wrapper per un pacchetto php predefinito. Qui ci sono le classi:instanceof error in php wrapper class

class phpclass1 
    :: ping() 
    :: __construct(array $options) 
    :: clear() 
    :: addDoc(phpclass2 $string) 

... 

class phpclass2 
    :: __construct() 
    :: update() 
... 

ecco le classi wrapper che ho scritto per il sopra 2 classi:

class wrapper1 { 
    private $conn; 

    public function __construct(phpclass1 $object) { 
     $this->conn = $object; 
    } 

    public function add(wrapper2 $document) { 
     return $this->conn->addDoc($document); 
    } 
} 

class wrapper2 extends phpclass2 { 
    private $doc; 
    public function __construct() { 
     $this->doc = new phpclass2(); 
    }  
} 

Here's how I'm using them: 
$options = array (...); 
$object = new phpclass1($options); 
$conn = new wrapper1($object); 
$doc = new wrapper2(); 
.... 
.... 
$conn->add($doc); 

Tutto stava funzionando fino a quando ho usato la funzione add. Si dà un errore: Argument 1 passed to phpclass1::addDoc() must be an instance of phpclass2, instance of wrapper2 given

Cosa mi manca? Ho provato molte cose, ma completamente perso qui.

+8

L'argomento di 'phpclass1 :: addDoc()' è digitato come un 'phpclass2' e lo si passa' $ document', che è un 'wrapper2'. A meno che 'wrapper2' non estenda' phpclass2', il tipo hint fallirà. –

+0

@ Michael Berkowski: Ci ho provato, ma c'era qualche errore. (Immagino che il pacchetto php che sto usando non possa intrattenere tale duplicazione/clonazione di istanze). Quindi mi chiedevo se ci potesse essere un altro modo. – xan

+2

Avremmo bisogno di vedere quale sia l'errore. Finché non si tenta di sovrascrivere i metodi 'final' o' private', si dovrebbe essere in grado di estendere il salvataggio di classe per qualche caso potenzialmente esotico. –

risposta

2

Hai definito

class phpclass1 :: addDoc(phpclass2 $string) 

Questo metodo si aspetta l'argomento sia un oggetto di phpclass2, ma si sta passando

return $this->conn->addDoc($document); 

attraverso

$conn->add($doc); 

e $ doc è un oggetto di wrapper2 non phpclass2

Per fissare aggiungere un nuovo metodo pubblico

wrapper2::getDoc() 

public function add(wrapper2 $document) { 
    return $this->conn->addDoc($document->getDoc()); 
} 
+0

Lui è corretto, stai passando il tipo sbagliato, puoi anche risolverlo facendo' wrapper2' estendere 'phpclass2'. Vedi anche [Proxy Pattern] (http://www.mwop.net/blog/263-Proxies-in-PHP.html) – NDM

+0

@NickyDeMaeyer: Ho modificato il mio codice per estendere' la classe 'wrapper2' a 'phpclass2'. Ma, ancora dà un errore: 'phpclass1 :: addDoc(): wrapper2 non è valido. – xan

+0

Stai ancora passando l'oggetto sbagliato a $ this-> conn-> addDoc(). Stai passando un oggetto di wrapper2 invece se un oggetto di phpclass2. La soluzione con l'aggiunta di un nuovo metodo pubblico è così semplice, perché non la implementerai? –

0

tuo phpclass1::addDoc è di tipo accennato di prendere solo un oggetto di phpclass2. Il metodo wrapper1::add accetta un oggetto di tipo wrapper2 e quindi lo passa a phpclass1::addDoc In base alle classi questo non è coerente come wrapper2 non è un'istanza di phpclass2.

È necessario modificare la vostra typehint o consentire la classe wrapper2 per fornire l'oggetto phpclass2 che sta avvolgendo o estendere il wrapper2 in modo che sia un caso di phpclass2

+0

Ho modificato il mio codice per "estendere' la classe' wrapper2' a 'phpclass2'. Ma, ancora dà un errore: 'phpclass1 :: addDoc(): wrapper2 non è valido. – xan

2

IL PROBLEMA

Sei Digitare suggerendo un metodo wrapper1 per accettare il tipo di wrapper2 tutto bene. All'interno del metodo wrapper1 si dichiara

public function add(wrapper2 $document) { 
     return $this->conn->addDoc($document); 
    } 

dove $conn è definito come un'istanza phpclass1. Il problema si pone come la chiama

return $this->conn->addDoc($document); 

che è in attesa di un tipo di phpclass2 ma $ documento è in realtà un tipo di wrapper2 come lo prendiamo non è possibile modificare né phpclass1 O phpclass2 è necessario modificare le classi wrapper.

Le soluzioni

Soluzione 1

o cambiare wrapper2 to be

class wrapper2 { 
    private $doc; 
    public function __construct() { 
     $this->doc = new phpclass2(); 
    } 
    public function GetDoc() 
    { 
     return $this->doc; 
    } 
} 

e utilizzare i seguenti

$conn->add($doc->GetDoc()); 

Soluzione 2

modificare la firma di $ doc; all'interno di wrapper2 per public e utilizzare come segue

$conn->add($doc->doc); 

per ulteriori informazioni su typehinting in php uno sguardo alla pagina di documentazione per esso php type hinting

un'altra cosa da considerare è hai bisogno/voglia di digitare suggerire, non mettere un argomento per/contro come è già stato discusso a lungo, solo una domanda che potreste voler chiedere.

Se la risposta è sì, si consiglia di leggere il seguente link che parla di buoni modi e motivi per utilizzare il tipo che alludono

Spero che questo aiuta

+0

Grazie mille. Funziona, anche se genera un errore per 'destruct':' Warning: phpclass2 :: __ destruct(): ' – xan

+0

Su una nota completamente diversa, c'è un altro modo per implementare le classi wrapper? – xan

+0

a seconda delle tue opinioni su di essi potresti utilizzare le interfacce usate in combinazione con le tue classi wrapper, ma per quanto ne so io avrei fatto lo stesso di quello che hai fatto. Per quanto riguarda l'avviso di distruzione, qual è l'errore completo? –

0

Change public function add(wrapper2 $document) al public function add($document) il type hinting è il problema .