2011-07-04 35 views
41

Làm thế nào bạn có thể dễ dàng tránh nhận được lỗi này/thông báo:Làm thế nào để tránh không xác định bù đắp

Notice: Undefined offset: 1 in /var/www/page.php on line 149 

... trong mã này:

list($func, $field) = explode('|', $value); 

Có phải lúc nào cũng hai giá trị được trả về bởi phát nổ, nhưng nếu bạn muốn sử dụng danh sách() làm thế nào bạn có thể dễ dàng tránh được thông báo?

Trả lời

93
list($func, $field) = array_pad(explode('|', $value, 2), 2, null); 

Hai thay đổi:

  • Nó giới hạn kích thước của mảng được trả về bởi explode() để 2. Có vẻ như, đó không quá này đang bị truy nã
  • Nếu có ít hơn hai giá trị trở lại , nó gắn thêm null cho đến khi mảng chứa 2 giá trị.Xem Manual: array_pad() để biết thêm thông tin

Điều này có nghĩa, nếu không có | trong $value, $field === null. Tất nhiên bạn có thể sử dụng mọi giá trị bạn muốn xác định làm mặc định cho $field (thay vì null). Nó cũng có thể trao đổi các hành vi của $func$field

list($func, $field) = array_pad(explode('|', $value, 2), -2, null); 

Bây giờ $funcnull, khi không có | trong $value.

1

Bạn nhận được một undefined offset khi điều bạn đang cố gắng phát nổ chuỗi bởi ($value) không thực sự có nó, tôi tin.

Câu hỏi này rất giống với câu hỏi này: undefined offset when using php explode(), trong đó có giải thích rõ hơn cần giải quyết đầy đủ vấn đề của bạn.

Để kiểm tra sự xuất hiện của '|' để ngăn chặn lỗi, bạn có thể làm:

$pos = strpos($value,'|'); 

if(!($pos === false)) { 
    //$value does contain at least one | 
} 

Hy vọng điều này sẽ hữu ích.

+0

@Down Cử tri bạn có thể giải thích lý do tại sao không? Tôi không có vấn đề gì với việc bị downvoted nếu tôi đã thực hiện một lỗi, nếu bạn có thể giải thích tại sao tôi có thể sửa bài viết và cũng học từ nơi tôi đã đi sai! Chúc mừng. –

+0

Bạn vẫn có thể gặp lỗi ngay cả khi 'strpos' trả về' true'. '$ value = 'gần như | hoàn hảo'; $ pos = strpos ($ value, '|'); if ($ pos === true) {danh sách ($ một, $ hai, $ ba) = phát nổ ('|', $ value); } ' –

0
if (count(explode('|', $value))==2) 
    list($func, $field) = explode('|', $value); 

Tuy nhiên, nó không phải là tối ưu.

+1

Phát nổ hai lần? Tại sao không chỉ phát hiện nếu có một nhân vật ống, sau đó phát nổ? –

0

tôi có lẽ muốn chia nhỏ ra thành hai bước

$split = explode('|', $value); 
$func = $split[0]; 
if(count($split) > 1) 
    $field = $split[1]; 
else 
    $field = NULL; 

Có lẽ một nhanh hơn và cách gọn gàng mặc dù.

+0

Điều này sẽ để lại '$ field' undefined mặc dù, đó là hầu như không có bất kỳ tốt hơn so với một chỉ số không xác định. – phant0m

+0

Có bạn đã đúng. Tôi đã thêm một dòng để đặt nó thành NULL trong trường hợp nó đã được định nghĩa trước đó. Nhưng trong mọi trường hợp, tôi nghĩ bạn muốn kiểm tra giá trị của trường $ trước khi bạn sử dụng nó. –

8

Tôi không biết một cách trực tiếp để làm điều này mà cũng bảo sự tiện lợi của

list($func, $field) = explode('|', $value); 

Tuy nhiên, vì nó thực sự đáng tiếc không để có thể làm được điều này, bạn có thể muốn xem xét một cách tiếp cận gián tiếp lén lút:

list($func, $field) = explode('|', $value.'|'); 

tôi đã nối vào $value như nhiều | s khi cần thiết để đảm bảo rằng explode sẽ sản xuất ít nhất 2 mục trong mảng. Đối với các biến số n, hãy thêm n-1 ký tự dấu tách.

Bằng cách này bạn sẽ không gặp bất kỳ lỗi nào, bạn giữ nhiệm vụ thuận tiện list và mọi giá trị không tồn tại trong đầu vào sẽ được đặt thành chuỗi trống. Đối với phần lớn các trường hợp, trường hợp sau không nên cung cấp cho bạn bất kỳ vấn đề nào để ý tưởng trên sẽ hoạt động.

+0

Nếu đó là tất cả về 'không hiển thị' thông báo, chúng ta không thể chỉ ngăn chặn nó bằng cách thực hiện @explode()? Tôi biết nó không đẹp, nhưng nó có đúng không? Nếu bạn thực sự muốn 'tránh' nó, thì bạn hoàn toàn đúng ... – KilZone

+3

@KilZone: Nó không thực sự là "không hiển thị" nó, mà đúng hơn là trong suy nghĩ của "mã này được viết như vậy nếu nó bao giờ đưa ra một lỗi, nó đã có lỗi ". Ngoài ra, toán tử '@' tốt nhất nên tránh nếu có thể. Bạn biết [cảnh báo đó] (http://php.net/manual/en/language.operators.errorcontrol.php) trong tài liệu của nhà điều hành không? Tôi đã rơi cho điều đó nhiều hơn một lần. – Jon

+0

Phải, tôi có thể thấy điểm của bạn (và của clarkk), dù sao tôi vẫn đang tự hỏi. Ow và vâng tôi biết cảnh báo đó, đây không phải là lần đầu tiên tôi nhìn chằm chằm vào một màn hình trống mà trang của tôi đáng lẽ phải có. – KilZone

-1

này đã làm việc cho tôi:

@list($func, $field) = explode('|', $value); 
+0

Lỗi ứng phó, không bao giờ là điều tốt! – bart

+0

Tôi đồng ý với bạn @bart. Điều đó đúng trong hầu hết các trường hợp nhưng trong trường hợp cụ thể này tôi không thể thấy vấn đề lớn để không sử dụng nó. – Delmo

0

tôi thường đi qua vấn đề này, vì vậy tôi muốn có một chức năng cho phép một cái gì đó đẹp hơn cú pháp mà không cần thiết đệm mảng hoặc chuỗi.

// Put array entries in variables. Undefined index defaults to null 
function toVars($arr, &...$ret) 
{ 
    $n = count($arr); 
    foreach ($ret as $i => &$r) { 
     $r = $i < $n ? $arr[$i] : null; 
    } 
} 

// Example usage 
toVars(explode('|', $value), $func, $field); 

Đối với mục đích của tôi, tôi thường làm việc với một mảng, nhưng bạn có thể viết một chức năng tương tự bao gồm các chức năng nổ, như thế này ...

// Explode and put entries in variables. Undefined index defaults to null 
function explodeTo($delimiter, $s, &...$ret) 
{ 
    $arr = explode($delimier, $s); 
    $n = count($arr); 
    foreach ($ret as $i => &$r) { 
     $r = $i < $n ? $arr[$i] : null; 
    } 
} 

// Example usage 
toVars('|', $value, $func, $field); 

Yêu cầu PHP5.6 hoặc ở trên cho hàm variadic: http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list

Các vấn đề liên quan