2009-04-24 15 views

risposta

48

Se si utilizza PHP5 (e si dovrebbe essere), dare un'occhiata alle classi SPL ArrayObject. La documentazione non è troppo buona, ma penso che se estendessi ArrayObject, avresti la tua matrice "finta".

EDIT: Ecco il mio rapido esempio; Tuttavia, temo di non avere un valido caso d'uso:

class a extends ArrayObject { 
    public function offsetSet($i, $v) { 
     echo 'appending ' . $v; 
     parent::offsetSet($i, $v); 
    } 
} 

$a = new a; 
$a[] = 1; 
+4

Non solo una risposta utile, ma la risposta giusta. Io uso sempre gli ArrayObjects, ed è un modo elegante non solo sostituire gli array, ma estendere l'intero modello-oggetto e far scattare a PHP un calcio serio. – AlexanderJohannesen

+11

Non è una risposta utile o la risposta giusta. La domanda riguarda l'overloading dell'operatore, non se esiste o meno una libreria con un oggetto chiamato ArrayObject. – fijiaaron

+55

-1 Utilizzare l'interfaccia ArrayAccess. Non estendere ArrayObject.Tu stai ereditando molte logiche di cui probabilmente non hai bisogno e inoltre l'estensione di ArrayObject è imprevedibile in molti aspetti, perché c'è così tanta magia coinvolta. – NikiC

19

Il concetto di PHP di sovraccarico e operatori (vedere Overloading e Array Operators) non è come il concetto di C++. Non credo sia possibile sovraccaricare operatori come +, -, [], ecc

Possibili soluzioni

+1

Meglio l'Iterator è lo SPL ArrayObject, che ho collegato al di sotto. Fornisce l'intera gamma di funzionalità di array. – cbeer

2

Sembra non essere una funzionalità della lingua, vedere questo bug. Tuttavia, sembra che ci sia un package che ti permette di fare una sorta di sovraccarico.

+0

Guardando il pacchetto, sembra non essere compatibile con qualsiasi php> 5.5, e non è stato aggiornato dal 2013 – Benubird

0

In parole semplici, no; e suggerirei che se pensate di aver bisogno di un sovraccarico in stile C++, potrebbe essere necessario ripensare la soluzione al vostro problema. O forse considera di non usare PHP.

Per parafrasare Jamie Zawinski, "Hai un problema e pensa, 'Lo so! Userò l'overloading dell'operatore!' Ora hai due problemi. "

+4

-1 la risposta è semplicemente errata, poiché è possibile sovraccaricare l'operatore []. Inoltre, è probabile che @Chad non stia cercando di risolvere un problema con l'overloading dell'operatore, ma mantenendo il suo codice pulito e conciso. – Josiah

+1

Ecco perché ho detto "Metti semplicemente, no" piuttosto che "No". Non volevo spiegare che lo fai estendendo alcune classi in modi strani, perché 1) l'overloading dell'operatore è un'idea abbastanza cattiva anche quando la sintassi per farlo è pulita, e 2) la sintassi per farlo in PHP non è non pulito – dirtside

+4

Hai bisogno di ripensare il mio design? Quindi, se voglio fare aritmetica complessa o aritmetica data estesa, devo usare le chiamate di funzione anziché gli operatori? Che schifo. –

22

In realtà, la soluzione ottimale è quella di implementare i quattro metodi dell'interfaccia ArrayAccess: http://php.net/manual/en/class.arrayaccess.php

Se volete anche di utilizzare l'oggetto nel contesto di 'foreach', che avrebbe dovuto attuare la interfaccia 'Iterator': http://www.php.net/manual/en/class.iterator.php

+1

+1. Per implementare l'interfaccia ArrayAccess è l'UNICA risposta valida al problema dell'OP. Tutti gli altri sono non ottimali. – hijarian

8

per una soluzione semplice e pulita in PHP 5.0 +, è necessario implementa il ArrayAccess interface e sovrascrivere le funzioni offsetGet, offsetSet, offsetExists e offsetUnset. Ora puoi usare l'oggetto come un array.

Esempio:

<?php 
class A implements ArrayAccess { 
    private $data = array(); 

    public function offsetGet($offset) { 
     return isset($this->data[$offset]) ? $this->data[$offset] : null; 
    } 

    public function offsetSet($offset, $value) { 
     if ($offset === null) { 
      $this->data[] = $value; 
     } else { 
      $this->data[$offset] = $value; 
     } 
    } 

    public function offsetExists($offset) { 
     return isset($this->data[$offset]); 
    } 

    public function offsetUnset($offset) { 
     unset($this->data[$offset]); 
    } 
} 

$obj = new A; 
$obj[] = 'a'; 
$obj['k'] = 'b'; 
echo $obj[0], $obj['k']; // print "ab" 
+1

Questa è la migliore (la più accurata) risposta in merito alla domanda OP. Se vuoi semplicemente usare l'operatore '[]' sul tuo oggetto, l'implementazione dell'interfaccia 'ArrayAccess' è la strada da percorrere. –

Problemi correlati