On 5.4 I would also assume that the shortened array syntax would be usable to define an array:
<?php
$myArray = []; // instead of array();
?>
Nothing major but it could be of convenience.
آرایهها
یک 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(6 => 5, 13 => 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(5 => 43, 32, 56, "b" => 12);
// ...this array
array(5 => 43, 6 => 32, 7 => 56, "b" => 12);
?>
پیش از 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(5 => 1, 12 => 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(1, 2, 3, 4, 5);
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(1 => 'one', 2 => 'two', 3 => '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(1, 2);
$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 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());
?>
کد بالا نشان میدهد که دو کلید با نامهای 'AA' دارد در حالی که یکی از آنها دارای نام '\0A\0A' است.
مقایسه
میتوان آرایههای را با استفاده از تابع 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(1 => '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",
5 => "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(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
// $arr1 is still array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>
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.
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.
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.
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]
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).
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');
?>
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.
[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
)
)
*/
?>
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;
}
?>
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.
Like in Perl, you can use curly braces ({}) instead of square brackets ([]) to access array members:
<?php
$a = array ();
$a[7] = 'seven';
$a{'hello'} = 'world';
print $a{7} . ' ' . $a['hello'];
?>
Prints 'seven world'.
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.
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.
