array

PHP'de bir dizi aslında sıralı bir eşlemdir. Bir eşlem, değerleri anahtarlarla ilişkilendiren bir veri türüdür. Bu veri türü farklı kullanım amaçları için en iyilenebilir; bir dizi, bir yöneysel liste, bir isim-değer çiftleri tablosu, bir sözlük, bir nesne listesi, yığıt, kuyruk ve daha bir sürü başka şey olarak ele alınabilir. Dizilerin değerleri, ağaçlar, diziler ve hatta çok boyutlu diziler bile olabilir.

Tüm bu veri yapılarının açıklanması bu kılavuzun amacını aşar. Fakat, en azından her biri için birer örnek verilebilir. Bu konuda daha fazla bilgi edinmek için bu konuyla ilgili olarak yayımlanmış eserleri inceleyiniz.

Sözdizimi

Bir dizinin array() ile belirtilmesi

Bir dizi array() işlevi kullanılarak belirtilebilir. Değiştirge olarak, birbirlerinden virgüllerle ayrılmış çok sayıda anahtar => değer çifti alabilir.

array(  anahtar  =>  değer
     , ...
     )
// anahtar sadece integer veya string türünde olabilir.
// değer herhangi bir türde herhangi bir değer olabilir.
<?php
$dizi 
= array("fu" => "bar"12 => true);

echo 
$dizi["fu"]; // bar
echo $dizi[12];    // 1
?>

Bir anahtar ya integer ya da string türünde olabilir. Bir anahtar, sadece onluk tamsayı gösterimiyle belirtilmişse bir tamsayı anahtar olarak yorumlanır. Yani, "8" belirtilmeşse bu tamsayı 8 olarak ele alınacak ama "08" belirtilmişse dizge "08" olarak ele alınacaktır. float türünde belirtilen bir anahtar integer türüne aşağı yuvarlanır. PHP için indisli ve ilişkisel diziler, her ikisi de integer ve string türünde indisler içerebildiğinden aynı çeşitten dizilerdir.

değer herhangi bir PHP türünde herhangi bir değer olabilir.

Bilginize:

Tanımlanmamış bir dizi anahtarına erişmeye çalışmakla tanımsız bir değişkene erişmeye çalışmak arasında fark yoktur: E_NOTICE seviyesinde bir hata iletisi çıktılanır ve sonuç NULL olur

<?php
$dizi 
= array("birdizi" => array(=> 513 => 9"a" => 42));

echo 
$dizi["birdizi"][6];    // 5
echo $dizi["birdizi"][13];   // 9
echo $dizi["birdizi"]["a"];  // 42
?>

Bir anahtar belirtmeksizin bir değer atanıyorsa değer, mevcut tamsayı anahtarların en büyüğüne bir eklenerek elde edilen tamsayı anahtarlı elemana atanır. Bir anahtar mevcut anahtarlardan biriyle değer atıyorsa, yeni değer mevcut eleman değerinin üzerine yazılır.

<?php
// Bu iki dizi birbirinin aynıdır:
array(=> 433256"b" => 12);

array(
=> 43=> 32=> 56"b" => 12);
?>
Uyarı

PHP 4.3.0 öncesinde, en büyük indisi bir negatif tamsayı olan bir diziye anahtarsız değer atanması durumunda değere anahtarı yukarıda açıklandığı gibi atanırdı. PHP 4.3.0 ve sonrasında ise böyle bir durumda yeni değer 0 anahtarına atanmaktadır.

anahtar olarak TRUE belirtilirse bu tamsayı 1 olarak, FALSE belirtilirse tamsayı 0 olarak yorumlanır. anahtar olarak NULL kullanımı bir boş dizge olarak yorumlanır. Boş dizgeyle anahtar belirtimi, yeni değerin boş dizge anahtarlı olarak atanmasına sebep olur ve bu, anahtar belirtmeksizin (boş köşeli ayraçlarla) atama yapmak anlamında değerlendirilmez.

