2009-04-24 11 views

Respuesta

48

Si está utilizando PHP5 (y debería hacerlo), eche un vistazo a las clases SPL ArrayObject. La documentación no es muy buena, pero creo que si extiendes ArrayObject, tendrías tu matriz "falsa".

EDITAR: Aquí está mi ejemplo rápido; Me temo que no tengo un caso de uso valiosa sin embargo:

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

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

No solo es una respuesta útil, sino la respuesta correcta. Yo uso ArrayObjects todo el tiempo, y es una forma elegante no solo de anular las matrices, sino de extender todo el modelo de objetos y hacer que PHP patee un trasero serio. – AlexanderJohannesen

+11

No es una respuesta útil o la respuesta correcta. La pregunta es sobre la sobrecarga del operador, no si existe o no una biblioteca con un objeto llamado ArrayObject. – fijiaaron

+55

-1 Usa la interfaz ArrayAccess. No extienda ArrayObject.Estás heredando mucha lógica que probablemente no necesites y, además, la extensión de ArrayObject es impredecible en muchos aspectos, porque hay tanta magia involucrada. – NikiC

19

El concepto de PHP de sobrecarga y operadores (ver Overloading, y Array Operators) no es como el concepto de C++. No creo que es posible sobrecargar operadores como +, -, [], etc.

Soluciones Posibles

+1

Mejor que el iterador es el SPL ArrayObject, que me he vinculado a continuación. Proporciona toda la gama de funcionalidad de matriz. – cbeer

2

Parece que no es una característica del idioma, consulte este bug. Sin embargo, parece que hay un package que le permite hacer algún tipo de sobrecarga.

+0

Al mirar el paquete, parece no ser compatible con ningún php> 5.5 y no se ha actualizado desde 2013 – Benubird

0

En pocas palabras, no; y sugeriría que si crees que necesitas una sobrecarga de estilo C++, es posible que necesites replantear la solución a tu problema. O tal vez considere no usar PHP.

Parafraseando a Jamie Zawinski, "Tienes un problema y piensas, '¡Lo sé! ¡Usaré la sobrecarga del operador!' Ahora tienes dos problemas ".

+4

-1 la respuesta es simplemente incorrecta, ya que es posible sobrecargar el operador []. Además, es probable que @Chad no esté tratando de resolver un problema con la sobrecarga del operador, pero manteniendo su código ordenado y conciso. – Josiah

+1

Es por eso que dije "Simplemente, no" en lugar de "No". No quería explicar que lo hicieras ampliando ciertas clases de maneras extrañas, porque 1) la sobrecarga del operador es una mala idea incluso cuando la sintaxis para hacerlo es limpia, y 2) la sintaxis para hacerlo en PHP no es suficiente. no limpio – dirtside

+4

¿Necesito repensar mi diseño? Entonces, si quiero hacer una aritmética compleja o aritmética extensa de fechas, ¿tengo que usar llamadas de función en lugar de operadores? Yuck. –

22

En realidad, la solución óptima es poner en práctica los cuatro métodos de la interfaz ArrayAccess: http://php.net/manual/en/class.arrayaccess.php

Si también desea utilizar el objeto en el contexto de la 'foreach', que tendría que poner en práctica el interfaz 'iterador': http://www.php.net/manual/en/class.iterator.php

+1

+1. Implementar la interfaz ArrayAccess es la ÚNICA respuesta válida al problema del OP. Todos los demás son subóptimos. – hijarian

8

para una solución simple y limpio en PHP 5.0 o superior, tiene que implementa el ArrayAccess interface y anular las funciones offsetGet, offsetSet, offsetExists y offsetUnset. Ahora puede usar el objeto como una matriz.

Ejemplo:

<?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

Esta es la mejor (más precisa) respuesta con respecto a la pregunta OP. Si simplemente desea utilizar el operador '[]' en su objeto, implementar la interfaz 'ArrayAccess' es el camino a seguir. –

Cuestiones relacionadas