ตรวจสอบว่าเซสชัน PHP เริ่มขึ้นแล้ว


461

ฉันมีไฟล์ PHP ที่บางครั้งเรียกจากหน้าเว็บที่เริ่มเซสชันและบางครั้งมาจากหน้าเว็บที่ไม่ได้เริ่มเซสชัน ดังนั้นเมื่อฉันมีsession_start()สคริปต์นี้บางครั้งฉันได้รับข้อความข้อผิดพลาดสำหรับ "เซสชั่นเริ่มแล้ว" สำหรับสิ่งที่ฉันได้ใส่บรรทัดเหล่านี้:

if(!isset($_COOKIE["PHPSESSID"]))
{
  session_start();
}

แต่ครั้งนี้ฉันได้รับข้อความเตือนนี้:

แจ้งให้ทราบล่วงหน้า: ตัวแปรที่ไม่ได้กำหนด: _SESSION

มีวิธีที่ดีกว่าในการตรวจสอบว่าเซสชั่นได้เริ่มขึ้นแล้ว?

ถ้าฉันใช้@session_startมันจะทำให้สิ่งต่าง ๆ ทำงานอย่างถูกต้องและเพียงแค่ปิดคำเตือน?



ดูเพิ่มเติมได้ที่คำตอบของ Stackoverflow: stackoverflow.com/questions/1545357/…
contact-form.co_you_go

คำตอบ:


761

วิธีที่แนะนำสำหรับเวอร์ชันของPHP> = 5.4.0, PHP 7

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

การอ้างอิง: http://www.php.net/manual/en/function.session-status.php

สำหรับเวอร์ชันของPHP <5.4.0

if(session_id() == '') {
    session_start();
}

1
ฉันคิดว่ามีปัญหากับโซลูชันสำหรับ PHP <5.4 session_id ถูกตั้งค่าเซสชันเวลา FIRST เริ่มต้น แต่จะไม่ถูกลบเมื่อปิดเซสชัน ตัวอย่างเช่นหากมีอยู่ก่อนหน้าโค้ดของคุณรหัสเช่นsession_start();session_write_close();: เงื่อนไข if จะล้มเหลว แต่เราไม่มีเซสชันเปิด ...
Nicol

@Nicolo Martini ตามที่ฉันเข้าใจ: เซสชันเริ่มต้นsession_start()ที่ด้านบนสุดของสคริปต์จะปิดเมื่อสคริปต์ออกหรือเมื่อsession_write_closed()ถูกเรียกก่อนที่สคริปต์จะออก คือปิดเซสชันเมื่อข้อมูลถูกเขียนไปยังคุกกี้เซสชันและเซสชันถูกปลดล็อคเพื่อให้เข้าถึงได้โดยสคริปต์อื่นที่เรียก 'session_start' ด้วย การปิดไม่ได้หมายความว่าเซสชันจะถูกทำลายดังนั้น คุณสามารถปิดเซสชั่นโดยการออกสคริปต์ปัจจุบันหรือโทรและคุณสามารถเปิดอีกครั้งโดยการเรียกsession_write_close() session_start()ความเข้าใจของฉันอย่างน้อย
สเตฟาน

1
นี่เป็นวิธีที่ดีในการเริ่มเซสชันหรือไม่? เพราะในลิงค์ไม่มีอะไรเกี่ยวข้องกับคำตอบนี้
csandreas1

@ csandreas1 คุณจะเห็นจากลิงก์คำอธิบายของ session_status และค่าส่งคืนที่คาดไว้ คำตอบสำหรับคำถามของคุณคือใช่!
lovelyramos

ฉันเคยล้มเหลวนี้ในบางสถานการณ์ - ฉันเคยใช้ถ้า (! isset ($ _ SESSION)) กับความสำเร็จ
Scott

161

สำหรับเวอร์ชั่นของ PHP ก่อน PHP 5.4.0:

if(session_id() == '') {
    // session isn't started
}

ถึงแม้ว่า IMHO คุณควรคิดเกี่ยวกับการปรับเปลี่ยนรหัสการจัดการเซสชันของคุณอีกครั้งหากคุณไม่ทราบว่าเซสชันนั้นเริ่มหรือไม่ ...

ที่กล่าวว่าความคิดเห็นของฉันเป็นแบบอัตนัยและมีสถานการณ์ (ตัวอย่างซึ่งอธิบายไว้ในความคิดเห็นด้านล่าง) ซึ่งอาจเป็นไปไม่ได้ที่จะรู้ว่าถ้าเริ่มเซสชัน


