PHP ตรวจสอบการมีอยู่ของตัวแปร คำถาม: จะตรวจสอบได้อย่างไรว่ามีตัวแปรอยู่หรือไม่

ฉันต้องการตรวจสอบว่ามีตัวแปรอยู่หรือไม่ ตอนนี้ฉันทำสิ่งนี้:

ลอง: myVar ยกเว้น NameError: # ทำอะไรสักอย่าง

มีวิธีอื่นที่ไม่มีข้อยกเว้นหรือไม่?


2018-05-09 13:10

คำตอบ:

วิธีตรวจสอบการมีอยู่ของตัวแปรในเครื่อง:

หาก "myVar" ใน locals(): มี # myVar อยู่

วิธีตรวจสอบการมีอยู่ของตัวแปรร่วม:

หาก "myVar" ใน globals(): มี # myVar อยู่

หากต้องการตรวจสอบว่าวัตถุมีคุณสมบัติหรือไม่:

ถ้า hasattr(obj, "attr_name"): มี # obj.attr_name อยู่


2018-05-09 13:16

การใช้ตัวแปรที่ไม่ได้ถูกกำหนดหรือตั้งค่า (โดยนัยหรือชัดเจน) มักจะไม่ดีเสมอไป ใดๆเนื่องจากสิ่งนี้บ่งชี้ว่าตรรกะของโปรแกรมไม่ได้รับการคิดอย่างถูกต้องและอาจส่งผลให้เกิดพฤติกรรมที่คาดเดาไม่ได้

เคล็ดลับถัดไปซึ่งคล้ายกับของคุณ จะช่วยให้แน่ใจว่าตัวแปรมี บางมูลค่าก่อนใช้งาน:

ลอง: myVar ยกเว้น NameError: myVar = None # ตอนนี้คุณสามารถใช้ myVar ได้อย่างอิสระโดยไม่ต้องบ่นกับ Python

อย่างไรก็ตาม ฉันยังคงไม่คิดว่านี่เป็นความคิดที่ดี ในความคิดของฉัน คุณควรปรับโครงสร้างโค้ดของคุณใหม่เพื่อป้องกันไม่ให้สถานการณ์นี้เกิดขึ้น


2018-05-09 13:19

การใช้ try /ยกเว้น เป็นวิธีที่ดีที่สุดในการตรวจสอบการมีอยู่ของตัวแปร แต่เกือบจะแน่นอนว่ามีวิธีที่ดีกว่าในการทำสิ่งที่คุณทำมากกว่าการตั้งค่า/ทดสอบตัวแปรโกลบอล

ตัวอย่างเช่น หากคุณต้องการเริ่มต้นตัวแปรระดับโมดูลในครั้งแรกที่เรียกใช้ฟังก์ชันบางอย่าง คุณควรใช้โค้ดดังนี้:

My_variable = ไม่มี def InitMyVariable(): global my_variable ถ้า my_variable เป็น None: my_variable = ...


2018-05-09 13:27

สำหรับวัตถุ/โมดูล คุณก็สามารถทำได้เช่นกัน

"var" ใน dir (obj)

ตัวอย่างเช่น,

>>> คลาส บางสิ่งบางอย่าง(วัตถุ): ... ผ่าน ... >>> c = บางสิ่งบางอย่าง() >>> c.a = 1 >>> "a" ใน dir(c) True >>> "b" ใน dir (ค) เท็จ


2017-10-28 18:39

วิธีง่ายๆ คือเริ่มต้นใช้งานก่อนด้วย myVar = None

หลังจากนั้น:

หาก myVar ไม่ใช่ None: # ทำอะไรสักอย่าง


2018-06-04 18:46

ฉันเดาว่าการทดสอบจะถูกใช้ในฟังก์ชันที่คล้ายกับคำตอบของผู้ใช้ 97370 ฉันไม่ชอบคำตอบนี้เพราะมันทำให้เนมสเปซส่วนกลางเสียหาย วิธีหนึ่งในการแก้ไขปัญหานี้คือการใช้คลาสแทน:

คลาส InitMyVariable (วัตถุ): my_variable = ไม่มี def __call__ (ตนเอง): ถ้า self.my_variable เป็นไม่มี: self.my_variable = ...

ฉันไม่ชอบสิ่งนี้เพราะมันทำให้โค้ดซับซ้อนและทำให้เกิดคำถามเช่นว่าสิ่งนี้จะตรวจสอบรูปแบบการเขียนโปรแกรม Singleton หรือไม่ โชคดีที่ Python อนุญาตให้ฟังก์ชันมีแอตทริบิวต์มาระยะหนึ่งแล้ว ทำให้เรามีวิธีแก้ปัญหาง่ายๆ นี้:

Def InitMyVariable(): ถ้า InitMyVariable.my_variable เป็นไม่มี: InitMyVariable.my_variable = ... InitMyVariable.my_variable = ไม่มี