array veya object türünde anahtar belirtilemez. Aksi takdirde şöyle bir uyarı alırsınız: Illegal offset type (Kuraldışı konumlama türü).

Köşeli ayraçlarla atama ve değişiklik yapmak

Mevcut bir dizi, doğrudan değer atamak suretiyle değiştirilebilir.

Bu işlem, diziye köşeli ayraçlar arasında belirtilen bir anahtar kullanılarak değer atamak biçeminde yapılır. Diziye yeni bir değer atamak için köşeli ayraçlar boş olarak ([]) belirtilebilir.

$dizi[anahtar] = değer;
$dizi[] = değer;

// anahtar sadece integer veya string türünde olabilir.
// değer herhangi bir türde herhangi bir değer olabilir.

$dizi mevcut değilse oluşturulur, dolayısıyla bu da yeni bir dizi oluşturma yöntemidir. Belli bir değeri değiştirmek için yeni değer elemana mevcut anahtar kullanılarak atanır. Belli bir elemanı (anahtar/değer çiftini) diziden silmek için unset() işlevi kullanılır.

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

$dizi[] = 56;    // Betiğin bu noktasında bu atama
                 // $dizi[13] = 56; ile aynıdır

$dizi["x"] = 42// "x" anahtarlı yeni bir eleman atar

unset($dizi[5]); // Elemanı diziden siler

unset($dizi);    // Dizinin tamamını siler
?>

Bilginize:

Yukarıda değinildiği gibi, bir diziye yeni değeri bir anahtar belirtmeden atamak, mevcut en büyük tamsayı indisine bir eklenerek elde edilen anahtar kullanılarak gerçekleşir. Dizide henüz bir tamsayı indis yoksa anahtar olarak 0 (sıfır) kullanılır.

Dikkat ederseniz, dizinin mevcut olması halinde, yeni bir değer atamak için en büyük tamsayı indisli anahtar kullanmaya gerek yoktur. Buna sadece dizi yeniden indislenmişse gerek olabilir. Aşağıdaki örnek anlatımı pekiştirecektir:

<?php
// Basit bir dizi oluşturalım.
$dizi = array(12345);
print_r($dizi);

// Şimdi bütün elemanları silelim ama dizi kalsın:
foreach ($dizi as $i => $value) {
    unset(
$dizi[$i]);
}
print_r($dizi);

// Bir eleman ekleyelim (dikkat: yeni anahtar 0 değil 5 olacak!)
$dizi[] = 6;
print_r($dizi);

// Yeniden indisleyelim:
$dizi array_values($dizi);
$dizi[] = 7;
print_r($dizi);
?>

Yukarıdaki örneğin çıktısı:

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

Kullanışlı işlevler

Dizilerle çalışmak için kullanılabilecek işlevlerin tamamını Dizi İşlevleri bölümünde bulabilirsiniz.

Bilginize:

unset() işlevi bir diziden anahtar silmeyi mümkün kılar. Ama bu silme işlemi dizinin yeniden indislenmesiyle sonuçlanmaz. Eğer silme işleminin gerçekten "sil ve kaydır" yapmasını istiyorsanız, anahtarı sildikten sonra array_values() işlevini kullanarak diziyi yeniden indislemelisiniz.

<?php
$a 
= array(=> 'bir'=> 'iki'=> 'üç');
unset(
$a[2]);
/* Bu silme işlemi dizi şöyle tanımlanmış gibi sonuçlanacaktır:
   $a = array(1 => 'bir', 3 => 'üç');
   böyle DEĞİL:
   $a = array(1 => 'bir', 2 =>'üç');
*/

$b array_values($a);
// $b artık array(0 => 'bir', 1 =>'üç') olmuştur
?>

foreach denetim yapısı özellikle diziler için tasarlanmıştır. Diziler üzerinde hareket edilmesini kolaylaştırır.

Diziler ne yapar, ne yapmaz?

$foo[bar] niye yanlıştır?

Bir dizge sayıllı indis daima tırnak içinde kullanılır. Örneğin, $foo[bar] yanlışken $foo['bar'] doğrudur. Ama, neden? Eski betiklerde şu sözdizimine sıkça rastlanır:

