คอมพิวเตอร์ Windows อินเทอร์เน็ต

เซสชัน 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 ซึ่งคุณสามารถตั้งค่าไดเร็กทอรีของคุณเองสำหรับบันทึกไฟล์เซสชันได้ มีความปลอดภัยมากกว่าเมื่อเก็บไว้ในไดเร็กทอรีชั่วคราวที่ใช้ร่วมกันของเซิร์ฟเวอร์โดยค่าเริ่มต้น

ข้อมูลเพิ่มเติม:

  • นอกจากคุกกี้แล้ว กลไกเซสชันยังส่งส่วนหัวที่ห้ามการแคชหน้า (ตัวจำกัดแคชเดียวกัน) สำหรับ html สิ่งนี้ถูกต้องและจำเป็น แต่เมื่อคุณพยายามส่งไฟล์ที่มีสคริปต์ที่ตรวจสอบการอนุญาต Internet Explorer ปฏิเสธที่จะดาวน์โหลด เป็นเพราะชื่อนี้ เรียก
    session_cache_limiter("ส่วนตัว");
    ก่อนเริ่มเซสชันควรแก้ปัญหา
  • ดูเหมือนว่าแปลก คุณไม่สามารถใช้ดัชนีตัวเลขในอาร์เรย์ $_SESSION - $_SESSION, $_SESSION["10"] - เซสชันจะไม่ทำงาน
  • ไม่สามารถตั้งค่า session.use_trans_sid โดยใช้ ini_set() ระหว่างเวอร์ชัน 4.2 และ 5.0 ได้ เริ่มต้นจาก 5.0 ก็เป็นไปได้อีกครั้ง
  • ก่อนหน้าเวอร์ชัน 4.3.3, PHP จะส่งคุกกี้ก็ต่อเมื่อคำขอไม่มีตัวระบุเมื่อเซสชันเริ่มต้น ตอนนี้คุกกี้จะถูกส่งทุกครั้งที่โทรไปที่ session_start()

    ตัวอย่างการให้สิทธิ์โดยใช้ 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;
    ?>

    เคาน์เตอร์


    ในเซสชันปัจจุบันของการทำงานกับเบราว์เซอร์ คุณเปิดหน้านี้
    เวลา
    ปิดเบราว์เซอร์เพื่อรีเซ็ตตัวนับนี้
    คลิกที่นี่เพื่อรีเฟรชหน้า!
    ในการเปลี่ยนแต่ละครั้ง ตัวนับจะเพิ่มขึ้น 1)

    ขอบคุณที่ให้ความสนใจ! ขอให้โชคดีในความพยายามของคุณ!

    เนื่องจาก HTTP เป็นโปรโตคอลไคลเอนต์-เซิร์ฟเวอร์ เซสชัน HTTP ประกอบด้วยสามขั้นตอน:

    1. ไคลเอนต์สร้างการเชื่อมต่อ TCP (หรือการเชื่อมต่ออื่นหากไม่มีการใช้การขนส่ง TCP)
    2. ลูกค้าส่งคำขอและรอการตอบกลับ
    3. เซิร์ฟเวอร์ประมวลผลคำขอและส่งการตอบกลับที่มีรหัสสถานะและข้อมูลที่เกี่ยวข้อง

    เริ่มต้นด้วย HTTP/1.1 การเชื่อมต่อจะไม่ปิดหลังจากเฟสที่สาม เนื่องจากไคลเอ็นต์ได้รับอนุญาตให้เริ่มต้นคำขออื่นได้ นั่นคือขั้นตอนที่สองและสามสามารถทำซ้ำได้

    กำลังสร้างการเชื่อมต่อ

    เนื่องจาก HTTP เป็นโปรโตคอลไคลเอนต์-เซิร์ฟเวอร์ การเชื่อมต่อจึงถูกสร้างขึ้นโดยไคลเอนต์เสมอ ในการเปิดการเชื่อมต่อใน HTTP หมายถึงการสร้างการเชื่อมต่อผ่านการขนส่งที่เหมาะสม โดยปกติคือ TCP

    ในกรณีของ TCP คอมพิวเตอร์จะใช้พอร์ต 80 เป็นพอร์ตเซิร์ฟเวอร์ HTTP เริ่มต้นในคอมพิวเตอร์ แม้ว่าจะมีการใช้พอร์ตอื่นเช่น 8000 หรือ 8080 URL ของหน้าที่โหลดจะมีชื่อโดเมนและพอร์ต ซึ่งสามารถ ละเว้นหากตรงกับพอร์ตเริ่มต้น

    เราหมายถึง:โมเดลไคลเอนต์/เซิร์ฟเวอร์ไม่อนุญาตให้เซิร์ฟเวอร์ส่งข้อมูลไปยังไคลเอนต์โดยไม่ได้ร้องขอข้อมูลนั้นอย่างชัดเจน เพื่อแก้ไขปัญหานี้ นักพัฒนาเว็บใช้เทคนิคต่างๆ: ping เซิร์ฟเวอร์เป็นระยะโดยใช้อ็อบเจ็กต์ XMLHTTPRequest Javascript, HTML WebSockets API หรือโปรโตคอลที่คล้ายคลึงกัน

    ส่งคำขอของลูกค้า

    เมื่อสร้างการเชื่อมต่อแล้ว user-agent สามารถส่งคำขอได้ (ตัวแทนผู้ใช้มักจะเป็นเว็บเบราว์เซอร์ แต่อาจไม่ใช่) คำขอของไคลเอ็นต์คือคำสั่งข้อความที่คั่นด้วย CRLF (ตัวแบ่งบรรทัด) คำขอประกอบด้วยสามช่วงตึก:

    1. บรรทัดแรกมีวิธีการร้องขอและพารามิเตอร์:
      • เส้นทางไปยังเอกสาร - URL ที่แน่นอนโดยไม่ต้องระบุโปรโตคอลและชื่อโดเมน
      • เวอร์ชันโปรโตคอล HTTP
    2. แต่ละบรรทัดที่ต่อเนื่องกันคือส่วนหัวของ HTTP และส่งข้อมูลบางอย่างเกี่ยวกับประเภทข้อมูลที่ต้องการไปยังเซิร์ฟเวอร์ (เช่น ภาษาอะไร ประเภท MIME) หรือคำแนะนำในการเปลี่ยนพฤติกรรมของเซิร์ฟเวอร์ (เช่น อย่าส่งคำตอบหากข้อมูลนั้นอยู่ในแคชอยู่แล้ว) ส่วนหัว HTTP เหล่านี้สร้างบล็อกที่ลงท้ายด้วยสตริงว่าง
    3. บล็อกสุดท้ายเป็นทางเลือกและมีข้อมูลเพิ่มเติม ส่วนใหญ่ใช้วิธี 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 ซึ่งจัดกลุ่มเป็นสามบล็อกที่แตกต่างกัน:

    1. บรรทัดแรกคือบรรทัดสถานะประกอบด้วยการยอมรับเวอร์ชัน HTTP ที่ใช้และสถานะของคำขอ (และค่าที่มนุษย์อ่านได้)
    2. บรรทัดต่อไปนี้คือส่วนหัว HTTP ที่ให้ข้อมูลแก่ลูกค้าเกี่ยวกับข้อมูลที่ส่ง (เช่น ประเภท ขนาด อัลกอริธึมการบีบอัด คำแนะนำในการแคช) เช่นเดียวกับคำขอของไคลเอ็นต์ ส่วนหัว HTTP เหล่านี้จะสร้างบล็อกที่ลงท้ายด้วยสตริงว่าง
    3. บล็อกสุดท้ายมีข้อมูล (ถ้ามี)

    ตัวอย่างคำตอบ

    เรียกข้อมูลหน้าเว็บสำเร็จ:

    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 (เนื้อหามีหน้ามาตรฐานที่จะแสดงหากลูกค้าไม่สามารถตามลิงค์ได้) 301 ย้ายอย่างถาวร

    ย้ายอย่างถาวร

    เอกสารที่ได้ย้ายมาที่นี่.


    เซิร์ฟเวอร์ Apache/2.2.3 (Red Hat) ที่พอร์ต 80

    ข้อความว่าทรัพยากรที่ร้องขอไม่มีอยู่: