2010-07-21 16 views
17

Thông thường trong PHP, tôi thấy:Sử dụng 'or die()' để ngăn chặn về lỗi trong PHP

$result = mysql_query($query) or die(); 

Đến từ trăn, tôi biết tại sao điều này nên làm việc, bởi vì or trả về giá trị đầu tiên nếu nó là đúng theo ngữ cảnh boolean và giá trị thứ hai khác (xem this).

Nhưng khi tôi thử các kỹ thuật nói trên trong PHP trong bối cảnh khác, ví dụ như một cái gì đó như:

$name = "John Doe"; 
echo $name or "Anonymous"; 

Các or không trả về giá trị đầu tiên ("John Doe"), nó sẽ trả về 1.

Tại sao điều này làm việc trong trường hợp kết quả mysql_query(), nhưng không phải trong các trường hợp khác? Có xấu khi sử dụng trong một trường hợp mysql_query() (bỏ qua thực tế là tôi không trả lại một lỗi hữu ích cho người dùng)?

Trả lời

33

Trong PHP, gán biến (dấu bằng) và các hàm đều được ưu tiên hơn toán tử or. Điều đó có nghĩa là một hàm được thực hiện trước, sau đó giá trị trả về của hàm được sử dụng trong so sánh or. Đổi lại, khi bạn sử dụng hai giá trị/biến cùng với toán tử or, nó so sánh hai giá trị trước tiên rồi trả về giá trị Boolean.

Do đó, tự đánh giá trong ví dụ này là:

$result = mysql_query($query) or die(); 
  1. mysql_query($query)
    Returns hoặc Kết quả là thiết lập cho các truy vấn DQL như SELECT, hoặc một giá trị Boolean cho DDL, DML hoặc các truy vấn DCL chẳng hạn như CREATE, DROP, INSERT, UPDATE, DELETEALTER.

  2. $result = mysql_query($query)
    Kết quả của việc thực hiện truy vấn này được gán cho biến $result.

  3. $result /* = ... */ or die();
    Nếu nó là một trong hai kết quả thiết lập hoặc true, nó được coi là đúng (hay còn gọi là "truthy") nên tình trạng or là hài lòng và tuyên bố kết thúc tại đây. Nếu không, tập lệnh sẽ die() thay thế.


echo là một cấu trúc ngôn ngữ và do đó không thực sự trả về một giá trị, vì vậy nó không chạy như một chức năng trước khi so sánh or được thực hiện.

Như $name or "Anonymous" luôn là đúng bởi vì chuỗi "Anonymous" không bị để trống và do đó truthy, các echo ngầm chuyển đổi true để 1, do đó sản lượng đó.

Trình tự đánh giá trong ví dụ này là:

$name = "John Doe"; 
echo $name or "Anonymous"; 
  1. $name = "John Doe";
    Khá đơn giản - gán chuỗi John Doe để $name.

  2. $name or "Anonymous"
    PHP phát hiện ra rằng $name chứa chuỗi John Doe, vì vậy những gì kết thúc lên được đánh giá như sau:

  3. "John Doe" or "Anonymous"
    Kể từ ít nhất một chuỗi là phi trống rỗng ở đây, nó được coi là trung thực và điều kiện là hài lòng. Đánh giá này sau đó trả về true.

  4. echo true /* $name or... */;
    Chuyển đổi true để 1 và in số 1.

+2

+1 Giải thích tuyệt vời. – karim79

+3

+1 tuyệt vời từ, "truthy" –

+0

Sau đó, tôi đoán điều này sẽ làm việc với các chức năng in như 'printf', hoặc là vấn đề này, becaus nó tạo ra đầu ra? Đó là một chức năng nên nó hoạt động đúng không? –

0

Đó là vì echo không phải là chức năng, đó là ngôn ngữ xây dựng. Nó bắt chước là một chức năng, nhưng nó thực sự không phải là :)

Tôi sẽ không bao giờ sử dụng die() như thế này, nó là loại thô. Bạn nên xử lý các lỗi của bạn một cách thích hợp, không chỉ bảo lãnh.

