Масиви

Масивът в PHP всъщност представлява подредена асоциация (ordered map). Асоциацията е тип, който асоциира стойности към ключове. Този тип е оптимизиран по няколко направления, така че можете да го използвате като реален масив, като списък (вектор), хеш-таблица (което е реализация на асоциация), речник, колекция, стек, опашка и др. Тъй като за стойност може да имате друг масив, много лесно можете да симулирате и дървета.

Описанието на тези структури от данни е извън обхвата на това ръководство, но ще намерите поне един пример за всяка от тях. За повече информация по тази обширна тема ви препоръчваме да се насочите към външна литература.

Синтаксис

Указване посредством array()

Масив може да бъде създаден посредством езиковата конструкция array(). Тя приема определено количество двойки ключ => стойност , разделени със запетаи.

array(  ключ =>  стойност
     , ...
     )
// ключът може да бъде цяло число или низ
// стойността може да бъде всякаква
    

<?php
$arr 
= array("foo" => "bar"12 => true);

echo 
$arr["foo"]; // bar
echo $arr[12];    // 1
?>

Ключът може да бъде или цяло число, или низ. Ако ключът е представен като обикновено цяло число, той ще бъде интерпретиран като такова (т.е. "8" ще се интерпретира като 8, докато "08" - като "08"). Плаващите числа в ключовете се съкращават до цели. В PHP не съществуват различни типове за индексирани и асоциативни масиви; има само един тип масив, който може да съдържа едновременно целочислени и низови индекси.

Стойността може да бъде от всякакъв тип.

<?php
$arr 
= array("somearray" => array(=> 513 => 9"a" => 42));

echo 
$arr["somearray"][6];    // 5
echo $arr["somearray"][13];   // 9
echo $arr["somearray"]["a"];  // 42
?>

Ако не укажете изрично ключ за дадена стойност, то ще се вземе най-голямата стойност от целочислените индекси и новият ключ ще бъде тази стойност + 1. Ако укажете ключ, който вече има присвоена стойност, то тази стойност ще бъде презаписана.

<?php
// Този масив е същият като ...
array(=> 433256"b" => 12);

// ...този.
array(=> 43=> 32=> 56"b" => 12);
?>

Предупреждение

От PHP 4.3.0 насам поведението за генериране на индекси се промени. Сега ако добавяте към масив, в който текущият максимален ключ е отрицателен, следващият създаден ключ ще бъде нула (0). А преди, новият индекс щеше да бъде установен в най-големия съществуващ ключ + 1, както е случая с положителните индекси.

Използването на TRUE като ключ ще се изчисли като целочислено 1. Употребата на FALSE като ключ ще се изчисли като целочислено 0. Използването на NULL като ключ ще се изчисли като празнен низ. Употребата на празен низ като ключ ще създаде (или презапише) ключ с празен низ и съответната му стойност; това не е същото като използването на празни квадратни скоби.

Не можете да използвате масиви или обекти като ключове. Ако се опитате да го направите ще предизвикате предупреждение: Illegal offset type (невалиден тип отместване).

Създаване/променяне с квадратни скоби

Можете също да променяте съществуващ масив чрез изрично установяване на стойностите в него.

Това се осъществява чрез присвояване на стойностите в масива, като ключовете се указват в квадратни скоби. Можете също да пропуснете ключа като добавите празна двойка квадратни скоби ("[]") към името на променливата.

$arr[key] = value;
$arr[] = value;
// key може да бъде цяло число или низ
// value може да бъде каква да е стойност
    
Ако масивът $arr все още не съществува, той ще бъде създаден. Така че това също е и алтернативен начин за указване на масив. За да промените дадена стойност, просто присвоете нова стойност на елемента, указан чрез ключа му. Ако искате да премахнете някоя двойка ключ/стойност, трябва да я унищожите посредством unset().

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

$arr[] = 56;    // Това е същото като $arr[13] = 56;
                // в този момент на скрипта

$arr["x"] = 42// Това добавя нов елемент към
                // масива с ключ "x"
                
unset($arr[5]); // Това премахва елемент от масива

unset($arr);    // Това изтрива целия масив
?>

Забележка: Както беше споменато по-горе, ако предоставите квадратните скоби без указан ключ, тогава ще бъде взет максималния съществуващ целочислен индекс и новият ключ ще бъде тази стойност + 1 . Ако все още няма целочислени индекси, ключът ще бъде 0 (нула). Ако укажете ключ, който вече има присвоена стойност, то тази стойност ще бъде презаписана.

Предупреждение

От PHP 4.3.0 насам поведението за генериране на индекси, описано по-горе, се промени. Сега ако добавяте към масив, в който текущият максимален ключ е отрицателен, следващият създаден ключ ще бъде нула (0). А преди, новият индекс щеше да бъде установен в най-големия съществуващ ключ + 1, както е случая с положителните индекси.


Забележете, че максималната целочислена стойност, използвана за целта, не е задължително да същестува в масива в момента. Тя просто трябва да е съществувала някога в масива от последния път, когато масивът е бил повторно индексиран. Следният пример пояснява:

<?php
// Създаване на обикновен масив.
$array = array(12345);
print_r($array);

// Сега изтриваме всеки елемент, но оставяме самия масив непокътнат:
foreach ($array as $i => $value) {
    unset(
$array[$i]);
}
print_r($array);

// Добавяне на елемент (забележете, че новият ключ е 5, а не 0, както
// вероятно бихте очаквали).
$array[] = 6;
print_r($array);

// Повторно индексиране:
$array array_values($array);
$array[] = 7;
print_r($array);
?>

Примерът по-горе ще изведе:

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

Полезни функции

Има няколко полезни функции за работа с масиви. Вж. раздел функции за масиви.

Забележка: Функцията unset() позволява унищожаването на ключове от масив, при което масивът НЯМА да бъде повторно индексиран. Ако използвате единствено "обичайните целочислени индекси" (започващи от нула, увеличаващи се с едно), можете да постигнете ефекта на повторно индексиране като използвате array_values().

<?php
$a 
= array(=> 'one'=> 'two'=> 'three');
unset(
$a[2]);
/* ще доведе до масив, който би бил дефиниран като
   $a = array(1 => 'one', 3 => 'three');
   а НЕ като
   $a = array(1 => 'one', 2 =>'three');
*/

$b array_values($a);
// Сега $b е array(0 => 'one', 1 =>'three')
?>


Контролната структура foreach е създадена специално за масиви. Тя предоставя лесен начин за обхождане на масив.

Правилна и неправилна употреба на масиви

Защо $foo[bar] е погрешно?

Винаги трябва да заграждате низовите индекси на масиви с апострофи. Например използвайте $foo['bar'], а не $foo[bar]. Но защо все пак $foo[bar] е неправилно? Може би сте виждали следния синтаксис в по-стари скриптове:

<?php
$foo
[bar] = 'враг';
echo 
$foo[bar];
// etc
?>

Това е погрешно, но работи. Защо тогава все пак е погрешно? Причината е, че този код използва недефинирана константа (bar), а не низ ('bar' - забележете апострофите) и в бъдеще е възможно PHP да дефинира константи, които за нещастие на кода ви, да имат същото име. Това работи, защото PHP автоматично преобразува голия низ (не-апострофиран низ, който не отговаря на нито един известен символ) в низ, съдържащ голия низ. Например ако няма дефинирана константа bar, PHP ще сложи на нейно място низа 'bar' и ще използва него.

Забележка: Това не означава, че трябва винаги да апострофирате ключа. Не трябва да апострофирате ключове, които са константи или променливи, тъй като това ще попречи на PHP да ги интерпретира.

<?php
error_reporting
(E_ALL);
ini_set('display_errors'true);
ini_set('html_errors'false);
// Прост масив:
$array = array(12);
$count count($array);
for (
$i 0$i $count$i++) {
    echo 
"\nПроверка $i: \n";
    echo 
"Неправилно: " $array['$i'] . "\n";
    echo 
"Правилно: " $array[$i] . "\n";
    echo 
"Неправилно: {$array['$i']}\n";
    echo 
"Правилно: {$array[$i]}\n";
}
?>

Примерът по-горе ще изведе:

Проверка 0: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Неправилно: 
Правилно: 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Неправилно: 
Правилно: 1

Проверка 1: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Неправилно: 
Правилно: 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Неправилно: 
Правилно: 2

Още илюстриращи примери:

<?php
// Let's show all errors
error_reporting(E_ALL);

$arr = array('fruit' => 'apple''veggie' => 'carrot');

// Правилно
print $arr['fruit'];  // apple
print $arr['veggie']; // carrot

// Неправилно. Това работи, но също така хвърля грешка в PHP от ниво
// E_NOTICE, заради недефинирана константа fruit
// 
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];    // apple

// Нека дефинираме константа, за да демонстрираме какво става. Ще
// присвоим стойност 'veggie' на константа fruit.
define('fruit''veggie');

// Забележете разликата сега
print $arr['fruit'];  // apple
print $arr[fruit];    // carrot

