ฉันได้เห็นการใช้@
ด้านหน้าฟังก์ชั่นบางอย่างดังต่อไปนี้:
$fileHandle = @fopen($fileName, $writeAttributes);
การใช้สัญลักษณ์นี้คืออะไร?
ฉันได้เห็นการใช้@
ด้านหน้าฟังก์ชั่นบางอย่างดังต่อไปนี้:
$fileHandle = @fopen($fileName, $writeAttributes);
การใช้สัญลักษณ์นี้คืออะไร?
คำตอบ:
มันระงับข้อความแสดงข้อผิดพลาด - ดูผู้ควบคุมข้อผิดพลาดในคู่มือ PHP
isset()
ไม่จำเป็นเพื่อหลีกเลี่ยงundefined offset
ข้อผิดพลาด
มันหยุดข้อผิดพลาด
ดูตัวควบคุมข้อผิดพลาดในคู่มือ:
PHP รองรับตัวควบคุมข้อผิดพลาดหนึ่งตัว: ที่เครื่องหมาย (@) เมื่อผนวกกับนิพจน์ใน PHP ข้อความแสดงข้อผิดพลาดที่อาจสร้างขึ้นโดยนิพจน์นั้นจะถูกละเว้น
หากคุณตั้งค่าฟังก์ชันตัวจัดการข้อผิดพลาดแบบกำหนดเองด้วยset_error_handler ()มันจะยังคงถูกเรียก แต่ตัวจัดการข้อผิดพลาดแบบกำหนดเองนี้สามารถ (และควร) เรียกerror_reporting ()ซึ่งจะส่งกลับ 0 เมื่อการเรียกที่เรียกใช้ข้อผิดพลาดถูกนำหน้าด้วย @ ...
@
สัญลักษณ์คือควบคุมความผิดพลาดผู้ประกอบการ (aka "ความเงียบ" หรือ "ปิดขึ้น" ผู้ประกอบการ) มันทำให้ PHP ระงับข้อความแสดงข้อผิดพลาด (การแจ้งเตือนคำเตือนร้ายแรง ฯลฯ ) ที่สร้างขึ้นโดยการแสดงออกที่เกี่ยวข้อง มันทำงานเหมือนกับโอเปอเรเตอร์ unary ตัวอย่างเช่นมันมีลำดับความสำคัญและการเชื่อมโยง ด้านล่างเป็นตัวอย่าง:
@echo 1 / 0;
// generates "Parse error: syntax error, unexpected T_ECHO" since
// echo is not an expression
echo @(1 / 0);
// suppressed "Warning: Division by zero"
@$i / 0;
// suppressed "Notice: Undefined variable: i"
// displayed "Warning: Division by zero"
@($i / 0);
// suppressed "Notice: Undefined variable: i"
// suppressed "Warning: Division by zero"
$c = @$_POST["a"] + @$_POST["b"];
// suppressed "Notice: Undefined index: a"
// suppressed "Notice: Undefined index: b"
$c = @foobar();
echo "Script was not terminated";
// suppressed "Fatal error: Call to undefined function foobar()"
// however, PHP did not "ignore" the error and terminated the
// script because the error was "fatal"
จะเกิดอะไรขึ้นหากคุณใช้ตัวจัดการข้อผิดพลาดที่กำหนดเองแทนตัวจัดการข้อผิดพลาด PHP มาตรฐาน:
หากคุณตั้งค่าฟังก์ชันตัวจัดการข้อผิดพลาดแบบกำหนดเองด้วย set_error_handler () มันจะยังคงถูกเรียก แต่ตัวจัดการข้อผิดพลาดแบบกำหนดเองนี้สามารถ (และควร) เรียก error_reporting () ซึ่งจะส่งกลับ 0 เมื่อการเรียกที่เรียกใช้ข้อผิดพลาดถูกนำหน้าด้วย @ .
นี่คือตัวอย่างในตัวอย่างรหัสต่อไปนี้:
function bad_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
echo "[bad_error_handler]: $errstr";
return true;
}
set_error_handler("bad_error_handler");
echo @(1 / 0);
// prints "[bad_error_handler]: Division by zero"
ตัวจัดการข้อผิดพลาดไม่ได้ตรวจสอบว่า@
สัญลักษณ์มีผล คู่มือแนะนำต่อไปนี้:
function better_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
if(error_reporting() !== 0) {
echo "[better_error_handler]: $errstr";
}
// take appropriate action
return true;
}
โปรดทราบว่าแม้จะมีข้อผิดพลาดถูกซ่อนอยู่ตัวจัดการข้อผิดพลาดแบบกำหนดเองใด ๆ (ตั้งค่าด้วยset_error_handler
) จะยังคงถูกใช้งาน!
เช่นเดียวกับที่บางคนตอบก่อนหน้านี้: @
โอเปอเรเตอร์ระงับข้อผิดพลาดทั้งหมดใน PHP รวมถึงประกาศคำเตือนและแม้แต่ข้อผิดพลาดที่สำคัญ
แต่: ได้ โปรดอย่าใช้ตัว@
ดำเนินการเลย
ทำไม?
เพราะเมื่อคุณใช้@
โอเปอเรเตอร์ในการกำจัดข้อผิดพลาดคุณจะไม่รู้ว่าจะเริ่มเมื่อเกิดข้อผิดพลาดได้ที่ไหน ฉันมีบางส่วน "สนุก" กับรหัสเดิมที่นักพัฒนาบางคนใช้ตัว@
ดำเนินการค่อนข้างบ่อย โดยเฉพาะอย่างยิ่งในกรณีเช่นการทำงานของไฟล์การโทรผ่านเครือข่าย ฯลฯ เป็นกรณีทั้งหมดที่ผู้พัฒนาจำนวนมากแนะนำให้ใช้ตัว@
ดำเนินการเนื่องจากบางครั้งอยู่นอกขอบเขตเมื่อเกิดข้อผิดพลาดขึ้นที่นี่ (ตัวอย่างเช่นบุคคลที่สาม API ไม่สามารถเข้าถึงได้ )
แต่ประเด็นที่ยังไม่ได้ใช้คืออะไร ลองมาดูจากสองมุมมอง:
ในฐานะนักพัฒนาซอฟต์แวร์:เมื่อ@
มีการใช้งานฉันไม่ทราบว่าจะเริ่มจากตรงไหน หากมีการเรียกใช้ฟังก์ชั่นหลายร้อยหรือหลายพันครั้งโดยมี@
ข้อผิดพลาดอาจเหมือนกับทุกครั้ง ไม่สามารถทำการดีบักอย่างสมเหตุสมผลในกรณีนี้ และแม้ว่ามันจะเป็นเพียงข้อผิดพลาดของบุคคลที่สาม - แต่ก็ไม่เป็นไรและคุณก็ทำได้เร็ว ;-) ยิ่งไปกว่านั้นควรเพิ่มรายละเอียดให้เพียงพอในบันทึกข้อผิดพลาดดังนั้นนักพัฒนาสามารถตัดสินใจได้อย่างง่ายดายว่ารายการบันทึกเป็นสิ่งที่ต้องตรวจสอบเพิ่มเติมหรือหากเป็นเพียงความล้มเหลวของบุคคลที่ 3 ที่อยู่นอกขอบเขตของนักพัฒนา
ในฐานะผู้ใช้:ผู้ใช้ไม่สนใจเลยว่าอะไรคือสาเหตุของข้อผิดพลาดหรือไม่ มีซอฟต์แวร์สำหรับให้พวกเขาทำงานเพื่อทำงานให้เสร็จ ฯลฯ โดยเฉพาะพวกเขาไม่สนใจว่ามันเป็นความผิดของนักพัฒนาหรือปัญหาของบุคคลที่สาม โดยเฉพาะอย่างยิ่งสำหรับผู้ใช้ฉันขอแนะนำให้บันทึกข้อผิดพลาดทั้งหมดแม้ว่าจะอยู่นอกขอบเขตก็ตาม บางทีคุณอาจสังเกตว่า API เฉพาะนั้นออฟไลน์บ่อยๆ คุณทำอะไรได้บ้าง? คุณสามารถพูดคุยกับคู่ค้า API ของคุณและหากพวกเขาไม่สามารถรักษาความมั่นคงไว้ได้คุณควรมองหาพันธมิตรรายอื่น
ในระยะสั้น:คุณควรจะรู้ว่ามีบางสิ่งบางอย่างเช่น@
(ความรู้อยู่เสมอดี) แต่เพียงไม่ได้ใช้มัน นักพัฒนาหลายคน (โดยเฉพาะอย่างยิ่งรหัสการแก้จุดบกพร่องจากผู้อื่น) จะขอบคุณมาก
@
เป็นระเบียบเรียบร้อยแล้วทำสิ่งนี้มีประโยชน์อย่างยิ่งโดยเฉพาะถ้าคุณไม่ส่งคืนtext/html
(หรือคล้ายกัน) ให้กับลูกค้า (อาจกลับมาimage/png
หรือ "json")
if( session_status() == PHP_SESSION_NONE ) session_start();
มันเป็นแอพที่ฉันสืบทอดมาและมีหลายที่ที่สคริปต์การตั้งค่าถูกเรียกหลายครั้งดังนั้นฉันต้องทดสอบ หากมีปัญหาจะเกิดขึ้นเพียงแค่ใช้@session_start();
อะไร?
@$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;
ดีกว่าทางเลือกอื่น ๆ ของการมีการตรวจสอบของผู้ออกบัตรในแต่ละระดับและกรอกข้อมูลในกรณีที่ไม่ใช่
สมมติว่าเราไม่ได้ใช้โอเปอเรเตอร์ "@" ดังนั้นรหัสของเราจะเป็นดังนี้:
$fileHandle = fopen($fileName, $writeAttributes);
และถ้าไฟล์ที่เราพยายามเปิดไม่พบ? มันจะแสดงข้อความผิดพลาด
ในการระงับข้อความแสดงข้อผิดพลาดเราใช้ตัวดำเนินการ "@" เช่น:
$fileHandle = @fopen($fileName, $writeAttributes);
@
วิธีแก้ปัญหาแบบนี้ตั้งแต่แรก ภาษาการเขียนโปรแกรมอื่นมีการจัดการข้อยกเว้นอย่างสม่ำเสมอเพื่อจัดการสถานการณ์stackoverflow.com/questions/1087365
หากการเปิดล้มเหลวข้อผิดพลาดของระดับ E_WARNING จะถูกสร้างขึ้น คุณอาจใช้ @ เพื่อระงับคำเตือนนี้
@
ไม่แสดงข้อความผิดพลาด
มันถูกใช้ในตัวอย่างโค้ดเช่น:
@file_get_contents('http://www.exaple.com');
หากไม่สามารถเข้าถึงโดเมน " http://www.exaple.com " ข้อผิดพลาดจะปรากฏ แต่@
ไม่มีสิ่งใดปรากฏขึ้น
PHP สนับสนุนผู้ประกอบการควบคุมความผิดพลาดที่หนึ่ง: (@)
เครื่องหมาย เมื่อผนวกกับนิพจน์ใน PHP ข้อความแสดงข้อผิดพลาดที่อาจสร้างขึ้นโดยนิพจน์นั้นจะถูกละเว้น
หากคุณได้ตั้งค่าฟังก์ชั่นจัดการข้อผิดพลาดที่กำหนดเองด้วยset_error_handler()
แล้วมันจะยังคงได้รับการเรียก แต่จัดการข้อผิดพลาดที่กำหนดเองสามารถ (และควร) โทรerror_reporting()
ซึ่งจะกลับมาเมื่อมีสายที่เรียกข้อผิดพลาดที่ถูกนำหน้าด้วย0
@
<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?>
บันทึก:-
1) @ -operator ใช้งานได้กับนิพจน์เท่านั้น
2) กฎง่ายๆคือถ้าคุณสามารถนำค่าของบางสิ่งมาคุณสามารถเพิ่มตัวดำเนินการ @ ให้กับมันได้ ตัวอย่างเช่นคุณสามารถเติมลงในตัวแปรฟังก์ชั่นและรวมถึงการโทรค่าคงที่และอื่น ๆ คุณไม่สามารถเติมให้ฟังก์ชันหรือคำจำกัดความของคลาสหรือโครงสร้างที่มีเงื่อนไขเช่น if and foreach และอื่น ๆ
คำเตือน:-
ปัจจุบันคำนำหน้าโอเปอเรเตอร์ควบคุมข้อผิดพลาด "@" จะปิดใช้งานการรายงานข้อผิดพลาดเพื่อหาข้อผิดพลาดที่สำคัญซึ่งจะยุติการทำงานของสคริปต์ เหนือสิ่งอื่นใดซึ่งหมายความว่าหากคุณใช้ "@" เพื่อระงับข้อผิดพลาดจากฟังก์ชั่นบางอย่างและไม่สามารถใช้งานได้หรือมีการพิมพ์ผิดสคริปต์จะตายที่นั่นโดยไม่มีข้อบ่งชี้ว่าทำไม
มันอาจจะคุ้มที่จะเพิ่มที่นี่มีตัวชี้ไม่กี่เมื่อใช้ @ คุณควรทราบสำหรับการทำงานลงอย่างสมบูรณ์ดูโพสต์นี้: http://mstd.eu/index.php/2016/06/30/php- ไฟอย่างรวดเร็วสิ่งที่เป็นที่สัญลักษณ์ที่ใช้สำหรับใน PHP /
ตัวจัดการข้อผิดพลาดยังคงทำงานอยู่แม้ว่าจะมีสัญลักษณ์ @ เตรียมไว้แล้วก็หมายความว่าตั้งค่าระดับความผิดพลาดเป็น 0 ซึ่งจะต้องจัดการอย่างเหมาะสมในตัวจัดการข้อผิดพลาดที่กำหนดเอง
การเตรียมการรวมด้วย @ จะตั้งข้อผิดพลาดทั้งหมดในไฟล์รวมเป็นระดับข้อผิดพลาดที่ 0
@
ไม่แสดงข้อความแสดงความผิดพลาดที่เกิดจากฟังก์ชัน fopen
โยนข้อผิดพลาดเมื่อไฟล์ไม่ออก @
สัญลักษณ์ทำให้การดำเนินการเพื่อย้ายไปยังบรรทัดถัดไปแม้ไฟล์จะไม่มีอยู่ ข้อเสนอแนะของฉันจะไม่ใช้สิ่งนี้ในสภาพแวดล้อมท้องถิ่นของคุณเมื่อคุณพัฒนาโค้ด PHP