<?php
$foo
[bar] = 'düşman';
echo 
$foo[bar];
// ve saire
?>

Bu yanlıştır, ama çalışır. Bunun sebebi, bu kodun bir dizgeden ziyade tanımsız bir sabit (bar) belirtiyor olmasıdır. PHP ilerde şans eseri ismi aynı zamanda değeri olan bir sabit tanımlayabilir. PHP özdevinimli olarak bir çıplak dizgeyi (tırnak içine alınmamış bir dizgeyi), bu çıplak dizgeyi içeren bir dizgeye dönüştüreceğinden bu çalışır. Örneğin, bar isminde tanımlanmış bir sabit yoksa, PHP bar sabitine 'bar' dizgesini yerleştirecek ve bunu kullanacaktır.

Bilginize: Bu, "anahtarlar daima tırnak içine alınır" demek değildir. sabitleri ve değişkenleri tek tırnak içine almayın, çünkü o zaman yorumlanmazlar.

<?php
error_reporting
(E_ALL);
ini_set('display_errors'true);
ini_set('html_errors'false);
// Basit bir dizi:
$dizi = array(12);
$sayaç count($dizi);
for (
$i 0$i $sayaç$i++) {
    echo 
"\n$i indisi inceleniyor: \n";
    echo 
"Kötü: " $dizi['$i'] . "\n";
    echo 
"İyi: " $dizi[$i] . "\n";
    echo 
"Kötü: {$dizi['$i']}\n";
    echo 
"İyi: {$dizi[$i]}\n";
}
?>

Yukarıdaki örneğin çıktısı:

0 indisi inceleniyor:

Notice: Undefined index: $i in /dosya/yolu/betik.php on line 10
Kötü:
İyi: 1

Notice: Undefined index: $i in /dosya/yolu/betik.php on line 12
Kötü:
İyi: 1

1 indisi inceleniyor:

Notice: Undefined index: $i in /dosya/yolu/betik.php on line 10
Kötü:
İyi: 2

Notice: Undefined index: $i in /dosya/yolu/betik.php on line 12
Kötü:
İyi: 2

Bu davranışla ilgili diğer örnekler:

<?php
// Tüm hataları görelim
error_reporting(E_ALL);

$dizi = array('meyve' => 'elma''sebze' => 'havuç');

// Doğru
print $dizi['meyve'];  // elma
print $dizi['sebze'];  // havuç

// Yanlış. Bu çalışır, fakat meyve tanımlanmamış bir sabit
// olmadığından E_NOTICE seviyesinde bir PHP hatası oluşur
//
// Notice: Use of undefined constant meyve - assumed 'meyve'...
print $dizi[meyve];    // elma

// Bu, neler olup bittiğini gösteren bir sabit tanımlar;
// 'sebze' değeri meyve sabitine atanır.
define('meyve''sebze');

// Şimdi farkı görelim
print $dizi['meyve'];  // elma
print $dizi[meyve];    // havuç

// Bir dizge içinde olduğundan bu da doğrudur.
// Dizge içinde kalan sabitler, sabit olarak ele alınmazlar;
// dolayısıyla burada bir E_NOTICE oluşmaz.
print "Turfanda $dizi[meyve]";      // Turfanda elma

// Bir istisna: Dizge içinde kaşlı ayraç içine alınmış
// sabitler, sabit olarak ele alınırlar.
print "Turfanda {$dizi[meyve]}";     // Turfanda havuç
print "Turfanda {$dizi['meyve']}";   // Turfanda elma

// Bu çalışmaz ve şöyle bir çözümleme hatasıyla sonuçlanır:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Bu, dizgeler içindeki süper küresellere de uygulanır.
print "Turfanda $dizi['meyve']";
print 
"Turfanda $_GET['foo']";

// Ard arda eklemek de bir seçenektir
print "Turfanda " $dizi['meyve']; // Turfanda elma
?>

