değer veya başvuru tarafından geçirilen php diziler nelerdir?

4 Cevap php

Bir dizinin referans geçirilen bir yöntem veya işlev için bağımsız değişken olarak geçirilen zaman?

Bu ne yapıyor hakkında:


    $a = $array(1,2,3);
    $b = $a

$ A $ bir başvuru b?

4 Cevap

Sorunuzun ikinci kısmı için, array page of the manual, devletler görmek (quoting):

Array assignment always involves value copying. Use the reference operator to copy an array by reference.

Ve verilen örnek:

<?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
?>


For the first part, the best way to be sure is to try ;-)

Bu kod örneği düşünün:

function my_func($a) {
    $a[] = 30;
}

$arr = array(10, 20);
my_func($arr);
var_dump($arr);

Bu çıktıyı vereyim:

array
  0 => int 10
  1 => int 20

Bir kopya olarak geçti, ve bir başvuru: fonksiyonu parametre olarak geçildi "dışarıdan" bir dizi modifiye değil gösterir.

Eğer referans olarak geçti istiyorsanız, işlevi, bu şekilde değiştirmeniz gerekir:

function my_func(& $a) {
    $a[] = 30;
}

Ve çıkış olacaktır:

array
  0 => int 10
  1 => int 20
  2 => int 30

Bu süre, gibi, dizi "referans" kabul edilmiştir.


Don't hesitate to read the References Explained section of the manual : it should answer some of your questions ;-)

Eğer aradığınız yöntemi / fonksiyonu içinde değiştirilmiş SÜRECE ilk soru ile ilgili olarak, dizi referans olarak geçirilir. Eğer yöntemi / fonksiyonu içinde diziyi değiştirmeye çalışırsanız, bunun bir ilk kopyası yapılır, ve sonra sadece kopya değiştirilir. Bu gerçek aslında öyle değil zaman dizi değeri tarafından geçirilir gibi görünüyor yapar.

Eğer israf etmeyin: Örneğin, bu ilk durumda, (parametre tanımında & karakteri kullanarak) referans ile $ my_array kabul etmek işlevi tanımlayarak olmasa bile, yine de (yani referans olarak geçti alır Gereksiz bir kopyası bellek).

function handle_array($my_array) {  

    // ... read from but do not modify $my_array
    print_r($my_array);

    // ... $my_array effectively passed by reference since no copy is made
}

Eğer diziyi değiştirmez Ancak, onun bir kopyası (daha fazla bellek kullanır ama etkilenmemiş özgün dizi bırakır) ilk yapılır.

function handle_array($my_array) {

    // ... modify $my_array
    $my_array[] = "New value";

    // ... $my_array effectively passed by value since requires local copy
}

http://www.thedeveloperday.com/php-lazy-copy/: Bilginize - daha fazla bilgi burada - bu "tembel kopya" ya da "copy-on-write" olarak bilinir

Bir dizi PHP bir yöntem veya işleve geçirilen zaman açıkça şöyle, referans olarak geçmek sürece, bu değeri tarafından geçirilir:

function test(&$array) {
    $array['new'] = 'hey';
}

$a = $array(1,2,3);
// prints [0=>1,1=>2,2=>3]
var_dump($a);
test($a);
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

İkinci soruda, $b $a için bir referans değil, ama bir kopyasını $a.

Much ilk örnek gibi, $a aşağıdakileri yaparak başvurabilirsiniz:

$a = array(1,2,3);
$b = &$a;
// prints [0=>1,1=>2,2=>3]
var_dump($b);
$b['new'] = 'hey';
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

Ben kendim için bu yazıyorum düşünüyorum. Ben bir blog veya bir şey olmalı ...

Whenever people talk of references (or pointers, for that matters), they usually end up in a logomachy (just look at this thread!).
PHP being a venerable language, I thought I should add up to the confusion (even though this a summary of the above answers). Because, although two people can be right at the same time, you're better off just cracking their heads together into one answer.

Öncelikle, bilmeli you're not a pedant if you don't answer in a black-and-white manner. Şeyler "evet / hayır" daha karmaşıktır.

Okuma veya değiştirme: Gördüğünüz gibi, bütün by-value/by-reference şey çok ne tam olarak sizin yöntem / fonksiyon kapsamında bu dizi ile yapıyoruz ilişkilidir?

What does PHP says? (aka "change-wise")

manual Bu (vurgu benim) diyor ki:

By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.

To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition

Büyük, ciddi, dürüst Tanrı programcılar başvurular hakkında konuşmak Bildiğim kadarıyla söyleyebilirim, genellikle altering the value of that reference bahsedeceğiz. Ve bu tam olarak ne manuel görüşmeler: hey, if you want to CHANGE the value in a function, consider that PHP's doing "pass-by-value".