// Следното е наред, защото е вътре в низ. В низовете не се търсят константи,
// така че няма да има грешка от ниво E_NOTICE.
print "Hello $arr[fruit]";      // Hello apple

// С едно изключение. Фигурните скоби заобикалящи масиви в низове, позволяват
// намирането на константи.
print "Hello {$arr[fruit]}";    // Hello carrot
print "Hello {$arr['fruit']}";  // Hello apple

// Това няма да работи, ще предизвика синтактична грешка подобна на:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Разбира се, това се отнася също и за употребата на свръхглобални в низове.
print "Hello $arr['fruit']";
print 
"Hello $_GET['foo']";

// Същото може да бъде постигнато и чрез съединяване
print "Hello " $arr['fruit']; // Hello apple
?>

В случай, че повишите нивото на error_reporting() до E_NOTICE (например, задавайки го на ниво E_ALL), ще можете да видите тези грешки. По подразбиране нивото на error_reporting е такова, че да не ги показва.

Както беше споменато и в раздел синтаксис, между квадратните скоби ('[' и ']') трябва да има израз. Това означава, че бихте могли да пишете неща подобни на това:

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

Това е пример за използване на стойност, върната от функция, като индекс на масив. PHP също разбира и от константи, както може би сте забелязали в случая с тези от вида E_*.

<?php
$error_descriptions
[E_ERROR]   = "Настъпи фатална грешка";
$error_descriptions[E_WARNING] = "PHP изведе предупреждение";
$error_descriptions[E_NOTICE]  = "Това е просто информиращо съобщение";
?>

Забележете, че E_ERROR също е валиден индентификатор, също както bar в първия пример. Последният пример всъщност е идентичен на следното:

<?php
$error_descriptions
[1] = "Настъпи фатална грешка";
$error_descriptions[2] = "PHP изведе предупреждение";
$error_descriptions[8] = "Това е просто информиращо съобщение";
?>

понеже E_ERROR е равно на 1, и т.н.

Както вече обяснихме по-горе, $foo[bar] работи, но е погрешно. Работи, понеже се очаква bar, заради синтаксиса си, да бъде константен израз. В този случай, обаче, не съществува константа с името bar. Тогава PHP приема, че сте имали предвид литерала bar, като низа "bar", но че сте забравили да напишете кавичките.

Защо е лошо тогава?

В даден момент от бъдещето е възможно екипът на PHP да реши да добави нова константа или ключова дума, или пък вие да решите да добавите константа в собственото си приложение и в този случай се оказвате в беда. Например, вече не можете да използвате думите empty и default по този начин, защото те са специални запазени ключови думи.

Забележка: Да повторим, в рамките на низ, ограден от кавички, е валидно да не заграждате индексите на масивите с апострофи - така "$foo[bar]" е валидно. Вижте горните примери за причините, както и разделът за синтактичен разбор на променливи в низ.

Преобразуване в масив

За всеки от типовете: integer (цяло число), float (плаващ), string (низ), boolean (булев) или resource (ресурс), ако преобразувате стойност в масив ще получите масив с единствен елемент (с индекс 0), който е скаларната стойност, която сте подали.

Ако преобразувате обект в масив ще получите свойствата (член-променливите) на обекта като елементи на масива. Ключовете са имената на член-променливите, с някои изключния: частните (private) променливи ще имат добавено името на класа пред името на променливата; защитените (protected) променливи ще имат добавено "*" пред името на променливата. Тези допълнителни стойности имат null байт от двете страни. Това би могло да доведе до неочаквани резултати.

<?php

class {
    private 
$A// Това ще стане '\0A\0A'
}

class 
extends {
    private 
$A// Това ще стане '\0B\0A'
    
public $AA// Това ще стане 'AA'
}

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

В горния пример ще изглежда, че има два ключа 'AA', въпреки че единият от тях всъщност е '\0A\0A'.

Ако преобразувате стойността NULL в масив ще получите празен масив.

Сравняване

Можете да сравнявате масиви посредством array_diff() или чрез някой от операторите за масиви.

Примери

Типът масив в PHP е много гъвкав, така че ето няколко примера, които да демонстрират пълната мощ на масивите.

<?php
// това
$a = array( 'color' => 'red',
            
'taste' => 'sweet',
            
'shape' => 'round',
            
'name'  => 'apple',
                       
4        // ключът ще бъде 0
          
);

// е абсолютно еквивалентно на
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // ключът ще бъде 0

$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// ще създаде масив array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// или просто array('a', 'b', 'c')
?>

