เซสชัน HTTP จะกำหนดค่าพารามิเตอร์ของเซสชันการเชื่อมต่อระยะไกลของเซิร์ฟเวอร์เทอร์มินัลได้อย่างไร อีกครั้งเกี่ยวกับฟังก์ชัน session_name() และ session_id()
เว็บเซิร์ฟเวอร์ไม่ได้รักษาการเชื่อมต่อถาวรกับไคลเอนต์ และแต่ละคำขอจะถือว่าเป็นคำขอใหม่ โดยไม่มีการเชื่อมต่อใดๆ กับคำขอก่อนหน้านี้
นั่นคือ คุณไม่สามารถติดตามคำขอจากผู้เข้าชมคนเดียวกัน หรือเก็บตัวแปรสำหรับการดูหน้าเว็บแต่ละหน้า มันคือการแก้ปัญหาทั้งสองที่เซสชันถูกคิดค้น
โดยสรุปแล้ว เซสชันเป็นกลไกที่ช่วยให้คุณระบุเบราว์เซอร์ได้โดยไม่ซ้ำกันและสร้างไฟล์สำหรับเบราว์เซอร์นี้บนเซิร์ฟเวอร์ที่เก็บตัวแปรเซสชัน
ฉันจะไม่อธิบายรายละเอียดเกี่ยวกับความต้องการกลไกดังกล่าว กรณีเหล่านี้คือกรณีของหนังสือเรียน เช่น ตะกร้าสินค้าใน e-shop การอนุญาต และปัญหาที่ไม่ซับซ้อน เช่น การปกป้องส่วนที่โต้ตอบของไซต์จากสแปม
โดยหลักการแล้ว มันค่อนข้างง่ายที่จะสร้างอะนาล็อกของเซสชันของคุณเอง ซึ่งใช้งานไม่ได้เหมือน PHP ในตัว แต่มีสาระสำคัญคล้ายกัน เกี่ยวกับคุกกี้และฐานข้อมูล
เมื่อขอสคริปต์ เราจะดูว่ามีคุกกี้ที่มีชื่อเฉพาะเข้ามาหรือไม่ หากไม่มีคุกกี้ เราจะตั้งค่าและเขียนบรรทัดใหม่พร้อมข้อมูลผู้ใช้ลงในฐานข้อมูล หากมีคุกกี้ เราก็อ่านจากฐานข้อมูล ด้วยคำขออื่น เราจะลบบันทึกเก่าออกจากฐานข้อมูล และตอนนี้เรามีกลไกเซสชันพร้อมแล้ว ง่ายมาก. แต่มีความแตกต่างบางประการที่ทำให้ควรใช้กลไกเซสชันในตัว
หากเปิดใช้งานเพียงอันแรก เมื่อเริ่มเซสชัน (ทุกครั้งที่เรียกใช้ session_start()) คุกกี้จะถูกตั้งค่าสำหรับไคลเอ็นต์ เบราว์เซอร์ส่งคืนคุกกี้นี้อย่างถูกต้องในทุกคำขอครั้งต่อไปและ PHP มี ID เซสชัน ปัญหาเริ่มต้นขึ้นหากเบราว์เซอร์ไม่ส่งคืนคุกกี้ ในกรณีนี้ หากไม่มีคุกกี้พร้อมตัวระบุ PHP จะเริ่มเซสชันใหม่ตลอดเวลา และกลไกจะไม่ทำงาน
หากเปิดใช้งานเพียงอันที่สอง จะไม่มีการตั้งค่าคุกกี้ และสิ่งที่เกิดขึ้นก็เพราะเหตุนี้ โดยพื้นฐานแล้ว มันคุ้มค่าที่จะใช้กลไกเซสชันในตัว หลังจากที่สคริปต์ทำงาน และหน้าถูกสร้างขึ้นอย่างสมบูรณ์ PHP จะสแกนมันทั้งหมดและเพิ่มไปยังแต่ละลิงก์และการถ่ายโอนตัวระบุเซสชันในแต่ละรูปแบบ ดูเหมือนว่านี้:
ดัชนีกลายเป็น
ดัชนี
การเพิ่มช่องที่ซ่อนอยู่ในแบบฟอร์ม
และเบราว์เซอร์เมื่อคลิกลิงก์ใด ๆ หรือเมื่อคลิกที่ปุ่มในแบบฟอร์มจะส่งตัวแปรที่เราต้องการในคำขอ - รหัสเซสชัน!
ด้วยเหตุผลที่ชัดเจน ID จะถูกเพิ่มไปยังลิงก์ที่เกี่ยวข้องเท่านั้น
ในทางทฤษฎี ในเซสชันที่สร้างขึ้นเองกับคุณเกี่ยวกับคุกกี้และฐานข้อมูล คุณสามารถระบุแหล่งที่มาของการโอน id ไปยังลิงก์ทั้งหมดได้ด้วยตนเอง จากนั้นเซสชันของเราจะทำงานโดยไม่คำนึงถึงคุกกี้ แต่คุณเห็นไหมว่าจะดีกว่าไหมเมื่อมีคนอื่นทำงานนี้ ;-)
ทั้งสองตัวเลือกถูกเปิดใช้งานโดยค่าเริ่มต้นใน PHP เวอร์ชันล่าสุด PHP ทำงานอย่างไรในกรณีนี้? คุกกี้ถูกตั้งค่าเสมอ ลิงก์จะเติมข้อความอัตโนมัติก็ต่อเมื่อ PHP ไม่พบคุกกี้ ID เซสชัน เมื่อผู้ใช้เข้าชมไซต์เป็นครั้งแรกในเซสชั่นนี้ คุกกี้จะถูกตั้งค่าและลิงก์จะเสร็จสมบูรณ์ ในคำขอถัดไป หากรองรับคุกกี้ PHP จะเห็นคุกกี้และหยุดลิงก์การเติม หากคุกกี้ไม่ทำงาน PHP ยังคงเพิ่ม id ไปยังลิงก์อย่างถูกต้อง และเซสชันจะไม่สูญหาย
ผู้ใช้ที่มีคุกกี้ทำงานจะเห็นลิงก์ยาวพร้อมรหัสเพียงครั้งเดียว
วุ้ย. เสร็จสิ้นด้วยการโอนตัวระบุ
ตอนนี้ยังคงผูกไฟล์ที่มีข้อมูลทางฝั่งเซิร์ฟเวอร์ไว้
PHP จะทำเพื่อเรา ง่ายพอที่จะเขียน
session_start();
$_SESSION["test"]="สวัสดีชาวโลก!";
และ PHP จะเขียนการทดสอบตัวแปรลงในไฟล์ที่เกี่ยวข้องกับเซสชันนี้
มีบันทึกที่สำคัญมากที่นี่
อาร์เรย์ $_SESSION เป็นแบบพิเศษ
อันที่จริงมีตัวแปรที่เราต้องการให้พร้อมใช้งานในสคริปต์ต่างๆ
ในการวางตัวแปรในเซสชัน การกำหนดตัวแปรให้กับองค์ประกอบของอาร์เรย์ $_SESSION ก็เพียงพอแล้ว
เพื่อให้ได้ค่าของมัน - เพียงแค่อ้างถึงองค์ประกอบเดียวกัน ตัวอย่างจะอยู่ด้านล่าง
การรวบรวมขยะ - การลบไฟล์ PHP ที่ล้าสมัยนั้นจัดการด้วยตัวเองเช่นกัน เช่นเดียวกับการเข้ารหัสข้อมูลและสิ่งอื่น ๆ ที่จำเป็นมากมาย จากการดูแลนี้ การทำงานกับเซสชันจึงทำได้ง่ายมาก
อันที่จริงเราได้มาถึงตัวอย่างการทำงานของเซสชันแล้ว
ตัวอย่างมีขนาดเล็กมาก:
session_start();
echo "คุณได้อัปเดตหน้านี้ ".$_SESSION["counter"]++." ครั้ง ";
เสียงสะท้อน "
อัปเดต";
?>
เราตรวจสอบว่าเรามีตัวแปรตัวนับในเซสชันหรือไม่ ถ้าไม่มี เราจะสร้างมันขึ้นมาด้วยค่า 0 จากนั้นแสดงค่าของตัวแปรนั้นและเพิ่มขึ้นทีละตัว ค่าที่เพิ่มขึ้นจะถูกเขียนไปยังเซสชัน และครั้งต่อไปที่มีการเรียกสคริปต์ ตัวแปรจะมีค่าเป็น 1 และอื่นๆ
ทุกอย่างง่ายมาก
ในการเข้าถึงตัวแปรเซสชันบนหน้าใดๆ ของไซต์ คุณต้องเขียนบรรทัดเดียวเท่านั้น (!) ที่จุดเริ่มต้นของทุกไฟล์ที่เราต้องการเซสชัน:
session_start();
จากนั้นเข้าถึงองค์ประกอบของอาร์เรย์ $_SESSION ตัวอย่างเช่น การตรวจสอบการให้สิทธิ์จะมีลักษณะดังนี้:
session_start();
ถ้า ($_SESSION["ได้รับอนุญาต"]<>1) {
ส่วนหัว ("ตำแหน่ง: /auth.php");
ทางออก;
}
การลบตัวแปรออกจากเซสชัน
หากคุณมี register_globals=off ก็เพียงพอที่จะเขียน
unset($_SESSION["var"]);
ถ้าไม่เช่นนั้น ใกล้เคียงที่จะเขียนกับเธอ
session_unregister("var");
ข้อผิดพลาดที่พบบ่อยที่สุดที่ PHP พ่นเมื่อพยายามทำงานกับเซสชันคือ:
ทั้งสอง
คำเตือน: ไม่สามารถส่งคุกกี้ของเซสชัน - ส่งส่วนหัวแล้ว
คำเตือน: ไม่สามารถส่งตัวจำกัดแคชเซสชัน - ส่งส่วนหัวแล้ว
เกิดจากสาเหตุเดียวกัน วิธีแก้ปัญหาอธิบายไว้ในของปลอมนี้
ที่สาม,
คำเตือน: open(/tmp\sess_SID, O_RDWR) ล้มเหลว: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว (2) ใน full_script_path ในหมายเลขบรรทัด(เมื่อก่อนดูเหมือน คำเตือน: ไม่สามารถเขียนข้อมูลเซสชัน (ไฟล์) โปรดตรวจสอบว่าการตั้งค่าปัจจุบันของ session.save_path ถูกต้อง (/tmp)),
หากแปลจากภาษาอังกฤษจะอธิบายปัญหาโดยละเอียด: ไม่มีเส้นทางไปยังไดเร็กทอรีที่ระบุใน php.ini ซึ่งเขียนไฟล์เซสชัน ข้อผิดพลาดนี้เป็นวิธีที่ง่ายที่สุดในการแก้ไข เพียงเขียนไดเร็กทอรีที่มีอยู่และสามารถเขียนได้ เช่น
session.save_path = c:\windows\temp
และอย่าลืมรีสตาร์ท Apache หลังจากนั้น
ปรากฏว่าความเฉลียวฉลาดของมนุษย์ไม่มีขีดจำกัด ดังนั้นฉันจึงต้องอธิบาย:
ข้อความแสดงข้อผิดพลาดที่สาม (ไม่พบไดเร็กทอรี) จะส่งผลให้เกิดสองข้อความแรกอย่างหลีกเลี่ยงไม่ได้ เนื่องจากข้อความแสดงข้อผิดพลาดจะส่งออกไปยังเบราว์เซอร์และไม่สามารถใช้ส่วนหัวได้หลังจากนั้น ดังนั้นอย่ารีบเร่งที่จะหาข้อสรุปก่อนเวลาอันควร แต่ก่อนอื่นให้เขียนเส้นทางที่ถูกต้อง!
ปัญหาที่พบบ่อยที่สุดรองลงมาของเซสชันคือปัญหาใหญ่ของ register_globals อย่าให้ชื่อตัวแปรสคริปต์ที่ตรงกับดัชนีของอาร์เรย์ $_SESSION!
ด้วย register_globals=บนค่าต่างๆ จะเขียนทับกันและคุณจะสับสน
และด้วย register_globals=off ข้อผิดพลาดอื่นจะปรากฏขึ้น: "สคริปต์ของคุณอาจใช้ผลข้างเคียงของเซสชันซึ่งมีอยู่จนถึง PHP 4.2.3" ในกรณีที่มีตัวแปรเซสชันในสคริปต์ที่ไม่มีค่าและเป็นโกลบอล ตัวแปรที่มีชื่อเดียวกัน ในการกำจัด คุณต้องเริ่มต้นตัวแปรก่อนใช้งานเสมอ (หรืออย่างน้อยก็ตรวจสอบการมีอยู่) และอย่าให้ชื่อตัวแปรส่วนกลางที่ตรงกับดัชนีของอาร์เรย์ $_SESSION
หากไม่ได้ผล แต่ไม่มีข้อความปรากฏขึ้นให้เพิ่มสองบรรทัดที่จุดเริ่มต้นของสคริปต์ที่รับผิดชอบในการแสดงข้อผิดพลาดทั้งหมดบนหน้าจอ - เป็นไปได้มากที่จะมีข้อผิดพลาด แต่คุณไม่เห็น .
ini_set("display_errors",1);
error_reporting(E_ALL);
หรือเห็นข้อผิดพลาดใน error_log โดยทั่วไป หัวข้อของการแสดงข้อความแสดงข้อผิดพลาดอยู่นอกเหนือขอบเขตของบทความนี้ ดังนั้น อย่างน้อยต้องแน่ใจว่าคุณสามารถมองเห็นข้อความเหล่านั้นได้ คุณสามารถอ่านเพิ่มเติมเล็กน้อยเกี่ยวกับการค้นหาข้อผิดพลาดในส่วนนี้
หากคุณแน่ใจว่าไม่มีข้อผิดพลาด แต่ตัวอย่างข้างต้นใช้ไม่ได้ผล เป็นไปได้ว่า PHP ไม่ได้เปิดใช้งานการส่ง id ผ่าน url คุกกี้ไม่ทำงานด้วยเหตุผลบางอย่าง.
ดูว่ามีอะไรเกิดขึ้นกับคุกกี้ของคุณ
โดยทั่วไป หากเซสชันใช้งานไม่ได้สำหรับคุณ ก่อนอื่นให้ลองส่งตัวระบุเซสชันด้วยตนเอง นั่นคือสร้างลิงก์และกำหนดตัวระบุให้กับเซสชันนั้น:
session_start();
if (!isset($_SESSION["counter"])) $_SESSION["counter"]=0;
echo "คุณได้อัปเดตหน้านี้ ".$_SESSION["counter"]++" ครั้ง
อัปเดต";
?>
เมื่อทำเช่นนี้ ตรวจสอบให้แน่ใจว่าไม่ได้รวมคำสั่ง 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; b=b
หากเบราว์เซอร์ส่งคืนคุกกี้อื่นที่ไม่ใช่รหัสเซสชัน
หากเบราว์เซอร์ไม่ส่งคืนคุกกี้ - ตรวจสอบว่าคุกกี้ทำงานหรือไม่
ตรวจสอบให้แน่ใจว่าโดเมนที่คุณกำลังเข้าถึงมีชื่อที่ถูกต้อง (ที่มีอย่างน้อยหนึ่งจุดและไม่มีอักขระที่ไม่ถูกต้อง เช่น ขีดล่าง) และล้างแคชของเบราว์เซอร์ นี่คือสาเหตุหลักสองประการที่ทำให้คุกกี้ไม่ทำงาน
หากตัวอย่างจากที่นี่ใช้ได้ผล แต่โค้ดของคุณใช้ไม่ได้ แสดงว่าปัญหาไม่ได้อยู่ที่เซสชัน แต่เกิดจากอัลกอริทึม ค้นหาตำแหน่งที่คุณสูญเสียตัวแปร โอนตัวอย่างจากที่นี่ทีละขั้นตอน ดีบักสคริปต์ของคุณ
ปัญหาอื่นอาจเกิดขึ้นได้หากคุณใช้การเปลี่ยนเส้นทางส่วนหัวหรือการนำทาง JavaScript
ความจริงก็คือว่า PHP เพิ่มตัวระบุเซสชันโดยอัตโนมัติเฉพาะกับลิงก์ของ form แต่จะไม่ทำเช่นนี้กับส่วนหัว จาวาสคริปต์ เมตาแท็ก
ดังนั้น คุณต้องเพิ่มตัวระบุด้วยตนเอง เช่น:
ส่วนหัว ("ตำแหน่ง: /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" ]);
ถ้า ($row && password_verify ($_POST [ "auth_pass" ], $row [ "pass" ])) (
$_SESSION [ "user_id" ] = $row [ "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/en/ref.session.php - ข้อมูลล่าสุดและล่าสุดเกี่ยวกับการสนับสนุนเซสชันใน PHP ในเอกสารอย่างเป็นทางการ รวมถึงความคิดเห็นของผู้ใช้จำนวนมาก แนะนำให้อ่านเป็นอย่างยิ่ง
http://phpclub.ru/manrus/f/ref.session.html - การแปลบทนี้เป็นภาษารัสเซียที่ล้าสมัยมาก จากเอกสารที่แปลโดย Alexander Piramidin
http://phpclub.ru/detail/article/sessions
บทความชื่อ "ความจริงเกี่ยวกับเซสชัน" ที่น่าสมเพช ทิ้งความประทับใจไว้เป็นสองเท่า ในตอนเริ่มต้น ผู้เขียนพูดถึงกลไกของเซสชันที่เข้าถึงได้มาก แต่วิธีการที่เขาเสนอตอนท้ายบทความนั้นค่อนข้างคลุมเครือ
บทความในตำราเรียนโดย Dmitry Borodin จากเว็บไซต์
ไม่แนะนำอย่างยิ่งให้ http://php.spb.ru/
พวกหล่อนล้าสมัยมาก ไม่เพียงแต่มีความไม่ถูกต้องจริงเท่านั้น แต่เซสชันใน PHP ไม่ได้ทำงานมาเป็นเวลานาน
ขอบคุณมากสำหรับ Dima มันเป็นบทความแรกเกี่ยวกับเซสชั่นในภาษารัสเซียฉันศึกษาด้วยตัวเอง แต่ตอนนี้ฉันต้องส่งไปยังส่วนที่เหลือที่สมควรได้รับ
นอกจากนี้ น่าเสียดายที่บทความอื่นๆ มากมายบนอินเทอร์เน็ตและไม่ได้รับการอัปเดตมาหลายปีนั้นล้าสมัย
เซสชัน (จากภาษาละติน - เซสซิโอ - การประชุม ภาษาอังกฤษ - เซสชัน) เป็นช่วงเวลาที่ครอบคลุมงานของผู้ใช้บนอินเทอร์เน็ตตั้งแต่วินาทีแรกที่เปิดลิงก์แรกจนถึงลิงก์สุดท้าย คำนวณจากความแตกต่างของเวลาระหว่างคำขอเริ่มต้นและคำขอสุดท้าย อย่างไรก็ตาม ผู้ใช้อาจดูหน้าสุดท้ายในเวลาต่างกัน ซึ่งทำให้ยากต่อการวัดเวลาระหว่างสองคำขอ
เซสชันเกี่ยวข้องกับโปรโตคอล HTTP และคุกกี้อย่างไร
เซสชันคืออะไรสามารถอธิบายได้ตั้งแต่โปรโตคอล HTTP โดยตัวมันเอง โปรโตคอลนี้ไม่ได้ให้วิธีการคงสถานะระหว่างสองการดำเนินการ กล่าวคือ พูดง่ายๆ คือ เปิดหน้าหนึ่งแล้วเปลี่ยนจากหน้านั้นไปยังอีกหน้าหนึ่ง HTTP จะไม่สามารถระบุได้ว่าคำขอทั้งสองเป็นของผู้ใช้รายเดียวกัน และนี่คือที่มาของวิธีการติดตามพิเศษ - การจัดการเซสชัน (เซสชันของเรา)
ดังนั้น เมื่อตอบคำถามว่าเซสชันคืออะไร เราสามารถพูดได้ว่ามันเป็นอ็อบเจ็กต์ลอจิคัลเสริมที่อำนวยความสะดวกในการถ่ายโอนข้อมูลระหว่างคำขอ HTTP ที่ต่อเนื่องกันจากผู้ใช้รายเดียว
คุกกี้ เช่น เซสชัน เก็บข้อมูลเกี่ยวกับผู้ใช้ในขณะที่เขาย้ายผ่านหน้าต่างๆ และปรับปรุงการทำงานของโปรโตคอล แต่ต่างจากข้อที่สองที่ข้อมูลถูกเก็บไว้ในไฟล์ชั่วคราวบนเซิร์ฟเวอร์ ข้อมูลจะถูกเก็บไว้ในคอมพิวเตอร์ของผู้ใช้ในรูปแบบของเศษเล็กเศษน้อย
เซสชั่นมีไว้เพื่ออะไร?
การใช้เซสชันเป็นสิ่งที่ขาดไม่ได้เมื่อทำงานกับไซต์ต่างๆ เช่น ฟอรัม กระดานข่าว และร้านอินเทอร์เน็ต เพราะในกรณีนี้ คุณต้องบันทึกข้อมูลผู้ใช้ไว้หลายหน้า
ขั้นตอนของเซสชัน
เซสชั่นทั้งหมดสามารถแบ่งออกเป็นสามขั้นตอน:
- การเปิดเซสชัน (เมื่อผู้ใช้เริ่มทำงานกับบางไซต์)
- การบัญชีสำหรับตัวแปรเซสชัน (เมื่อนำทางไปยังหน้าต่างๆ)
- สิ้นสุดเซสชัน
เนื่องจากข้อมูลเซสชั่นถูกเก็บไว้ในเซิร์ฟเวอร์ของบุคคลที่สาม จึงเป็นการดีที่สุดที่จะไม่จัดเก็บข้อมูลจำนวนมากในเซิร์ฟเวอร์ แต่ควรใช้คุกกี้
เซสชันใน PHP หรือวิธีการที่ข้อมูลเกี่ยวกับผู้ใช้หรือผู้ซื้อที่เข้าสู่ไซต์ จะถูกบันทึกเมื่อสลับไปมาระหว่างหน้าต่างๆ ของไซต์โดยไม่ยาก บทเรียนมีความสำคัญมาก เกี่ยวข้องกับการสร้างไซต์ 95%
เซสชันใน php . คืออะไร
เซสชันใช้เพื่อเก็บข้อมูลเกี่ยวกับข้อมูลชั่วคราว (เช่น ที่ผู้ใช้เข้าชมไซต์) เมื่อนำทางระหว่างหน้าต่างๆ ของไซต์เดียวกัน เมื่อใช้เซสชัน ข้อมูลจะถูกเก็บไว้ในไฟล์ชั่วคราวบนเซิร์ฟเวอร์ส่วนใหญ่มักจะใช้เซสชัน (และคุกกี้ด้วย) เมื่อสร้างร้านค้าออนไลน์ ฟอรัม กระดานข่าว เครือข่ายสังคมออนไลน์ บล็อก และทรัพยากรอื่น ๆ ความสะดวกของระบบเซสชั่นอยู่ที่การจัดเก็บข้อมูลชั่วคราวของผู้ใช้/ผู้ซื้อที่เข้าสู่ระบบ ซึ่งข้อมูลที่สามารถเข้าถึงได้อย่างรวดเร็วในช่วงเวลาหนึ่ง เซสชันมีวันหมดอายุตามธรรมชาติ - จนกว่าเบราว์เซอร์จะปิด หากคุณปิดเฉพาะเพจ เมื่อคุณเปิดไซต์ ข้อมูลเกี่ยวกับผู้ใช้ / ผู้ซื้อจะยังปรากฏอยู่
ตรรกะของเซสชัน
เซสชัน (หรือเซสชัน) เป็นการจัดเก็บข้อมูลชั่วคราวชนิดหนึ่ง ฉันเตือนคุณทันทีว่ามันคุ้มค่าที่จะบันทึกข้อมูลจำนวนเล็กน้อย ตัวอย่างเช่น การเข้าสู่ระบบและรหัสผ่านของผู้ใช้ที่ป้อนหรือหมายเลขซีเรียลในฐานข้อมูลตัวอย่างงาน
1.
ผู้ใช้ป้อนชื่อผู้ใช้และรหัสผ่านและเข้าสู่เว็บไซต์
2.
ข้อมูลที่มีการเข้าสู่ระบบและรหัสผ่านจะถูกเก็บไว้ในเซสชันของหน้าใดหน้าหนึ่งของเว็บไซต์:
ไฟล์ index.php
session_start(); // แต่ละไฟล์ที่คุณต้องการใช้ข้อมูลเซสชันต้องมีคำสั่ง "start session" ที่จุดเริ่มต้นของโค้ด
$login = "ผู้ดูแลระบบ";
$password = "ผ่าน";
$_SESSION["login"] = $เข้าสู่ระบบ; // บันทึกตัวแปรที่มีล็อกอิน
$_SESSION["password"] = $รหัสผ่าน; // บันทึกตัวแปรที่มีรหัสผ่าน
3. เมื่อคุณไปที่หน้าอื่นของไซต์ ข้อมูลนี้จะยังสามารถใช้ได้:
ไฟล์ example.php(หรือหน้าอื่นๆ)
Echo "การเข้าสู่ระบบของคุณ ".$_SESSION["login"]; // พิมพ์ว่า "ล็อกอินของคุณคือแอดมิน" แม้ว่าเราจะไม่ได้เขียนข้อมูลใดๆ ในหน้านี้ก็ตาม!
ดูมันง่าย!
4. หากคุณต้องการล้างข้อมูลเซสชัน ให้ทำดังนี้
ไฟล์ example.php
session_start(); // "เริ่มเซสชัน" อีกครั้ง
Unset($_SESSION["เข้าสู่ระบบ"]); // ดังนั้นตัวแปรจึงไม่ได้ลงทะเบียนหรือ "ถูกทำลาย"
echo "ข้อมูลเข้าสู่ระบบของคุณคือ ".$_SESSION["login"]; // แสดง "การเข้าสู่ระบบของคุณ" เนื่องจากเราทำลายมันในบรรทัดสุดท้ายจึงไม่มีข้อมูล
session_destroy(); // ทำลายเซสชั่น ข้อมูลทั้งหมด รวมทั้ง $_SESSION["password"] หายไป เมื่อได้รับการร้องขอ ข้อผิดพลาดจะปรากฏขึ้น
โดยทั่วไป การถ่ายโอนดังกล่าวจะคล้ายกับวิธี POST แต่คุณไม่จำเป็นต้องเขียนโค้ดเพิ่มเติมอีกต่อไป และข้อมูลทั้งหมดที่ถ่ายโอนจากเพจหนึ่งไปอีกเพจหนึ่งจะถูกเก็บไว้ในไฟล์ชั่วคราวบนเซิร์ฟเวอร์ อีกครั้ง เซสชันควรมีข้อมูลจำนวนเล็กน้อย ดังนั้นจึงเหมาะสำหรับการจัดเก็บการเข้าสู่ระบบ / รหัสผ่าน ตะกร้าสินค้า และไดรฟ์ข้อมูลขนาดเล็กอื่นๆ
การส่งค่าหรืออาร์เรย์โดยใช้เซสชัน PHP
คุณสามารถเขียนไปยังเซสชันได้ไม่เพียงแค่สตริงเท่านั้น แต่ยังรวมถึงอาร์เรย์ของข้อมูลด้วย อย่าหักโหมจนเกินไปกับขนาดของอาร์เรย์ เพราะทั้งหมดนี้จะส่งผลต่อประสิทธิภาพการทำงานและพื้นที่ว่างบนเซิร์ฟเวอร์ใช้หน้าเริ่มต้นซ้ำ index.php
session_start();
$r = array("หนึ่ง", "สอง", "สาม");
$_SESSION["arr"] = $r;
ไปยังหน้าที่จะแสดงทุกอย่าง
เราบันทึกข้อมูลในเซสชันและไปตามลิงก์ไปยังหน้าอื่นซึ่งจะแสดงข้อมูลทั้งหมด
ไฟล์ปลายทาง หน้า test.phpที่จะเปิดอาร์เรย์
session_start();
print_r($_SESSION["arr"]);
// เอาท์พุท
/*
อาร์เรย์
=> หนึ่ง
=> สอง
=> สาม
*/
?>
คุณอาจต้องการแปรงขึ้นใน. โดยทั่วไปแล้ว ทุกอย่างควรมีความชัดเจน
ฟังก์ชันอื่นๆ สำหรับการทำงานกับเซสชัน
session_unregister(สตริง)- เซสชั่นลืมค่าของตัวแปรส่วนกลางที่กำหนด;session_destroy()- เซสชันถูกทำลาย (เช่น หากผู้ใช้ออกจากระบบโดยกดปุ่มออก)
session_set_cookie_params (อายุการใช้งาน int [, เส้นทางสตริง [, โดเมนสตริง]])- การใช้ฟังก์ชันนี้ คุณสามารถกำหนดระยะเวลาที่เซสชันจะใช้งานได้โดยการตั้งค่า unix_timestamp ที่กำหนดเวลาตายของเซสชัน
รายการฟังก์ชันสำหรับการทำงานกับเซสชัน (เซสชัน) ใน php
session_cache_expire - ส่งคืนการหมดอายุของแคชปัจจุบัน
session_cache_limiter - รับและ/หรือตั้งค่าตัวจำกัดแคชปัจจุบัน
session_commit - นามแฝงสำหรับ session_write_close()
session_decode - ถอดรหัสข้อมูลเซสชันจากสตริง
session_destroy - ทำลายข้อมูลทั้งหมดที่ลงทะเบียนสำหรับ session
session_encode - เข้ารหัสข้อมูลเซสชันปัจจุบันเป็นสตริง
session_get_cookie_params - รับพารามิเตอร์คุกกี้ของเซสชัน
session_id - รับและ/หรือตั้งค่า ID เซสชันปัจจุบัน
session_is_registered - กำหนดว่าตัวแปรถูกลงทะเบียนใน session . หรือไม่
session_module_name - รับและ/หรือตั้งค่าโมดูลเซสชันปัจจุบัน
session_name - รับและ/หรือตั้งชื่อเซสชันปัจจุบัน
session_regenerate_id - แก้ไขรหัสเซสชันปัจจุบันด้วยรหัสที่สร้างขึ้นใหม่
session_register - ลงทะเบียนตัวแปรตั้งแต่หนึ่งตัวขึ้นไปสำหรับเซสชันปัจจุบัน
session_save_path - รับและ/หรือกำหนดเส้นทางการบันทึกของเซสชันปัจจุบัน
session_set_cookie_params - ตั้งค่าพารามิเตอร์คุกกี้ของเซสชัน
session_set_save_handler - ตั้งค่าฟังก์ชั่นการจัดเก็บเซสชันระดับผู้ใช้
session_start - เริ่มต้นข้อมูลเซสชัน
session_unregister - ยกเลิกการลงทะเบียนตัวแปรจาก session ปัจจุบัน
session_unset - ยกเลิกการตั้งค่าตัวแปรเซสชันทั้งหมด
session_write_close - เขียนข้อมูลเซสชันและสิ้นสุด session
ตัวอย่างเซสชัน
จำนวนการดูหน้าเว็บระหว่างเซสชัน เป็นตัวอย่างที่ดีในการทำงาน อย่างไรก็ตาม หลังจากปิดเบราว์เซอร์ การนับถอยหลังจะเริ่มขึ้นอีกครั้งเคาน์เตอร์เข้าชมหน้าเดียวภายในช่วงเดียว
// ตัวอย่างง่ายๆ ของการใช้เซสชันโดยไม่มีคุกกี้
session_name("ทดสอบ");
session_start();
$_SESSION["นับ"] = @$_SESSION["นับ"] + 1;
?>
เคาน์เตอร์
ในเซสชันปัจจุบันของการทำงานกับเบราว์เซอร์ คุณเปิดหน้านี้
=$_SESSION["count"]?>เวลา
ปิดเบราว์เซอร์เพื่อรีเซ็ตตัวนับนี้
คลิกที่นี่เพื่อรีเฟรชหน้า!
ในการเปลี่ยนแต่ละครั้ง ตัวนับจะเพิ่มขึ้น 1)
ขอบคุณที่ให้ความสนใจ! ขอให้โชคดีในความพยายามของคุณ!
เนื่องจาก HTTP เป็นโปรโตคอลไคลเอนต์-เซิร์ฟเวอร์ เซสชัน HTTP ประกอบด้วยสามขั้นตอน:
- ไคลเอนต์สร้างการเชื่อมต่อ TCP (หรือการเชื่อมต่ออื่นหากไม่มีการใช้การขนส่ง TCP)
- ลูกค้าส่งคำขอและรอการตอบกลับ
- เซิร์ฟเวอร์ประมวลผลคำขอและส่งการตอบกลับที่มีรหัสสถานะและข้อมูลที่เกี่ยวข้อง
เริ่มต้นด้วย HTTP/1.1 การเชื่อมต่อจะไม่ปิดหลังจากเฟสที่สาม เนื่องจากไคลเอ็นต์ได้รับอนุญาตให้เริ่มต้นคำขออื่นได้ นั่นคือขั้นตอนที่สองและสามสามารถทำซ้ำได้
กำลังสร้างการเชื่อมต่อ
เนื่องจาก HTTP เป็นโปรโตคอลไคลเอนต์-เซิร์ฟเวอร์ การเชื่อมต่อจึงถูกสร้างขึ้นโดยไคลเอนต์เสมอ ในการเปิดการเชื่อมต่อใน HTTP หมายถึงการสร้างการเชื่อมต่อผ่านการขนส่งที่เหมาะสม โดยปกติคือ TCP
ในกรณีของ TCP คอมพิวเตอร์จะใช้พอร์ต 80 เป็นพอร์ตเซิร์ฟเวอร์ HTTP เริ่มต้นในคอมพิวเตอร์ แม้ว่าจะมีการใช้พอร์ตอื่นเช่น 8000 หรือ 8080 URL ของหน้าที่โหลดจะมีชื่อโดเมนและพอร์ต ซึ่งสามารถ ละเว้นหากตรงกับพอร์ตเริ่มต้น
เราหมายถึง:โมเดลไคลเอนต์/เซิร์ฟเวอร์ไม่อนุญาตให้เซิร์ฟเวอร์ส่งข้อมูลไปยังไคลเอนต์โดยไม่ได้ร้องขอข้อมูลนั้นอย่างชัดเจน เพื่อแก้ไขปัญหานี้ นักพัฒนาเว็บใช้เทคนิคต่างๆ: ping เซิร์ฟเวอร์เป็นระยะโดยใช้อ็อบเจ็กต์ XMLHTTPRequest Javascript, HTML WebSockets API หรือโปรโตคอลที่คล้ายคลึงกัน
ส่งคำขอของลูกค้า
เมื่อสร้างการเชื่อมต่อแล้ว user-agent สามารถส่งคำขอได้ (ตัวแทนผู้ใช้มักจะเป็นเว็บเบราว์เซอร์ แต่อาจไม่ใช่) คำขอของไคลเอ็นต์คือคำสั่งข้อความที่คั่นด้วย CRLF (ตัวแบ่งบรรทัด) คำขอประกอบด้วยสามช่วงตึก:
- บรรทัดแรกมีวิธีการร้องขอและพารามิเตอร์:
- เส้นทางไปยังเอกสาร - URL ที่แน่นอนโดยไม่ต้องระบุโปรโตคอลและชื่อโดเมน
- เวอร์ชันโปรโตคอล HTTP
- แต่ละบรรทัดที่ต่อเนื่องกันคือส่วนหัวของ HTTP และส่งข้อมูลบางอย่างเกี่ยวกับประเภทข้อมูลที่ต้องการไปยังเซิร์ฟเวอร์ (เช่น ภาษาอะไร ประเภท MIME) หรือคำแนะนำในการเปลี่ยนพฤติกรรมของเซิร์ฟเวอร์ (เช่น อย่าส่งคำตอบหากข้อมูลนั้นอยู่ในแคชอยู่แล้ว) ส่วนหัว HTTP เหล่านี้สร้างบล็อกที่ลงท้ายด้วยสตริงว่าง
- บล็อกสุดท้ายเป็นทางเลือกและมีข้อมูลเพิ่มเติม ส่วนใหญ่ใช้วิธี POST
ขอตัวอย่าง
เราได้รับหน้าหลักของเว็บไซต์ และบอกเซิร์ฟเวอร์ว่า user-agent ชอบหน้านั้นเป็นภาษาฝรั่งเศส ถ้าเป็นไปได้:
GET / HTTP/1.1 โฮสต์: เว็บไซต์ยอมรับภาษา: fr
ให้ความสนใจกับบรรทัดว่างในตอนท้าย ซึ่งแยกบล็อกข้อมูลออกจากบล็อกส่วนหัว เนื่องจากไม่มีส่วนหัวของ Content-Length: HTTP ในคำขอ บล็อกข้อมูลจึงว่างเปล่าและเซิร์ฟเวอร์สามารถเริ่มประมวลผลคำขอได้ทันทีที่ได้รับสตริงว่าง ซึ่งบ่งชี้จุดสิ้นสุดของส่วนหัว
ส่งผลการส่งแบบฟอร์ม:
POST /contact_form.php HTTP/1.1 โฮสต์: เว็บไซต์ ความยาวเนื้อหา: 64 ประเภทเนื้อหา: application/x-www-form-urlencoded name=Joe%20User&request=Send%20me%20one%20of%20your%20catalogue
วิธีการขอ
HTTP กำหนดชุดของวิธีการร้องขอที่ระบุการดำเนินการที่ต้องการบนทรัพยากร แม้ว่าจะเป็นคำนามได้ แต่บางครั้งเมธอดคำขอเหล่านี้ก็ถูกเรียกว่าคำสั่ง HTTP คำขอ GET และ POST ที่พบบ่อยที่สุดคือ:
- GET ใช้เพื่อขอเนื้อหาของทรัพยากรที่ระบุ คำขอที่ใช้ GET ควรรับเฉพาะข้อมูลเท่านั้น
- วิธี POST จะส่งข้อมูลไปยังเซิร์ฟเวอร์เพื่อให้สามารถเปลี่ยนสถานะได้ วิธีนี้มักใช้สำหรับแบบฟอร์ม HTML
โครงสร้างการตอบสนองของเซิร์ฟเวอร์
หลังจากที่ตัวแทนที่แนบมาได้ส่งคำขอแล้ว เว็บเซิร์ฟเวอร์จะประมวลผลและส่งการตอบกลับ โดยการเปรียบเทียบกับคำขอของไคลเอ็นต์ การตอบสนองของเซิร์ฟเวอร์คือคำสั่งข้อความที่คั่นด้วย CRLF ซึ่งจัดกลุ่มเป็นสามบล็อกที่แตกต่างกัน:
- บรรทัดแรกคือบรรทัดสถานะประกอบด้วยการยอมรับเวอร์ชัน HTTP ที่ใช้และสถานะของคำขอ (และค่าที่มนุษย์อ่านได้)
- บรรทัดต่อไปนี้คือส่วนหัว HTTP ที่ให้ข้อมูลแก่ลูกค้าเกี่ยวกับข้อมูลที่ส่ง (เช่น ประเภท ขนาด อัลกอริธึมการบีบอัด คำแนะนำในการแคช) เช่นเดียวกับคำขอของไคลเอ็นต์ ส่วนหัว HTTP เหล่านี้จะสร้างบล็อกที่ลงท้ายด้วยสตริงว่าง
- บล็อกสุดท้ายมีข้อมูล (ถ้ามี)
ตัวอย่างคำตอบ
เรียกข้อมูลหน้าเว็บสำเร็จ:
HTTP/1.1 200 วันที่ตกลง: วันเสาร์ 09 ต.ค. 2010 14:28:02 น. เซิร์ฟเวอร์ GMT: Apache ปรับปรุงล่าสุด: อังคาร 01 ธันวาคม 2009 20:18:22 GMT ETag: "51142bc1-7449-479b075b2891b" ช่วงที่ยอมรับ: ไบต์ เนื้อหา-ความยาว: 29769 ประเภทเนื้อหา: text/html(ที่นี่ไป 29769 ไบต์ของหน้าเว็บที่ร้องขอ)
ข้อความว่าทรัพยากรที่ร้องขอถูกย้าย:
HTTP/1.1 301 เซิร์ฟเวอร์ถูกย้ายอย่างถาวร: Apache/2.2.3 (Red Hat) ประเภทเนื้อหา: text/html; charset=iso-8859-1 วันที่: เสาร์ 09 ต.ค. 2553 14:30:24 GMT สถานที่: (นี่คือที่อยู่ใหม่ของทรัพยากรที่ร้องขอ ลูกค้าคาดว่าจะร้องขอมัน) Keep-Alive: หมดเวลา = 15 สูงสุด = 98 ยอมรับช่วง: ไบต์ผ่าน: Moz-Cache-zlb05 การเชื่อมต่อ: Keep-Alive X-Cache-Info: แคช X-Cache-Info: แคช ความยาวเนื้อหา: 325 (เนื้อหามีหน้ามาตรฐานที่จะแสดงหากลูกค้าไม่สามารถตามลิงค์ได้)
ย้ายอย่างถาวร
เอกสารที่ได้ย้ายมาที่นี่.
เซิร์ฟเวอร์ Apache/2.2.3 (Red Hat) ที่พอร์ต 80
ข้อความว่าทรัพยากรที่ร้องขอไม่มีอยู่: