2012-05-22 28 views
5
$a=array('a','b','c','d'); 

while(key($a)!==NULL){ 
    echo key($a).'=>'.current($a).'<br/>'; 
    next ($a); 
} 

prev($a); 
var_dump(current($a)); 

Tại sao var_dump trả lại false thay vì "d"?Số lẻ con trỏ mảng php

+0

Tôi đoán khi bạn đã đi hết phần kết thúc, giá trị sẽ không còn hoạt động nữa. Không chắc chắn mặc dù. – Corbin

+0

@Corbin Tôi hy vọng bạn đúng, mặc dù không ngạc nhiên khi các nhà phát triển PHP đã không đề cập đến trong tài liệu ... – Alnitak

Trả lời

4

Đó chắc chắn là do thiết kế, và mặc dù tôi đã chải qua PHP tài liệu, tôi có thể tìm thấy không có tham chiếu đến thực tế rằng khi bạn vô hiệu hóa con trỏ bằng cách next ing qua cuối mảng bạn không còn có thể sử dụng prev, mã nguồn PHP (zend_hash.c) làm rõ điều gì đang diễn ra:

ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos) 
{ 
    HashPosition *current = pos ? pos : &ht->pInternalPointer; 

    IS_CONSISTENT(ht); 

    if (*current) { 
     *current = (*current)->pListNext; 
     return SUCCESS; 
    } else 
     return FAILURE; 
} 

ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos) 
{ 
    HashPosition *current = pos ? pos : &ht->pInternalPointer; 

    IS_CONSISTENT(ht); 

    if (*current) { 
     *current = (*current)->pListLast; 
     return SUCCESS; 
    } else 
     return FAILURE; 
} 

Như bạn có thể thấy, zend_hash_move_backwards_ex (trong đó, PHP, được ánh xạ tới prev) kiểm tra có hay không con trỏ hiện nay là hợp lệ trước khi làm bất cứ điều gì, và zend_hash_move_forward_ex sẽ thiết lập các giá trị cho pListNext mà sẽ là null trong trường hợp của phần tử cuối cùng.

tức là không giống như bạn mong đợi, nextprev không chỉ tăng hoặc giảm con trỏ C một cách mù quáng sau đó kiểm tra kết quả để trả về giá trị hoặc NULL, chúng thực sự kiểm tra con trỏ trước khi tăng hoặc giảm.

Đây là chắc chắn một lỗ hổng trong tài liệu và chắc chắn cần được ghi lại. Như đã đề cập trong câu trả lời khác, bạn có thể sử dụng end để chuyển đến phần tử cuối cùng sau khi con trỏ đã bị vô hiệu hóa bằng cách lặp qua danh sách.

Tuy nhiên, bạn sẽ có thể thực hiện logic mà bạn muốn (không cần phải sử dụng end()) bằng cách sao chép con trỏ trước mỗi tiến trình và sau đó sử dụng con trỏ nhân bản sau khi đến cuối mảng. (nhưng không có lý do thực sự tốt để làm điều này nếu bạn đã biết prev() bị hỏng theo thiết kế về điều hướng ngược của một mảng đã được lặp lại)

(Chủ đề: Tôi rất vui khi thấy truyền thống PHP được tôn trọng) sử dụng inconsistentfunction names vẫn còn hoạt động và ngay cả trong mã C cơ bản: zend_hash_move_forward_ex vs zend_hash_move_backward*s*_ex.)

0
$a=array('a','b','c','d'); 

while(key($a)!==NULL){ 
    echo key($a).'=>'.current($a).'<br/>'; 
    next ($a); 
} 

prev($a); 
var_dump(current($a)); 

trong mã này tiếp theo trả về giá trị tiếp theo và ở cuối vòng lặp, nó cung cấp phần tử cuối cùng nhưng con trỏ tiến tới tức là null. nên var_dump(current($a)); retunrs bạn false

nhưng

$a=array('a','b','c','d'); 

while(key($a)!==NULL){ 
    echo key($a).'=>'.current($a).'<br/>'; 
    next ($a); 
} 

//prev($a); 
end(($a); 
var_dump(current($a)); 

bạn sẽ nhận được mong muốn của bạn yếu tố d như nó trỏ tới phần tử cuối cùng d

+0

Tôi nghĩ rằng OP nhận ra rằng, câu hỏi thực sự là lý do tại sao bạn không thể sử dụng 'prev' sau ' tiếp theo' đến cuối mảng. –

+0

Tôi đã giải thích lý do tại sao anh ta nhận được giá trị sai –