Example #1 Употреба на array()

<?php
// асоциативен масив
$map = array( 'version'    => 4,
              
'OS'         => 'Linux',
              
'lang'       => 'english',
              
'short_tags' => true
            
);
            
// цифрови ключове
$array = array( 7,
                
8,
                
0,
                
156,
                -
10
              
);
// това е същото като array(0 => 7, 1 => 8, ...)

$switching = array(         10// ключ = 0
                    
5    =>  6,
                    
3    =>  7
                    
'a'  =>  4,
                            
11// ключ = 6 (най-големият целочислен индекс беше 5)
                    
'8'  =>  2// ключ = 8 (целочислен!)
                    
'02' => 77// ключ = '02'
                    
0    => 12  // стойността 10 ще бъде заменена от 12
                  
);
                  
// празен масив
$empty = array();         
?>

Example #2 Колекция

<?php
$colors 
= array('red''blue''green''yellow');

foreach (
$colors as $color) {
    echo 
"Do you like $color?\n";
}

?>

Примерът по-горе ще изведе:

Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?

Прякото променяне на стойности в масив е възможно след PHP 5 чрез подаването им по референция. Предишните версии се нуждаят от заобиколно решение:

Example #3 Колекция

<?php
// PHP 5
foreach ($colors as &$color) {
    
$color strtoupper($color);
}
unset(
$color); /* осигуряване, че последващо писане в
$color няма да промени последния елемент на масива */

// заобикаляне за по-стари версии
foreach ($colors as $key => $color) {
    
$colors[$key] = strtoupper($color);
}

print_r($colors);
?>

Примерът по-горе ще изведе:

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

Този пример създава масив, започвайки с ключ едно.

Example #4 Едно-базиран индекс

<?php
$firstquarter  
= array(=> 'January''February''March');
print_r($firstquarter);
?>

Примерът по-горе ще изведе:

Array 
(
    [1] => 'January'
    [2] => 'February'
    [3] => 'March'
)

Example #5 Попълване на масив

<?php
// пълнене на масив с всички неща от дадена директория
$handle opendir('.');
while (
false !== ($file readdir($handle))) {
    
$files[] = $file;
}
closedir($handle); 
?>

Масивите са подредени. Можете също да променяте реда с помощта на някоя подреждаща функции. Вижте раздел функции за масиви за повече информация. Можете да получите броя на елементите в масив с функцията count().

Example #6 Подреждане на масив

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

Тъй като стойността на масив може да бъде всякаква, то съответно тя може да бъде и друг масив. По този начин можете да правите рекурсивни и многомерни масиви.

Example #7 Рекурсивни и многомерни масиви

<?php
$fruits 
= array ( "fruits"  => array ( "a" => "orange",
                                       
"b" => "banana",
                                       
"c" => "apple"
                                     
),
                  
"numbers" => array ( 1,
                                       
2,
                                       
3,
                                       
4,
                                       
5,
                                       
6
                                     
),
                  
"holes"   => array (      "first",
                                       
=> "second",
                                            
"third"
                                     
)
                );

// някои примери за достъп до масива по-горе
echo $fruits["holes"][5];    // отпечатва "second"
echo $fruits["fruits"]["a"]; // отпечатва "orange"
unset($fruits["holes"][0]);  // премахва "first"

// създаване на нов много-измерен масив
$juices["apple"]["green"] = "good"
?>

Трябва да сте наясно, че присвояването в масиви винаги става с копиране по стойност. Това също означава, че вътрешният масивен указател, използван от current() и подобните й функции, се изчиства. За да копирате масив по референция, трябва да използвате референтния оператор.

<?php
$arr1 
= array(23);
$arr2 $arr1;
$arr2[] = 4// $arr2 е променен,
             // $arr1 е все още array(2, 3)
             
$arr3 = &$arr1;
$arr3[] = 4// сега $arr1 и $arr3 са едно и също
?>

add a note add a note

User Contributed Notes 20 notes

up
61
mlvljr
2 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
36
chris at ocportal dot com
10 months 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
43
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
1
brta dot akos at gmail dot com
3 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
37
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
16
ivegner at yandex dot ru
7 months 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
30
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
27
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
20
caifara aaaat im dooaat be
8 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
0
ffe
3 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
0
note dot php dot lorriman at spamgourmet dot org
3 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
-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
-4
harry at ddtechnologies dot com
9 months 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
-7
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
-8
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
-11
Walter Tross
3 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
-16
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
-27
azuleta at eycambiental dot com
7 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.
up
-51
carl at linkleaf dot com
6 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.
To Top