There's another case that they don't mention, though: what if I don't change anything - just read?
What if you pass an array to a method which doesn't explicitly marks a reference, and we don't change that array in the function scope? Aka:

<?php
function printArray($array) {}
$x = array(1);
printArray($x);

, Benim adam gezgin okumak.

What does PHP actually do? (aka "memory-wise")

Hatta daha ciddi zaman aynı büyük ve ciddi programcılar, onlar referanslar açısından "bellek optimizasyonları" hakkında konuşun. Yani PHP yapar. PHP is a dynamic, loosely typed language, that uses copy-on-write and reference counting, o why. Nedeniyle

Çeşitli fonksiyonlara BÜYÜK diziler geçmek için ideal olmaz, ve PHP bunların kopyalarını (bu da ne "pass-by-value" yapar, sonra hepsi) yapmak için:

<?php

// filling an array with 10000 elements of int 1
// let's say it grabs 3 mb from you RAM
$x = array_fill(0, 10000, 1); 

// pass by value, right? RIGHT?
function readArray($arr) { // <-- a new symbol (variable) gets created here
    echo count($arr); // let's just read the array
}

readArray($x);

Bu aslında pass-by-value ise orada o dizinin two kopyaları olan, doğru çünkü Eh şimdi, biz, bazı 3MB + RAM gitmiş olurdu?

Yanlış. Sürece biz $arr değişkeni değiştirmek yok gibi, bu bir referans var, memory-wise. Sadece bunu görmüyorum. PHP mentions user-land referanslar when talking about &$someVar, iç ve (işareti ile) açık olanları ayırt etmek nedeni budur.

Facts

Yani, when an array is passed as an argument to a method or function is it passed by reference?

I came up with three (yeah, three) cases:
a) the method/function only reads the array argument
b) the method/function modifies the array argument
c) the method/function array argument is explicitly marked as a reference (with an ampersand)


Öncelikle, bu dizi aslında (run here) yiyor ne kadar bellek görelim:

<?php
$start_memory = memory_get_usage();
$x = array_fill(0, 10000, 1);
echo memory_get_usage() - $start_memory; // 1331840

Bu birçok bayt. Harika.

a) the method/function only reads the array argument

Şimdi bir argüman olarak only reads dedi dizisi bir işlev yapalım ve biz okuma mantık alır ne kadar bellek görürsünüz:

<?php

function printUsedMemory($arr) 
{
    $start_memory = memory_get_usage();

    count($arr);       // read
    $x = $arr[0];      // read (+ minor assignment)
    $arr[0] - $arr[1]; // read

    echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}

$x = array_fill(0, 10000, 1); // this is 1331840 bytes
printUsedMemory($x);

Ister sanırım? Ben 80 olsun! See for yourself. Bu PHP kılavuzu atlar ki parçasıdır. $arr param aslında geçmiş-by-value edilmiş ise, 1331840 bayt benzer bir şey görmek istiyorum. Bu $arr bir referans gibi değil davranır gibi görünüyor? İşte o is a referanslar - çünkü bir iç biri.

b) the method/function modifies the array argument

Şimdi, bunun yerine ondan okuma, write o param edelim:

<?php

function printUsedMemory($arr)
{
    $start_memory = memory_get_usage();

    $arr[0] = 1; // WRITE!

    echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}

$x = array_fill(0, 10000, 1);
printUsedMemory($x);

Yine, see for yourself, ama benim için, o 1331840 olmaya oldukça yakın. Bu durumda, dizi is aslında $arr kopyalanan yüzden.

c) the method/function array argument is explicitly marked as a reference (with an ampersand)

Şimdi a write operation to an explicit reference (run here) alır ne kadar bellek görelim - fonksiyon imzadaki işareti not:

<?php

function printUsedMemory(&$arr) // <----- explicit, user-land, pass-by-reference
{
    $start_memory = memory_get_usage();

    $arr[0] = 1; // WRITE!

    echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}

$x = array_fill(0, 10000, 1);
printUsedMemory($x);

Benim bahis 200 max almak olduğunu! Yani bu reading from a non-ampersand param yaklaşık olarak kadar bellek yiyor.

Conclusions

a) the method/function only reads the array argument => implicit (internal) reference
b) the method/function modifies the array argument => value
c) the method/function array argument is explicitly marked as a reference (with an ampersand) => explicit (user-land) reference

Or this:
- non-ampersand array param: passed by reference; the writing operations alter a new copy of the array, copy which is created on the first write;
- ampersand array param: passed by reference; the writing operations alter the original array.

Unutmayın - PHP olmayan ampersanı dizi param bir değer kopyasını the moment you write yapar. İşte copy-on-write demek. Sana bu davranış, C kaynak göstermek isterdim, ama orada lekelenmeler var. Iyi kullanılması xdebug_debug_zval().

Pascal MARTIN haklıydı. Kosta Kontos daha çok oldu.

Answer

Duruma göre değişir.