2018-03-25 20:31

2018-05-09 13:12

วิธีที่มักจะทำงานได้ดีในการจัดการสถานการณ์ประเภทนี้คือการไม่ตรวจสอบอย่างชัดเจนว่ามีตัวแปรอยู่หรือไม่ แต่เพียงดำเนินการต่อและสรุปการใช้งานครั้งแรกของตัวแปรที่อาจไม่มีอยู่จริงในการลอง/ยกเว้น NameError

ฟังก์ชันว่าง (11)

ฉันมี (หรือไม่มี) ตัวแปร $_GET["myvar"] ที่มาจากสตริงการสืบค้นของฉัน และฉันต้องการตรวจสอบว่าตัวแปรนั้นมีอยู่หรือไม่ และค่านั้นตรงกับบางสิ่งในคำสั่ง if ของฉันหรือไม่:

สิ่งที่ฉันทำและคิดว่าไม่ใช่วิธีที่ดีที่สุดที่จะทำ:

if(isset($_GET["myvar"]) && $_GET["myvar"] == "something") : ทำบางสิ่งบางอย่าง

นี่เป็นกรณีง่ายๆ แต่ลองจินตนาการว่าต้องเปรียบเทียบตัวแปร $myvar เหล่านี้หลายๆ ตัว

คำตอบ

สิ่งนี้คล้ายกับคำตอบที่ยอมรับ แต่ใช้ in_array แทน ฉันชอบใช้ Empty() ในสถานการณ์นี้ ฉันขอแนะนำให้ใช้การประกาศอาร์เรย์สตริงใหม่ที่มีอยู่ใน PHP 5.4.0+

$allowed = ["บางสิ่งบางอย่าง", "ไม่มีอะไร"]; if(!empty($_GET["myvar"]) && in_array($_GET["myvar"],$allowed))(..)

นี่คือฟังก์ชั่นตรวจสอบค่าหลายค่าพร้อมกัน

$arrKeys = array_keys($_GET); $allowed = ["บางสิ่งบางอย่าง", "ไม่มีอะไร"]; ฟังก์ชั่น checkGet($arrKeys,$allowed) ( foreach($arrKeys as $key) ( if(in_array($_GET[$key],$allowed)) ( $values[$key]; ) ) ส่งคืน $values; )

ฉันใช้ฟังก์ชันที่มีประโยชน์ของตัวเองทั้งหมด ต่อ()ซึ่งประกาศตัวแปรโดยอัตโนมัติ

$element1 = exst($arr["key1"]); $val2 = exst($_POST["key2"], "ไม่มีค่า"); /** * Function exst() - ตรวจสอบว่ามีการตั้งค่าตัวแปรหรือไม่ * (คัดลอก/วางในตำแหน่งใด ๆ ของโค้ดของคุณ) * * หากตั้งค่าตัวแปรและไม่ว่างเปล่าจะส่งกลับตัวแปร (ไม่มีการแปลง) * หากตัวแปร ไม่ได้ตั้งค่าหรือว่างเปล่า ส่งคืนค่า $default * * @param mix $var * @param mix $default * * @return Mixed */ function exst(& $var, $default = "") ( $t = "" ; if (!isset($var) || !$var) ( if (isset($default) && $default != "") $t = $default; ) else ( $t = $var; ) ถ้า (is_string ($t)) $t = ตัด($t);

คุณสามารถผ่านไปได้เพียง if($_GET["myvar"] == "something") เนื่องจากเงื่อนไขนั้นจะถือว่าตัวแปรนั้นมีอยู่ด้วย หากไม่เป็นเช่นนั้น นิพจน์ก็จะส่งผลให้เกิด false ด้วย

ฉันคิดว่ามันโอเคที่จะทำสิ่งนี้ในเงื่อนไขข้างต้น ไม่มีอันตรายอะไรจริงๆ

คำถามของฉันคือ: มีวิธีการทำเช่นนี้โดยไม่ต้องประกาศตัวแปรสองครั้งหรือไม่?

ไม่ ไม่มีทางที่จะทำสิ่งนี้ได้อย่างถูกต้องโดยไม่ต้องตรวจสอบสองครั้ง ฉันเกลียดมันเหมือนกัน

วิธีหนึ่งในการหลีกเลี่ยงปัญหานี้คือการนำเข้าตัวแปร GET ที่เกี่ยวข้องทั้งหมดที่จุดศูนย์กลางจุดเดียวไปยังอาร์เรย์หรือวัตถุบางประเภท (MVC ส่วนใหญ่จะทำเช่นนี้โดยอัตโนมัติ) และตั้งค่าคุณสมบัติทั้งหมดที่จำเป็นในภายหลัง (แทนที่จะเข้าถึงตัวแปรแบบสอบถามผ่านโค้ด)

ถ้า (isset($_GET["myvar"]) == "บางสิ่งบางอย่าง")

ขอบคุณ Mellowsoon และ Pekka ฉันได้ค้นคว้าที่นี่และได้สิ่งนี้:

  • ตรวจสอบและประกาศตัวแปรแต่ละตัวเป็นโมฆะ (ถ้าเป็นเช่นนั้น) ก่อนใช้งาน (ตามที่แนะนำ):
!isset($_GET["myvar"]) ? $_GET["มายวาร์"] = 0:0;

*ตกลง มันเรียบง่ายแต่ใช้งานได้ดี คุณสามารถเริ่มใช้ตัวแปรได้ทุกที่หลังจากบรรทัดนี้

  • การใช้อาร์เรย์สำหรับทุกกรณี:
$myvars = array("var1", "var2", "var3"); foreach($myvars เป็น $key) !isset($_GET[$key]) ? $_GET[$คีย์] =0:0;

* หลังจากนี้คุณสามารถใช้ตัวแปรของคุณได้ (var1, var2, var3... ฯลฯ)

PS: ฟังก์ชั่นที่ได้รับวัตถุ JSON ควรจะดีกว่า (หรือสตริงคั่นด้วยการระเบิด / การระเบิดแบบธรรมดา)

ยินดีต้อนรับแนวทางที่ดีกว่า :)