error_reporting yönergesine E_NOTICE seviyesinden hataları gösterecek bir atama yapılırsa (örneğin, E_ALL atanarak), böyle kullanımlar hemen görünür duruma gelir. error_reporting yönergesinin öntanımlı değeriyle E_NOTICE seviyesinden hatalar gösterilmez.

Sözdizimi bölümünde değinildiği gibi, köşeli ayraçlar ('[' ve ']') içinde belirtilenlerin birer ifade olması gerekir. Yani, aşağıdaki gibi bir kod çalışacaktır:

<?php
echo $dizi[birişlev($bar)];
?>

Bu, bir işlevin dönüş değerinin dizi indisi olarak kullanımına bir örnektir. PHP kendi sabitlerini de tanır:

<?php
$error_descriptions
[E_ERROR]   = "Ölümcül bir hata oluştu";
$error_descriptions[E_WARNING] = "PHP bir uyarı verdi";
$error_descriptions[E_NOTICE]  = "Bu sadece bilgilendirici bir uyarı";
?>

E_ERROR sabitinin de ilk örnekteki bar kadar geçerli bir betimleyici oluşuna dikkat ediniz. Fakat, E_ERROR eşittir 1, vb. olduğundan aşağıdaki örnek de aynı işi yapar:

<?php
$error_descriptions
[1] = "Ölümcül bir hata oluştu";
$error_descriptions[2] = "PHP bir uyarı verdi";
$error_descriptions[8] = "Bu sadece bilgilendirici bir uyarı";
?>

O halde bunun nesi kötü?

Bilinmeyen bir gelecekte PHP ekibi başkalarının kodlarıyla çelişen bir sabit, bir anahtar sözcük veya bir değişken eklemek isteyebilir. Örneğin, empty ve default birer anahtar sözcük olduklarından bu amaçla kullanılmaları yanlıştır.

Bilginize: Yinelemek gerekirse, çift tırnak imleri arasına alınmış bir dizge, dizi indisini tırnak içine almadığından geçerlidir; yani, "$foo[bar]" geçeridir. Yukarıdaki örnekleri bu gözle tekrar inceleyin ve ayrıca dizgelerin içinde değişken çözümleme bölümüne de bakın.

Diziye dönüşüm

integer, float, string, boolean veya resource türünde bir değeri array türünde bir değere dönüştürme işlemi, sıfır indisli bir elemana bu değerin atanması ile sonuçlanır. Başka bir deyişle, (array)$sayılDeğer ile array($sayılDeğer) arasında bir fark yoktur.

Bir object türü array türüne dönüştürme işlemi, elemanları nesnenin üyeleri olan bir dizi ile sonuçlanır. Anahtarlar, bir kaç istisnai durum dışında üyelerin isimleridir: Tamsayı özellikler erişilebilir değildir; private değişkenlerin önüne sınıf isimleri getirilir; public değişkenlerin önünde bir '*' olur. Diğer taraftan, başlarına birşeyler eklenmiş böyle değişkenlerin değerleri NULL olur. Bu durum beklenmedik davranışlara yol açabilir:

<?php

class {
    private 
$A// Bu '\0A\0A' haline gelir.
}

class 
extends {
    private 
$A// Bu '\0B\0A' haline gelir.
    
public $AA// Bu 'AA' haline gelir.
}

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

Bu örneğin çıktısı 'AA' isimli iki anahtar görüntülerse de onlardan birinin ismi aslında '\0A\0A''dır.

NULL, bir diziye dönüştürülmek istenirse sonuç boş bir dizi olur.

Karşılaştırma

Dizileri array_diff() işleviyle veya dizi işleçleri kullanılarak karşılaştırmak mümkündür.

Örnekler

PHP'nin array türü çok yeteneklidir. Bazı örnekler:

<?php
// Bu:
$a = array( 'renk'   => 'kırmızı',
            
'lezzet' => 'tatlı',
            
'şekil'  => 'yuvarlak',
            
'isim'   => 'elma',
            
4        // anahtarı 0 olacaktır
          
);

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