37
ไม่จำเป็นว่าจะต้องรู้ว่าเซสชั่นของคุณเริ่มต้นแล้วหรือไม่ หากคุณขี้เกียจโหลด (เริ่มเซสชันเมื่อจำเป็นครั้งแรกเท่านั้น) การทดสอบในคำตอบของคุณจะดีมาก
drewm

1
นอกจากนี้ในบางสภาวะแวดล้อม apache ยังมีการตั้งค่าเริ่มต้นอัตโนมัติใหม่อีกด้วย
LeonardChallis

ตัวอย่างสำหรับการทดสอบว่า session_id () ส่งคืนสตริงว่างในไฟล์รวม:
tgoneil

3
ความคิดเห็นเกี่ยวกับการจัดการเซสชันซ้ำหากคุณไม่ทราบว่ามีการดำเนินการซ้ำหรือไม่เกี่ยวข้องกันจริงๆ ตัวอย่างเช่นหากการเข้ารหัสคุณสมบัติขั้นสูงในธีม WordPress คุณจะไม่รู้เลยว่าปลั๊กอินเริ่มต้นแล้วโดยใช้เซสชันโดยไม่ตรวจสอบ โลกแห่งการเข้ารหัสนั้นไม่ใช่ขาวดำเสมอ: P
Jimbo Jonny

อืมจุดดีแน่นอน ฉันยอมรับว่าความคิดเห็นของฉันเป็นแบบอัตนัย - ฉันจะแก้ไขคำตอบเพื่อสะท้อนสิ่งนี้
Alex

71

PHP 5.4 แนะนำsession_status ()ซึ่งเชื่อถือได้มากกว่าการพึ่งพาsession_id()ซึ่งมีความน่าเชื่อถือมากกว่าการพึ่งพา

พิจารณาตัวอย่างต่อไปนี้:

session_id('test');
var_export(session_id() != ''); // true, but session is still not started!
var_export(session_status() == PHP_SESSION_ACTIVE); // false

ดังนั้นเพื่อตรวจสอบว่าเซสชันเริ่มทำงานหรือไม่วิธีที่แนะนำใน PHP 5.4 คือ:

session_status() == PHP_SESSION_ACTIVE

3
ตัวอย่างของรหัสที่ใช้ session_status เมื่อมีและวิธีเก่ากว่าที่ดูเหมือนว่าจะไม่สมบูรณ์แบบที่นี่ BTW คำใบ้คำใบ้ :)
Jimbo Jonny

1
ขอบคุณสำหรับการอัพเดทของเบนจามิน เป็นการดีที่จะรู้ว่าวิธีการใหม่สามารถใช้เป็น PHP 5.4
โลแกน

1
นี่เป็นวิธีที่ดีกว่ามากในการตรวจสอบสิ่งนี้คุณไม่ทราบว่าคุณได้เริ่มเซสชันโดยเฉพาะเมื่อผู้ใช้ล้างคุกกี้เมื่อพวกเขาอยู่ในระหว่างการเรียกดูเว็บไซต์หรือไม่ ... ฉันมักจะรหัสสำหรับ 2 ปี ไม่เคยรู้เลยว่าผู้ใช้จะทำอะไร ;-) สำหรับตัวฉันเองฉันมีไฟล์ Config.php ขนาดเล็กที่เรียกใช้กับสคริปต์ของฉันทั้งหมดเพื่อตั้งค่าตัวแปรและข้อมูลอื่น ๆ ดังนั้นเพียงแค่เพิ่มสิ่งนี้ลงในไฟล์นั้น เป็นสิ่งจำเป็น
Andy Braham

35

คุณสามารถทำได้และมันง่ายมาก

if (!isset($_SESSION)) session_start();

หวังว่าจะช่วย :)


6
@zloctb: ฉันไม่สามารถนึกถึงสถานการณ์ใด ๆ ที่ฉันทำ$_SESSION=array();ดังนั้นคำตอบนี้ดูเหมือนจะไม่เป็นไร
halfer

5
@halfer ดูคำตอบของ Ryan หากsession_destroy()ได้รับการเรียกก็$_SESSIONยังคงสามารถตั้งค่าได้ นอกจากนี้ในการทดสอบหน่วยคุณอาจตั้งค่า$_SESSIONโดยตรง แต่ฉัน upvoting นี้เป็นสถานการณ์ที่ปฏิบัติส่วนใหญ่คำตอบนี้ควรจะดีพอ (จนกว่า PHP 5.3 จะไม่เห็นอีกต่อไป ... )
27899 Darren Cook

22
if (version_compare(phpversion(), '5.4.0', '<')) {
     if(session_id() == '') {
        session_start();
     }
 }
 else
 {
    if (session_status() == PHP_SESSION_NONE) {
        session_start();
    }
 }

21

ก่อนหน้า PHP 5.4 ไม่มีวิธีการที่เชื่อถือได้ในการรู้อื่นนอกจากตั้งค่าสถานะโกลบอล

พิจารณา:

var_dump($_SESSION); // null
session_start();
var_dump($_SESSION); // array
session_destroy();
var_dump($_SESSION); // array, but session isn't active.

หรือ:

session_id(); // returns empty string
session_start();
session_id(); // returns session hash
session_destroy();
session_id(); // returns empty string, ok, but then
session_id('foo'); // tell php the session id to use
session_id(); // returns 'foo', but no session is active.

ดังนั้นก่อน PHP 5.4 คุณควรตั้งค่าบูลีนระดับโลก


12

สำหรับทุกรุ่น php

if ((function_exists('session_status') 
  && session_status() !== PHP_SESSION_ACTIVE) || !session_id()) {
  session_start();
}

1
ในทำนองเดียวกันเราสามารถทำได้if ((defined('PHP_SESSION_ACTIVE') && session_status() !== PHP_SESSION_ACTIVE) || !session_id())
Anthony Hatzopoulos

9

ตรวจสอบสิ่งนี้:

<?php
/**
* @return bool
*/
function is_session_started()
{
    if ( php_sapi_name() !== 'cli' ) {
        if ( version_compare(phpversion(), '5.4.0', '>=') ) {
            return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
        } else {
            return session_id() === '' ? FALSE : TRUE;
        }
    }
    return FALSE;
}

// Example
if ( is_session_started() === FALSE ) session_start();
?>

แหล่งที่มาhttp://php.net


6

ใช้session_id ()มันจะส่งกลับสตริงที่ว่างเปล่าถ้าไม่ได้ตั้งค่า $_COOKIEมันเป็นความน่าเชื่อถือกว่าการตรวจสอบ

if (strlen(session_id()) < 1) {
    session_start();
}


5

สิ่งนี้ควรใช้ได้กับ PHP ทุกเวอร์ชัน มันเป็นตัวกำหนดเวอร์ชัน PHP จากนั้นตรวจสอบเพื่อดูว่าเซสชันนั้นเริ่มต้นตามเวอร์ชัน PHP หรือไม่ ถ้าเซสชันไม่ได้เริ่มต้นขึ้น

function start_session() {
  if(version_compare(phpversion(), "5.4.0") != -1){
    if (session_status() == PHP_SESSION_NONE) {
      session_start();
    }
  } else {
    if(session_id() == '') {
      session_start();
    }
  }
}

4

สิ่งเดียวที่คุณต้องทำคือ:

<?php
if(!isset($_SESSION))
{
session_start();
}
?>

นี่คือสิ่งที่ฉันใช้ในช่วงเวลาหลายปี ใครแนะนำไม่ให้ใช้อันนี้? แน่นอนว่าเป็นเรื่องดีที่จะใช้การตรวจสอบว่ามีการเริ่มเซสชันบางครั้ง - ในบางสภาพแวดล้อม apache มีการตั้งค่าเริ่มต้นอัตโนมัติ, ขี้เกียจโหลด (เริ่มเฉพาะเซสชันเมื่อต้องการครั้งแรก) หรือเพียงแค่บางครั้งต้องทำการแฮ็คอย่างรวดเร็ว
K . Kilian Lindberg

IS ตอบสนองเหมือนข้างต้น (@miyuru)

2

ไม่แน่ใจเกี่ยวกับประสิทธิภาพของการแก้ปัญหาดังกล่าว แต่นี่เป็นโครงการที่ทำงานได้นอกจากนี้ยังใช้หากคุณต้องการกำหนดภาษาเริ่มต้น

   /**
    * Start session
    * Fall back to ukrainian language
    */
   function valid_session() {
    if(session_id()=='') {
        session_start();
        $_SESSION['lang']='uk';
        $_SESSION['lang_id']=3;
    }
    return true;
  }

