PHP 8.0.15 Released!

Arrays

Um array no PHP é na verdade um mapa ordenado. Um mapa é um tipo que relaciona valores a chaves. Este tipo é otimizado para várias usos diferentes: ele pode ser tratado como um array, uma lista (vetor), hashtable (que é uma implementação de mapa), dicionário, coleção, pilha, fila e provavelmente mais. Assim como existe a possibilidade dos valores do array serem outros arrays, árvores e arrays multidimensionais.

A explicação dessas estruturas está além do escopo deste manual, mas pelo menos um exemplo é dado para cada uma delas. Para mais informações, busque a considerável literatura que existe sobre esse extenso tópico.

Sintaxe

Especificando com array()

Um array pode ser criado com o construtor de linguagem array(). Ele leva qualquer quantidade de pares separados por vírgula chave => valor como argumentos.

array(
    chave  => valor,
    chave2 => valor2,
    chave3 => valor3,
    ...
)

A vírgula após o último elemento do array é opcional e pode ser omitida. Isso geralmente é feito para arrays em uma única linha, por exemplo, array(1, 2) é preferível em vez de array(1, 2, ). Para arrays escritos em várias linhas, por outro lado, a vírgula à direita do último elemento é usada frequentemente, para permitir a adição de forma simples de novos elementos ao final.

Nota:

Existe uma sintaxe curta que substitui array() por [].

Exemplo #1 Um array simples

<?php
$array 
= array(
    
"foo" => "bar",
    
"bar" => "foo",
);

// Utilizando a sintaxe curta
$array = [
    
"foo" => "bar",
    
"bar" => "foo",
];
?>

A chave pode ser um int ou uma string. O valor pode ser de qualquer tipo.

Adicionalmente, as seguintes coerções ocorrerão a chave:

  • strings contendo quaisquer ints válidos, serão convertidos para o tipo int. Por exemplo, a chave"8" será, na verdade, armazenada como 8. Entretanto, "08" não será convertido, por não ser um inteiro decimal válido.
  • floats também são convertidos para ints, isso significa que a parte fracionária será removida. Por exemplo, a chave 8.7 será na verdade armazenada como 8.
  • bools são convertidos para ints, igualmente, por exemplo, a chave true, será na verdade armazenada como 1 e a chave false como 0.
  • null será convertido para uma string vazia, por exemplo, a chave null na verdade será armazenada como "".
  • arrays e objects não podem ser usados como chaves. Fazer isso resultará em um aviso: Illegal offset type.

Se vários elementos na declaração do array utilizam a mesma chave, apenas o último será utilizado, enquanto todos os outros serão sobrescritos.

Exemplo #2 Exemplo de conversão de tipo e sobrescrita

<?php
$array 
= array(
    
1    => "a",
    
"1"  => "b",
    
1.5  => "c",
    
true => "d",
);
var_dump($array);
?>

O exemplo acima irá imprimir:

array(1) {
  [1]=>
  string(1) "d"
}

Como todas as chaves do exemplo acima foram convertidas para 1, o valor será sobrescrito a cada novo elemento e o valor final atribuído "d", será o único que restará.

As chaves dos arrays no PHP podem conter, ao mesmo tempo, int e string, por que o PHP não faz distinção entre arrays indexados e associativos.

Exemplo #3 Misturando int e string nas chaves

<?php
$array 
= array(
    
"foo" => "bar",
    
"bar" => "foo",
    
100   => -100,
    -
100  => 100,
);
var_dump($array);
?>

O exemplo acima irá imprimir:

array(4) {
  ["foo"]=>
  string(3) "bar"
  ["bar"]=>
  string(3) "foo"
  [100]=>
  int(-100)
  [-100]=>
  int(100)
}

A key é opcional. Se não for especificada, o PHP utilizará o incremento da chave do tipo int com maior valor utilizado.

Exemplo #4 Arrays indexados sem chaves

<?php
$array 
= array("foo""bar""hello""world");
var_dump($array);
?>

O exemplo acima irá imprimir:

array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(5) "hello"
  [3]=>
  string(5) "world"
}

É possível especificar a chave somente para alguns elementos e omití-las para outros:

Exemplo #5 Chaves em alguns elementos

<?php
$array 
= array(
         
"a",
         
"b",
    
=> "c",
         
"d",
);
var_dump($array);
?>

O exemplo acima irá imprimir:

array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
}

Como pode ver, o último valor "d" foi atribuído a chave 7. Isso acontece porque a chave com maior inteiro antes dela era 6.

Exemplo #6 Exemplo de sobrescrita e cast de tipo complexo

Este exemplo inclui todas as variações de cast de tipo de chaves e sobrescrita de elementos.