// . . . buna tamamen eşdeğerdir:
$a = array();
$a['renk']   = 'kırmızı';
$a['lezzet'] = 'tatlı';
$a['şekil']  = 'yuvarlak';
$a['isim']   = 'elma';
$a[]         = 4;        // anahtarı 0 olacaktır

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

// Yukarıdaki kod çalıştırıldığında $a, array('renk' => 'kırmızı',
// 'lezzet' => 'tatlı', 'şekil' => 'yuvarlak', 'isim' => 'elma', 0 => 4)
// dizisiyle, $b ise array(0 => 'a', 1 => 'b', 2 => 'c') veya basitçe
// array('a', 'b', 'c') dizisiyle sonuçlanacaktır.
?>

Örnek 1 - array() kullanımı

<?php
// Özellik eşlemeli dizi
$map = array( 'sürüm'    => 4,
              
'sistem'   => 'Linux',
              
'dil'      => 'english',
              
'kısaltma' => true
            
);

// tamamen sayısal anahtarlar
$dizi = array(  7,
                
8,
                
0,
              
156,
              -
10
              
);
// Bu, array(0 => 7, 1 => 8, ...) ile aynıdır

$geçişli = array(        10// key = 0
                 
5    =>  6,
                 
3    =>  7,
                 
'a'  =>  4,
                         
11// anahtar = 6 (en büyük tamsayı indis 5 idi)
                 
'8'  =>  2// anahtar = 8 (tamsayı!)
                 
'02' => 77// anahtar = '02'
                 
0    => 12  // 10 değerinin üzerine 12 yazılacak
                  
);

// boş dizi
$boş = array();
?>

Örnek 2 - Döngü içinde elemen değiştirme

<?php
$renkler 
= array('Turuncu''Pembe''Mor''Turkuaz');

foreach (
$renkler as $renk) {
    echo 
"$renk rengi sever misiniz?\n";
}

?>

Yukarıdaki örneğin çıktısı:

Turuncu rengi sever misiniz?
Pembe rengi sever misiniz?
Mor rengi sever misiniz?
Turkuaz rengi sever misiniz?

PHP5'ten beri dizi değerleri gönderimli aktarıldıklarından dizi değerlerini doğrudan değiştirmek mümkündür. Fakat arada bazı şeyler yapmak gerekir:

Örnek 3 - Derlem

<?php
<?php
$renkler 
= array('Turuncu''Pembe''Mor''Turkuaz');

// PHP 5
foreach ($renkler as &$renk) {
    
$renk strtoupper($renk);
}

unset(
$renk); /* Aşağıdaki atamalarda $renk son
                 dizi elemanını değiştirmesin */

// Eski sürümü yeniden elde edelim
foreach ($renkler as $anahtar => $renk) {
    
$renkler[$anahtar] = strtoupper($renk);
}

print_r($renkler);
?>

Yukarıdaki örneğin çıktısı:

Array
(
    [0] => TURUNCU
    [1] => PEMBE
    [2] => MOR
    [3] => TURKUAZ
)

Bu örnekte dizi indisleri 1'den başlatılmaktadır.

Örnek 4 - İndisi 1'den başlatmak

<?php
$ilkçeyrek  
= array(=> 'Ocak''Şubat''Mart');
print_r($ilkçeyrek);
?>

Yukarıdaki örneğin çıktısı:

Array
(
    [1] => Ocak
    [2] => Şubat
    [3] => Mart
)

Örnek 5 - Diziyi doldurmak

<?php
// bir diziyi bir dizin'in içeriği ile dolduralım
$tutamak opendir('.');
while (
false !== ($dosya readdir($tutamak))) {
    
$dosyalar[] = $dosya;
}
closedir($tutamak);
?>

Diziler sıralıdır. Sıralama çeşitli sıralama işlevleri ile değiştirilebilir. Daha fazla bilgi için Dizi İşlevleri bölümüne bakınız. Bir dizinin eleman sayısını öğrenmek için count()işlevi kullanılabilir.

Örnek 6 - Dizi elemanlarının sıraya sokulması

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

