PHP session_id () ได้รับการอัปเดตในทุกคำขอ $ _COOKIE ว่างเปล่า การรักษาความปลอดภัยตัวระบุเซสชันใน PHP Session ใน php
เว็บเซิร์ฟเวอร์ไม่รองรับ การเชื่อมต่อถาวรกับลูกค้า และคำขอแต่ละรายการจะได้รับการประมวลผลเหมือนเป็นคำขอใหม่ โดยไม่มีการเชื่อมต่อใดๆ กับคำขอก่อนหน้านี้
นั่นคือ คุณไม่สามารถติดตามคำขอจากผู้เยี่ยมชมคนเดียวกัน หรือบันทึกตัวแปรสำหรับเขาระหว่างมุมมองต่างๆ แต่ละหน้า... เซสชันถูกคิดค้นขึ้นเพื่อแก้ปัญหาทั้งสองนี้
โดยสรุปแล้ว เซสชันเป็นกลไกที่ช่วยให้คุณระบุเบราว์เซอร์ได้โดยไม่ซ้ำกัน และสร้างไฟล์สำหรับเบราว์เซอร์นี้บนเซิร์ฟเวอร์ ซึ่งเก็บตัวแปรเซสชันไว้
ฉันจะไม่อธิบายรายละเอียดเกี่ยวกับความต้องการกลไกดังกล่าว กรณีเหล่านี้คือกรณีของหนังสือเรียน เช่น ตะกร้าสินค้าใน e-store การอนุญาต และไม่ใช่ปัญหาเล็กๆ น้อยๆ ทั้งหมด เช่น การปกป้องส่วนที่โต้ตอบของไซต์จากสแปม
โดยหลักการแล้ว มันค่อนข้างง่ายที่จะสร้างแอนะล็อกของเซสชันของคุณเอง ซึ่งใช้งานไม่ได้เท่ากับ PHP ในตัว แต่มีสาระสำคัญคล้ายกัน เกี่ยวกับคุกกี้และฐานข้อมูล
เมื่อขอสคริปต์ เราจะดูว่ามีคุกกี้ที่มีชื่อเฉพาะหรือไม่ หากไม่มีคุกกี้ ให้ตั้งค่าและเขียนบรรทัดใหม่พร้อมข้อมูลผู้ใช้ลงในฐานข้อมูล หากมีคุกกี้ เราก็อ่านจากฐานข้อมูล ด้วยคำขออีกครั้ง เราจะลบบันทึกเก่าออกจากฐานข้อมูล และตอนนี้เรามีกลไกของเซสชันพร้อมแล้ว มันไม่ยากเลย แต่มีความแตกต่างบางประการที่ทำให้ควรใช้กลไกเซสชันในตัว
หากเปิดใช้งานเฉพาะครั้งแรก เมื่อเริ่มต้นเซสชัน (ที่การโทรแต่ละครั้ง session_start ()) มีการติดตั้งคุกกี้สำหรับลูกค้า เบราว์เซอร์ส่งคืนคุกกี้นี้อย่างถูกต้องทุกครั้งที่มีการร้องขอ และ PHP มีตัวระบุเซสชัน ปัญหาเริ่มต้นขึ้นหากเบราว์เซอร์ไม่ส่งคืนคุกกี้ ในกรณีนี้ PHP จะเริ่มเซสชันใหม่เสมอโดยไม่ได้รับคุกกี้พร้อมตัวระบุ และกลไกจะไม่ทำงาน
หากเปิดใช้งานเพียงตัวที่สอง แสดงว่าไม่มีการตั้งค่าคุกกี้ และสิ่งที่เกิดขึ้นคือ โดยพื้นฐานแล้ว มันคุ้มค่าที่จะใช้กลไกเซสชันในตัว หลังจากที่สคริปต์ทำงาน และหน้าถูกสร้างขึ้นอย่างสมบูรณ์แล้ว PHP จะตรวจสอบทั้งหมดและผนวก ID เซสชันต่อท้ายลิงก์แต่ละลิงก์และแต่ละแบบฟอร์ม ดูเหมือนว่านี้:
ดัชนีกลายเป็น
ดัชนี
และเพิ่มช่องที่ซ่อนอยู่ในแบบฟอร์ม
และเบราว์เซอร์เมื่อคุณคลิกที่ลิงค์ใด ๆ หรือเมื่อคุณคลิกที่ปุ่มในแบบฟอร์มจะส่งคำขอตัวแปรที่เราต้องการ - ตัวระบุเซสชัน!
ด้วยเหตุผลที่ชัดเจน ID จะถูกเพิ่มลงในลิงก์ที่เกี่ยวข้องเท่านั้น
ในทางทฤษฎี ในเซสชันโฮมเมดของเราเกี่ยวกับคุกกี้และฐานข้อมูล คุณสามารถกำหนดการโอน id ไปยังลิงก์ทั้งหมดได้ด้วยตนเอง - จากนั้นเซสชันของเราจะทำงานโดยอิสระจากคุกกี้ แต่คุณเห็นไหม - ดีกว่าเมื่อมีคนอื่นทำงานนี้ ;-)
โดยค่าเริ่มต้นใน เวอร์ชั่นล่าสุด PHP ทั้งสองตัวเลือกรวมอยู่ด้วย PHP จัดการกับสิ่งนี้อย่างไร คุกอยู่เสมอแสดง และลิงก์จะเติมข้อความอัตโนมัติก็ต่อเมื่อ PHP ไม่พบคุกกี้ที่มี ID เซสชัน เมื่อผู้ใช้เข้าชมไซต์เป็นครั้งแรกในระหว่างเซสชันนี้ เขาจะได้รับคุกกี้และเพิ่มลิงก์ ในคำขอถัดไป หากรองรับคุกกี้ PHP จะเห็นคุกกี้และหยุดทำลิงก์ให้เสร็จสิ้น หากคุกกี้ไม่ทำงาน PHP ยังคงเพิ่ม id ไปยังลิงก์อย่างถูกต้องและเซสชันจะไม่สูญหาย
ผู้ใช้ที่มีคุกกี้ทำงานจะเห็นลิงก์ยาวพร้อมรหัสเพียงครั้งเดียว
ฟู่. ด้วยการโอนตัวระบุเสร็จสิ้น
ตอนนี้ยังคงผูกไฟล์ที่มีข้อมูลทางฝั่งเซิร์ฟเวอร์ไว้
PHP จะทำสิ่งนี้ให้เรา แค่เขียนก็พอ
session_start ();
$ _SESSION ["test"] = "สวัสดีชาวโลก!" ;
และ PHP จะเขียนตัวแปรทดสอบไปยังไฟล์ที่เกี่ยวข้องกับเซสชันนี้
มีจุดสำคัญมากที่นี่
Array $ _SESSION- พิเศษ.
อันที่จริงเป็นตัวแปรที่เราต้องการให้พร้อมใช้งานในสคริปต์ต่างๆ
ในการวางตัวแปรในเซสชัน เพียงแค่กำหนดให้กับองค์ประกอบของอาร์เรย์ $ _SESSION
เพื่อให้ได้ค่ามันก็เพียงพอแล้วที่จะอ้างถึงองค์ประกอบเดียวกัน ตัวอย่างจะอยู่ด้านล่าง
การรวบรวมขยะ - การลบที่ล้าสมัย ไฟล์ PHPทำเองด้วย เช่นเดียวกับการเข้ารหัสข้อมูลและสิ่งอื่น ๆ ที่จำเป็น จากการดูแลนี้ การทำงานกับเซสชันจึงเป็นเรื่องง่ายมาก
อันที่จริงแล้ว เรามาถึงตัวอย่างการทำงานของเซสชัน
ตัวอย่างมีขนาดเล็กมาก:
session_start ();
เสียงก้อง "คุณได้อัปเดตหน้านี้"... $ _SESSION ["ตัวนับ"] ++ " ครั้งหนึ่ง. " ;
เสียงสะท้อน "
อัปเดต ";
?>
เราตรวจสอบว่าเรามีตัวแปรตัวนับในเซสชันหรือไม่ ถ้าไม่มี ให้สร้างด้วยค่า 0 แล้วส่งออกค่าของตัวแปรนั้นและเพิ่มขึ้นหนึ่งค่า ค่าที่เพิ่มขึ้นจะถูกเขียนไปยังเซสชัน และครั้งต่อไปที่มีการเรียกสคริปต์ ตัวแปรจะมีค่าเป็น 1 เป็นต้น
ทุกอย่างง่ายมาก
เพื่อให้สามารถเข้าถึงตัวแปรเซสชันบนหน้าใด ๆ ของไซต์ คุณต้องเขียนบรรทัดเดียวเท่านั้น (!) ที่จุดเริ่มต้นของแต่ละไฟล์ซึ่งเราต้องการเซสชัน:
session_start ();
จากนั้นอ้างอิงถึงองค์ประกอบของอาร์เรย์ $ _SESSION ตัวอย่างเช่น การตรวจสอบการให้สิทธิ์จะมีลักษณะดังนี้:
session_start ();
ถ้า ($ _SESSION ["ได้รับอนุญาต"]<>
1
) {
ส่วนหัว ("ตำแหน่ง: /auth.php");
ทางออก;
}
การลบตัวแปรออกจากเซสชัน
หากคุณมี register_globals = off ก็เขียน
ยกเลิกการตั้งค่า ($ _ SESSION ["var"]);
ถ้าไม่เช่นนั้น ใกล้เคียงฉันต้องเขียนกับเธอ
session_unregister ("var");
ข้อผิดพลาดที่พบบ่อยที่สุดที่ PHP ให้ไว้เมื่อพยายามทำงานกับเซสชันคือ:
ทั้งสอง,
คำเตือน: ไม่สามารถส่งคุกกี้ของเซสชัน - ส่งส่วนหัวแล้ว
คำเตือน: ไม่สามารถส่งตัวจำกัดแคชเซสชัน - ส่งส่วนหัวแล้ว
เกิดจากสาเหตุเดียวกัน การแก้ปัญหาได้อธิบายไว้ในข้อเท็จจริงนี้
ที่สาม,
คำเตือน: เปิด (/ tmp \ sess_SID, O_RDWR) ล้มเหลว: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว (2) ใน full_script_path ในหมายเลขบรรทัด(ก่อนหน้านี้เธอดูเหมือน คำเตือน: ไม่สามารถเขียนข้อมูลเซสชัน (ไฟล์) โปรดตรวจสอบว่าการตั้งค่าปัจจุบันของ session.save_path ถูกต้อง (/ tmp)),
หากแปลจากภาษาอังกฤษ จะอธิบายปัญหาโดยละเอียด: ไม่มีเส้นทางที่ระบุใน php.ini ไปยังไดเร็กทอรีที่เขียนไฟล์เซสชัน ข้อผิดพลาดนี้เป็นวิธีที่ง่ายที่สุดในการแก้ไข เพียงเขียนไดเร็กทอรีที่มีอยู่และสามารถเขียนได้ เช่น
session.save_path = c: \ windows \ temp
และอย่าลืมรีสตาร์ท Apache หลังจากนั้น
ปรากฏว่า สติปัญญาของมนุษย์ไม่มีขีดจำกัด ดังนั้นฉันจึงต้องอธิบาย:
ข้อความแสดงข้อผิดพลาดที่สาม (ไม่พบไดเร็กทอรี) UNAVAILABLE จะนำไปสู่สองข้อความแรก เนื่องจากข้อความแสดงข้อผิดพลาดจะส่งออกไปยังเบราว์เซอร์และคุณไม่สามารถใช้ส่วนหัวหลังจากนั้นได้ ดังนั้นอย่ารีบเร่งที่จะหาข้อสรุปก่อนเวลาอันควร แต่ก่อนอื่นให้เขียนเส้นทางที่ถูกต้อง!
ปัญหาที่พบบ่อยที่สุดรองลงมาเมื่อต้องรับมือกับเซสชันคือปัญหาใหญ่ของ register_globals อย่าให้ตัวแปรสคริปต์ชื่อเดียวกับดัชนีของอาร์เรย์ $ _SESSION!
เมื่อ register_globals = on ค่าต่างๆ จะเขียนทับกันและคุณจะสับสน
และถ้า register_globals = off ข้อผิดพลาดอื่นจะปรากฏขึ้น: "สคริปต์ของคุณอาจใช้ผลข้างเคียงของเซสชันซึ่งมีอยู่จนถึง PHP 4.2.3" ... เพื่อกำจัดมัน คุณควรเริ่มต้นตัวแปรก่อนใช้งานเสมอ (หรืออย่างน้อยก็ตรวจสอบการมีอยู่) และอย่าตั้งชื่อตัวแปรส่วนกลางที่ตรงกับดัชนีของอาร์เรย์ $ _SESSION
หากไม่ได้ผล แต่ไม่มีแสดงข้อความใด ๆ ให้เพิ่มสองบรรทัดที่จุดเริ่มต้นของสคริปต์ที่รับผิดชอบในการแสดงข้อผิดพลาดทั้งหมดบนหน้าจอ - ค่อนข้างเป็นไปได้ว่ามีข้อผิดพลาด แต่คุณไม่เห็น พวกเขา.
ini_set ("display_errors", 1);
error_reporting (E_ALL);
หรือเห็นข้อผิดพลาดใน error_log โดยทั่วไป หัวข้อของการแสดงข้อความแสดงข้อผิดพลาดอยู่นอกเหนือขอบเขตของบทความนี้ ดังนั้น อย่างน้อยต้องแน่ใจว่าคุณสามารถมองเห็นข้อความเหล่านั้นได้ คุณสามารถอ่านรายละเอียดเพิ่มเติมเล็กน้อยเกี่ยวกับการแก้ไขปัญหาในส่วนนี้
หากคุณแน่ใจว่าไม่มีข้อผิดพลาด แต่ตัวอย่างที่ให้มาใช้งานไม่ได้ เป็นไปได้ว่า PHP ไม่ได้เปิดใช้งานการถ่ายโอน id ผ่าน url และคุกกี้ด้วยเหตุผลบางอย่างไม่ทำงาน.
ดูสิ่งที่คุณมีกับคุกกี้
โดยทั่วไป หากเซสชันของคุณ "ไม่ทำงาน" ก่อนอื่นให้ลองโอนตัวระบุเซสชันด้วยตนเอง นั่นคือสร้างลิงก์และกำหนดตัวระบุให้กับเซสชันนั้น:
session_start ();
ถ้า (! isset ($ _ SESSION ["ตัวนับ"])) $ _SESSION ["ตัวนับ"] = 0;
เสียงก้อง "คุณได้อัปเดตหน้านี้"... $ _SESSION ["ตัวนับ"] ++ " ครั้งหนึ่ง.
อัปเดต ";
?>
เมื่อทำเช่นนี้ ตรวจสอบให้แน่ใจว่าไม่ได้เปิดใช้งานคำสั่ง session.use_only_cookies ซึ่งจะป้องกันไม่ให้ PHP ยอมรับ ID เซสชันหากส่งผ่าน URL
หากตัวอย่างนี้ใช้ไม่ได้ผล แสดงว่าปัญหาอยู่ใน banal ความผิดพลาด(ครึ่งหนึ่งของ "ปัญหา" ของเซสชันมาจากชื่อตัวแปรที่สะกดผิด) หรือด้วย เวอร์ชั่นเก่า PHP: รองรับเซสชันในเวอร์ชัน 4.0 และ array $ _SESSION- ใน 4.1 (ก่อนหน้านี้ใช้ $ HTTP_SESSION_VARS).
หากใช้งานได้ แสดงว่าปัญหาอยู่ในคุกกี้ ติดตามว่าเซิร์ฟเวอร์ใส่คุกกี้ประเภทใดในเบราว์เซอร์ ไม่ว่าเบราว์เซอร์จะส่งคืนคุกกี้หรือไม่ การค้นหามีประโยชน์มากในขณะที่ดูการแลกเปลี่ยนส่วนหัว HTTP ระหว่างเบราว์เซอร์และเซิร์ฟเวอร์
การอธิบายว่าคุกกี้ทำงานอย่างไรนั้นอยู่นอกเหนือขอบเขตของข้อความที่มีขนาดใหญ่เกินไปนี้อยู่แล้ว แต่อย่างน้อยต้องแน่ใจว่าเซิร์ฟเวอร์ส่งคุกกี้พร้อมตัวระบุ และเบราว์เซอร์จะกลับมา และในขณะที่ตัวระบุตรงกัน =)
การตั้งค่าคุกกี้ควรมีลักษณะดังนี้
ชุดคุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6;
หรืออย่างไร
ชุดคุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; เส้นทาง = /
(หากคุณกำลังขอสคริปต์ที่ไม่ได้มาจากไดเรกทอรีราก)
การตอบสนองของเซิร์ฟเวอร์ควรมีลักษณะดังนี้
คุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6
หรือ
คุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; ข = ข
หากเบราว์เซอร์ส่งคืนคุกกี้อื่นนอกเหนือจาก ID เซสชัน
หากเบราว์เซอร์ไม่ส่งคืนคุกกี้ ให้ตรวจสอบว่าคุกกี้ทำงานหรือไม่
ตรวจสอบให้แน่ใจว่าโดเมนที่คุณกำลังเข้าถึงมีชื่อปกติ (ซึ่งมีอย่างน้อยหนึ่งจุดและไม่มีอักขระต้องห้าม เช่น ขีดล่าง) และล้างแคชของเบราว์เซอร์ ซึ่งเป็นสาเหตุหลักสองประการที่ทำให้คุกกี้ไม่ทำงาน
หากตัวอย่างจากที่นี่ใช้งานได้ แต่รหัสของคุณใช้ไม่ได้ แสดงว่าปัญหาไม่ได้อยู่ที่เซสชัน แต่อยู่ในอัลกอริทึม ค้นหาตำแหน่งที่คุณสูญเสียตัวแปร โอนตัวอย่างจากที่นี่ทีละขั้นตอน ดีบักสคริปต์ของคุณ
ปัญหาอื่นอาจเกิดขึ้นได้หากคุณใช้การเปลี่ยนเส้นทางส่วนหัวหรือการนำทาง JavaScript
ความจริงก็คือ PHP ต่อท้ายตัวระบุเซสชันโดยอัตโนมัติเฉพาะกับลิงก์ของแบบฟอร์ม แต่จะไม่ทำเช่นนี้กับส่วนหัว จาวาสคริปต์ เมตาแท็ก
ดังนั้น คุณต้องเพิ่มตัวระบุด้วยตนเอง เช่น:
ส่วนหัว ("ตำแหน่ง: /script.php?". session_name (). "=". session_id ());
นอกจากนี้ยังหายากมาก และไม่มีความชัดเจนว่าปัญหามาจากไหน ปัญหาคือการตั้งค่า session.save_handler มีค่าอื่นที่ไม่ใช่ไฟล์ หากไม่เป็นเช่นนั้นให้แก้ไข
ความปลอดภัย
การรักษาความปลอดภัยเซสชันเป็นหัวข้อที่กว้างใหญ่ ดังนั้น ผมจะเน้นประเด็นหลักสองสามข้อ
สิ่งที่ตำราเรียนมากที่สุดคือไม่ผ่านตัวระบุผ่าน แถบที่อยู่... สิ่งนี้เขียนแม้กระทั่งใน php.ini แต่สิ่งนี้จะจำกัดการทำงานของเซสชัน หากคุณตัดสินใจทำตามคำแนะนำนี้ นอกจาก session.use_trans_sid = 0 แล้ว อย่าลืม session.use_only_cookies = 1
ขอแนะนำให้ผูกเซสชันกับที่อยู่ IP ด้วยวิธีนี้ หากตัวระบุถูกขโมย คนร้ายจะยังไม่สามารถใช้งานได้ในกรณีส่วนใหญ่
ขอแนะนำให้ใช้คำสั่ง session.save_path ซึ่งคุณสามารถตั้งค่าไดเร็กทอรีของคุณเองสำหรับบันทึกไฟล์เซสชันได้ มีความปลอดภัยมากกว่าเมื่อเก็บไว้ในไดเร็กทอรีชั่วคราวที่ใช้ร่วมกันที่เป็นค่าเริ่มต้นของเซิร์ฟเวอร์
session_cache_limiter ("ส่วนตัว");
ต้องแก้ปัญหาก่อนเริ่มเซสชัน
ตัวอย่างการให้สิทธิ์โดยใช้ sessions
มาอธิบายทั้งหมดข้างต้นด้วยตัวอย่างเล็กๆ น้อยๆ กัน:
มาสร้างไฟล์ auth.php กันเถอะ:
ถ้า (isset ($ _ POST ["auth_name"]))
{
$ sql = "เลือก * จากผู้ใช้ WHERE name =? S";
$ row = $ db -> getRow ($ sql, $ _POST ["auth_name"]);
if ($ row && password_verify ($ _POST ["auth_pass"], $ row ["pass"])) (
$ _SESSION ["user_id"] = $ แถว ["id"];
}
ส่วนหัว ("ตำแหน่ง: http: //". $ _SERVER ["HTTP_HOST"]. $ _SERVER ["REQUEST_URI"]);
ทางออก;
}
if (isset ($ _ GET ["action"]) และ $ _GET ["action"] == "logout") (
session_start ();
session_destroy ();
ส่วนหัว ("ตำแหน่ง: http: //". $ _SERVER ["HTTP_HOST"]. "/");
ทางออก;
}
if (! isset ($ _ SESSION ["user_id"])) (
?>
ทางออก;
}
ตอนนี้ก็เพียงพอที่จะเขียนสคริปต์ที่มีการป้องกันทั้งหมดในบรรทัด
ต้องการ "auth.php";
ในตัวอย่างนี้ ถือว่าเซสชันได้เริ่มขึ้นแล้ว และมีการเชื่อมต่อกับฐานข้อมูลโดยใช้ Class เพื่อความปลอดภัยและความสะดวกในการทำงานกับ MySQL นอกจากนี้ยังถือว่ารหัสผ่านถูกแฮชโดยใช้ฟังก์ชัน password_hash ที่แนะนำ
ตัวอย่างของไฟล์ที่ได้รับการป้องกัน:
session_start ();
รวม "safemysql.class.php";
$ db = ใหม่ safemysql (["db" => "test"]);
รวม "auth.php";
?>
ความลับ
ออกจากระบบ
อุ๊ปส์! ลิงค์ที่มีประโยชน์มาก:
http://www.php.net/manual/ru/ref.session.php - ข้อมูลล่าสุดและเป็นปัจจุบันเกี่ยวกับการสนับสนุนเซสชันใน PHP ในเอกสารอย่างเป็นทางการ บวกกับความคิดเห็นของผู้ใช้จำนวนมาก แนะนำให้อ่านเป็นอย่างยิ่ง
http://phpclub.ru/manrus/f/ref.session.html - การแปลบทนี้เป็นภาษารัสเซียที่ล้าสมัยมาก จากเอกสารที่แปลโดย Alexander Pyramidin
http://phpclub.ru/detail/article/sessions
บทความที่มีชื่ออวดดีว่า "ความจริงเกี่ยวกับเซสชัน" มันทิ้งความประทับใจที่ไม่ชัดเจน ในตอนเริ่มต้น ผู้เขียนพูดถึงกลไกของเซสชันได้ง่ายมาก แต่วิธีที่เขานำเสนอในช่วงท้ายของบทความนั้นค่อนข้างคลุมเครือ
บทความในตำราเรียนโดย Dmitry Borodin จากเว็บไซต์
ไม่แนะนำอย่างยิ่งให้ http://php.spb.ru/
พวกหล่อนล้าสมัยมาก ไม่เพียงแต่มีความไม่ถูกต้องตามข้อเท็จจริงเท่านั้น แต่เซสชันใน PHP ไม่ได้ถูกใช้มาเป็นเวลานาน
ขอบคุณมากสำหรับ Dima สำหรับเธอ นี่เป็นบทความแรกเกี่ยวกับเซสชั่นในภาษารัสเซีย ฉันศึกษาด้วยตัวเอง แต่ตอนนี้ ฉันต้องส่งเธอไปพักผ่อนที่สมควรได้รับ
นอกจากนี้ น่าเสียดายที่บทความอื่นๆ มากมายบนอินเทอร์เน็ตและไม่ได้รับการอัปเดตมาหลายปีก็ล้าสมัยเช่นกัน
เซสชันใน PHP เป็นกลไกในการจัดเก็บข้อมูลเกี่ยวกับคอมพิวเตอร์ของลูกค้าทางฝั่งเซิร์ฟเวอร์ อันที่จริง เซสชันใน PHP ไม่ใช่หัวข้อที่ยาก แต่เพื่อให้เข้าใจ คุณจำเป็นต้องรู้ว่าคุกกี้ทำงานอย่างไรใน PHP ดังนั้น หากคุณไม่ทราบว่าคุกกี้ทำงานอย่างไรใน PHP ให้อ่านบทความที่เกี่ยวข้องก่อน แล้วจึงกลับมาที่นี่
คำว่า session แปลจากภาษาอังกฤษเป็นเซสชัน ดังนั้นความหมายของเซสชันใน PHP จึงชัดเจนขึ้น แต่โปรแกรมเมอร์เคยชินกับคำว่า "เซสชัน" และเราจะใช้ในบทความนี้
เซสชันใน PHP นั้นคล้ายกับกลไกคุกกี้มาก ซึ่งเป็นคู่คีย์ => ค่าเดียวกัน แต่จะถูกเก็บไว้ที่ฝั่งเซิร์ฟเวอร์เท่านั้น
Session_start () ฟังก์ชั่น
เราจำเป็นต้องเริ่มเซสชัน เนื่องจากมีฟังก์ชัน session_start () ฟังก์ชันนี้เริ่มเซสชันหรือเซสชัน สิ่งที่คุณเรียกว่า
ขอแนะนำให้เรียกใช้ฟังก์ชัน session_start () ที่จุดเริ่มต้นของหน้า แต่ในตัวอย่างของฉัน ฉันไม่ทำเช่นนั้น
$ _SESSION อาร์เรย์
เซสชันคือกลุ่มของตัวแปรที่จัดเก็บไว้บนเซิร์ฟเวอร์แต่อ้างอิงถึงผู้เยี่ยมชมที่ไม่ซ้ำกันหนึ่งราย ย้ำนะคะ ช่วงเวลาสำคัญ: เซสชั่นถูกเก็บไว้ในเซิร์ฟเวอร์.
เพื่อให้แน่ใจว่าผู้เข้าชมแต่ละคนมีปฏิสัมพันธ์กับข้อมูลของเขาจากเซสชันของเขา ข้อมูลนี้จึงถูกนำมาใช้ ไฟล์คุกกี้คำสั่งเพื่อสร้าง PHP ให้ตัวเอง คุณไม่จำเป็นต้องกังวลกับมัน คุกกี้นี้มีความหมายสำหรับเซิร์ฟเวอร์เท่านั้นและไม่สามารถใช้เพื่อดึงข้อมูลผู้ใช้ได้
บนเซิร์ฟเวอร์ ข้อมูลเซสชันจะถูกเก็บไว้ใน ไฟล์ข้อความและมีอยู่ในโปรแกรม PHP ในอาร์เรย์ $ _SESSION หากต้องการบันทึกตัวแปรในเซสชัน คุณต้องกำหนดค่าให้กับตัวแปรในอาร์เรย์นี้
มาเริ่มใช้ตัวอย่างกันในที่สุด ทุกอย่างง่ายมาก
ตอนนี้ เรามาลองรับค่าจากอาร์เรย์ $ _SESSION ในอีกตัวอย่างหนึ่ง
โปรดทราบว่าหากในตัวอย่างที่สอง เราลบฟังก์ชัน session_start () เราจะเข้าถึงข้อมูลของอาร์เรย์ $ _SESSION ไม่ได้
Session_id () ฟังก์ชั่น
หลังจากสร้างเซสชันแล้ว คุณจะเข้าถึงตัวระบุเซสชันที่ไม่ซ้ำกันโดยอัตโนมัติโดยใช้ฟังก์ชัน session_id () ฟังก์ชันนี้ช่วยให้คุณตั้งค่าและรับค่าของตัวระบุเซสชันได้
คุณสามารถดูในแถบเครื่องมือสำหรับนักพัฒนาเบราว์เซอร์ของคุณ (ใน Chrome สำหรับสิ่งนี้ ให้กด Ctrl + Shift + I จากนั้นไปที่ Resources แล้วคุณจะพบคุกกี้) โดเมนนี้วางคุกกี้สำหรับเบราว์เซอร์ของคุณชื่อ PHPSESSID และบางอย่าง เช่นนี้: "7g5df9rkd1hhvr33lq1k6c72p7"
ด้วยค่าของ PHPSESSID ที่เซิร์ฟเวอร์จะกำหนดเบราว์เซอร์ของคุณและทำงานกับชุดตัวแปรที่เหมาะสมซึ่งจะพร้อมใช้งานสำหรับสคริปต์ผ่านอาร์เรย์ $ _SESSION ตามที่กล่าวไว้ก่อนหน้านี้
Session_name () ฟังก์ชั่น
หากฟังก์ชัน session_id () อนุญาตให้คุณรับค่าของตัวระบุเซสชัน ฟังก์ชัน session_name () จะช่วยให้คุณค้นหาชื่อของเซสชันได้
อีกครั้งเกี่ยวกับฟังก์ชัน session_start ()
ตอนนี้เราทราบข้อมูลเพิ่มเติมเกี่ยวกับการผสมผสานของเซสชันใน PHP แล้ว และเราต้องกลับไปที่ฟังก์ชัน session_start () อีกครั้ง ฟังก์ชันนี้เริ่มต้นกลไกเซสชันสำหรับผู้ใช้ปัจจุบัน สิ่งนี้เกิดขึ้นได้อย่างไร:
- หากผู้ใช้เปิดเว็บไซต์เป็นครั้งแรก session_start () จะตั้งค่าคุกกี้บนไคลเอนต์และสร้างที่เก็บข้อมูลชั่วคราวบนเซิร์ฟเวอร์ที่เชื่อมโยงกับ ID ผู้ใช้
- กำหนดร้านค้าที่เชื่อมโยงกับตัวระบุปัจจุบันที่ส่งผ่าน
- หากมีข้อมูลอยู่ในที่เก็บข้อมูลบนเซิร์ฟเวอร์ ข้อมูลนั้นจะถูกวางไว้ในอาร์เรย์ $ _SESSION
- หาก register_globals จากไฟล์ php.ini เปิดอยู่ องค์ประกอบทั้งหมดของอาร์เรย์ $ _SESSION จะกลายเป็นตัวแปรส่วนกลาง
ตัวอย่างการใช้งานเซสชัน
ตอนนี้เราจะมาดูตัวอย่างที่จะช่วยให้คุณทำการทดลองกับเซสชันได้เล็กน้อย
เคาน์เตอร์
ในเซสชั่นปัจจุบัน คุณได้เปิดเพจ=$_SESSION["count"]?>ครั้งหนึ่ง.
เปิดตัวอย่างใน "> แท็บนี้
งานของเซสชันทั้งหมดอ้างอิงจากอาร์เรย์ $ _SESSION ซึ่งเห็นได้ชัดเจนในตัวอย่างนี้
หากคุณปิดหน้าต่างเบราว์เซอร์ เซสชันจะสิ้นสุดลง ตัวนับของเราจะถูกรีเซ็ตเป็นศูนย์ พฤติกรรมของเซสชันใน PHP สามารถเปลี่ยนแปลงได้ เราจะกลับมาที่ปัญหานี้เพิ่มเติมในบทความ
จบเซสชั่น
ในการสิ้นสุดเซสชัน เราต้องการ:
- ล้างอาร์เรย์ $ _SESSION
- ลบที่เก็บข้อมูลชั่วคราวบนเซิร์ฟเวอร์
- ลบคุกกี้เซสชั่น
คุณสามารถล้างอาร์เรย์ $ _SESSION โดยใช้ฟังก์ชัน session_unset ()
ฟังก์ชัน session_destroy () ลบที่เก็บข้อมูลชั่วคราวบนเซิร์ฟเวอร์ อีกอย่าง เธอไม่ทำอะไรเลย
คุณต้องลบเซสชันคุกกี้โดยใช้ฟังก์ชัน setcookie () ซึ่งเราเรียนรู้ในบทเรียนเรื่องการใช้คุกกี้ใน PHP
ตัวอย่างการสิ้นสุดเซสชัน:
เซสชั่นสิ้นสุดแล้ว
ตอนนี้คุณสามารถทำการทดสอบ: เรียกใช้ตัวอย่างด้วยตัวนับในหน้าต่างเดียว ปิดตัวนับ จากนั้นเรียกใช้ตัวอย่างด้วยการลบเซสชันและรีเฟรชหน้าด้วยตัวนับอีกครั้ง
การลบคุกกี้สามารถทำได้ดังนี้:
setcookie (session_name (), "", เวลา () - 60 * 60 * 24 * 32, "/")
อีกครั้งเกี่ยวกับฟังก์ชัน session_name () และ session_id ()
ฟังก์ชัน session_name () และ session_id () ไม่ค่อยได้ใช้ในทางปฏิบัติ แต่ฉันกำลังเขียนเกี่ยวกับฟังก์ชันเหล่านี้ เนื่องจากบทความจำเป็นต้องเปิดเผยกลไกของเซสชันใน PHP
คุณสามารถใช้ฟังก์ชันเหล่านี้เพื่อกำหนดชื่อและรหัสเซสชันของคุณเองได้ แต่ไม่แนะนำ หากคุณต้องการตั้งค่า ให้เขียนฟังก์ชันเหล่านี้ด้วยอาร์กิวเมนต์ก่อนฟังก์ชัน session_start () ดังในตัวอย่างด้านล่าง:
จากตัวอย่างนี้ ผู้ใช้ทั้งหมดจะได้รับรหัสเซสชันเดียวกัน
มาดูรายละเอียดกันที่นี่กันดีกว่า หากคุณเรียกใช้ตัวอย่างจากส่วนเกี่ยวกับฟังก์ชัน session_name () (นี่คือลิงก์) ในเบราว์เซอร์ต่างๆ (เช่น ใน Chrome และ Internet Explorer) แต่ละเบราว์เซอร์จะมีเซสชันเฉพาะของตัวเอง ตัวระบุ เบราว์เซอร์จะเก็บคุกกี้ไว้ในโฟลเดอร์ของตนเอง ดังนั้นฟังก์ชัน session_start () จะให้ตัวระบุเฉพาะของเบราว์เซอร์แต่ละตัว ดังนั้น พื้นที่จัดเก็บที่ไม่ซ้ำกันบนเซิร์ฟเวอร์จะถูกสร้างขึ้นสำหรับแต่ละเบราว์เซอร์ ดังนั้น ตัวนับ (อันนี้) จะทำงานแยกกันในแต่ละเบราว์เซอร์
หากคุณตั้งค่าตัวระบุเซสชันเดียวกันสำหรับผู้ใช้ทั้งหมด พวกเขาจะทำงานกับที่เก็บเดียวกันบนเซิร์ฟเวอร์ ต่อไปนี้คือตัวอย่างเคาน์เตอร์ที่จะนับการเข้าชมจากเบราว์เซอร์ต่างๆ:
100) (session_unset (); session_destroy ();)?>
เคาน์เตอร์หมายเลข 2
เปิดหน้าในเบราว์เซอร์ต่างๆ=$_SESSION["count"]?>ครั้งหนึ่ง.
เปิดตัวอย่างใน "> แท็บนี้
หากคุณรันตัวอย่างนี้ คุณจะเห็นยูนิตอยู่ที่นั่นไม่ได้ ผู้เยี่ยมชมรายอื่นอาจเปลี่ยนค่าในที่เก็บเซสชันบนเซิร์ฟเวอร์ไปแล้ว ฉันไม่รู้ว่าเซิร์ฟเวอร์จะลบที่เก็บข้อมูลในกรณีนี้เมื่อใด ดังนั้นหากตัวนับเกิน 100 ฉันจะสิ้นสุดเซสชัน
ตั้งเวลารอ
โดยค่าเริ่มต้น เซสชันจะ "อยู่" จนกว่าผู้เยี่ยมชมจะปิดหน้าต่างเบราว์เซอร์ นี่เป็นเพราะว่าฟังก์ชัน session_start () ตั้งค่าคุกกี้ดังกล่าวให้กับลูกค้า
อายุการใช้งานของเซสชันสามารถเปลี่ยนแปลงได้โดยใช้ฟังก์ชัน session_set_cookie_params () นี่คือไวยากรณ์
session_set_cookie_params (อายุการใช้งาน int [, เส้นทางสตริง [, โดเมนสตริง [, bool ปลอดภัย]]])
ในทางปฏิบัติ ก็เพียงพอแล้วที่จะใช้เฉพาะพารามิเตอร์แรก (ตลอดอายุการใช้งาน) ที่นี่คุณจดเวลาเป็นวินาที ซึ่งกำหนดว่าเซิร์ฟเวอร์ควรจำสถานะเซสชันหลังจากปิดเบราว์เซอร์มากเพียงใด
ฟังก์ชัน session_set_cookie_params () ใช้กับระยะเวลาของสคริปต์เท่านั้น
นี่คือตัวอย่างการใช้ฟังก์ชันนี้:
เคาน์เตอร์หมายเลข 3
ค่าตัวนับ:=$_SESSION["count"]?>.
เปิดเคาน์เตอร์ใน "> แท็บนี้
ปิดตัวนับและปิดเบราว์เซอร์ หลังจาก 30 วินาทีให้เปิดตัวอย่างนี้อีกครั้ง เซสชั่นของคุณจะถูกบันทึกไว้
เซสชั่นเป็นจริงง่ายมาก คุณเพียงแค่ต้องเข้าใจว่ามีไว้เพื่ออะไรและจัดการอย่างไร มาตอบคำถามแรกกันก่อน
บางทีคุณอาจรู้ว่าเว็บเซิร์ฟเวอร์ไม่ได้รักษาการเชื่อมต่อแบบถาวรกับไคลเอ็นต์ และคำขอแต่ละรายการจะได้รับการประมวลผลเป็นคำขอใหม่ โดยไม่ต้องสื่อสารกับคำขอก่อนหน้านี้
นั่นคือ คุณไม่สามารถติดตามคำขอจากผู้เยี่ยมชมคนเดียวกัน หรือบันทึกตัวแปรสำหรับเขาระหว่างการดูหน้าต่างๆ แยกกัน เซสชันถูกคิดค้นขึ้นเพื่อแก้ปัญหาทั้งสองนี้
โดยสรุปแล้ว เซสชันเป็นกลไกที่ช่วยให้คุณระบุเบราว์เซอร์ได้โดยไม่ซ้ำกัน และสร้างไฟล์สำหรับเบราว์เซอร์นี้บนเซิร์ฟเวอร์ ซึ่งเก็บตัวแปรเซสชันไว้
ฉันจะไม่อธิบายรายละเอียดเกี่ยวกับความต้องการกลไกดังกล่าว กรณีเหล่านี้ เช่น ตะกร้าสินค้าในร้านค้าออนไลน์ การอนุญาต และไม่ใช่ปัญหาเล็กๆ น้อยๆ ทั้งหมด เช่น การปกป้องส่วนที่โต้ตอบของไซต์จากสแปม
โดยหลักการแล้ว มันค่อนข้างง่ายที่จะสร้างแอนะล็อกของเซสชันของคุณเอง ซึ่งใช้งานไม่ได้เท่ากับ PHP ในตัว แต่มีสาระสำคัญคล้ายกัน เกี่ยวกับคุกกี้และฐานข้อมูล
เมื่อขอสคริปต์ เราจะดูว่าคุกกี้มีชื่อเฉพาะหรือไม่ หากไม่มีคุกกี้ ให้ตั้งค่าและเขียนบรรทัดใหม่พร้อมข้อมูลผู้ใช้ลงในฐานข้อมูล หากมีคุกกี้ เราก็อ่านจากฐานข้อมูล ด้วยคำขออีกครั้ง เราจะลบบันทึกเก่าออกจากฐานข้อมูล และตอนนี้เรามีกลไกของเซสชันพร้อมแล้ว มันไม่ยากเลย แต่มีความแตกต่างบางประการที่ทำให้ควรใช้กลไกเซสชันในตัว
ก่อนอื่น คุณต้องระบุเบราว์เซอร์ก่อน ในการทำเช่นนี้ คุณต้องให้ตัวระบุที่ไม่ซ้ำกับเขาและขอให้เขาโอนไปพร้อมกับคำขอแต่ละครั้ง ฉันรู้สึกละอายที่จะยอมรับ แต่เมื่อฉันเรียนรู้เกี่ยวกับเซสชันเป็นครั้งแรก ฉันคิดว่านี่เป็นกลไกพิเศษบางอย่าง ซึ่งเป็นวิธีใหม่ในการสื่อสารระหว่างเบราว์เซอร์และเซิร์ฟเวอร์ - "เซสชัน" ตัวระบุเซสชันจะถูกส่งผ่านในลักษณะพิเศษบางอย่าง แต่ความผิดหวังช่างโหดร้าย ...
เซสชันใช้วิธีการถ่ายโอนข้อมูลมาตรฐานและเป็นที่รู้จัก จริงๆแล้วไม่มีคนอื่น
ตัวระบุเป็นตัวแปรปกติ โดยค่าเริ่มต้น ชื่อของมันคือ PHPSESSID
หน้าที่ของ PHP คือส่งไปที่เบราว์เซอร์เพื่อส่งคืนพร้อมกับคำขอครั้งต่อไป จากส่วนคำถามที่พบบ่อยที่กล่าวถึงแล้ว เป็นที่ชัดเจนว่าตัวแปรสามารถส่งผ่านได้สองวิธีเท่านั้น: ในคุกกี้หรือในคำขอ POST / GET
PHP ใช้ทั้งสองตัวเลือก
การตั้งค่าสองอย่างใน php.ini รับผิดชอบสิ่งนี้:
session.use_cookies - ถ้าเท่ากับ 1 ดังนั้น PHP จะส่งตัวระบุไปยังคุกกี้ ถ้า 0 - แสดงว่าไม่ใช่
session.use_trans_sid ถ้าเท่ากับ 1 ดังนั้น PHP จะส่งผ่าน ต่อท้าย URL และแบบฟอร์ม ถ้า 0 - แสดงว่าไม่ใช่
คุณสามารถเปลี่ยนพารามิเตอร์เหล่านี้และพารามิเตอร์เซสชันอื่นๆ ได้ในลักษณะเดียวกับการตั้งค่า PHP อื่นๆ ในไฟล์ php.ini รวมถึงการใช้คำสั่ง ini_set () หรือในไฟล์การกำหนดค่าเว็บเซิร์ฟเวอร์
หากเปิดใช้งานเฉพาะครั้งแรก เมื่อเริ่มต้นเซสชัน (ที่การโทรแต่ละครั้ง session_start ()) คุกกี้ถูกตั้งค่าให้กับลูกค้า เบราว์เซอร์ส่งคืนคุกกี้นี้อย่างถูกต้องทุกครั้งที่มีการร้องขอ และ PHP มีตัวระบุเซสชัน ปัญหาเริ่มต้นขึ้นหากเบราว์เซอร์ไม่ส่งคืนคุกกี้ ในกรณีนี้ หากไม่มีคุกกี้พร้อมตัวระบุ PHP จะเริ่มเซสชันใหม่ตลอดเวลา และกลไกจะไม่ทำงาน
หากเปิดใช้งานเพียงตัวที่สอง จะไม่มีการตั้งค่าคุกกี้ และสิ่งที่เกิดขึ้นคือ โดยพื้นฐานแล้ว มันคุ้มค่าที่จะใช้กลไกเซสชันในตัว หลังจากที่สคริปต์ทำงาน และหน้าถูกสร้างขึ้นอย่างสมบูรณ์แล้ว PHP จะตรวจสอบทั้งหมดและผนวก ID เซสชันต่อท้ายลิงก์แต่ละลิงก์และแต่ละแบบฟอร์ม ดูเหมือนว่านี้:
ดัชนี
กลายเป็น
ดัชนี
และเพิ่มช่องที่ซ่อนอยู่ในแบบฟอร์ม
ในทางทฤษฎี ในเซสชันโฮมเมดของเรากับคุณเกี่ยวกับคุกกี้และฐาน คุณสามารถกำหนดการโอน id ไปยังลิงก์ทั้งหมดได้ด้วยตนเอง - จากนั้นเซสชันของเราจะทำงานโดยไม่คำนึงถึงคุกกี้ แต่คุณเห็นไหม - ดีกว่าเมื่อมีคนอื่นทำงานนี้ ;-)
ทั้งสองตัวเลือกถูกเปิดใช้งานโดยค่าเริ่มต้นใน PHP เวอร์ชันล่าสุด PHP จัดการกับสิ่งนี้อย่างไร คุกอยู่เสมอแสดง และลิงก์จะเติมข้อความอัตโนมัติก็ต่อเมื่อ PHP ไม่พบคุกกี้ที่มี ID เซสชัน เมื่อผู้ใช้เข้าชมไซต์เป็นครั้งแรกในระหว่างเซสชันนี้ คุกกี้จะถูกวางบนเขาและเพิ่มลิงก์ ในคำขอครั้งต่อไป หากรองรับคุกกี้ PHP จะเห็นคุกกี้และหยุดทำลิงก์ให้เสร็จ หากคุกกี้ไม่ทำงาน PHP ยังคงเพิ่ม id ไปยังลิงก์อย่างถูกต้องและเซสชันจะไม่สูญหาย
ผู้ใช้ที่มีคุกกี้จะเห็นลิงก์ยาวพร้อม ID เพียงครั้งเดียว
ด้วยการโอนตัวระบุเสร็จสิ้น ตอนนี้ยังคงผูกไฟล์ที่มีข้อมูลทางฝั่งเซิร์ฟเวอร์ไว้ PHP จะทำสิ่งนี้ให้เรา แค่เขียนว่า:
session_start ();
$ _SESSION ["test"] = "สวัสดีชาวโลก!" ;
และ PHP จะเขียนตัวแปรทดสอบไปยังไฟล์ที่เกี่ยวข้องกับเซสชันนี้
มีจุดสำคัญมากที่นี่
Array $ _SESSION- พิเศษ.
อันที่จริงเป็นตัวแปรที่เราต้องการให้พร้อมใช้งานในสคริปต์ต่างๆ
ในการวางตัวแปรในเซสชัน เพียงแค่กำหนดให้กับองค์ประกอบของอาร์เรย์ $ _SESSION
เพื่อให้ได้ค่ามันก็เพียงพอแล้วที่จะอ้างถึงองค์ประกอบเดียวกัน ตัวอย่างจะอยู่ด้านล่าง
การรวบรวมขยะ - PHP ยังเกี่ยวข้องกับการลบไฟล์ที่ล้าสมัย เช่นเดียวกับการเข้ารหัสข้อมูลและสิ่งอื่น ๆ ที่จำเป็น จากการดูแลนี้ การทำงานกับเซสชันจึงเป็นเรื่องง่ายมาก
อันที่จริงแล้ว เรามาถึงตัวอย่างการทำงานของเซสชัน
ตัวอย่างมีขนาดเล็กมาก:
session_start ();
เสียงก้อง "คุณได้อัปเดตหน้านี้"... $ _SESSION ["ตัวนับ"] ++ " ครั้งหนึ่ง. " ;
เสียงสะท้อน "
อัปเดต ";
?>
เราตรวจสอบว่าเรามีตัวแปรตัวนับในเซสชันหรือไม่ ถ้าไม่มี ให้สร้างด้วยค่า 0 แล้วส่งออกค่าของตัวแปรนั้นและเพิ่มขึ้นหนึ่งค่า ค่าที่เพิ่มขึ้นจะถูกเขียนไปยังเซสชัน และครั้งต่อไปที่มีการเรียกสคริปต์ ตัวแปรจะมีค่าเป็น 1 เป็นต้น ทุกอย่างง่ายมาก
เพื่อให้สามารถเข้าถึงตัวแปรเซสชันบนหน้าใด ๆ ของไซต์ คุณต้องเขียนบรรทัดเดียวเท่านั้น (!) ที่จุดเริ่มต้นของแต่ละไฟล์ซึ่งเราต้องการเซสชัน:
session_start ();
session_start ();
ถ้า ($ _SESSION ["ได้รับอนุญาต"]<>
1
) {
ส่วนหัว ("ตำแหน่ง: /auth.php");
ทางออก;
}
การลบตัวแปรออกจากเซสชัน หากคุณมี register_globals = off ก็เขียน
ยกเลิกการตั้งค่า ($ _ SESSION ["var"]);
ถ้าไม่เช่นนั้น ใกล้เคียงด้วยคุณต้องเขียน:
session_unregister ("var");
สิ่งสำคัญคือต้องเข้าใจว่าควรใช้เซสชันใดและไม่ควรใช้เซสชันใด
อันดับแรก จำไว้ว่าเซสชั่นสามารถใช้ได้เมื่อผู้ใช้ต้องการเท่านั้น ไม่ให้ขัดขวางเขา ท้ายที่สุด เขาสามารถกำจัดตัวระบุเมื่อใดก็ได้!
ตัวอย่างเช่น เมื่อตรวจสอบว่าบุคคลกรอกแบบฟอร์มและไม่ใช่สคริปต์ ผู้ใช้เองก็สนใจในเซสชันที่ทำงานอยู่ มิฉะนั้น เขาจะไม่สามารถส่งแบบฟอร์มได้! แต่สำหรับการจำกัดจำนวนคำขอสคริปต์ เซสชันไม่เหมาะสมอีกต่อไป - สคริปต์ที่เป็นอันตรายจะไม่ส่งคืนตัวระบุ
ประการที่สอง. สิ่งสำคัญคือต้องเข้าใจอย่างชัดเจนว่าเซสชันคือเซสชันของการทำงานกับไซต์ตามที่บุคคลเข้าใจ มาทำงานปิดเบราว์เซอร์ - เซสชันสิ้นสุดลง เหมือนตอนดูหนัง หากคุณต้องการดูอีก - ซื้อตั๋วใหม่ เริ่มเซสชันใหม่ นอกจากนี้ยังมีคำอธิบายทางเทคนิคสำหรับเรื่องนี้ รับประกันได้ว่ากลไกเซสชันจะทำงานจนกว่าเบราว์เซอร์จะปิดเท่านั้น ท้ายที่สุดแล้ว คุกกี้อาจไม่ทำงานสำหรับลูกค้า และแน่นอนว่าในกรณีนี้ ลิงก์ทั้งหมดที่เสริมด้วยตัวระบุจะหายไปเมื่อปิด
อย่างไรก็ตาม เซสชันอาจหายไปโดยไม่ต้องปิดเบราว์เซอร์ เนื่องจากข้อจำกัดที่กล่าวถึงในบทความนี้ กลไกจัดการเซสชันไม่สามารถตรวจพบเมื่อผู้ใช้ปิดเบราว์เซอร์ สำหรับสิ่งนี้ ระยะหมดเวลาถูกใช้ - เวลาที่กำหนดไว้ หลังจากนั้นเราถือว่าผู้ใช้ออกจากไซต์แล้ว โดยค่าเริ่มต้น พารามิเตอร์นี้คือ 24 นาที
หากคุณต้องการบันทึกข้อมูลผู้ใช้เป็นเวลานาน ให้ใช้คุกกี้และฐานข้อมูลบนเซิร์ฟเวอร์หากจำเป็น โดยเฉพาะอย่างยิ่ง นี่คือวิธีการทำงานของระบบการอนุญาตที่เป็นที่นิยมทั้งหมด:
เมื่อระบุผู้ใช้แล้ว เซสชันจะเริ่มต้นขึ้นและสัญญาณการอนุญาตจะถูกส่งไปในนั้น
- หากจำเป็นต้อง "จำ" ผู้ใช้ คุกกี้จะถูกตั้งค่าเป็นผู้ใช้ซึ่งระบุตัวเขา
- ในครั้งต่อไปที่ผู้ใช้เข้าสู่ไซต์ เพื่อที่จะเข้าสู่ระบบ เขาต้องป้อนรหัสผ่าน มิฉะนั้นระบบจะรับรู้โดยคุกกี้ที่ตั้งไว้ก่อนหน้านี้ และเซสชันจะเริ่มต้นขึ้น เซสชันใหม่ แทนที่จะทำต่อในเซสชันเก่า
ประการที่สาม มันไม่คุ้มที่จะเริ่มต้นเซสชันตามอำเภอใจสำหรับทุกคนที่เข้าสู่ไซต์ สิ่งนี้จะสร้างภาระที่ไม่จำเป็นอย่างสมบูรณ์ อย่าใช้เซสชั่นสำหรับมโนสาเร่ - ตัวอย่างเช่นในเคาน์เตอร์ เซสชั่นการโทร spilogue แน่นอนนับตามสถิติการโทรและไม่ใช้กลไกเซสชันที่คล้ายกับ PHP
นอกจากนี้ ลองใช้เครื่องมือค้นหาที่จัดทำดัชนีไซต์ของคุณ หากโรบ็อตค้นหาไม่รองรับคุกกี้ ตามค่าเริ่มต้นแล้ว PHPSESSID จะส่ง PHPSESSID ไปยังลิงก์ ซึ่งอาจไม่เป็นที่พอใจสำหรับเสิร์ชเอ็นจิ้น ซึ่งตามข่าวลือ ไม่ชอบลิงก์ไดนามิกอยู่แล้ว แต่ที่นี่ โดยทั่วไป กับการโทรแต่ละครั้ง - ที่อยู่ใหม่!
หากเซสชันใช้เพื่อจำกัดการเข้าถึงส่วนปิดของไซต์ ทุกอย่างเป็นเพียงเครื่องมือค้นหาและไม่ควรจัดทำดัชนี หากคุณต้องแสดงหน้าเดียวกันแก่ผู้ใช้ทั้งที่ได้รับอนุญาตและไม่ได้รับอนุญาต เคล็ดลับดังกล่าวจะช่วยได้ - เพื่อเริ่มเซสชันเฉพาะกับผู้ที่ป้อนรหัสผ่านหรือผู้ที่เริ่มเซสชันแล้ว
เมื่อต้องการทำเช่นนี้ ที่จุดเริ่มต้นของแต่ละหน้า แทนที่จะเป็นเพียง session_start ()พวกเราเขียน:
if (isset ($ _ REQUEST [session_name ()])) session_start ();
ดังนั้นเราจึงเริ่มเซสชันเฉพาะผู้ที่ส่งตัวระบุเท่านั้น
ดังนั้นจึงจำเป็นต้องส่งให้ผู้ใช้เป็นครั้งแรก - ในขณะที่ได้รับอนุญาต
ถ้าชื่อและโรงจอดรถถูกต้อง - เขียน session_start () !
ข้อผิดพลาดที่พบบ่อยที่สุดที่ PHP ให้ไว้เมื่อพยายามทำงานกับเซสชันคือ:
ทั้งสอง,
คำเตือน: ไม่สามารถส่งคุกกี้ของเซสชัน - ส่งส่วนหัวแล้ว
คำเตือน: ไม่สามารถส่งตัวจำกัดแคชเซสชัน - ส่งส่วนหัวแล้ว
เกิดจากสาเหตุเดียวกัน การแก้ปัญหาได้อธิบายไว้ในข้อเท็จจริงนี้
คำเตือน: เปิด (/ tmp \ sess_SID, O_RDWR) ล้มเหลว: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว (2) ใน full_script_path ในหมายเลขบรรทัด
ก่อนหน้านี้เธอดูเหมือน
คำเตือน: ไม่สามารถเขียนข้อมูลเซสชัน (ไฟล์) โปรดตรวจสอบว่าการตั้งค่าปัจจุบันของ session.save_path ถูกต้อง (/ tmp) ,
หากแปลจากภาษาอังกฤษ จะอธิบายปัญหาโดยละเอียด: ไม่มีเส้นทางที่ระบุใน php.ini ไปยังไดเร็กทอรีที่เขียนไฟล์เซสชัน ข้อผิดพลาดนี้เป็นวิธีที่ง่ายที่สุดในการแก้ไข เพียงเขียนไดเร็กทอรีที่มีอยู่และสามารถเขียนได้ เช่น
session.save_path = c: \ windows \ temp
และอย่าลืมรีสตาร์ท Apache หลังจากนั้น
ปรากฏว่า สติปัญญาของมนุษย์ไม่มีขีดจำกัด ดังนั้นฉันจึงต้องอธิบาย:
ข้อความแสดงข้อผิดพลาดที่สาม (ไม่พบไดเร็กทอรี) UNAVAILABLE จะนำไปสู่สองข้อความแรก เนื่องจากข้อความแสดงข้อผิดพลาดจะส่งออกไปยังเบราว์เซอร์และคุณไม่สามารถใช้ส่วนหัวหลังจากนั้นได้ ดังนั้นอย่ารีบเร่งที่จะหาข้อสรุปก่อนเวลาอันควร แต่ก่อนอื่นให้เขียนเส้นทางที่ถูกต้อง!
ปัญหาที่พบบ่อยที่สุดรองลงมาเมื่อต้องรับมือกับเซสชันคือปัญหาใหญ่ของ register_globals อย่าให้ตัวแปรสคริปต์ชื่อเดียวกับดัชนีของอาร์เรย์ $ _SESSION!
เมื่อ register_globals = on ค่าต่างๆ จะเขียนทับกันและคุณจะสับสน
หากไม่ได้ผล แต่ไม่มีแสดงข้อความใด ๆ ให้เพิ่มสองบรรทัดที่จุดเริ่มต้นของสคริปต์ที่รับผิดชอบในการแสดงข้อผิดพลาดทั้งหมดบนหน้าจอ - ค่อนข้างเป็นไปได้ว่ามีข้อผิดพลาด แต่คุณไม่เห็น พวกเขา.
ini_set ("display_errors", 1);
error_reporting (E_ALL);
หรือเห็นข้อผิดพลาดใน error_log โดยทั่วไป หัวข้อของการแสดงข้อความแสดงข้อผิดพลาดอยู่นอกเหนือขอบเขตของบทความนี้ ดังนั้น อย่างน้อยต้องแน่ใจว่าคุณสามารถมองเห็นข้อความเหล่านั้นได้ คุณสามารถอ่านรายละเอียดเพิ่มเติมเล็กน้อยเกี่ยวกับการแก้ไขปัญหาในส่วนนี้
หากคุณแน่ใจว่าไม่มีข้อผิดพลาด แต่ตัวอย่างที่ให้มาใช้งานไม่ได้ เป็นไปได้ว่า PHP ไม่ได้เปิดใช้งานการถ่ายโอน id ผ่าน url และคุกกี้ด้วยเหตุผลบางอย่างไม่ทำงาน.
ดูสิ่งที่คุณมีกับคุกกี้
โดยทั่วไป หากเซสชันของคุณ "ไม่ทำงาน" ก่อนอื่นให้ลองโอนตัวระบุเซสชันด้วยตนเอง นั่นคือสร้างลิงก์และกำหนดตัวระบุให้กับเซสชันนั้น:
session_start ();
ถ้า (! isset ($ _ SESSION ["ตัวนับ"])) $ _SESSION ["ตัวนับ"] = 0;
เสียงก้อง "คุณได้อัปเดตหน้านี้"... $ _SESSION ["ตัวนับ"] ++ " ครั้งหนึ่ง.
อัปเดต ";
?>
เมื่อทำเช่นนี้ ตรวจสอบให้แน่ใจว่าไม่ได้เปิดใช้งานคำสั่ง session.use_only_cookies ซึ่งจะป้องกันไม่ให้ PHP ยอมรับ ID เซสชันหากส่งผ่าน URL
หากตัวอย่างนี้ใช้ไม่ได้ผล แสดงว่าปัญหาอยู่ใน banal ความผิดพลาด(ครึ่งหนึ่งของ "ปัญหา" ของเซสชันมาจากชื่อตัวแปรที่สะกดผิด) หรือใน PHP เวอร์ชันเก่าเกินไป: รองรับเซสชันปรากฏในเวอร์ชัน 4.0 และอาร์เรย์ $ _SESSION- ใน 4.1 (ก่อนหน้านี้ใช้ $ HTTP_SESSION_VARS).
หากใช้งานได้ แสดงว่าปัญหาอยู่ในคุกกี้ ติดตาม - คุกกี้ประเภทใดที่เซิร์ฟเวอร์ใส่ในเบราว์เซอร์ ไม่ว่าเบราว์เซอร์จะส่งคืนหรือไม่ การค้นหามีประโยชน์มากในขณะที่ดูการแลกเปลี่ยนส่วนหัว HTTP ระหว่างเบราว์เซอร์และเซิร์ฟเวอร์
การอธิบายวิธีการทำงานของคุกกี้นั้นอยู่นอกเหนือขอบเขตของสิ่งนี้และข้อความจำนวนมาก แต่อย่างน้อยตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ส่งคุกกี้พร้อมตัวระบุและเบราว์เซอร์กลับมา และในขณะที่ตัวระบุตรงกัน =)
การตั้งค่าคุกกี้ควรมีลักษณะดังนี้
ชุดคุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6;
ชุดคุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; เส้นทาง = /
(หากคุณกำลังขอสคริปต์ที่ไม่ได้มาจากไดเรกทอรีราก)
การตอบสนองของเซิร์ฟเวอร์ควรมีลักษณะดังนี้
คุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6
คุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; ข = ข
หากเบราว์เซอร์ส่งคืนคุกกี้อื่นที่ไม่ใช่รหัสเซสชัน
หากตัวอย่างจากที่นี่ใช้งานได้ แต่รหัสของคุณใช้ไม่ได้ แสดงว่าปัญหาไม่ได้อยู่ที่เซสชัน แต่อยู่ในอัลกอริทึม ค้นหาตำแหน่งที่คุณสูญเสียตัวแปร โอนตัวอย่างจากที่นี่ทีละขั้นตอน ดีบักสคริปต์ของคุณ
ปัญหาอื่นอาจเกิดขึ้นได้หากคุณใช้การเปลี่ยนเส้นทางส่วนหัวหรือการนำทาง JavaScript
ความจริงก็คือ PHP ต่อท้ายตัวระบุเซสชันโดยอัตโนมัติเฉพาะกับลิงก์ของแบบฟอร์ม แต่จะไม่ทำเช่นนี้กับส่วนหัว จาวาสคริปต์ เมตาแท็ก
ดังนั้น คุณต้องเพิ่มตัวระบุด้วยตนเอง เช่น:
ส่วนหัว ("ตำแหน่ง: /script.php?". session_name (). "=". session_id ());
นอกจากนี้ยังหายากมาก และไม่มีความชัดเจนว่าปัญหามาจากไหน ปัญหาคือการตั้งค่า session.save_handler มีค่าอื่นที่ไม่ใช่ไฟล์ หากไม่เป็นเช่นนั้นให้แก้ไข
- นอกจากคุกกี้แล้ว กลไกเซสชันยังส่งส่วนหัวที่ห้ามการแคชหน้า (ตัวจำกัดแคชเดียวกัน) สำหรับ html สิ่งนี้ถูกต้องและจำเป็น แต่เมื่อคุณพยายามส่งไฟล์ที่มีสคริปต์ที่ตรวจสอบการอนุญาต Internet Explorer ปฏิเสธที่จะดาวน์โหลด เป็นเพราะชื่อนี้ เรียก
session_cache_limiter ("ส่วนตัว");
ต้องแก้ปัญหาก่อนเริ่มเซสชัน - ผิดปกติพอสมควร แต่ในอาร์เรย์ $ _SESSIONคุณไม่สามารถใช้ดัชนีตัวเลข - $ _SESSION [1], $ _SESSION ["10"]- เซสชันจะไม่ทำงาน
- ไม่สามารถตั้งค่า session.use_trans_sid ด้วย . ระหว่าง 4.2 ถึง 5.0 ได้ ini_set ()... เริ่มต้นจาก 5.0 ก็เป็นไปได้อีกครั้ง
- ก่อนหน้าเวอร์ชัน 4.3.3 คุกกี้ PHP ส่งคุกกี้เฉพาะเมื่อคำขอไม่มีตัวระบุเมื่อเริ่มต้นเซสชัน ตอนนี้คุกกี้จะถูกส่งไปทุกครั้งที่โทร session_start
หากคุณมีคำถามเพิ่มเติมหรือบางอย่างไม่ชัดเจน - ยินดีต้อนรับสู่ .ของเรา
เซสชันเป็นวิธีง่ายๆ ในการจัดเก็บข้อมูลสำหรับผู้ใช้แต่ละรายด้วยรหัสเซสชันที่ไม่ซ้ำกัน สามารถใช้เพื่อรักษาสถานะระหว่างคำขอของเพจ โดยปกติ ID เซสชันจะถูกส่งไปยังเบราว์เซอร์ผ่านคุกกี้เซสชันและใช้เพื่อดึงข้อมูลเซสชันที่มีอยู่ การไม่มี ID เซสชันหรือคุกกี้เซสชันบอกให้ PHP สร้างเซสชันใหม่และสร้าง ID เซสชันใหม่
เซสชันใช้เทคโนโลยีที่เรียบง่าย เมื่อสร้างเซสชันแล้ว PHP จะได้รับเซสชันที่มีอยู่โดยใช้ตัวระบุที่ส่งผ่าน (โดยปกติมาจากคุกกี้ของเซสชัน) หรือหากไม่มีสิ่งใดผ่าน เซสชันใหม่จะถูกสร้างขึ้น PHP จะเติม $ _SESSION superglobal ด้วยข้อมูลเซสชันหลังจากเริ่มเซสชัน เมื่อออกจาก PHP จะทำให้เนื้อหาของ $ _SESSION superglobal เป็นอนุกรมโดยอัตโนมัติ และส่งไปยังที่เก็บข้อมูลโดยใช้ตัวจัดการเซสชันเพื่อบันทึกเซสชัน
ตามค่าเริ่มต้น PHP จะใช้ตัวจัดการไฟล์ภายในเพื่อบันทึกเซสชัน ซึ่งตั้งค่าไว้ในตัวแปร INI ของ session.save_handler ตัวจัดการนี้บันทึกข้อมูลบนเซิร์ฟเวอร์ในไดเร็กทอรีที่ระบุในคำสั่งคอนฟิกูเรชัน session.save_path
สามารถเริ่มเซสชันได้ด้วยตนเองโดยใช้ฟังก์ชัน session_start ()... หากกำหนดคำสั่ง session.auto_start เป็น 1 เซสชันจะเริ่มต้นโดยอัตโนมัติเมื่อเริ่มต้นคำขอ
เซสชันมักจะสิ้นสุดลงเมื่อ PHP ดำเนินการสคริปต์เสร็จสิ้น แต่ก็สามารถยุติได้ด้วยตนเองโดยใช้ฟังก์ชัน session_write_close ().
คำเตือน
ความสนใจ
ความคิดเห็น:
เซสชันที่ใช้ไฟล์ (ค่าเริ่มต้นใน PHP) จะบล็อกไฟล์เซสชันทันทีที่เปิดเซสชันด้วยฟังก์ชัน session_start ()หรือทางอ้อมโดยระบุ session.auto_start หลังจากบล็อกแล้ว สคริปต์อื่นจะไม่สามารถเข้าถึงไฟล์เซสชันเดียวกันได้จนกว่าจะปิดหรือเมื่อสคริปต์สิ้นสุดหรือเมื่อมีการเรียกใช้ฟังก์ชัน session_write_close ().
นี่น่าจะเป็นปัญหาสำหรับไซต์ที่ใช้ AJAX เป็นจำนวนมากและสร้างคำขอพร้อมกันหลายรายการ วิธีที่ง่ายที่สุดในการแก้ปัญหานี้คือเรียกใช้ฟังก์ชัน session_write_close ()ทันทีที่มีการเปลี่ยนแปลงที่จำเป็นทั้งหมดในเซสชั่น ควรให้ใกล้กับจุดเริ่มต้นของสคริปต์ คุณยังสามารถใช้กลไกเซสชันอื่นที่สนับสนุนการทำงานพร้อมกันได้
ตั้งแต่เริ่มต้น ทุกคนยอมรับ PHP อย่างไม่หยุดยั้ง แต่ทันทีที่พวกเขาเริ่มสร้างโครงการที่ใหญ่พอในภาษานี้ นักพัฒนาก็ประสบปัญหาใหม่ - ไม่มีแนวคิดของตัวแปรทั่วโลกใน PHP! นั่นคือ สคริปต์ถูกดำเนินการ ส่งหน้าที่สร้างขึ้นไปยังไคลเอนต์ และทรัพยากรทั้งหมดที่ใช้โดยสคริปต์นี้ถูกทำลาย เพื่อแสดงให้เห็น สมมติว่ามีสองหน้าในไซต์เดียวกันคือ index.php และ dothings.php แหล่งที่มาของหน้าเหล่านี้มีลักษณะดังนี้:
index.php dothings.phpหากคุณเรียกใช้สคริปต์ทั้งสองนี้ ในหน้าแรก เราจะเห็นข้อความจารึกว่า "ฉันถูกกำหนดให้กับ index.php" และหน้าที่สองจะว่างเปล่า
นักพัฒนาเว็บไซต์เริ่มใช้คุกกี้เพื่อเก็บตัวแปรทั่วโลกโดยไม่ลังเลใจในฝั่งไคลเอ็นต์ กระบวนการมีลักษณะดังนี้: ผู้ใช้มาที่หน้าแรกของไซต์ ดำเนินการบางอย่าง และข้อมูลทั้งหมดที่เกี่ยวข้องกับผู้ใช้รายนี้ ซึ่งอาจจำเป็นในหน้าอื่นของไซต์ จะถูกเก็บไว้ในเบราว์เซอร์ของเขาในแบบฟอร์ม ของคุกกี้ วิธีนี้มีข้อเสียค่อนข้างมาก เนื่องจากนักพัฒนาหลายคนหันหลังให้ PHP ในคราวเดียว ตัวอย่างเช่น เราต้องอนุญาตให้ผู้ใช้อนุญาตให้เขาเข้าถึงส่วนที่ถูกจำกัด (หรือเฉพาะของเขาเอง) ของไซต์ คุณจะต้องส่งคุกกี้ให้กับผู้ใช้ ซึ่งจะทำหน้าที่เป็นตัวระบุภายหลังบนไซต์ วิธีการนี้จะยุ่งยากและไม่สะดวกทันทีที่ไซต์เริ่มรวบรวมข้อมูลเพิ่มเติมเกี่ยวกับพฤติกรรมของผู้ใช้ เนื่องจากข้อมูลทั้งหมดที่ส่งไปยังผู้ใช้ควรได้รับการเข้ารหัสเพื่อไม่ให้ปลอมแปลงได้ เมื่อเร็วๆ นี้ การปลอมแปลงคุกกี้ทำให้สามารถ "ซ้อน" แชทได้มากกว่าหนึ่งแชท และบางครั้งอาจเข้าถึงอีเมลของคนอื่นได้ นอกจากนี้ยังมีคนแปลกหน้าในโลกที่เบราว์เซอร์ไม่รองรับคุกกี้
ฉันจะไม่พูดถึงปัญหาทางเทคโนโลยีของโครงสร้างของกลไกเซสชัน แต่จะอธิบายเฉพาะวิธีการทำงานอย่างถูกต้องกับเซสชันใน PHP เท่านั้น
วิธีการทำงานกับเซสชัน?
หากคุณทดสอบตัวอย่างจากบทความ (หรือสคริปต์ของคุณ) บนโฮสติ้งเชิงพาณิชย์ใด ๆ ไม่ควรมีปัญหากับการทำงานกับเซสชัน หากคุณตั้งค่าเซิร์ฟเวอร์ของคุณเอง (ไม่ว่าจะเป็นเซิร์ฟเวอร์จริงหรืออีมูเลเตอร์) ข้อผิดพลาดเกี่ยวกับเนื้อหาต่อไปนี้อาจปรากฏขึ้น:
"คำเตือน: เปิด (/ var / state / php / sess_6f71d1dbb52fa88481e752af7f384db0, O_RDWR) ล้มเหลว: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว (2)"
หมายความว่า PHP ของคุณได้รับการกำหนดค่าไม่ถูกต้อง คุณสามารถแก้ปัญหานี้ได้โดยการเขียนเส้นทางที่ถูกต้อง (ไปยังไดเร็กทอรีที่มีอยู่) เพื่อบันทึกเซสชันในไฟล์ php.ini และรีสตาร์ทเซิร์ฟเวอร์
สคริปต์ใด ๆ ที่จะใช้ตัวแปร (ข้อมูล) จากเซสชันควรมีบรรทัดต่อไปนี้:
Session_start ();
คำสั่งนี้บอกเซิร์ฟเวอร์ว่าหน้าที่กำหนดต้องการตัวแปรทั้งหมดที่เกี่ยวข้องกับผู้ใช้ที่กำหนด (เบราว์เซอร์) เซิร์ฟเวอร์ใช้ตัวแปรเหล่านี้จากไฟล์และทำให้พร้อมใช้งาน เป็นสิ่งสำคัญมากที่จะต้องเปิดเซสชันก่อนที่จะส่งข้อมูลใดๆ ไปยังผู้ใช้ ในทางปฏิบัติ แนะนำให้เรียกใช้ฟังก์ชัน session_start () ที่จุดเริ่มต้นของหน้า เช่น
Session_start (); ?>
... ในการตั้งค่าไดเร็กทอรีที่จะบันทึกไฟล์เซสชัน ให้ใช้ฟังก์ชัน session_save_path (): session_save_path ($ _ SERVER ["DOCUMENT_ROOT"] "/ Session"); session_start ();เมื่อเริ่มเซสชันแล้ว คุณสามารถตั้งค่าตัวแปรส่วนกลางได้ เมื่อกำหนดค่าให้กับฟิลด์ใดๆ ในอาร์เรย์ $ _SESSION ตัวแปรที่มีชื่อเดียวกันจะถูกลงทะเบียนโดยอัตโนมัติเป็นตัวแปรเซสชัน อาร์เรย์นี้มีอยู่ในทุกหน้าที่ใช้เซสชัน ตัวอย่างเช่น มาวิเคราะห์โปรแกรมกัน:
index.php ตกลง. โหลดเซสชั่นแล้ว! มาดูกันดีกว่าว่ามีอะไรบ้าง: dothings.phpเมื่อไฟล์เหล่านี้ถูกรันตามลำดับ สคริปต์ "index.php" ตัวแรกจะให้ผลลัพธ์ดังต่อไปนี้:
ตกลง. โหลดเซสชั่นแล้ว! มาดูกันดีกว่าว่ามีอะไรบ้าง:และ "dothings.php" ตัวที่สองคือ:
ฉันถูกถามที่ index.phpตัวแปร $ a มีอยู่ในทุกหน้าของไซต์นี้ที่เริ่มเซสชัน
ฟังก์ชันและเทคนิคที่เป็นประโยชน์อื่นๆ สำหรับการทำงานกับเซสชัน:
- ยกเลิกการตั้งค่า ($ _ SESSION ["a"])- เซสชัน "ลืม" ค่าของตัวแปรที่กำหนดโดยเซสชัน
- session_destroy ()- เซสชันถูกทำลาย (เช่น หากผู้ใช้ออกจากระบบโดยกดปุ่ม "ออก")
- session_set_cookie_params (อายุการใช้งาน int [, เส้นทางสตริง [, โดเมนสตริง]])- การใช้ฟังก์ชันนี้ คุณสามารถกำหนดระยะเวลาที่จะ "ใช้งาน" เซสชั่นได้โดยการตั้งค่า unix_timestamp ซึ่งจะกำหนดเวลาที่เซสชั่น "ตาย" โดยค่าเริ่มต้น เซสชันจะ "อยู่" จนกว่าไคลเอ็นต์จะปิดหน้าต่างเบราว์เซอร์
- session_write_close ()- บันทึกตัวแปรเซสชันและปิด นี่เป็นสิ่งจำเป็นในการเปิดไซต์ในหน้าต่างใหม่ หากหน้ามีการประมวลผลนานและได้บล็อกไฟล์เซสชันสำหรับเบราว์เซอร์ของคุณ
ตัวอย่างของ
ทีนี้มาดูการใช้งานจริงของกลไกเซสชันกัน เราจะมาดูตัวอย่างง่ายๆ แต่มีประโยชน์สองสามตัวอย่าง
การให้สิทธิ์ผู้ใช้
คำถามเกี่ยวกับการอนุญาตผู้ใช้โดยใช้เซสชัน PHP จะถูกถามอย่างต่อเนื่องในการประชุมการเขียนโปรแกรมเว็บ กลไกการอนุญาตผู้ใช้ในระบบโดยใช้เซสชันนั้นค่อนข้างดีจากมุมมองด้านความปลอดภัย (ดูหัวข้อ)
ตัวอย่างของเราจะประกอบด้วยสามไฟล์: index.php, authorize.php และ secretplace.php ไฟล์ index.php มีแบบฟอร์มที่ผู้ใช้จะใส่ชื่อผู้ใช้และรหัสผ่าน แบบฟอร์มนี้จะส่งข้อมูลไปยังไฟล์ authorize.php ซึ่งในกรณีที่อนุญาตสำเร็จ จะอนุญาตให้ผู้ใช้เข้าถึงไฟล์ secretplace.php และแสดงข้อความแสดงข้อผิดพลาด
ตัวอย่าง: index.php
ความปลอดภัย
ดังนั้น เราสามารถโอนตัวระบุจากหน้าหนึ่ง (สคริปต์ PHP) ไปยังหน้าอื่น (จนกว่าจะมีการโทรครั้งต่อไปจากไซต์ของเรา) ซึ่งหมายความว่าเราสามารถแยกแยะผู้เยี่ยมชมไซต์ทั้งหมดได้ เนื่องจากตัวระบุเซสชันเป็นตัวเลขที่มีขนาดใหญ่มาก (128 บิต) จึงไม่มีโอกาสเกิดขึ้นจริง ดังนั้นผู้โจมตีจึงเหลือตัวเลือกต่อไปนี้:
- มีโทรจันในคอมพิวเตอร์ของผู้ใช้ที่ขโมยหมายเลขเซสชัน
- ผู้โจมตีจับการรับส่งข้อมูลระหว่างคอมพิวเตอร์ของผู้ใช้กับเซิร์ฟเวอร์ แน่นอนว่ามีโปรโตคอล SSL ที่ปลอดภัย (เข้ารหัส) แต่ไม่ใช่ทุกคนที่ใช้มัน
- เพื่อนบ้านเข้ามาที่คอมพิวเตอร์ของผู้ใช้ของเราและขโมยหมายเลขเซสชัน
สถานการณ์ดังกล่าวโดยพิจารณาจากข้อเท็จจริงที่ว่ามีคนขโมยบางสิ่งบางอย่างจากใครบางคนโดยทั่วไปไม่อยู่ในความสามารถของโปรแกรมเมอร์ สิ่งนี้ควรได้รับการดูแลโดยผู้ดูแลระบบและผู้ใช้เอง
อย่างไรก็ตาม PHP มักจะถูกหลอก มาดูจุดแฮ็กที่เป็นไปได้ในโปรแกรมการอนุญาตผู้ใช้:
- ไฟล์ authorize.php - ความพยายามที่จะเดารหัสผ่านโดยใช้สคริปต์บุคคลที่สาม
- ไฟล์ secretplace.php เป็นความพยายามในการหลอกลวงโปรแกรมโดยป้อนค่าของตัวแปร $ log_user ลงในแถบที่อยู่ของเบราว์เซอร์ เช่น
"http://www.yoursite.ru/secretplace.php? log_user = แฮ็กเกอร์"
ดังนั้น ในโปรแกรมของเรา "หลุม" สองช่องจึงมองเห็นได้ชัดเจน หลุมหนึ่งมีขนาดเล็กและไม่สังเกตเห็นได้ชัดเจนเป็นพิเศษ แต่ช่องที่สองนั้นใหญ่มาก โดยที่แฮ็กเกอร์ส่วนใหญ่จะปีนขึ้นไปโดยไม่จำเป็น
วิธีการ "แพทช์" หลุมที่ 1?เราจะไม่เขียนโค้ดจำนวนมากเพื่อบล็อกที่อยู่ IP ฯลฯ แต่เพียงแค่ตรวจสอบว่าคำขอมาจากที่ใด หรือมากกว่าจากหน้าของคำขอ หากเป็นหน้าใด ๆ จากไซต์ของเรา ทุกอย่างก็เรียบร้อยดี แต่ ในกรณีอื่นๆ ทั้งหมด เราจะไม่ปล่อยให้มันเข้ามา มาแก้ไขไฟล์ authorize.php กันเถอะ:
Authorize.php V2 หน้า ... ส่วนหัว ("ตำแหน่ง: secretplace.php"); ทางออก; )))?> คุณป้อนรหัสผ่านไม่ถูกต้อง!วิธีกำจัด "หลุม" หมายเลข 2?
สมมติว่าคุณมีเว็บไซต์ที่มนุษย์ทุกคนสามารถลงทะเบียนเพื่อโพสต์ในฟอรัมได้ โดยปกติ ในฟอรัมผู้ใช้บางคน (ผู้ดูแลระบบ ผู้ตรวจสอบ) จะมีโอกาสมากกว่าคนอื่นๆ เช่น พวกเขาสามารถลบข้อความจากผู้ใช้รายอื่นได้ คุณเก็บระดับการเข้าถึงของผู้ใช้ในเซสชันในตัวแปร $ user_status โดยที่ $ user_status = 10 สอดคล้องกับการเข้าถึงระบบแบบเต็ม ผู้โจมตีที่มายังไซต์เพียงแค่ต้องลงทะเบียนตามปกติ แล้วเพิ่มในแถบที่อยู่ของเบราว์เซอร์ ? user_status = 10... ดังนั้นคุณจึงมีผู้ดูแลระบบใหม่ในฟอรัมของคุณ!
โดยหลักการแล้ว ตัวแปรใดๆ ของสคริปต์สามารถตั้งค่าได้โดยใช้บรรทัดที่อยู่ โดยเพียงแค่เพิ่มเครื่องหมายคำถามและชื่อของตัวแปรด้วยค่าตามที่อยู่แบบเต็มของสคริปต์ มาแก้ไขรหัสของเราเพื่อหลีกเลี่ยงสิ่งนี้:
secretplace.php V2 ยกเลิกการตั้งค่าตัวแปร ($ _ SESSION ["logged_user"]); // เปิดเซสชัน session_start (); / * คุณไม่สามารถไปที่หน้านี้ได้ ... หากชื่อผู้ใช้ไม่ได้ลงทะเบียน เราจะเปลี่ยนเส้นทางไปยังหน้า index.php เพื่อเข้าสู่ระบบและรหัสผ่าน ... ในความเป็นจริงคุณสามารถทำอะไรได้มากมาย ตัวอย่างเช่น จำ IP ของผู้ใช้ และหลังจากพยายามเข้าถึงไฟล์เป็นครั้งที่สาม ให้บล็อกมัน * / if (! isset ($ _ SESSION ["logged_user"])) (ส่วนหัว ("ตำแหน่ง: index.php"); exit;)?> เฮ้,คุณอยู่ในเพจลับ! ผลลัพธ์กลไกเซสชันเป็นคุณสมบัติที่ยอดเยี่ยมของภาษา PHP เซสชันนั้นเรียบง่าย ยืดหยุ่นมากในการใช้งาน อย่างไรก็ตาม มีบางแห่งในบางแห่งที่บันทึกความเป็นไปได้ของเซสชัน PHP (มีให้ตั้งแต่เวอร์ชัน 4.0.3) - ในเซสชัน คุณสามารถจัดเก็บตัวแปรได้ไม่เพียงเท่านั้น แต่ยังรวมถึงอ็อบเจ็กต์ด้วย
ตัวอย่างของ
?>// การแทรก SID ลงในลิงก์โดยอัตโนมัติ ini_set ("session.use_trans_sid", จริง); session_start (); ?> คลิกที่นี่!
คลิกที่นี่ !!
// ตัวอย่างการทำงานกับเซสชัน session_start (); // หากเพิ่งเข้าชมไซต์ ให้รีเซ็ตตัวนับ ถ้า (! isset ($ _ SESSION ["count"])) $ _SESSION ["count"] = 0; // เพิ่มตัวนับในเซสชั่น $ _SESSION ["นับ"] = $ _SESSION ["นับ"] + 1; ?>
เคาน์เตอร์
=$_SESSION["count"]?>เวลาปิดเบราว์เซอร์ของคุณเพื่อรีเซ็ตตัวนับ
"target =" _blank "> เปิดหน้าต่างเบราว์เซอร์ลูก
// ตัวอย่างง่ายๆ ของการใช้เซสชันโดยไม่มีคุกกี้ session_name ("ทดสอบ"); session_start (); $ _SESSION ["นับ"] = @ $ _ SESSION ["นับ"] + 1; ?>
เคาน์เตอร์
ในเซสชันปัจจุบันของการทำงานกับเบราว์เซอร์ คุณได้เปิดหน้านี้=$_SESSION["count"]?>เวลาปิดเบราว์เซอร์ของคุณเพื่อรีเซ็ตตัวนับนี้
?=SID?>"> คลิกที่นี่เพื่อรีเฟรชหน้า!