PHP Australia Conference 2015

آرایه‌ها

یک array در PHP در حقیقت یک نقشه ترتیبی است. یک نقشه یک نوع پیونددهنده مقدارها به کلیدها است. این نوع برای کاربردهای مختلف بهینه‌سازی شده است. می‌تواند بصورت یک آرایه٬ لیست (بردار)٬ جدول درهم‌سازی (یک پیاده‌اسزی نقشه)٬ دیکشنری٬ مجموعه٬ پشته٬ صف٬ و حتی بیشتر با آن رفتار شود. با توجه به این که مقدارهای array می‌تواند array دیگر٬ درخت و array چند بعدی نیز ممکن است.

توضیح این ساختارهای داده فراتر از حوزه این راهنما است اما حداقل یک مثال برای هر یک از آنها فراهم شده است. برای اطلاعات بیشتر به منابع گسترده موجود در این باره ببینید.

دستور

تعریف با استفاده از array()

یک array می‌تواند با استفاده از ساخت زبانی array() ساخته شود. پارامترهای آن تعداد دلخواهی زوج‌های کلید => مقدار است.

array(  key =>  value
     , ...
     )
// key یک integer یا string است
// value هر مقداری از هر نوعی باشد
<?php
$arr 
= array("foo" => "bar"12 => true);

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

یک key می‌تواند integer یا یکor a string باشد. اگر یک کلید نمایش استاندارد integer بهمان صورت تفسیر خواهد گردید (برای نمونه "8" به عنوان 8 استاندارد خواهد شد در حالی که "08" به عنوان "08" ارزیابی خواهد شد). Float در key به integer گرد خواهد شد. انواع پیوندی و اندیسدار array نوع یکسانی در PHP هستند و هر دو شامل اندیس‌های integer و string است.

نوع می‌تواند هر نوع PHP باشد.

Note:

تلاش برای دسترسی به کلید آرایه تعریف نشده همانند دسترسی به هر متغیر تعریف نشده دیگر است: پیام خطای E_NOTICE-level ایجاد خواهد شد و نتیجه NULL بود.

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

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

اگر یک کلید تعیین نشده باشد٬ بیشترین مقدار اندیس integer انتخاب شده و کلید جدید همان مقدار به اضافه یک است. اگر یک کلید پیش از این یک مقدار اختصاص داده شده باشد. آن مقدار بازنویسی می‌گردد.

<?php
// This array is the same as ...
array(=> 433256"b" => 12);

// ...this array
array(=> 43=> 32=> 56"b" => 12);
?>
Warning

پیش از PHP 4.3.0 اضافه نمودن اعضا به یک array دارای کلید بیشترین منفی٬ یک کلید جدید براساس فرایند بالا تولید خواهد کرد. از زمان PHP 4.3.0 کلید جدید 0 خواهد بود.

استفاده از TRUE به عنوان key برابر مقدار integer 1 به عنوان کلید خواهد بود. استفاده از FALSE به عنوان key برابر مقدار integer 0 به عنوان کلید خواهد بود. استفاده از NULL به عنوان کلید برابر با مقدار رشته خالی ارزیابی خواهد گردید. استفاده از رشته خالی به عنوان کلید (یا بازنویسی) یک کلید با رشته خالی و مقدار آن خواهد ساخت. این کار همانند استفاده از براکت خالی نیست.

Array و object نمی‌توانند به عنوان کلید استفاده شود. انجام این کار یک هشدار تولید خواهد کرد: Illegal offset type.

ساخت/تغییر با استفاده از دستور براکت

یک array موجود با تعیین قطعی مقدار در آن تغییر خواهد یافت.

انتصاب مقادیر به array با تعیین کلید در براکت ممکن است. کلید را می‌توان حذف نمود که در نتیجه یک براکت خالی باقی خواهد ماند ([]).

$arr[key] = value;
$arr[] = value;
// key may be an integer or string
// value may be any value of any type

اگر $arr هنوز بوجود نیامده باشد٬ ساخته خواهد شد در نتیجه می‌توان گفت این کار راهی جایگزین برای ساخت یک array است. برای تغییر یک مقدار مشخص مقدار جدید با استفاده از کلید به آن انتصاب داده می‌شود. برای از بین بردن یک کلید/مقدار تابع unset() را بر روی آن فراخوانی نمایید.

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