2

@ ก่อนที่การเรียกฟังก์ชันจะหยุดข้อผิดพลาดใด ๆ ที่อาจถูกรายงานระหว่างการเรียกใช้ฟังก์ชัน

การเพิ่ม@ก่อนsession_startบอก PHP เพื่อหลีกเลี่ยงการพิมพ์ข้อความผิดพลาด

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

ใช้session_start()หลังจากที่คุณพิมพ์บางสิ่งไปยังเบราว์เซอร์แล้วทำให้เกิดข้อผิดพลาดดังนั้น PHP จะแสดงบางอย่างเช่น "ไม่สามารถส่งส่วนหัวได้: เริ่มต้นที่ (บรรทัดที่ 12)",@session_start()จะยังคงล้มเหลวในกรณีนี้ แต่ข้อความแสดงข้อผิดพลาดไม่ได้พิมพ์ จอภาพ

ก่อนที่จะรวมไฟล์หรือเปลี่ยนเส้นทางไปยังหน้าใหม่ให้ใช้ exit()ฟังก์ชั่นมิฉะนั้นจะทำให้เกิดข้อผิดพลาด

รหัสนี้สามารถใช้ได้ในทุกกรณี:


    <?php 
        if (session_status() !== PHP_SESSION_ACTIVE || session_id() === ""){
            session_start(); 
        }
    ?>

1

ใน PHP 5.3 มันใช้งานได้สำหรับฉัน:

if(!strlen(session_id())){
    session_name('someSpecialName');
    session_start();
} 

แล้วคุณมี หากคุณไม่ใส่คำสั่ง not at หากเริ่มเซสชันจะเริ่มต้นด้วยวิธีใด ๆ ที่ฉันทำไม่ได้


1

การตอบสนองตาม @Meliza Ramos Response (ดูการตอบกลับครั้งแรก) และhttp://php.net/manual/th/function.phpversion.php ,

การดำเนินการ:

  • กำหนด PHP_VERSION_ID หากไม่มีอยู่
  • กำหนดฟังก์ชั่นเพื่อตรวจสอบเวอร์ชั่นตาม PHP_VERSION_ID
  • กำหนดฟังก์ชั่นเพื่อ openSession () ที่ปลอดภัย

ใช้openSessionเท่านั้น()

    // PHP_VERSION_ID is available as of PHP 5.2.7, if our
    // version is lower than that, then emulate it
    if (!defined('PHP_VERSION_ID')) {
        $version = explode('.', PHP_VERSION);

        define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));


        // PHP_VERSION_ID is defined as a number, where the higher the number
        // is, the newer a PHP version is used. It's defined as used in the above
        // expression:
        //
        // $version_id = $major_version * 10000 + $minor_version * 100 + $release_version;
        //
        // Now with PHP_VERSION_ID we can check for features this PHP version
        // may have, this doesn't require to use version_compare() everytime
        // you check if the current PHP version may not support a feature.
        //
        // For example, we may here define the PHP_VERSION_* constants thats
        // not available in versions prior to 5.2.7

        if (PHP_VERSION_ID < 50207) {
            define('PHP_MAJOR_VERSION',   $version[0]);
            define('PHP_MINOR_VERSION',   $version[1]);
            define('PHP_RELEASE_VERSION', $version[2]);

            // and so on, ...
        }
    }

    function phpVersionAtLeast($strVersion = '0.0.0')
    {
        $version = explode('.', $strVersion);

        $questionVer = $version[0] * 10000 + $version[1] * 100 + $version[2];

        if(PHP_VERSION_ID >= $questionVer)
            return true;
        else
            return false;

    }

    function openSession()
    {
        if(phpVersionAtLeast('5.4.0'))
        {
            if(session_status()==PHP_SESSION_NONE)
                session_start();
        }
        else // under 5.4.0
        {
            if(session_id() == '')
                session_start();
        }
    }

1
if (version_compare(PHP_VERSION, "5.4.0") >= 0) {
    $sess = session_status();
    if ($sess == PHP_SESSION_NONE) {
        session_start();
    }
} else {
    if (!$_SESSION) {
        session_start();
    }
}

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



0

คุณควรจัดระเบียบรหัสของคุณใหม่เพื่อให้คุณเรียกใช้session_start()หนึ่งครั้งต่อการเรียกใช้หน้าเว็บ