+0

Tôi đã nói "bỏ qua thực tế là tôi không trả lại lỗi hữu ích cho người dùng" - đó không phải là một phần của câu hỏi.Bạn đã bỏ lỡ toàn bộ vấn đề với câu trả lời này. Nó không quan trọng thời tiết echo là một chức năng hay không. 'echo (false hoặc true);' hoặc 'printf (false hoặc true);' phải giống như '$ a = (false hoặc true); echo $ a; ' – rjmunro

+0

@rjmunro: Đoạn đầu tiên (cố gắng) trả lời câu hỏi của bạn. Điều gì sẽ 'echo $ name hoặc" John Doe ";' làm gì? '(echo $ name) hoặc" John Doe "' OR 'echo ($ name hoặc" John Doe ")'? Đó là một vấn đề quan trọng. Và do đó điều quan trọng là nó là một hàm (với một giá trị trả về) hay một cấu trúc ngôn ngữ (không có giá trị trả về). –

2

Tại sao nên or trở lại bất cứ điều gì? or là toán tử boolean bình thường. $a or $btrue nếu $a hoặc $b đánh giá là truefalse nếu không.

Sự khác biệt giữa ||or là, or có mức độ ưu tiên của toán tử thấp hơn, thậm chí thấp hơn =.Đây là lý do tại sao

$result = mysql_query($query) or die(); 

là giống như

($result = mysql_query($query)) or (die()); 

trong khi

$result = mysql_query($query) || die(); 

là giống như

$result = (mysql_query($query) || die()); 

Trong trường hợp của bạn

echo $name or "Anonymous"; 

được

(echo $name) or ("Anonymous"); 

gì bạn đang tìm kiếm có thể là các nhà điều hành ternary:

echo $name ?: 'Anonymous'; 

trên sẽ làm việc như của PHP 5.3, nếu bạn chỉ có PHP 5.2 sử dụng:

echo $name ? $name : 'Anonymous'; 
1

PHP thực hiện điều gì đó thường được gọi là "loại tung hứng". Nói cách khác: PHP biến đổi loại giá trị bất kỳ cho trường hợp sử dụng hiện tại. Vì Strings sẽ được chuyển thành giá trị "true", biểu thức của bạn trả về true. Nhưng echo muốn in một biểu thức chuỗi và biến đổi "true" thành 1. Kinda gây phiền nhiễu trong một số trường hợp, nhưng nếu bạn biết, bạn cũng biết cách xử lý;)

Kiểm tra điều này bằng cách: http://php.net/manual/en/types.comparisons.php

1

mệnh đề or được đánh giá đầu tiên và trả về một boolean có kết quả đầu ra là echo. Nếu bạn muốn xuất văn bản, bạn cần cấu trúc if/else như sau:

echo ($name ? $name : 'Anonymous'); 
+4

hoặc nếu bạn đang chạy PHP 5.3+, 'echo $ name?:" Anonymous ";' – nickf

2

Lý do thực sự xảy ra với tôi ngay sau khi đặt câu hỏi. Đó là về quyền ưu tiên của nhà điều hành. Các = xảy ra trước khi or, vì vậy:

$result = mysql_query($query) or die(); 

tương đương với:

($result = mysql_query($query)) or die(); 

không:

$result = (mysql_query($query) or die()); 

như nó sẽ là bằng Python. Vì vậy, điều này:

$a = false or true; 

sẽ đặt $a thành sai, không đúng, nhất định bắt tôi vào một thời điểm nào đó trong tương lai.

0

Nếu bạn muốn sao chép hành vi VÀ đầu ra đó vào màn hình/trình duyệt, bạn cần một hàm sẽ trả về một cái gì đó khác với TRUE. printf() có thể làm điều đó cho bạn.

echo microtime."&lt;br&gt;";< 
$str = ""; 
printf("%s",$str) or die(); 
echo "&lt;br&gt;".microtime(); 

Nếu $ str rỗng, null hoặc false die() sẽ được gọi, nếu không, tập lệnh sẽ kết thúc thực thi.

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