$arr[] = 56;    // This is the same as $arr[13] = 56;
                // at this point of the script

$arr["x"] = 42// This adds a new element to
                // the array with key "x"
                
unset($arr[5]); // This removes the element from the array

unset($arr);    // This deletes the whole array
?>

Note:

همانطور که در بالا ذکر شد بیشترین اندیس موجود integer به کار خواهد رفت و کلید جدید بیشترین مقدار کلید به اضافه یک است. اگر اندیس integer وجود نداشته باشد کلید 0 (صفر) خواهد بود. اگر یک کلید مقدار مشخص شده‌ای داشته باشد آن مقدار بازنویسی خواهد شد.

توجه کنید بیشترین مقدار کلید استفاده شده در اینجا ممکن است هم اکنون در arrayموجود نباشد . تنها پیشنیاز برای استفاده از کلید وجود آن در array است که از دفعه پیشین array دوباره اندیس گیرد. مثال پایین نشان می‌دهد :

<?php
// Create a simple array.
$array = array(12345);
print_r($array);

// Now delete every item, but leave the array itself intact:
foreach ($array as $i => $value) {
    unset(
$array[$i]);
}
print_r($array);

// Append an item (note that the new key is 5, instead of 0).
$array[] = 6;
print_r($array);

// Re-index:
$array array_values($array);
$array[] = 7;
print_r($array);
?>

The above example will output:

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

توابع مفید

توابع مفیدی برای کار با آرایه‌ها وجود دارد. بخش توابع آرایه را ببینید.

Note:

تابع unset() امکان حذف کلید از array را فراهم نمایید. آگاه باشید آرایه دوباره اندیس‌نگاری نخواهد شد. اگر یک رفتار واقعی حذف و جابجایی مورد نیاز باشد array با استفاده از تابع array_values() دوباره اندیس‌گذاری خواهد شد.

<?php
$a 
= array(=> 'one'=> 'two'=> 'three');
unset(
$a[2]);
/* will produce an array that would have been defined as
   $a = array(1 => 'one', 3 => 'three');
   and NOT
   $a = array(1 => 'one', 2 =>'three');
*/

$b array_values($a);
// Now $b is array(0 => 'one', 1 =>'three')
?>

ساختار کنترلی foreach برای array وجود دارد. یک راه ساده برای برعکس نمودن یک array ایجاد کرده است.

چه کارهایی باید با آرایه انجام دهید و چه کاری انجام ندهید

چرا $foo[bar] اشتباه است?

همیشه از نقل قول برای اندیس رشته‌ای استفاده نمایید. برای نمونه $foo['bar'] صحیح در حالی که $foo[bar] صحیح نیست. اما چرا? به صورت معمول با دستور زیر در اسکریپت‌های قدیمی روبرو خواهید شد:

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

این اشتباه است اما کار می‌کند. دلیل این امر وجود ثابت تعریف نشده (bar) به غیر از string ('bar' به علامت '' توجه نمایید) است. PHP ممکن است در آینده ثابت‌هایی همنام با چنین کدی تعریف نماید. این کد بدلیل تبدیل خودکار رشته بدون علامت (یک string بدون نقل قول که به هیچ یک از سمبل‌های شناخته شده مشابه نیست) به string به همراه string بدون علامت بدون مشکل عمل می‌نماید. برای نمونه اگر ثابتی با نام bar تعریف نشده باشد آنگاه PHP نوع داده string یعنی 'bar' را جایگزین کرده و از آن استفاده خواهد کرد.

Note: این به معنای استفاده همیشگی نقل قول برای کلید نیست. کلیدهایی که ثابت یا متغیر هستند نباید از نقل قول برای آنها استفاده کرد. چرا که نقل قول مانع از تفسیر آنها توسط PHP خواهد شد.

<?php
error_reporting
(E_ALL);
ini_set('display_errors'true);
ini_set('html_errors'false);
// Simple array:
$array = array(12);
$count count($array);
for (
$i 0$i $count$i++) {
    echo 
"\nChecking $i: \n";
    echo 
"Bad: " $array['$i'] . "\n";
    echo 
"Good: " $array[$i] . "\n";
    echo 
"Bad: {$array['$i']}\n";
    echo 
"Good: {$array[$i]}\n";
}
?>

The above example will output:

Checking 0: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Bad: 
Good: 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Bad: 
Good: 1

Checking 1: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Bad: 
Good: 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Bad: 
Good: 2

مثال‌هایی برای نمایش این رفتار:

<?php
// Show all errors
error_reporting(E_ALL);

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

// Correct
print $arr['fruit'];  // apple
print $arr['veggie']; // carrot

// Incorrect.  This works but also throws a PHP error of level E_NOTICE because
// of an undefined constant named fruit
// 
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];    // apple

// This defines a constant to demonstrate what's going on.  The value 'veggie'
// is assigned to a constant named fruit.
define('fruit''veggie');

// Notice the difference now
print $arr['fruit'];  // apple
print $arr[fruit];    // carrot

// The following is okay, as it's inside a string. Constants are not looked for
// within strings, so no E_NOTICE occurs here
print "Hello $arr[fruit]";      // Hello apple

// With one exception: braces surrounding arrays within strings allows constants
// to be interpreted
print "Hello {$arr[fruit]}";    // Hello carrot
print "Hello {$arr['fruit']}";  // Hello apple

// This will not work, and will result in a parse error, such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using superglobals in strings as well
print "Hello $arr['fruit']";
print 
"Hello $_GET['foo']";

// Concatenation is another option
print "Hello " $arr['fruit']; // Hello apple
?>

زمانی که error_reporting را برای نمایش خطاهای سطج show E_NOTICE تنظیم کرده باشید (برای نمونه با تنظیم مقدار به E_ALL) چنین کاربردهایی سریعا مشخص خواهد شد. به طور پیشفرض error_reporting notice را نشان نمی‌دهد.

همانطور که در بخش دستور گفته شد٬ هر چه داخل براکت قرار گیرد ('[' و ']') یک عبارت خواهد بود. این موضوع به معنای کارکرد کد زیر است:

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

این مثال استفاده از یک تابع برای بازگرداندن مقدار اندیس است. PHP در مورد ثابت‌ها نیز اطلاع دارد:

<?php
$error_descriptions
[E_ERROR]   = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE]  = "This is just an informal notice";
?>

توجه کنید که E_ERROR یک تشخیص دهنده صحیح است مانند bar در مثال ابتدایی است. اما در مثال آخر همانند زیر است:

<?php
$error_descriptions
[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
?>

زیرا E_ERROR برابر 1 است٬ غیره.

پس چرا این کار بد است؟

در زمانی در آینده تیم PHP کلمه کلیدی یا ثابت دیگری ممکن است اضافه نماید. برای نمونه استفاده از کلماتی مانند empty و default به این صورت اشتباه است زیرا آنها کلمات رزرو شده هستند.

Note: برای تکرار٬ در یک string با "" همراه نکردن اندیس‌های آرایه با نقل قول "$foo[bar]" نیز صحیح است. مثال بالا برای جزئیات بیشتر درباره چرایی آن بخش تحلیل متغیر در رشته را ببینید.

تبدیل آرایه

برای هر نوع دیگر: integer٬ float٬ string٬ boolean و resource٬ تبدیل یک مقدار به یک array یک آرایه با تک عضوی با اندیس صفر خواهد شد و مقدار آن مقدار خطی تبدیل شده است. به عبارت دیگر (array)$scalarValue دقیقا همانند array($scalarValue) است.

اگر یک object به array تبدیل شود نتیجه یک array خواهد بود و اعضای آن ویژگی‌های object است. کلید‌ها نام متغیرهای عضو است که چندین استثنا دارد: متغیرهای خصوصی نام کلاس را به نام متغیر اضافه خواهند کرد. متغیرهای حفاظت شده یک '*' به نام متغیر اضافه شده است. این مقدارهای اضافه شده بایت‌های null داشته که در هر طرف آن اضافه شده است. این نتیجه یک رفتار نامشخص ایجاد خواهد کرد:

<?php

class {
    private 
$A// This will become '\0A\0A'
}

class 
extends {
    private 
$A// This will become '\0B\0A'
    
public $AA// This will become 'AA'
}

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

کد بالا نشان می‌دهد که دو کلید با نام‌های 'AA' دارد در حالی که یکی از آنها دارای نام '\0A\0A' است.

تبدیل NULL به یک array یک array خالی ایجاد خواهد کرد.

مقایسه

می‌توان آرایه‌های را با استفاده از تابع array_diff() و عملگرهای آرایه استفاده نمود.

مثال‌ها

نوع آرایه در PHP همه فن حریف است. در اینجا چند مثال نشان داده شده است:

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

// is completely equivalent with
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // key will be 0

$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// will result in the array array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// or simply array('a', 'b', 'c')
?>

Example #1 استفاده از array()

<?php
// Array as (property-)map
$map = array( 'version'    => 4,
              
'OS'         => 'Linux',
              
'lang'       => 'english',
              
'short_tags' => true
            
);
            
// strictly numerical keys
$array = array( 7,
                
8,
                
0,
                
156,
                -
10
              
);
// this is the same as array(0 => 7, 1 => 8, ...)

$switching = array(         10// key = 0
                    
5    =>  6,
                    
3    =>  7
                    
'a'  =>  4,
                            
11// key = 6 (maximum of integer-indices was 5)
                    
'8'  =>  2// key = 8 (integer!)
                    
'02' => 77// key = '02'
                    
0    => 12  // the value 10 will be overwritten by 12
                  
);
                  
// empty array
$empty = array();         
?>

Example #2 مجموعه

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

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

?>

The above example will output:

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

تغییر مقدار array بصورت مستقیم ممکن است زیرا PHP 5 آنها را با مرجع ارسال می‌نماید. پیش از آن کارهای دیگری نیز باید انجام می‌شد:

Example #3 مجموعه

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

// Workaround for older versions
foreach ($colors as $key => $color) {
    
$colors[$key] = strtoupper($color);
}

print_r($colors);
?>

The above example will output:

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

این مثال ساخت آرایه براساس یک را نشان می‌دهد.

Example #4 اندیس براساس یک

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

The above example will output:

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

Example #5 پر نمودن یک آرایه

<?php
// fill an array with all items from a directory
$handle opendir('.');
while (
false !== ($file readdir($handle))) {
    
$files[] = $file;
}
closedir($handle); 
?>

Array دارای ترتیب است. ترتیب با استفاده از توابع مرتب کننده متفاوت قابل تغییر است. بخش توابع آرایه را برای اطلاعات بیشتر ببینید. تابع count() می‌ٰتواند تعداد اعضای موارد در array را بشمارد.

Example #6 مرتب نمودن یک آرایه

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

مقدار یک array هرچیزی می‌تواند باشد و حتی می‌تواند یک array دیگر باشد. این کار ایجاد array چندبعدی و بازگشتی را ممکن می‌سازد.

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"
                                     
)
                );

// Some examples to address values in the array above 
echo $fruits["holes"][5];    // prints "second"
echo $fruits["fruits"]["a"]; // prints "orange"
unset($fruits["holes"][0]);  // remove "first"

// Create a new multi-dimensional array
$juices["apple"]["green"] = "good"
?>

انتصاب Array همیشه کپی نمودن مقدار است. همچنین اشاره‌گر داخلی array استفاده شده توسط current() و توابع مشابه بازنویسی خواهد شد. از عملگر مرجع برای کپی نمودن array با مرجع استفاده نمایید.

<?php
$arr1 
= array(23);
$arr2 $arr1;
$arr2[] = 4// $arr2 is changed,
             // $arr1 is still array(2, 3)
             
$arr3 = &$arr1;
$arr3[] = 4// now $arr1 and $arr3 are the same
?>
add a note add a note

User Contributed Notes 22 notes

up
72
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
2
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
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
32
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
43
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
35
ia [AT] zoznam [DOT] sk
9 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
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
31
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
mathiasgrimm at gmail dot com
2 days ago
<?php

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

echo
$a['a']['non-existent']; // DOES NOT throw an E_NOTICE error as expected.

echo $a['b']['non-existent']; // throws an E_NOTICE as expected
?>

I added this bug to bugs.php.net (https://bugs.php.net/bug.php?id=68110)
however I made tests with php4, 5.4 and 5.5 versions and all behave the same way.

This, in my point of view, should be cast to an array type and throw the same error.

This is, according to the documentation on this page, wrong.

From doc:
"Note:
Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an E_NOTICE-level error message will be issued, and the result will be NULL."
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
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
-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
-5
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
-10
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
-18
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
-20
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
-5
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
8 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
-59
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
-43
azuleta at eycambiental dot com
1 year 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