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).
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 desse 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.
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 a direita do último elemento é
usada frequentemente, para permitir a adição de forma simples de novos elementos ao final.
A partir do PHP 5.4 você também pode utilizar a sintaxe contraída de array, que troca
array()
por []
.
Exemplo #1 Um array simples
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// a partir do PHP 5.4
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>
A chave pode ser um inteiro ou uma string. O valor pode ser de qualquer tipo.
Adicionalmente, as seguintes coerções ocorrerão a chave:
"8"
será, na verdade,
armazenada como 8
. Entretanto, "08"
não
será convertido, por não ser um inteiro decimal válido.
8.7
será na verdade
armazenada como 8
.
true
, será na verdade armazenada como 1
e a chave false
como 0
.
null
na verdade será armazenada como ""
.
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, inteiro e string, por que o PHP não faz distinção entre arrays indexados e associativos.
Exemplo #3 Misturando inteiro 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 chave é opcional. Se não for especificada, o PHP utilizará o incremento da chave do tipo inteiro 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",
6 => "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
.
Elementos do array podem ser acessados utilizando a sintaxe array[chave]
.
Exemplo #6 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:
Tanto colchetes quanto chaves podem ser utilizados intercambiávelmente para acessar elementos de um array (por exemplo,
$array[42]
e$array{42}
irão fazer a mesma coisa que o exemplo anterior).
A partir do PHP 5.4 é possível referenciar um elemento de um array como resultado de uma função ou método chamado diretamente. Antes, era possível somente através de uma variável temporária.
A partir do PHP 5.5 é possível referenciar elementos de um array literal.
Exemplo #7 Referenciando elemento de um array
<?php
function getArray() {
return array(1, 2, 3);
}
// on PHP 5.4
$secondElement = getArray()[1];
// previously
$tmp = getArray();
$secondElement = $tmp[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:
Referenciar um valor scalar de um array que não seja uma string gerará silenciosamente um
null
, isto é, sem emitir uma mensagem de erro.
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 integer 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á recomentado 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 silencionamente convertida em um array.
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() nele.
<?php
$arr = array(5 => 1, 12 => 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 inteiro é obtido, e a nova chave será esse o máximo + 1. Se nenhum índice inteiro 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(1, 2, 3, 4, 5);
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 )
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( 1 => 'um', 2 => 'dois', 3 => '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.
$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.
O fallback para tratar uma constante indefinida como string base está depreciado
a partir do PHP 7.2.0, e emitirá um erro de nível E_WARNING
.
Antes, um erro de nível E_NOTICE
era emitido.
Nota: Isto não que 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(1, 2);
$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 constrante 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 diferenca 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 concatenacao
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.
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.
Para qualquer dos tipos: integer, float,
string, boolean 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 objeto é convertido para um array, o resultado será um array em que seus elementos serão as propriedades do objeto. As chaves serão o nome das propriedades com pequenas notáveis exceções: propriedades inteiras serão inacessíveis; variáveis privada tem o nome da classe prefixando o nome da variável; variáveis protegidas tem um '*' prefixando o nome da variável. Estes prefixos tem bytes nulos em ambos os lados. Isto pode resultar em algum comportamento inesperado:
<?php
class A {
private $A; // This will become '\0A\0A'
}
class B extends A {
private $A; // This will become '\0B\0A'
public $AA; // This will become 'AA'
}
var_dump((array) new B());
?>
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.
É possível comparar arrays utilizando a função array_diff() e com a utilização dos operadores de array.
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 #8 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 #9 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 #10 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 #11 Array baseado em 1
<?php
$primeiroquarto = array(1 => 'Janeiro', 'Fevereiro', 'Março');
print_r($primeiroquarto);
?>
O exemplo acima irá imprimir:
Array ( [1] => 'Janeiro' [2] => 'Fevereiro' [3] => 'Março' )
Exemplo #12 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 #13 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 #14 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",
5 => "segundo",
"terceiro",
),
);
// Alguns exemplo de enderecos 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(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 é modificado,
// $arr1 continua sendo apenas array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // agora $arr1 e $arr3 sao os mesmos
?>
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).
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"
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']='';
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 )
"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.
--- 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...
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.
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;
}
?>
//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.......
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');
?>
[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
)
)
*/
?>
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
);
// 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
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).
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);
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]);
// ...
?>
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
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));
?>
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);
?>
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.