2012-07-02 42 views
7

Tôi đang cố gắng để chèn vào một mảng tại một điểm nhất định:PHP: Chèn tham chiếu vào một mảng?

$hi = "test"; 
$var2 = "next"; 
$arr = array(&$hi); 
$arr[] = &$var2; // this works 
array_splice($arr, 1, 0, &$var2); // this doesn't 

Tại sao cố gắng để chèn nó vào mảng với mối nối thất bại và sử dụng phương pháp đầu tiên không?

Trả lời

6

Câu trả lời nhanh chóng-và-bẩn, nhưng hãy lưu ý rằng gọi chức năng này với một tham chiếu bị phản đối và có thể (tùy thuộc vào cấu hình php của bạn) tạo ra một cảnh báo:

array_splice($arr, 1, 0, array(&$var2)); 

Các hows- và-whys trả lời: Điều gì đang xảy ra là khá tinh tế. Khi bạn làm mối nối, bởi vì bạn đã chèn một tham chiếu vào vị trí đó, $ var2 thực sự được gán lại. Bạn có thể xác minh nó với đoạn mã sau:

<?php 
    $hi = "test"; 
    $var2 = "next"; 
    $arr = array(&$hi); 
    $arr[] = &$var2; // this works 
    printf("=== var2 before splice:\n%s\n", var_export($var2, TRUE)); 
    array_splice($arr, 1, 0, &$var2); // this doesn't 
    printf("=== var2 after splice:\n%s\n", var_export($var2, TRUE)); 
?> 

Bạn sẽ nhận được kết quả sau:

=== var2 before splice: 
'next' 
=== var2 after splice: 
array (
    0 => 'next', 
) 

ý rằng trước khi hàn, $ var2 là một chuỗi, cũng giống như bạn mong đợi nó đến được ('kế tiếp'). Sau khi ghép nối, mặc dù, $ var2 đã được thay thế bằng một mảng chứa một phần tử, chuỗi 'next'.

Tôi nghĩ nguyên nhân của tài liệu là: "Nếu thay thế không phải là mảng, nó sẽ được nhập thành một (ví dụ: tham số $ array)." Vì vậy, những gì đang xảy ra là thế này:

  • Bạn đang đi qua & $ var2 vào mảng như thay.
  • Nội bộ, php đang chuyển đổi & $ var2 thành mảng (& $ var2). Nó thực sự có thể làm một cái gì đó tương đương với $ param = array ($ param), có nghĩa là & $ var2 sẽ được đặt thành mảng (& $ var2), và vì nó là tham chiếu chứ không phải bản sao của $ var2 như bình thường sẽ là, điều này đang ảnh hưởng đến biến mà thông thường sẽ nằm ngoài phạm vi của cuộc gọi.
  • Bây giờ nó di chuyển giá trị mới này của $ var2 đến vị trí kết thúc và chèn một bản sao của $ var2 ở vị trí thứ hai.

Tôi không chắc chắn chính xác tất cả các thuật sĩ về những gì đang xảy ra trong nội bộ, nhưng $ var chắc chắn sẽ được gán lại trong mối nối.Chú ý rằng nếu bạn sử dụng một biến thứ ba, vì nó không phải gán một cái gì đó để cái gì đó đã tồn tại như một tài liệu tham khảo, nó hoạt động như mong đợi:

<?php 
    $hi = "test"; 
    $var2 = "next"; 
    $var3 = "last"; 
    $arr = array(&$hi); 
    $arr[] = &$var2; // this works 
    array_splice($arr, 1, 0, &$var3); 
    printf("=== arr is now\n%s\n", var_export($arr, TRUE)); 
?> 

Tạo kết quả:

=== arr is now 
array (
    0 => 'test', 
    1 => 'last', 
    2 => 'next', 
) 
+0

P.S. Tôi nghĩ rằng lý do gọi nó với mảng (& $ var2) hoạt động là bởi vì nội bộ, mối nối không phải chuyển đổi & $ var2 thành mảng (& $ var2) có khả năng thông qua tự gán, do đó thay đổi $ var2 trong quá trình . Bạn đang tạo một mảng biểu tượng mới (& $ var2) một cách rõ ràng về mặt vật lý riêng biệt trong bộ nhớ mà không cần phải tự gán. –

+0

P.P.S. Loại tác dụng phụ không mong muốn này chính xác là lý do tại sao thời gian gọi qua tham chiếu đã không được chấp nhận. ;) –

+0

@AndyLobel bạn nên thay đổi câu trả lời được chấp nhận cho câu trả lời này. – Hamish

2

Bạn có thể cần đặt đối số cuối cùng thành mảng, nếu không, theo manual, bạn sẽ được nhập thành một.

array_splice($arr, 1, 0, array(&$var2)); 
+0

tehe cũng được thực hiện;) –

+0

Giải pháp là đúng, nhưng vì lý do @ Travesty3 của. Typecasting không phải là một vấn đề - đó là thời gian gọi đi qua tham chiếu thất bại. – Hamish

+0

từ hướng dẫn: 'Nếu thay thế chỉ là một phần tử thì không cần đặt mảng() xung quanh nó, trừ khi phần tử là một mảng, một đối tượng hoặc NULL.' – alfasin

1

Khi tôi thử ví dụ như của bạn, tôi nhận được cảnh báo cho biết "Gọi qua thời gian tham chiếu đã không được chấp nhận". Theo số this answer:

Bạn có thể đặt allow_call_time_pass_reference thành true trong tệp php.ini của mình. Nhưng đó là một hack.

0

Ở đây tôi đang lặp lại một mảng ($ values_arr) và lưu trữ các tham chiếu của mỗi biến trong mảng khác ($ params). Bạn có thể thay đổi cách sử dụng nó theo yêu cầu của bạn.

$params = array(); 
$values_arr = array('a', 'b', 123); 
foreach ($values_arr as $key=>&$val) { 
    $params[$key] = &$val; 
} 

quả

array (size=3) 
    0 => &string 'a' (length=1) 
    1 => &string 'b' (length=1) 
    2 => &int 123 
Các vấn đề liên quan