อัปเดต:

ใช้ $_REQUEST แทน $_GET ด้วยวิธีนี้ คุณจะครอบคลุมตัวแปร $_GET และ $_POST

Isset($_REQUEST[$key]) ? $_REQUEST[$key] =0:0;

วิธีแก้ปัญหาที่ฉันพบจากเกมคือทำ:

If($x=&$_GET["myvar"] == "something") ( // ทำสิ่งต่าง ๆ ด้วย $x )

เพื่อเป็นคำใบ้ คุณอาจพิจารณาแนวทางนี้:

จำเป็น = array("myvar" => "defaultValue1", "foo" => "value2", "bar" => "value3", "baz" => "value4"); $missing = array_diff($required, array_keys($_GET)); foreach($missing as $key => $default) ( $_GET[$key] = $default ; )

คุณตั้งค่าเริ่มต้นและตั้งค่าพารามิเตอร์ที่ไม่ได้รับให้เป็นค่าเริ่มต้น :)

น่าเสียดายที่นี่เป็นวิธีเดียวที่จะทำได้ แต่มีแนวทางในการทำงานกับอาร์เรย์ขนาดใหญ่ ตัวอย่างเช่นบางสิ่งเช่นนี้:

$required = array("myvar", "foo", "bar", "baz"); $missing = array_diff($required, array_keys($_GET));

ขณะนี้ตัวแปร $missing มีรายการค่าที่จำเป็นแต่หายไปจากอาร์เรย์ $_GET คุณสามารถใช้ $missing array เพื่อแสดงข้อความถึงผู้เยี่ยมชมได้

หรือคุณสามารถใช้สิ่งนี้:

$required = array("myvar", "foo", "bar", "baz"); $missing = array_diff($required, array_keys($_GET)); foreach($missing as $m) ( $_GET[$m] = null; )

ตอนนี้ทุกองค์ประกอบที่จำเป็นมีค่าเริ่มต้นตามค่าเริ่มต้น ตอนนี้คุณสามารถใช้ if ($_GET["myvar"] == "something") โดยไม่ต้องกังวลเกี่ยวกับคีย์ที่ไม่ได้ถูกตั้งค่า

อัปเดต

อีกวิธีในการล้างโค้ดคือใช้ฟังก์ชันที่ตรวจสอบว่าตั้งค่าไว้หรือไม่

ฟังก์ชัน getValue($key) ( if (!isset($_GET[$key])) ( return false; ) return $_GET[$key]; ) if (getValue("myvar") == "something") ( / /ทำอะไรสักอย่าง)

ทำไมไม่สร้างฟังก์ชันสำหรับสิ่งนี้ แปลงตัวแปรที่คุณต้องการตรวจสอบเป็นตัวแปรจริง เช่น

ฟังก์ชั่น _FX($name) ( if (isset($$name)) return $$name; else return null; )

ถ้าอย่างนั้นคุณก็ทำ _FX("param") == "123" เพียงแค่คิด

ฉันพบโค้ดที่ดีกว่า (มาก) ในการทำเช่นนี้หากคุณต้องการทดสอบบางอย่างใน.

หาก [[ $1 = "" ]] ดังนั้น echo "$1 ว่างเปล่า" มิฉะนั้น echo "$1 เต็มแล้ว" fi

ทำไมทั้งหมดนี้? ทุกอย่างใน Bash มีอยู่แล้ว แต่จะว่างเปล่าตามค่าเริ่มต้น ดังนั้น test -z และ test -n จึงไม่สามารถช่วยคุณได้