Bir dizinin elemanlarına her türlü değer atanabileceğinden başka bir dizi de atanabilir. Böylece iç içe ve çok boyutlu dizilerin oluşturulması mümkün olur.

Örnek 7 - İç içe ve çok boyutlu diziler

<?php
$yemişler 
= array ( "yemişler"  => array ( "a" => "iğde",
                                           
"b" => "badem",
                                           
"c" => "ceviz"
                                         
),
                    
"sayılar"   => array ( 1,
                                           
2,
                                           
3,
                                           
4,
                                           
5,
                                           
6
                                         
),
                    
"yuvalar"   => array (        "birinci",
                                            
5  => "ikinci",
                                                  
"üçüncü"
                                          
)
                );

// Yukarıdaki dizinin değerlerinin kullanıldığı bazı örnekler
echo $yemişler["yuvalar"][5];    // "ikinci" basar
echo $yemişler["meyveler"]["a"]; // "iğde" basar
unset($yemişler["yuvalar"][0]);  // "birinci" silinir

// Yeni bir çok boyutlu dizi oluşturalım
$meyveler["elma"]["yeşil"] = "ekşi";
?>

Dizi atamaları daima değerleri kopyalamak şeklinde gerçekleşir. Bir diziyi gönderimli olarak kopyalamak için gönderim işleci kullanılır.

<?php
$dizi1 
= array(23);
$dizi2 $dizi1;
$dizi2[] = 4// $dizi2 değişti,
              // $dizi1 hala array(2, 3)

$dizi3 = &$dizi1;
$dizi3[] = 4// şimdi $dizi1 ve $dizi3 aynı
?>
add a note add a note

User Contributed Notes 21 notes

up
67
mlvljr
3 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
33
chris at ocportal dot com
1 year 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
45
ken underscore yap atsign email dot com
6 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
42
jeff splat codedread splot com
9 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
17
ivegner at yandex dot ru
1 year 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
33
ia [AT] zoznam [DOT] sk
8 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
32
lars-phpcomments at ukmix dot net
9 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
2
note dot php dot lorriman at spamgourmet dot org
8 months 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
25
caifara aaaat im dooaat be
9 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
1
Ray.Paseur often uses Gmail
2 months ago
Array-to-String conversion by assignment or by using an array in a string context gives a string of data that contains only the word, 'Array' and this data substitution often occurs silently.  This happens because the standard PHP installation suppresses Notice-level messages, and the array-to-string conversion, even though it causes data loss, is only considered a Notice condition.  Here is how to discern what PHP is doing.
http://php.net/manual/en/language.types.array.php
http://php.net/manual/en/language.types.string.php#language.types.string.casting

<?php // demo/array_to_string.php
/**
* Starting with the default standard error-level of E_ALL ~ E_NOTICE
* OUTPUTS:
* Array
*/
$xyz = array('X', 'Y', 'Z');
echo
$xyz;

/**
* Setting the error-level of E_ALL causes Notice messages to appear
* OUTPUTS:
* Notice: Array to string conversion in /path/to/demo/array_to_string.php on line XXX
* Array
*/
error_reporting(E_ALL);
$xyz = array('X', 'Y', 'Z');
echo
$xyz;
up
1
martijntje at martijnotto dot nl
2 years ago
Please note that adding the magic __toString() method to your objects will not allow you to seek an array with it, it still throws an Illegal Offset warning.

The solution is to cast it to a string first, like this

$array[(string) $stringableObject]
up
-5
cromney at pointslope dot com
1 year ago
One thing to be careful of is making any assumptions about the underlying implementation with respect to performance. For example, the documentation talks about hash-maps, which might lead you to expect O(1) key lookups.

<?php

