2010-10-06 11 views
17

Estoy experimentando un comportamiento extraño con json_encode después de eliminar una clave de matriz numérica con unset. El siguiente código debería aclarar el problema. Me he encontrado que tanto desde la línea de comandos y como un mod Apache:PHP json_encode como objeto después de PHP array unset()

PHP versión Info:

C:\Users\usr\Desktop>php -v 
PHP 5.3.1 (cli) (built: Nov 20 2009 17:26:32) 
Copyright (c) 1997-2009 The PHP Group 
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies 

Código PHP

<?php 

$a = array(
    new stdclass, 
    new stdclass, 
    new stdclass 
); 
$a[0]->abc = '123'; 
$a[1]->jkl = '234'; 
$a[2]->nmo = '567'; 

printf("%s\n", json_encode($a)); 
unset($a[1]); 
printf("%s\n", json_encode($a)); 

salida Programa

C:\Users\usr\Desktop>php test.php 
[{"abc":"123"},{"jkl":"234"},{"nmo":"567"}] 
{"0":{"abc":"123"},"2":{"nmo":"567"}} 

Como puede ver, la primera vez que $a se convierte en JSON, se codifica como una matriz de JavaScript. La segunda vez (después de la llamada unset) $a se codifica como un objeto javascript. ¿Por qué es esto y cómo puedo prevenirlo?

+0

+1 porque es bueno ver una pregunta bien hecha. :) – Spudley

Respuesta

16

La razón de esto es que su matriz tiene un agujero en ella: tiene los índices 0 y 2, pero falla 1. JSON no puede codificar matrices con agujeros porque la sintaxis de la matriz no admite índices.

En su lugar, puede codificar array_values($a), que devolverá una matriz reindexada.

+0

Alternativamente, puede ordenar la matriz después de desarmar un elemento. – NullUserException

+0

@NullUserException Aunque eso tendrá el efecto secundario de, bueno, ordenar su matriz. – zneak

+0

Para aquellos que se preguntan sobre el comportamiento 'unset', vea el siguiente enlace y desplácese hacia abajo a" Funciones útiles ": http://us3.php.net/manual/en/language.types.array.php " The unset'() la función permite eliminar claves de una matriz. Tenga en cuenta que la matriz no se reindexará " – leepowers

5

Además de la técnica array_values es posible utilizar array_splice y quitar un elemento y re-índice en un solo paso:

unset($a[1]); 

lugar:

array_splice($a, 1, 1); 
+1

manera absolutamente perfecta para hacer el trabajo sin estropear la colección, ¡gracias! – CookieMonster

+1

Esto. La forma más elegante. – DQM

2

Try opción JSON_FORCE_OBJECT para utilizar json_encode, como: json_encode($a, JSON_FORCE_OBJECT), por lo que siempre tendrá el mismo resultado.