ถ้า [ $(#1) = 0 ] ดังนั้น echo "$1 ว่างเปล่า" else echo "$1 เต็มแล้ว" fi

คุณสามารถตรวจสอบว่ามีตัวแปรที่กำหนดอยู่หรือไม่ (นั่นคือ ตัวแปรนั้นถูกเตรียมใช้งานหรือไม่) เมื่อต้องการทำเช่นนี้ ให้ใช้ฟังก์ชัน:

อิเซต(ตัวแปร);

หากไม่มีตัวแปรอยู่ในปัจจุบัน (ไม่เคยกำหนดค่าใดๆ มาก่อนหรือถูกลบโดยฟังก์ชัน) ไม่ได้ตั้งค่า () ) ตามด้วยฟังก์ชัน ไอเซต () ผลตอบแทน เท็จ , มิฉะนั้น - จริง :

$x = 5;

ถ้า (ไอเซต($x))

เสียงสะท้อน ‘< บีอาร์ >ตัวแปร $ x มีอยู่ ', "ค่าของมันคือ $ x < บีอาร์ >”;

สิ่งต่อไปนี้จะปรากฏบนหน้าจอ:

ตัวแปร $ x มีอยู่ ค่าของมันคือ 5

สิ่งสำคัญคือต้องจำไว้ว่าเราไม่สามารถใช้ตัวแปรที่ไม่ได้เตรียมใช้งานในโปรแกรมได้ - สิ่งนี้จะสร้างคำเตือนจากล่าม PHP .

เพื่อตรวจสอบว่าค่าเป็นตัวแปรหรือไม่ ว่างเปล่า , มีการใช้ฟังก์ชัน:

ว่างเปล่า( ตัวแปร);

หากค่าของตัวแปรเป็น ศูนย์ ,“0”, โมฆะ , บรรทัดว่าง (“” ) เท็จ ตัวแปรไม่ได้รับการประกาศหรือเป็น อาร์เรย์ว่าง จากนั้นฟังก์ชันนี้จะส่งคืน จริง , มิฉะนั้น - เท็จ .

เพื่อตรวจสอบ พิมพ์ ตัวแปร มีการใช้ฟังก์ชัน:

Is_string(ตัวแปร);

เป็น _ ภายใน (ตัวแปร);

เป็น _ ลอย (ตัวแปร);

เป็น _ โมฆะ (ตัวแปร);

เป็น _ อาร์เรย์ (ตัวแปร);

เป็น _ ตัวเลข (ตัวแปร); - ถ้าตัวแปรเป็นตัวเลข ( จำนวนเต็ม , ลอย ) หรือสตริงที่มีเฉพาะตัวเลข

ฟังก์ชันเหล่านี้กลับมา จริง หากตัวแปรเป็นประเภทที่ระบุ

เอาท์พุทข้อมูล

เอาต์พุตที่ไม่ได้ฟอร์แมต

ไม่มีรูปแบบ เอาต์พุตของสตริงหรือค่าตัวแปรดำเนินการโดยฟังก์ชัน:

เสียงสะท้อน รายการตัวแปร

เสียงสะท้อน เส้น;

ที่ไหน รายการตัวแปร – ชื่อของตัวแปรเอาต์พุตคั่นด้วยเครื่องหมายจุลภาค

หากเรากำลังทำงานกับเว็บเบราว์เซอร์ ฟังก์ชันนี้จะกำหนดเส้นทางเอาต์พุตไปยังฝั่งไคลเอ็นต์ของเบราว์เซอร์ (ไปที่หน้าต่าง)

ดังที่ได้กล่าวไปแล้วหากพบชื่อตัวแปรในสตริงที่อยู่ในเครื่องหมายคำพูดคู่ ค่าที่เกี่ยวข้องจะแสดงบนหน้าจอแทนชื่อเหล่านี้ นอกจากนี้หากบรรทัดดังกล่าวมีแท็ก HTML (ที่จับอยู่ในวงเล็บมุม) จากนั้นเบราว์เซอร์จะแสดงสิ่งนี้ HTML -code ตามที่ควรทำเมื่อตีความ HTML -เอกสาร:

$ปี = 2012;

$ข้อความ = “ ปรารถนา ทุกคน ความสุข !”;

สะท้อน “

ของฉัน ยินดีด้วย !

”;

สะท้อน “ มาถึงแล้ว $ ปี ปี !
$ข้อความ
”;

?>

ชื่อระดับจะปรากฏบนหน้าจอ ชม 3 และกล่าวทักทายต่อด้วยคำว่า “ ความสุข!" จะแสดงเป็นตัวหนา ตัวเอียง:

ยินดีด้วย!

มันคือปี 2012! ฉันหวังว่าทุกคน ความสุข!

วิธีนี้คุณสามารถสร้างไซต์แบบไดนามิกได้

เอาต์พุตที่จัดรูปแบบแล้ว

จัดรูปแบบแล้ว เอาต์พุตช่วยให้คุณแสดงหมายเลขเอาต์พุตในระบบตัวเลขต่าง ๆ และในระบบทศนิยม - ในรูปแบบต่าง ๆ ( รูปแบบ - มันคล้ายกับเอาต์พุตที่จัดรูปแบบแล้วใน ศรี และดำเนินการโดยฟังก์ชัน:

พิมพ์ฉ (“รูปแบบ”, รายการผลลัพธ์);

วิ่ง (“รูปแบบ”, รายการผลลัพธ์);

ฟังก์ชันแรกจะแสดงข้อมูลที่จัดรูปแบบในหน้าต่างเบราว์เซอร์และส่งกลับปริมาณ

ฟังก์ชันที่สองจัดรูปแบบเฉพาะข้อมูลที่ส่งออกเท่านั้น แต่จะไม่ส่งออกข้อมูลดังกล่าว

รูปแบบ คือลำดับของตัวอธิบายการเปลี่ยนแปลงสำหรับค่าเอาต์พุต

ตัวอธิบายการเปลี่ยนแปลง สำหรับแต่ละค่าจะมีรูปแบบดังนี้

% PlaceholderAlignmentLength.AccuracyType

- รวม เป็นสัญลักษณ์ที่จะใช้ในการแปลงผลลัพธ์ให้เป็นค่าที่กำหนด ความยาว (ค่าเริ่มต้น - ช่องว่าง - หากเป็นอักขระอื่น จะต้องนำหน้าด้วยเครื่องหมายคำพูดเดียว ( เครื่องหมายอะพอสทรอฟี ),

- การจัดตำแหน่ง – โดยค่าเริ่มต้น – โดย ขวา ขอบของช่องเอาท์พุต หากมีเครื่องหมายลบ ( - ) จากนั้นโดย ซ้าย ,

- ความยาว – ความกว้างของฟิลด์เอาต์พุต - จำนวนช่องว่างที่จัดสรรสำหรับเอาต์พุตค่านี้ หากค่าเอาต์พุตมีอักขระน้อยกว่าค่าที่ระบุ ความยาว จากนั้นพื้นที่ที่เหลือจะเต็ม ช่องว่าง หรือเติมตัวอักษร

- ความแม่นยำ – จำนวนตำแหน่งทศนิยมในส่วนที่เป็นเศษส่วนของจำนวน

- พิมพ์ – ประเภทของมูลค่าเอาท์พุต:

ไบนารี่ ,

กับ เครื่องหมาย ,

ทั้งหมด ในระบบเลขทศนิยม

จริง ในรูปแบบเลขชี้กำลัง (จุดลอยตัว)

จริง ในรูปแบบจุดคงที่

เส้น ,

โอ ทั้งหมด ในระบบเลขฐานแปด

x ทั้งหมด ในระบบเลขฐานสิบหก

ตัวอย่าง:

PHP

$ ซ่าร์ป _1 = 6543.21;

$ ซ่าร์ป _2 = 45321.67;

$ ครอบครัว _1 = "บาลากานอฟ";

$ ครอบครัว _2 = "เบนเดอร์";

พิมพ์ฉ ("< ชม 1>เงินเดือน ชม. 1>");

printf("%".-12s%".10.2f ถู.", $fam_1, $zarp_1);

เสียงสะท้อน "
";

printf("%".-12s%".10.2f ถู.", $fam_2, $zarp_2);

เสียงสะท้อน "
";

?>

จุด ( ‘. - นามสกุลชิดซ้าย ( - ) ในความกว้างของฟิลด์ 12 ตัวอักษร ตัวเลขจะแสดงในรูปแบบจุดคงที่ในความกว้างของฟิลด์ 10 ตัวอักษรและแม่นยำ 2 ตำแหน่งทศนิยม จัดชิดขวา

เนื้อหานี้มีไว้สำหรับโปรแกรมเมอร์เว็บมือใหม่เป็นหลัก

การแนะนำ.

บ่อยครั้งที่ฉันได้รับการติดต่อจากลูกค้าที่ติดตั้ง CMS หรือโมดูลที่เขียนเองโดยโปรแกรมเมอร์เว็บมือใหม่ที่ไม่เข้าใจสิ่งที่จำเป็นในการปกป้องข้อมูลและมักจะคัดลอกฟังก์ชันการกรองโดยไม่ต้องคำนึงถึงวิธีการทำงานและสิ่งที่ต้องทำจริงๆ กับพวกเขา .

ที่นี่ฉันจะพยายามอธิบายรายละเอียดให้มากที่สุดเท่าที่จะเป็นไปได้ข้อผิดพลาดทั่วไปเมื่อกรองข้อมูลในสคริปต์ PHP และให้คำแนะนำง่ายๆ เกี่ยวกับวิธีการกรองข้อมูลอย่างถูกต้อง

มีบทความมากมายบนอินเทอร์เน็ตเกี่ยวกับการกรองข้อมูล แต่ยังไม่สมบูรณ์และไม่มีตัวอย่างโดยละเอียด

การซักถาม

การกรอง ความผิดพลาด #1
สำหรับตัวแปรตัวเลข จะใช้การตรวจสอบต่อไปนี้:
$number = $_GET["input_number"]; if (intval($number)) ( ... ดำเนินการแบบสอบถาม SQL... )
เหตุใดจึงนำไปสู่การฉีด SQL? ประเด็นก็คือผู้ใช้สามารถระบุในตัวแปรได้ อินพุต_หมายเลขความหมาย:
1"+ยูเนี่ยน+เลือก
ในกรณีเช่นนี้การตรวจสอบจะเสร็จสิ้นได้สำเร็จเพราะว่า ฟังก์ชัน intval รับค่าจำนวนเต็มของตัวแปร เช่น 1 แต่ในตัวแปรนั้นเอง $หมายเลขไม่มีการเปลี่ยนแปลง ดังนั้นโค้ดที่เป็นอันตรายทั้งหมดจะถูกส่งไปยังแบบสอบถาม SQL
การกรองที่ถูกต้อง:
$number = intval($_GET["input_number"]); if ($number) ( ... ดำเนินการค้นหา SQL... )
แน่นอนว่า เงื่อนไขสามารถเปลี่ยนแปลงได้ เช่น หากคุณต้องการเพียงช่วงหนึ่งเท่านั้น:
ถ้า ($number >= 32 และ $number<= 65)

หากคุณใช้ช่องทำเครื่องหมายหรือการเลือกหลายรายการด้วยค่าตัวเลข ให้ดำเนินการตรวจสอบต่อไปนี้:
$checkbox_arr = array_map("intval", $_POST["ช่องทำเครื่องหมาย"]);
array_map
ฉันยังเห็นการกรองในรูปแบบ:
$number = htmlspecialchars(intval($_GET["input_number"]));
htmlอักขระพิเศษ
หรือ:
$number = mysql_escape_string(intval($_GET["input_number"]));
mysql_escape_string

สิ่งนี้ไม่สามารถนำมาซึ่งอะไรได้นอกจากรอยยิ้ม :)

การกรอง ความผิดพลาด #2.
สำหรับตัวแปรสตริง จะใช้การกรองต่อไปนี้:
$input_text = addslashes($_GET["input_text"]);
ฟังก์ชัน addslashes จะหลีกฟังก์ชันพิเศษ อักขระแต่ไม่ได้คำนึงถึงการเข้ารหัสและการกรองฐานข้อมูลที่สามารถข้ามได้ ฉันจะไม่คัดลอกข้อความของผู้เขียนที่อธิบายช่องโหว่นี้และจะให้ลิงก์ไปยัง Chris Shiflett (คุณสามารถค้นหาคำแปลได้ใน RuNet)

ใช้ฟังก์ชัน mysql_escape_string หรือ mysql_real_escape_string ตัวอย่าง:
$input_text = mysql_escape_string($_GET["input_text"]);
หากคุณไม่คาดว่าจะรวมแท็ก html ไว้ วิธีที่ดีที่สุดคือการกรองต่อไปนี้:
$input_text = strip_tags($_GET["input_text"]); $input_text = htmlอักขระพิเศษ($input_text); $input_text = mysql_escape_string($input_text);
strip_tags - ลบแท็ก html
htmlspecialchars - แปลงพิเศษ อักขระในเอนทิตี html
ด้วยวิธีนี้ คุณจะป้องกันตัวเองจากการโจมตี XSS นอกเหนือจากการแทรก SQL
หากคุณต้องการแท็ก html แต่เพื่อแสดงซอร์สโค้ดเท่านั้น ให้ใช้:
$input_text = htmlอักขระพิเศษ($_GET["input_text"]); $input_text = mysql_escape_string($input_text);

หากเป็นสิ่งสำคัญสำหรับคุณที่ค่าของตัวแปรต้องไม่ว่างเปล่า ให้ใช้ฟังก์ชันตัดแต่ง ตัวอย่าง:
$input_text = ตัดแต่ง($_GET["input_text"]); $input_text = htmlอักขระพิเศษ($input_text); $input_text = mysql_escape_string($input_text);

การกรอง ข้อผิดพลาด #3
มันเกี่ยวข้องกับการค้นหาในฐานข้อมูล
หากต้องการค้นหาตามตัวเลข ให้ใช้การกรองที่อธิบายไว้ในข้อผิดพลาดแรก
หากต้องการค้นหาด้วยข้อความ ให้ใช้ตัวกรองที่อธิบายไว้ในข้อผิดพลาดที่สอง แต่ต้องมีการจอง
เพื่อให้ผู้ใช้ไม่สามารถดำเนินการผิดพลาดเชิงตรรกะได้ จำเป็นต้องลบหรือคัดกรองรายการพิเศษ อักขระ SQL
ตัวอย่างที่ไม่มีการเพิ่มเติม การประมวลผลสตริง:
$input_text = htmlอักขระพิเศษ($_GET["input_text"]); // ค้นหา: "%" $input_text = mysql_escape_string($input_text);
ผลลัพธ์จะเป็นแบบสอบถามเช่น:
... WHERE text_row ชอบ "%".$input_text"%" ... // WHERE text_row ชอบ "%%%"
สิ่งนี้จะเพิ่มภาระบนฐานอย่างมาก
ในสคริปต์ของฉัน ฉันใช้ฟังก์ชันที่จะลบอักขระที่ฉันไม่ต้องการออกจากการค้นหา:
ฟังก์ชั่น strip_data($text) ( $quotes = array ("\x27", "\x22", "\x60", "\t", "\n", "\r", "*", "%", "<", ">", "?", "!"); $goodquotes = array ("-", "+", "#"); $repquotes = array ("\-", "\+", "\#"); $text = ตัด(strip_tags($text)); $text = str_replace($quotes, "", $text); $text = str_replace($goodquotes, $repquotes, $text); $text = ereg_replace(" +" , " ", $ข้อความ); ส่งกลับ $ข้อความ)
แน่นอนว่าไม่ใช่อักขระทั้งหมดข้างต้นที่เป็นอันตราย แต่ในกรณีของฉันไม่จำเป็นต้องใช้อักขระเหล่านั้น ดังนั้นฉันจึงทำการค้นหาและแทนที่
ตัวอย่างการใช้การกรอง:
$input_text = strip_data($_GET["input_text"]); $input_text = htmlอักขระพิเศษ($input_text); $input_text = mysql_escape_string($input_text);
ฉันขอแนะนำให้คุณกำหนดขีดจำกัดจำนวนอักขระในการค้นหาอย่างน้อยไม่น้อยกว่า 3 เนื่องจาก... หากคุณมีบันทึกจำนวนมากในฐานข้อมูลการค้นหาอักขระ 1-2 ตัวจะเพิ่มภาระในฐานข้อมูลอย่างมาก
การกรอง ข้อผิดพลาด #4
ค่าในตัวแปรจะไม่ถูกกรอง $_คุกกี้- บางคนคิดว่าเนื่องจากตัวแปรนี้ไม่สามารถส่งผ่านแบบฟอร์มได้ นี่จึงเป็นการรับประกันความปลอดภัย
ตัวแปรนี้ปลอมแปลงได้ง่ายมากกับเบราว์เซอร์ใด ๆ โดยการแก้ไขคุกกี้ของไซต์
ตัวอย่างเช่น ใน CMS ที่รู้จักกันดีแห่งหนึ่ง มีการตรวจสอบเทมเพลตไซต์ที่ใช้:
ถ้า (@is_dir (MAIN_DIR . "/template/" . $_COOKIE["skin"]))( $config["skin"] = $_COOKIE["skin"]; ) $tpl->dir = MAIN_DIR "/แม่แบบ/" . $config["สกิน"];
ในกรณีนี้ คุณสามารถแทนที่ค่าของตัวแปรได้ $_คุกกี้["สกิน"]และทำให้เกิดข้อผิดพลาดซึ่งคุณจะเห็นเส้นทางที่แน่นอนไปยังโฟลเดอร์ไซต์
หากคุณใช้ค่าคุกกี้เพื่อบันทึกลงในฐานข้อมูล ให้ใช้การกรองแบบใดแบบหนึ่งที่อธิบายไว้ข้างต้น ซึ่งจะนำไปใช้กับตัวแปรด้วย $_เซิร์ฟเวอร์.
การกรอง ข้อผิดพลาด #5
รวมคำสั่งแล้ว register_globals- อย่าลืมปิดหากเปิดอยู่
ในบางสถานการณ์ คุณสามารถส่งค่าของตัวแปรที่ไม่ควรส่งผ่านได้ เช่น หากไซต์มีกลุ่ม ดังนั้นสำหรับกลุ่มที่ 2 ตัวแปร $group ควรว่างเปล่าหรือเท่ากับ 0 แต่ก็เพียงพอที่จะปลอมแปลง แบบฟอร์มโดยเพิ่มรหัส:

ในตัวแปรสคริปต์ PHP $groupจะเท่ากับ 5 หากไม่ได้ประกาศไว้ในสคริปต์ด้วยค่าเริ่มต้น
การกรอง ข้อผิดพลาด #6
ตรวจสอบไฟล์ที่คุณดาวน์โหลด
ตรวจสอบจุดต่อไปนี้:
  1. นามสกุลไฟล์. ขอแนะนำให้ห้ามการดาวน์โหลดไฟล์ที่มีนามสกุล: php, php3, php4, php5 เป็นต้น
  2. ไฟล์ถูกอัพโหลดไปยังเซิร์ฟเวอร์ move_uploaded_file หรือไม่
  3. ขนาดไฟล์
การตรวจสอบ. ความผิดพลาด #1.
ฉันพบกรณีที่คำขอ AJAX (เช่น: การเพิ่มชื่อเสียง) ชื่อหรือ ID ของผู้ใช้ถูกส่งไป (ซึ่งชื่อเสียงเพิ่มขึ้น) แต่ใน PHP เองไม่มีการตรวจสอบว่ามีผู้ใช้ดังกล่าวอยู่หรือไม่
ตัวอย่างเช่น:
$user_id = intval($_REQUEST["user_id"]); ... ใส่เข้าไปใน REPLOG SET uid = "($user_id)", plus = "1" ... ... อัปเดต Users SET ชื่อเสียง = ชื่อเสียง+1 WHERE user_id = "($user_id)" ...
ปรากฎว่าเรากำลังสร้างรายการในฐานข้อมูลที่ไม่มีประโยชน์สำหรับเราเลย
การตรวจสอบ. ความผิดพลาด #2.
เมื่อดำเนินการประเภทต่างๆ (เพิ่ม แก้ไข ลบ) ข้อมูล อย่าลืมตรวจสอบสิทธิ์ของผู้ใช้ในการเข้าถึงฟังก์ชันนี้และคุณสมบัติเพิ่มเติม (โดยใช้แท็ก html หรือความสามารถในการเผยแพร่เนื้อหาโดยไม่ต้องมีการตรวจสอบ)

นานมาแล้ว ฉันได้แก้ไขข้อผิดพลาดที่คล้ายกันในโมดูลฟอรัมหนึ่ง เมื่อผู้ใช้คนใดสามารถแก้ไขข้อความถึงฝ่ายบริหารได้

การตรวจสอบ. ข้อผิดพลาด #3
เมื่อใช้ไฟล์ php หลายไฟล์ ให้ทำการตรวจสอบง่ายๆ
ในไฟล์ ดัชนี.php(หรือในไฟล์หลักอื่น ๆ ) เขียนบรรทัดต่อไปนี้ก่อนเชื่อมต่อไฟล์ php อื่น:
กำหนด("READFILE", จริง);
ที่จุดเริ่มต้นของไฟล์ php อื่น ๆ เขียน:
if (! กำหนด ("READFILE")) ( exit ("ผิดพลาด ผิดวิธีในการส่งไฟล์.
ไปที่หลัก."); }
การดำเนินการนี้จะจำกัดการเข้าถึงไฟล์
การตรวจสอบ. ข้อผิดพลาด #4
ใช้แฮชสำหรับผู้ใช้ สิ่งนี้จะช่วยป้องกันไม่ให้ฟังก์ชันนี้หรือฟังก์ชันนั้นถูกเรียกผ่าน XSS
ตัวอย่างการรวบรวมแฮชสำหรับผู้ใช้:
$secret_key = md5(strtolower("http://site.ru/" . $member["name"] . sha1($password) . date("Ymd"))); // $secret_key คือแฮชของเรา
ถัดไป ในรูปแบบที่สำคัญทั้งหมด ให้แทนที่อินพุตด้วยค่าแฮชปัจจุบันของผู้ใช้:

ขณะรันสคริปต์ ให้ตรวจสอบ:
ถ้า ($_POST["secret_key"] !== $secret_key) ( exit ("ข้อผิดพลาด: secret_key!"); )
การตรวจสอบ. ข้อผิดพลาด #5
เมื่อส่งออกข้อผิดพลาด SQL ให้จำกัดการเข้าถึงข้อมูลง่ายๆ ตัวอย่างเช่น ตั้งรหัสผ่านสำหรับตัวแปร GET:
if ($_GET["passsql"] == "password") ( ... เอาต์พุตข้อผิดพลาด SQL... ) else ( ... แค่ข้อมูลเกี่ยวกับข้อผิดพลาด ไม่มีรายละเอียด... )
วิธีนี้จะช่วยให้คุณสามารถซ่อนข้อมูลจากแฮ็กเกอร์ที่สามารถช่วยแฮ็กไซต์ได้
การตรวจสอบ. ข้อผิดพลาด #5
พยายามไม่รวมไฟล์โดยรับชื่อไฟล์จากภายนอก
ตัวอย่างเช่น:
ถ้า (isset($_GET["file_name"])) ( รวม $_GET["file_name"] ".php"; )
ใช้สวิตช์