function find_val($n) {
 
$t = array();
 
$last = null;
 
  for (
$x = 0; $x < $n; $x++) {
   
$last = "" . $x;
   
$t[] = $last;
  }
 
 
var_dump(in_array($last, $t));


 
function
find_key($n) {
 
$t = array();
 
$last = null;
 
  for (
$x = 0; $x < $n; $x++) {
   
$last = "" . $x;
   
$t[$last] = true;
  }
 
 
var_dump(array_key_exists($last, $t));


$n = 1600000;

find_val($n);
// Time taken: 1123ms

find_key($n);
// Time taken: 803

/*

Additional Timings:

n        find_val(ms)  find_key(ms)
100000   99             82
200000   169            130
400000   301            217
800000   570            416
1600000  1123           803

*/
?>

In my tests, both in_array and array_key_exists exhibited the same order of growth.
up
-4
Anonymous
7 years ago
This page should include details about how associative arrays are implemened inside PHP; e.g. using hash-maps or b-trees.

This has important implictions on the permance characteristics of associative arrays and how they should be used; e.g. b-tree are slow to insert but handle collisions better than hashmaps.  Hashmaps are faster if there are no collisions, but are slower to retrieve when there are collisions.  These factors have implictions on how associative arrays should be used.
up
-5
Spudley
7 years ago
On array recursion...

Given the following code:

<?php
$myarray
= array('test',123);
$myarray[] = &$myarray;
print_r($myarray);
?>

The print_r() will display *RECURSION* when it gets to the third element of the array.

There doesn't appear to be any other way to scan an array for recursive references, so if you need to check for them, you'll have to use print_r() with its second parameter to capture the output and look for the word *RECURSION*.

It's not an elegant solution, but it's the only one I've found, so I hope it helps someone.
up
-8
harry at ddtechnologies dot com
1 year ago
PHP array_diff_assoc() Function

You can compare the keys and values of two arrays, and return the differences:

<?php
$a1
=array("red","green","blue","yellow");
$a2=array("red","green","blue");

$result=array_diff_assoc($a1,$a2);
print_r($result);
?>

http://www.show-ip.org
up
-16
Walter Tross
4 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.
up
-19
gtisza at gmail dot com
1 year ago
Be very careful when using a result as an array. <?php echo $a['foo']['bar']['baz'] ?> will throw an error if $a is an object, and throw a warning if $a is an array but does not have the right keys, but it will silently return true if $a is null or boolean or int, and if $a is a string, it will return its first character. (This is true even with E_STRICT set.) This can be a major gotcha with functions which return null or false if they are unsuccessful.
up
-4
brta dot akos at gmail dot com
8 months ago
Why not to user one-based arrays:

<?php
$a 
= array(1 => 'a', 'b', 'd');
print_r($a);
array_splice($a,2,0,'c');
print_r($a);
?>

output:
Array ( [1] => a [2] => b [3] => d ) Array ( [0] => a [1] => b [2] => c [3] => d )
up
-8
ffe
7 months ago
<?php

error_reporting
(E_ALL);

$res=42;

echo(
"+".$res[0]."+".$res[10]."+");

$res[0]=1;

?>

The last line correctly states "Warning: Cannot use a scalar value as an array", but the echo produces +++ as output with no warning. This seems strange to me.
up
-58
carl at linkleaf dot com
7 years ago
Its worth noting that there does not appear to be any functional limitations on the length or content of string indexes. The string indexes for your arrays can contain any characters, including new line characters, and can be of any length:

<?php

$key
= "XXXXX";
$test = array($key => "test5");

for (
$x = 0; $x < 500; $x++) {
 
$key .= "X";
 
$value = "test" . strlen($key);
 
$test[$key] = $value;
}

echo
"<pre>";
print_r($test);
echo
"</pre>";

?>

Keep in mind that using extremely long array indexes is not a good practice and could cost you lots of extra CPU time. However, if you have to use a long string as an array index you won't have to worry about the length or content.
up
-38
azuleta at eycambiental dot com
11 months ago
I think there's a mistake in the las example:
...'<?php
$arr1
= array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 ha cambiado,
             // $arr1 sigue siendo array(2, 3)
           
$arr3 = &$arr1;
$arr3[] = 4; // ahora $arr1 y $arr3 son iguales
?>'

I think it should be: ...'ahora $arr2 y $arr3 son iguales'...

Thanks.
To Top