<?php
$array 
= array(
    
1    => 'a',
    
'1'  => 'b'// o valor "a" será sobrescrito por "b"
    
1.5  => 'c'// o valor "b" será sobrescrito por "c"
    
-=> 'd',
    
'01'  => 'e'// não é uma string de inteiro e NÃO sobrescreve a chave 1
    
'1.5' => 'f'// não é uma string de inteiro e NÃO sobrescreve a chave 1
    
true => 'g'// o valor "c" será sobrescrito por "g"
    
false => 'h',
    
'' => 'i',
    
null => 'j'// o valor "i" será sobrescrito por "j"
    
'k',      // o valor "k" será alocado na chave 2. Isto porque é o maior inteiro após a chave 1
    
=> 'l'// o valor "k" será sobrescrito por "l"
);

var_dump($array);
?>

O exemplo acima irá imprimir:

array(7) {
  [1]=>
  string(1) "g"
  [-1]=>
  string(1) "d"
  ["01"]=>
  string(1) "e"
  ["1.5"]=>
  string(1) "f"
  [0]=>
  string(1) "h"
  [""]=>
  string(1) "j"
  [2]=>
  string(1) "l"
}

Acessando elementos do array com colchetes

Elementos do array podem ser acessados utilizando a sintaxe array[chave].

Exemplo #7 Acessando elementos do array

<?php
$array 
= array(
    
"foo" => "bar",
    
42    => 24,
    
"multi" => array(
         
"dimensional" => array(
             
"array" => "foo"
         
)
    )
);

var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>

O exemplo acima irá imprimir:

string(3) "bar"
int(24)
string(3) "foo"

Nota:

Anteriormente ao PHP 8.0.0, chaves e colchetes podiam ser utilizados para acessar elementos de um array (por exemplo, $array[42] e $array{42} irão fazer a mesma coisa que o exemplo anterior). O acesso por chaves está obsoleto desde o PHP 7.4.0 e não é mais suportado no PHP 8.0.0.

Exemplo #8 Referenciando elemento de um array

<?php
function getArray() {
    return array(
123);
}

$secondElement getArray()[1];

// or
list(, $secondElement) = getArray();
?>

Nota:

Tentativas de acesso a uma chave de array que não foi definida é o mesmo que acessar qualquer outra variável indefinida: uma mensagem de erro de nível E_NOTICE será emitida, e o resultado será null.

Nota:

Acessar um array através de uma chave que não é string retorna null. Anteriormente ao PHP 7.4.0 não era emitida uma mensagem. A partir do PHP 7.4.0 emite um E_NOTICE; e a partir do PHP 8.0.0 é emitido um E_WARNING.

Criando/modificando com a sintaxe de colchetes

Você pode também modificar um array existente explicitamente assimilando valores a ele.

Isto é feito apenas assimilando valores para o array enquanto especifica a chave em colchetes. Você pode omitir a chave, colocando um par vazio de colchetes ([]).

$arr[chave] = valor;
$arr[] = valor;
// chave pode ser tanto um int quanto uma string
// valor pode ser qualquer valor de qualquer tipo

Se ainda $arr não existir, será criado, servindo como alternativa para criação de um array. Entretanto, essa prática é desencorajada por que se $arr conter algum valor (por exemplo, uma string de uma variável de requisição), então este valor permanecerá e o [] funcionará como um operador de acesso a string. Sempre será recomendado a inicialização de uma variável por atribuição direta.

Nota: A partir do PHP 7.1.0, aplicar um operador de índice vazio a uma string lança um erro fatal. Antes, a string era silenciosamente convertida em um array.

Nota: A partir do PHP 8.1.0, criar um novo array a partir de false está obsoleto. Crir um array a partir de null e valores indefinidos ainda é permitido.

Para mudar um certo valor, apenas atribua um novo valor para um elemento especificado por sua chave. Se você quiser remover um par chave/valor, você precisa aplicar a função unset() na chave.

<?php
$arr 
= array(=> 112 => 2);

$arr[] = 56;    // Isto é o mesmo que $arr[13] = 56;
                // nesse ponto do script

$arr["x"] = 42// Isto acrescenta um novo elemento
                // para o array com a chave "x"

unset($arr[5]); // Isto remove um elemento do array

unset($arr);    // E isto apaga todo o array
?>

Nota:

Como mencionado acima, se nenhuma chave for especificada, o maior índice int é obtido, e a nova chave será esse o máximo + 1. Se nenhum índice int existir ainda, a chave será 0 (zero).

Note que a chave inteira de maior valor utilizada não precisa necessariamente existir no array. Ele precisa ter existido no array em algum momento desde sua última reindexação. Veja o seguinte exemplo:

<?php
// Criando um array normal
$array = array(12345);
print_r($array);

// Agora apagando todos os itens, mas deixando o array intacto:
foreach ($array as $i => $value) {
    unset(
$array[$i]);
}
print_r($array);

// Acrescentando um item (note que a chave é 5, em vez de zero).
$array[] = 6;
print_r($array);

// Reindexando:
$array array_values($array);
$array[] = 7;
print_r($array);
?>

O exemplo acima irá imprimir:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array
(
)
Array
(
    [5] => 6
)
Array
(
    [0] => 6
    [1] => 7
)

Funções úteis

Há uma série de funções úteis para trabalhar com arrays. Veja a seção sobre funções para arrays.

Nota:

A função unset() permite apagar chaves de um array. Esteja avisado que o array não será reindexado. Se um comportamento como "remover e deslocar" é o desejado, o array poderá ser reindexado utilizando a função array_values().

<?php
$a 
= array( => 'um'=> 'dois'=> 'três' );
unset( 
$a[2] );
/* irá produzir um array que pode ser definido como
   $a = array( 1=>'um', 3=>'três');
   e NÃO
   $a = array( 1 => 'um', 2 => 'três');
*/

$b array_values($a);
// Agora $b é o  array(1 => 'um', 2 =>'três')
?>

A estrutura de controle foreach existe especificamente para lidar com arrays. Ele provê uma maneira fácil de percorrer um array.

Array: faça e não faça

Porque $foo[bar] está errado?

Sempre utilize delimitadores em torno dos índices do array. Por exemplo, $foo['bar'] está correto, enquanto que $foo[bar], não está. Mas porque? É comum encontrar essa sintaxe em scripts antigos:

<?php
$foo
[bar] = 'inimigo';
echo 
$foo[bar];
// etc
?>

Isto está errado, mas funciona. A razão é que este código possui uma constante indefinida (bar) em vez de uma string ('bar' - repare nas aspas simples). Isto funciona, porque o PHP converte automaticamente uma string base (uma string não delimitada que não corresponde a nenhum símbolo conhecido) em uma string que contém a string base. Por exemplo, se não existir uma constante definida com o nome bar, então o PHP irá substituí-la pela string 'bar' e usá-la.

Aviso

O fallback que trata uma constante indefinida como uma string lança um erro do nível E_NOTICE. Isso está obsoleto desde o PHP 7.2.0, e lança um erro do nível E_WARNING. A partir do PHP 8.0.0, esse fallback foi removido e agora lança uma exceção Error.

Nota: Isto não significa que deve-se sempre delimitar as chaves. Não delimite chaves que sejam constantes ou variáveis, porque isso impedirá o PHP de interpretá-las.

<?php
error_reporting
(E_ALL);
ini_set('display_errors'true);
ini_set('html_errors'false);
// Arrays simples:
$array = array(12);
$count count($array);
for (
$i 0$i $count$i++) {
    echo 
"\nVerificando $i: \n";
    echo 
"Ruim: " $array['$i'] . "\n";
    echo 
"Bom: " $array[$i] . "\n";
    echo 
"Ruim: {$array['$i']}\n";
    echo 
"Bom: {$array[$i]}\n";
}
?>

O exemplo acima irá imprimir:

Verificando 0:
Notice: Undefined index:  $i in /path/to/script.html on line 9
Ruim:
Bom: 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Ruim:
Bom: 1

Verificando 1:
Notice: Undefined index:  $i in /path/to/script.html on line 9
Ruim:
Bom: 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Ruim:
Bom: 2

Mais exemplos para demonstrar esse comportamento:

<?php
// Mostrando todos os erros
error_reporting(E_ALL);

$arr = array('fruta' => 'maçã''legume' => 'cenoura');

// Correto
print $arr['fruta'];  // maçã
print $arr['legume']; // cenoura

// Errado. Isto funciona mas lança um erro PHP do
// nível E_NOTICE porque é utilizada uma constante indefinida (fruta)
//
// Repare: Quando utiliza-se a constante indefinida fruta, o PHP assume 'fruta'
print $arr[fruta];    // maçã

// Agora vamos definir uma constante para demonstrar o que pode acontecer. Nós
// vamos assimilar o valor 'legume' para a constante de nome fruta
define('fruta''legume');

// Observe a diferença agora
print $arr['fruit'];  // maçã
print $arr[fruit];    // cenoura

// O exemplo seguinte é normal dentro de uma string. Constantes não são
// observadas dentro de strings e por isso nenhum E-NOTICE não é lançado aqui
print "Olá $arr[fruta]";      // Olá maçã