4
เรียกมันว่าการกระทำหนึ่งครั้งต่อหนึ่งหน้าอาจไม่ต้องการในบางสถานการณ์
Timo Huovinen

หากคุณกำลังฆ่าเซสชันเพื่อสร้างมันขึ้นมาใหม่แน่นอน แต่นั่นเป็นกรณีพิเศษ โดยทั่วไปแอปพลิเคชันควรมีรหัสที่รันตอนเริ่มต้นครั้งเดียวซึ่งเป็นที่ที่ session_start () ไป
SamT

1
ตัวอย่างเช่นแอปพลิเคชันเก็บเซสชันบนไฟล์และต้องการโหลดคำขอช้าที่เกิดขึ้นพร้อมกัน 2 คำขอไม่มีคำขอเหล่านี้ต้องการเซสชัน แต่จะบล็อกอีกอันเนื่องจาก Session_start ล็อคไฟล์เซสชัน
Timo Huovinen

เผง @YuriKolovsky ถูกต้อง คำถามของอเล็กซ์เกี่ยวข้องกันเพราะกรณีเหล่านี้สามารถเกิดขึ้นได้และพวกเขาไม่ใช่เรื่องผิดปกติ
Paulo Coghi - Reinstate Monica

14
-1, เว็บไซต์ส่วนใหญ่ขับเคลื่อนด้วย CMS และมีสิ่งต่าง ๆ เช่นชุดรูปแบบและปลั๊กอินที่มักเขียนโดยบุคคลที่แตกต่างกันไม่เคยรู้ว่ารหัสของกันและกันเริ่มเซสชันหรือไม่ ความหมายว่านี่เป็นปัญหารหัสองค์กรเท่านั้นเป็นปัญหาที่ผิดพลาด
Jimbo Jonny


0

PHP_VERSION_IDนั้นมีให้ตั้งแต่ PHP 5.2.7 ดังนั้นให้ตรวจสอบก่อนและถ้าจำเป็นให้สร้างมันขึ้นมา session_statusมีให้ตั้งแต่ PHP 5.4 ดังนั้นเราต้องตรวจสอบด้วย:

if (!defined('PHP_VERSION_ID')) {
    $version = explode('.', PHP_VERSION);
    define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}else{
    $version = PHP_VERSION_ID;
}
if($version < 50400){
    if(session_id() == '') {
        session_start();
    }
}else{
    if (session_status() !== PHP_SESSION_ACTIVE) {
        session_start();
    }
}

0

ตามการปฏิบัติของฉันก่อนที่จะเข้าถึงที่$_SESSION[]คุณต้องโทรsession_startทุกครั้งเพื่อใช้สคริปต์ ดูลิงค์ด้านล่างสำหรับคู่มือ

http://php.net/manual/en/function.session-start.php

อย่างน้อยฉันsession_startก็สับสนว่าเป็นชื่อ session_loadสามารถจะมีความชัดเจนมากขึ้น


0

ฉันสิ้นสุดด้วยการตรวจสอบสถานะอีกครั้ง php 5.4+

if(session_status() !== PHP_SESSION_ACTIVE){session_start();};
if(session_status() !== PHP_SESSION_ACTIVE){die('session start failed');};

0

คุณสามารถใช้วิธีแก้ไขปัญหาต่อไปนี้เพื่อตรวจสอบว่าเซสชัน PHP เริ่มขึ้นแล้วหรือไม่:

if(session_id()== '')
{
   echo"Session isn't Start";
}
else
{
    echo"Session Started";
}

คำตอบที่ถูกต้องมีรายละเอียดเพิ่มเติม
ClémentPrévost

0

นี่คือสิ่งที่ฉันใช้เพื่อตรวจสอบว่าเซสชั่นเริ่มต้นขึ้นหรือไม่ โดยใช้ค่าว่างและค่าดังนี้:

if (empty($_SESSION)  && !isset($_SESSION))  {
    session_start();
}

-3

แทนที่session_start();ด้วย:

if (!isset($a)) {
    a = False;
    if ($a == TRUE) {
        session_start();
        $a = TRUE;
    }
}

มันมีข้อผิดพลาดของรหัสและจะใช้งานได้หากไฟล์เดียวกันจะรวมหลายครั้ง แต่จะไม่ทำงานหากอยู่ในช่วงปิด
BananaAcid
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.