2015-10-26 24 views
7

Kết quả:Lỗi ưu tiên toán tử PHP?

var_dump(null != $a = 15); 
var_dump($a); 

là:

bool(true) 
int(15) 

Tại sao kịch bản này không kích hoạt một lỗi? Vì != (toán tử không bằng nhau) có mức ưu tiên cao hơn = (toán tử gán), nên so sánh $a với null trước tiên?

+0

chắc chắn kỳ lạ. '$ a == null = 15' cũng cho các biến sai. Và đặt vào '(null! = $ A) = 15' sẽ tạo ra một lỗi' = 'không mong đợi. –

+0

Cách thay thế nào để diễn giải nó là 'null! = ($ A = 15)' có ở đó không? Với '(null! = $ A) = 15' bạn sẽ cố gán giá trị 15 cho một giá trị boolean; điều đó không hiệu quả. – VolkerK

+0

@VolkerK đây là một ví dụ, tập lệnh này không có mục đích thực tế! Sự phản chiếu của tôi bắt đầu với loại biểu thức mà tôi thấy (và sử dụng) rất nhiều 'if (! $ A = foo())'. –

Trả lời

6

Lý do duy nhất tôi có thể tìm thấy là các tài liệu nói rằng đây là vẫn quy phạm pháp luật: http://php.net/manual/en/language.operators.precedence.php#example-129

Nó có vẻ là một ngoại lệ với những gì được thể hiện trong bảng trên.

+0

Rất thích ghi chú nhỏ này! –

+3

Tôi nghĩ rằng một điều khác cần lưu ý là nhận xét sau đây về khả năng đọc: "Sử dụng dấu ngoặc đơn, ngay cả khi không cần thiết, có thể tăng khả năng đọc mã bằng cách tạo nhóm rõ ràng hơn là dựa vào quyền ưu tiên và kết hợp của toán tử ngầm." –

+0

Nó không phải là một "ngoại lệ có chủ ý"; không có quy tắc lexer bổ sung để rõ ràng "cho phép" điều này. Nó chỉ là cách bình thường nó hoạt động. Ví dụ trong hướng dẫn sử dụng chỉ là một lời nhắc nhở cho các nhà phát triển tự hỏi. – VolkerK

2

Đây không phải về quyền ưu tiên của toán tử nhưng về: danh sách ưu tiên toán tử không cho bạn biết chi tiết (thực sự, chúng không bao giờ làm), ví dụ: về các quy tắc của bison và kết quả mẫu phù hợp và ngăn xếp giảm.
Hãy lấy tuyên bố null != $a = 15;, để đơn giản mà không có var_dump.
Đây là cách trình phân tích cú pháp "xem" tuyên bố này - hoặc: thấy rằng nó một tuyên bố.
(Tôi hy vọng điều này sẽ được trả lại với một phông chữ có độ rộng cố ở khắp mọi nơi ...)

null      !=     $a         = 15       ; 
               T_VARIABLE       
identifier          compound_variable      T_LNUMBER 
namespace_name         reference_variable      common_scalar 
general_constant         base_variable       scalar 
scalar           base_variable_with_functions_calls  expr_without_variable 
expr_without_variable       variable       = expr 
expr      T_IS_NOT_EQUAL    \______ expr_without_variable _________/ 
    \__________________ expr ____________________________________________/           ; 
          \_________________  unticked_statement _______________________________________________/ 
                statement         

(Bạn có thể tra cứu các quy tắc ở https://github.com/php/php-src/blob/PHP-5.6.15/Zend/zend_language_parser.y)

Không có quy tắc đặc biệt cho các nhà điều hành phân công trong trường hợp này; đơn giản là không có cách nào khác để trình phân tích cú pháp khớp với tuyên bố, do đó ưu tiên không áp dụng.

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