// Com uma exceção: chaves envolvendo arrays dentro de strings
// ativam a checagem de constantes, como em
print "Olá {$arr[fruta]}";    // Hello cenoura
print "Olá {$arr['fruta']}";  // Hello maçã

// E isso não funciona, resultando em um erro de interpretação do tipo:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Isso se aplica ao uso de superglobais em strings
print "Olá $arr['fruta']";
print 
"Olá $_GET['foo']";

// Nesse caso, use concatenação
print "Olá " $arr['fruta']; // Olá maçã
?>

Quando a diretiva error_reporting for configurada para mostrar erros de nível E_NOTICE (configurando-a como E_ALL, por exemplo), se tornarão imediatamente visíveis. Por padrão, a diretiva error_reporting está configurada para não mostrar avisos.

Como especificado na seção sintaxe, o que estiver entre os colchetes ('[' e ']'), precisa ser uma expressão. Isso significa que códigos como estes funcionam:

<?php
echo $arr[algumafuncao($bar)];
?>

Isto é um exemplo de utilização de um valor de retorno de função como um índice de array. O PHP também aceita constantes:

<?php
$error_descriptions
[E_ERROR] = "Um erro fatal ocorreu";
$error_descriptions[E_WARNING] = "O PHP emitiu um alarme";
$error_descriptions[E_NOTICE] = "Apenas um aviso informal";
?>

Note que E_ERROR também é um identificador válido, assim como bar no primeiro exemplo. Mas no último exemplo seria, na verdade, o mesmo que escrever:

<?php
$error_descriptions
[1] = "Um erro fatal ocorreu";
$error_descriptions[2] = "O PHP emitiu um alarme";
$error_descriptions[8] = "Apenas um aviso informal";
?>

porque E_ERROR é igual a 1, e assim por diante.

Então porque isso é tão ruim?

Se em algum ponto do futuro, o time do PHP quiser acrescentar outra constante ou palavra chave, ou você mesmo introduzir outra constante na sua aplicação, você terá problemas. Por exemplo, já não se pode utilizar as palavras empty e default dessa maneira, desde que elas são palavras reservadas especiais.

Nota: Para reforçar, dentro de uma string delimitada por aspas duplas, é válido não englobar o índice do array com aspas simples, então "$foo[bar]" é válido. Veja os exemplos anteriores para detalhes assim como a seção sobre interpretação de variáveis em strings.

Convertendo para array

Para qualquer dos tipos: int, float, string, bool e resource, converter um valor para um array, resultará em um array com um único elemento com índice zero e valor escalar convertido. Em outras palavras, (array)$scalarValue é exatamente o mesmo que array($scalarValue).

Se um object é convertido para um array, o resultado será um array em que seus elementos serão as propriedades do object. As chaves serão os nomes das propriedades com pequenas notáveis exceções: propriedades inteiras serão inacessíveis; variáveis privadas tem o nome da classe prefixando o nome da variável; variáveis protegidas tem um '*' prefixando o nome da variável. Esses valores prefixados têm um byte NUL em cada lado. Propriedades tipadas não inicializadas são ignoradas.

<?php

class {
    private 
$B;
    protected 
$C;
    public 
$D;
    function 
__construct()
    {
        
$this->{1} = null;
    }
}

var_export((array) new A());
?>

O exemplo acima irá imprimir:

array (
  '' . "\0" . 'A' . "\0" . 'B' => NULL,
  '' . "\0" . '*' . "\0" . 'C' => NULL,
  'D' => NULL,
  1 => NULL,
)

Esses NUL podem ocasionar comportamentos inesperados:

<?php

class {
    private 
$A// Transformado na chave '\0A\0A'
}

class 
extends {
    private 
$A// Transformado na chave '\0B\0A'
    
public $AA// Transformado na chave 'AA'
}

var_dump((array) new B());
?>

O exemplo acima irá imprimir:

array(3) {
  ["BA"]=>
  NULL
  ["AA"]=>
  NULL
  ["AA"]=>
  NULL
}

Acima aparecem duas chaves chamadas 'AA', embora uma delas é, na verdade, nomeada '\0A\0A'.

Converter um valor null para um array, você terá um array vazio.

Comparando

É possível comparar arrays utilizando a função array_diff() e com a utilização dos operadores de array.

Expansão de arrays

Um array prefixado com ... será expandido no local desse operador. Somente arrays e objetos que implementem Traversable podem ser expandidos. A expansão de arrays com ... está disponível desde o PHP 7.4.0.

É possível realizar a expansão várias vezes, e adicionar elementos antes ou depois do operador...:

Exemplo #9 Expansão de arrays

<?php
// Utilizando a sintaxe curta.
// Também funciona com a sintax array().
$arr1 = [123];
$arr2 = [...$arr1]; //[1, 2, 3]
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3]
$arr4 = [...$arr1, ...$arr2111]; //[1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; //[1, 2, 3, 1, 2, 3]

function getArr() {
  return [
'a''b'];
}
$arr6 = [...getArr(), 'c' => 'd']; //['a', 'b', 'c' => 'd']
?>

Expandir um array com ... segue a semântica da função array_merge(). Ou seja, chaves strings sobrescrevem valores antigo e chaves inteiros são renumerados:

Exemplo #10 Expansão de arrays com chaves duplicadas

<?php
// string key
$arr1 = ["a" => 1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]

// integer key
$arr4 = [123];
$arr5 = [456];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Que resulta em [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// pois as chaves inteiras anteriores não são preservadas.
?>

Nota:

Chaves que não sejam inteiros ou strings lançam um TypeError. Essas chaves podem ser geradas por um objeto Traversable.

Nota:

Anteriormente ao PHP 8.1, expansão de arrays com chave string não era suportado:

<?php

$arr1 
= [123];
$arr2 = ['a' => 4];
$arr3 = [...$arr1, ...$arr2];
// Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5

$arr4 = [123];
$arr5 = [45];
$arr6 = [...$arr4, ...$arr5]; // works. [1, 2, 3, 4, 5]
?>

Exemplos

O tipo array do PHP é muito versátil. Temos aqui alguns exemplos:

<?php
// Isso:
$a = array( 'color' => 'red',
            
'taste' => 'sweet',
            
'shape' => 'round',
            
'name'  => 'apple',
            
4        // key will be 0
          
);

$b = array('a''b''c');

// é equivalente a isso:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // a chave será 0

$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';

// Após a execução do código acima, $ será o array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), e $b será o array
// array(0 => 'a', 1 => 'b', 2 => 'c'), ou simplesmente array('a', 'b', 'c').
?>

Exemplo #11 Utilizando array()

<?php
// Array como (propriedade-)mapa
$map = array( 'versao'     => 4,
              
'OS'         => 'Linux',
              
'lang'       => 'inglês',
              
'short_tags' => true
            
);

// apenas chaves numéricas
$array = array( 7,
                
8,
                
0,
                
156,
                -
10
              
);
// que é o mesmo que array( 0 => 7, 1 => 8, ...)

$switching = array(         10// chave = 0
                    
5    =>  6,
                    
3    =>  7,
                    
'a'  =>  4,
                            
11// chave = 6 (o índice máximo era 5)
                    
'8'  =>  2// chave = 8 (inteiro!)
                    
'02' => 77// chave = '02'
                    
0    => 12  // o valor 10 será sobrescrito por 12
                  
);

// array vazio
$empty = array();
?>

Exemplo #12 Coleção

<?php
$cores 
= array('vermelho''azul''verde''amarelo');

foreach (
$cores as $cor) {
    echo 
"Você gosta de $cor?\n";
}

?>

O exemplo acima irá imprimir:

Você gosta de vermelho?
Você gosta de azul?
Você gosta de verde?
Você gosta de amarelo?

É possível alterar diretamente os valores de um array passando-os como referência.

Exemplo #13 Alterando valores em um laço

<?php
foreach ($colors as &$color) {
    
$color strtoupper($color);
}
unset(
$color); /* ensure that following writes to
$color will not modify the last array element */

print_r($colors);
?>

O exemplo acima irá imprimir:

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

Este exemplo cria um array na base 1.

Exemplo #14 Array baseado em 1

<?php
$primeiroquarto  
= array(=> 'Janeiro''Fevereiro''Março');
print_r($primeiroquarto);
?>

O exemplo acima irá imprimir:

Array
(
    [1] => 'Janeiro'
    [2] => 'Fevereiro'
    [3] => 'Março'
)

Exemplo #15 Preenchendo um array

<?php
// preenchendo um array com todos os itens de um diretório
$handle opendir('.');
while (
false !== ($file readdir($handle))) {
    
$files[] = $file;
}
closedir($handle);
?>

arrays são ordenados. A ordem pode ser modificada utilizando várias funções de ordenação. Veja a seção de funções de arrays para mais informações. A função count() pode ser utilizada para contar o número de itens em um array.

Exemplo #16 Ordenando arrays

<?php
sort
($files);
print_r($files);
?>

Como o valor de um array pode ser qualquer coisa, isso significa que também poderá ser outro array. Isso habilita a criação de arrays recursivos e multidimensionais.

Exemplo #17 Arrays recursivos e multidimensionais

<?php
$fruits 
= array ( "frutas"  => array ( "a" => "laranja",
                                       
"b" => "banana",
                                       
"c" => "maçã",
                                     ),
                  
"numeros" => array ( 1,
                                       
2,
                                       
3,
                                       
4,
                                       
5,
                                       
6
                                     
),
                  
"buracos" => array (      "primeiro",
                                       
=> "segundo",
                                            
"terceiro",
                                     ),
                );

// Alguns exemplo de endereços dos valores do array acima
echo $fruits["buracos"][5];   // prints "segundo"
echo $fruits["frutas"]["a"];  // prints "laranja"
unset($fruits["buracos"][0]); // remove "primeiro"

// Criando um novo array multidimensional
$sucos["maca"]["verde"] = "bom";
?>

Atribuições de array sempre envolvem cópias de valores. Use o operador de referência para copiar um array por referência.

<?php
$arr1 
= array(23);
$arr2 $arr1;
$arr2[] = 4// $arr2 é modificado,
             // $arr1 continua sendo apenas array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4// agora $arr1 e $arr3 sao os mesmos
?>
add a note add a note

User Contributed Notes 20 notes

up
129
mlvljr
10 years ago
please note that when arrays are copied, the "reference status" of their members is preserved (http://www.php.net/manual/en/language.references.whatdo.php).
up
51
thomas tulinsky
5 years ago
I think your first, main example is needlessly confusing, very confusing to newbies:

$array = array(
    "foo" => "bar",
    "bar" => "foo",
);

It should be removed.

For newbies:
An array index can be any string value, even a value that is also a value in the array.
The value of array["foo"] is "bar".
The value of array["bar"] is "foo"

The following expressions are both true:
$array["foo"] == "bar"
$array["bar"] == "foo"
up
32
liberchen at gmail dot com
4 years ago
Since PHP 7.1, the string will not be converted to array automatically.

Below codes will fail:

$a=array();
$a['a']='';
$a['a']['b']=''; 
//Warning: Illegal string offset 'b'
//Warning: Cannot assign an empty string to a string offset

You have to change to as below:

$a=array();

$a['a']=array(); // Declare it is an array first
$a['a']['b']='';
up
59
jeff splat codedread splot com
16 years ago
Beware that if you're using strings as indices in the $_POST array, that periods are transformed into underscores:

<html>
<body>
<?php
    printf
("POST: "); print_r($_POST); printf("<br/>");
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    <input type="hidden" name="Windows3.1" value="Sux">
    <input type="submit" value="Click" />
</form>
</body>
</html>

Once you click on the button, the page displays the following:

POST: Array ( [Windows3_1] => Sux )
up
57
ken underscore yap atsign email dot com
14 years ago
"If you convert a NULL value to an array, you get an empty array."

This turns out to be a useful property. Say you have a search function that returns an array of values on success or NULL if nothing found.

<?php $values = search(...); ?>

Now you want to merge the array with another array. What do we do if $values is NULL? No problem:

<?php $combined = array_merge((array)$values, $other); ?>

Voila.
up
40
chris at ocportal dot com
8 years ago
Note that array value buckets are reference-safe, even through serialization.

<?php
$x
='initial';
$test=array('A'=>&$x,'B'=>&$x);
$test=unserialize(serialize($test));
$test['A']='changed';
echo
$test['B']; // Outputs "changed"
?>

This can be useful in some cases, for example saving RAM within complex structures.
up
24
Yesterday php&#39;er
4 years ago
--- quote ---
Note:
Both square brackets and curly braces can be used interchangeably for accessing array elements
--- quote end ---

At least for php 5.4 and 5.6; if function returns an array, the curly brackets does not work directly accessing function result, eg. WillReturnArray(){1} . This will give "syntax error, unexpected '{' in...".
Personally I use only square brackets, expect for accessing single char in string. Old habits...
up
39
ia [AT] zoznam [DOT] sk
16 years ago
Regarding the previous comment, beware of the fact that reference to the last value of the array remains stored in $value after the foreach:

<?php
foreach ( $arr as $key => &$value )
{
   
$value = 1;
}

// without next line you can get bad results...
//unset( $value );

$value = 159;
?>

Now the last element of $arr has the value of '159'. If we remove the comment in the unset() line, everything works as expected ($arr has all values of '1').

Bad results can also appear in nested foreach loops (the same reason as above).

So either unset $value after each foreach or better use the longer form:

<?php
foreach ( $arr as $key => $value )
{
   
$arr[ $key ] = 1;
}
?>
up
14
anisgazig at gmail dot com
3 years ago
//array keys are always integer and string data type and array values are all data type
//type casting and overwriting(data type of array key)
//----------------------------------------------------
$arr = array(
1=>"a",//int(1)
"3"=>"b",//int(3)
"08"=>"c",//string(2)"08"
"80"=>"d",//int(80)
"0"=>"e",//int(0)
"Hellow"=>"f",//string(6)"Hellow"
"10Hellow"=>"h",//string(8)"10Hellow"
1.5=>"j",//int(1.5)
"1.5"=>"k",//string(3)"1.5"
0.0=>"l",//int(0)
false=>"m",//int(false)
true=>"n",//int(true)
"true"=>"o",//string(4)"true"
"false"=>"p",//string(5)"false"
null=>"q",//string(0)""
NULL=>"r",//string(0)"" note null and NULL are same
"NULL"=>"s",//string(4)"NULL" ,,,In last element of multiline array,comma is better to used.
);
//check the data type name of key
foreach ($arr as $key => $value) {
var_dump($key);
echo "<br>";
}

//NOte :array and object data type in keys are Illegal ofset.......
up
25
caifara aaaat im dooaat be
16 years ago
[Editor's note: You can achieve what you're looking for by referencing $single, rather than copying it by value in your foreach statement. See http://php.net/foreach for more details.]

Don't know if this is known or not, but it did eat some of my time and maybe it won't eat your time now...

I tried to add something to a multidimensional array, but that didn't work at first, look at the code below to see what I mean:

<?php

$a1
= array( "a" => 0, "b" => 1 );
$a2 = array( "aa" => 00, "bb" => 11 );

$together = array( $a1, $a2 );

foreach(
$together as $single ) {
   
$single[ "c" ] = 3 ;
}

print_r( $together );
/* nothing changed result is:
Array
(
    [0] => Array
        (
            [a] => 0
            [b] => 1
        )
    [1] => Array
        (
            [aa] => 0
            [bb] => 11
        )
) */

foreach( $together as $key => $value ) {
   
$together[$key]["c"] = 3 ;
}

print_r( $together );

/* now it works, this prints
Array
(
    [0] => Array
        (
            [a] => 0
            [b] => 1
            [c] => 3
        )
    [1] => Array
        (
            [aa] => 0
            [bb] => 11
            [c] => 3
        )
)
*/

?>
up
25
lars-phpcomments at ukmix dot net
16 years ago
Used to creating arrays like this in Perl?

@array = ("All", "A".."Z");

Looks like we need the range() function in PHP:

<?php
$array
= array_merge(array('All'), range('A', 'Z'));
?>

You don't need to array_merge if it's just one range:

<?php
$array
= range('A', 'Z');
?>
up
5
tissus
3 years ago
In array(key=>value) construct key is also an expression.
This works fine:
  $a = array(
    1     =>0,
    1+1   =>1,
    $k    =>2,
    $x.'4'=>3
  );
up
7
note dot php dot lorriman at spamgourmet dot org
8 years ago
There is another kind of array (php>=  5.3.0) produced by

$array = new SplFixedArray(5);

Standard arrays, as documented here, are marvellously flexible and, due to the underlying hashtable, extremely fast for certain kinds of lookup operation.

Supposing a large string-keyed array

$arr=['string1'=>$data1, 'string2'=>$data2 etc....]

when getting the keyed data with

$data=$arr['string1'];

php does *not* have to search through the array comparing each key string to the given key ('string1') one by one, which could take a long time with a large array. Instead the hashtable means that php takes the given key string and computes from it the memory location of the keyed data, and then instantly retrieves the data. Marvellous! And so quick. And no need to know anything about hashtables as it's all hidden away.

However, there is a lot of overhead in that. It uses lots of memory, as hashtables tend to (also nearly doubling on a 64bit server), and should be significantly slower for integer keyed arrays than old-fashioned (non-hashtable) integer-keyed arrays. For that see more on SplFixedArray :

http://uk3.php.net/SplFixedArray

Unlike a standard php (hashtabled) array, if you lookup by integer then the integer itself denotes the memory location of the data, no hashtable computation on the integer key needed. This is much quicker. It's also quicker to build the array compared to the complex operations needed for hashtables. And it uses a lot less memory as there is no hashtable data structure. This is really an optimisation decision, but in some cases of large integer keyed arrays it may significantly reduce server memory and increase performance (including the avoiding of expensive memory deallocation of hashtable arrays at the exiting of the script).
up
1
dylanfj700 at gmail dot com
1 year ago
// Before php 5.4
$array = array(1,2,3);

// since php 5.4 , short syntax
$array = [1,2,3];

// I recommend using the short syntax if you have php version >= 5.4
up
-2
Denise Ignatova
4 years ago
When creating arrays , if we have an element with the same value as another element from the same array, we would expect PHP instead of creating new zval container to increase the refcount and point the duplicate symbol to the same zval. This is true except for value type integer.
Example:

$arr = ['bebe' => 'Bob', 'age' => 23, 'too' => 23 ];
xdebug_debug_zval( 'arr' );

Output:
arr:

(refcount=2, is_ref=0)
array (size=3)
  'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
  'age' => (refcount=0, is_ref=0)int 23
  'too' => (refcount=0, is_ref=0)int 23

but :
$arr = ['bebe' => 'Bob', 'age' => 23, 'too' => '23' ];
xdebug_debug_zval( 'arr' );

will produce:
arr:

(refcount=2, is_ref=0)
array (size=3)
  'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
  'age' => (refcount=0, is_ref=0)int 23
  'too' => (refcount=1, is_ref=0)string '23' (length=2)
or :

$arr = ['bebe' => 'Bob', 'age' => [1,2], 'too' => [1,2] ];
xdebug_debug_zval( 'arr' );

Output:
arr:

(refcount=2, is_ref=0)
array (size=3)
  'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
  'age' => (refcount=2, is_ref=0)
    array (size=2)
      0 => (refcount=0, is_ref=0)int 1
      1 => (refcount=0, is_ref=0)int 2
  'too' => (refcount=2, is_ref=0)
    array (size=2)
      0 => (refcount=0, is_ref=0)int 1
      1 => (refcount=0, is_ref=0)int 2
up
-1
ivail89 at mail dot ru
11 months ago
Function unset can delete array's element by reference only when you specify source array. See example:
<?php
$array
= [1, 2, 3, 4, 5];
foreach (
$array as $k => &$v){
    if (
$k >= 3){
        unset(
$v);
    }
}
echo
count($array); // 5
?>
In this case unset delete only reference, however original array didn't change.

Or different example:
<?php
$arr
= [1, 2];
$a = &$arr[0];
unset(
$a);
count($arr); // 2
?>

So for deleting element from first example need use key and array.
<?php
// ...
 
unset($array[$k]);
// ...
?>
up
-4
Anonymous
2 years ago
Wrappers for (array), returns array with normalize keys (without prefix):
<?php
function to_array_recursive($value): array
{
        if (!
is_object($value)) {
                return (array)
$value;
        }
       
$class = get_class($value);
       
$arr = [];
       
foreact ((array)  $value as $key => $val) {
               
$key = str_replace(["\0*\0", "\0{$class}\0"], '', $key);
               
$arr[$key] = is_object($val) ? to_array_recursive($val) : $val;
        }
        return
$arr;
}

function
to_array($value): array
{
       
$arr = (array) $value;
        if (!
is_object($value)) {
                return
$arr;
        }
       
$class = get_class($value);
       
$keys = str_replace(["\0*\0", "\0{$class}\0"], '', array_keys($arr));
        return
array_combine($keys, $arr);
}
?>
Demo:
<?php
class Test
{
        protected
$var = 1;
        protected
$var2;
        private
$TestVar = 3;
       
    public function
__construct($isParent = true)
    {
        if (
$isParent) {
           
$this->var2 = new self(! $isParent);
        }
    }
}

$obj = new Test();
var_dump((array) $obj, to_array_recursive($obj));
?>
up
-8
ivegner at yandex dot ru
8 years ago
Note that objects of classes extending ArrayObject SPL class are treated as arrays, and not as objects when converting to array.

<?php
class ArrayObjectExtended extends ArrayObject
{
    private
$private = 'private';
    public
$hello = 'world';
}

$object = new ArrayObjectExtended();
$array = (array) $object;

// This will not expose $private and $hello properties of $object,
// but return an empty array instead.
var_export($array);
?>
up
-1
phplatino at gmail dot com
5 months ago
to know the depth (dimension) of a ARRAY, you can use this:

function Dim_Ar($A, $i){
    if(!is_array($A))return 0;
    $t[] = 1;
    foreach($A AS $e)if(is_array($e))$t[] = Dim_Ar($e, ++ $i) + 1;
    return max($t);
    }

and use with:

$Q = ARRAY(ARRAY(ARRAY()), ARRAY(ARRAY()));// here depth/dimension is three

echo Dim_Ar($Q, 0);
up
-15
Walter Tross
11 years ago
It is true that "array assignment always involves value copying", but the copy is a "lazy copy". This means that the data of the two variables occupy the same memory as long as no array element changes.

E.g., if you have to pass an array to a function that only needs to read it, there is no advantage at all in passing it by reference.
To Top