Kiểm tra xem phiên PHP đã bắt đầu chưa


461

Tôi có một tệp PHP đôi khi được gọi từ một trang đã bắt đầu một phiên và đôi khi từ một trang không có phiên bắt đầu. Do đó, khi tôi có session_start()tập lệnh này, đôi khi tôi nhận được thông báo lỗi cho "phiên đã bắt đầu". Vì vậy, tôi đã đặt những dòng này:

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

nhưng lần này tôi nhận được tin nhắn cảnh báo này:

Lưu ý: Biến không xác định: _SESSION

Có cách nào tốt hơn để kiểm tra xem phiên đã bắt đầu chưa?

Nếu tôi sử dụng @session_startnó sẽ làm cho mọi thứ hoạt động đúng và chỉ cần tắt các cảnh báo?



Xem thêm câu trả lời này của Stackoverflow: stackoverflow.com/questions/1545357/ trên
contact-form.co_you_go

Câu trả lời:


761

Cách được đề xuất cho các phiên bản PHP> = 5.4.0, PHP 7

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

Tham khảo: http://www.php.net/manual/en/feft.session-status.php

Đối với các phiên bản PHP <5.4.0

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

1
Tôi nghĩ rằng có một vấn đề với giải pháp cho PHP <5.4. session_id được đặt phiên thời gian FIRST được bắt đầu, nhưng nó không bị xóa khi đóng phiên. Vì vậy, ví dụ: nếu có, trước đoạn trích của bạn, một mã như session_start();session_write_close();: thì điều kiện if không thành công nhưng chúng tôi không có phiên mở ...
Nicolò Martini

@Nicolo Martini Theo tôi hiểu: Một phiên bắt đầu session_start()ở đầu tập lệnh được ĐÓNG khi tập lệnh thoát, HOẶC khi session_write_closed()được gọi trước khi tập lệnh thoát. Tức là một phiên CLOSES khi dữ liệu của nó được ghi vào cookie phiên và phiên được mở khóa để truy cập bởi một tập lệnh khác cũng gọi là 'session_start'. Do đó, ĐÓNG không có nghĩa là phiên bị KHAI THÁC. Bạn có thể đóng một phiên bằng cách thoát khỏi tập lệnh hiện tại hoặc gọi session_write_close()và bạn có thể mở lại bằng cách gọi session_start(). Sự hiểu biết của tôi, ít nhất.
Stefan

1
Đây vẫn là một cách tốt để bắt đầu một phiên? Bởi vì trong liên kết không có gì liên quan đến câu trả lời này
csandreas1

@ csandreas1 bạn sẽ thấy từ liên kết mô tả của session_status và các giá trị trả về dự kiến ​​của nó. Câu trả lời cho câu hỏi của bạn là có!
Lovelyramos

Tôi đã gặp thất bại này trong một số trường hợp - Tôi đã sử dụng nếu (! Oetet ($ _ SESSION)) thành công
Scott

161

Đối với các phiên bản PHP trước PHP 5.4.0:

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

Mặc dù vậy, IMHO, bạn thực sự nên suy nghĩ về việc cấu trúc lại mã quản lý phiên của mình nếu bạn không biết liệu phiên có được bắt đầu hay không ...

Điều đó nói rằng, ý kiến ​​của tôi là chủ quan, và có những tình huống (ví dụ được mô tả trong các ý kiến ​​dưới đây) trong đó có thể không thể biết nếu phiên bắt đầu.


37
Không nhất thiết là không biết nếu phiên của bạn được bắt đầu. Nếu bạn lười tải (chỉ bắt đầu phiên khi cần lần đầu tiên) thì bài kiểm tra trong câu trả lời của bạn sẽ hoàn toàn ổn.
vẽ

1
Ngoài ra, trong một số môi trường, apache có phiên tự khởi động được thiết lập
LeonardChallis

Một ví dụ để kiểm tra nếu session_id () trả về chuỗi trống trong tệp bao gồm:
tgoneil

3
Nhận xét về tái cấu trúc quản lý phiên nếu bạn không biết liệu nó có bị rách hay không thực sự không liên quan. Ví dụ: nếu mã hóa các tính năng nâng cao vào chủ đề WordPress, bạn sẽ không bao giờ biết liệu plugin đã bắt đầu sử dụng phiên hay chưa mà không kiểm tra. Thế giới mã hóa không phải lúc nào cũng đen trắng: P
Jimbo Jonny

Mmm, điểm tốt thực sự. Tôi thừa nhận rằng những bình luận của tôi rất chủ quan - Tôi sẽ sửa đổi câu trả lời của mình để phản ánh điều này.
Alex

71

PHP 5.4 đã giới thiệu session_status () , đáng tin cậy hơn là dựa vàosession_id() .

Hãy xem xét đoạn trích sau:

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

Vì vậy, để kiểm tra xem một phiên có được bắt đầu hay không, cách được đề xuất trong PHP 5.4 là:

session_status() == PHP_SESSION_ACTIVE

3
Một đoạn mã sử dụng session_status khi có sẵn và các phương thức cũ hơn khi không có vẻ hoàn hảo ở đây BTW, gợi ý gợi ý :)
Jimbo Jonny

1
Cảm ơn bạn đã cập nhật Benjamin. Thật tốt khi biết rằng một phương thức mới có thể được sử dụng kể từ PHP 5.4.
Logan

1
Đây là một cách tốt hơn để kiểm tra điều này, bạn không phải lúc nào cũng biết liệu bạn có bắt đầu phiên hay không, đặc biệt là khi người dùng xóa cookie khi họ đang duyệt trang web ... Tôi luôn viết mã cho 2 tuổi, bạn không bao giờ biết người dùng sẽ làm gì ;-) Đối với bản thân tôi, tôi có một tệp Config.php nhỏ được gọi trên tất cả các tập lệnh của mình để thiết lập các biến và thông tin khác vì vậy chỉ cần thêm tệp này vào tệp đó luôn đảm bảo rằng phiên được bắt đầu nếu nó là cần thiết
Andy Braham

35

bạn có thể làm điều này, và nó thực sự dễ dàng.

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

Hy vọng nó giúp :)


6
@zloctb: Tôi không thể nghĩ ra bất kỳ tình huống nào tôi sẽ làm $_SESSION=array();, vì vậy câu trả lời này có vẻ ổn.
halfer

5
@halfer Xem câu trả lời của Ryan. Nếu session_destroy()đã được gọi thì $_SESSIONvẫn có thể được thiết lập. Ngoài ra, trong các bài kiểm tra đơn vị, bạn có thể đặt $_SESSIONtrực tiếp. Nhưng tôi đã ủng hộ điều này, vì trong hầu hết các tình huống thực tế, câu trả lời này phải đủ tốt (cho đến khi PHP 5.3 không bao giờ được nhìn thấy nữa ...)
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

Trước PHP 5.4, không có cách nào đáng tin cậy để biết ngoài việc đặt cờ toàn cầu.

Xem xét:

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

Hoặc là:

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.

Vì vậy, trước PHP 5.4, bạn nên thiết lập một boolean toàn cầu.


12

Đối với tất cả phiên bản php

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

1
Tương tự, người ta cũng có thể làmif ((defined('PHP_SESSION_ACTIVE') && session_status() !== PHP_SESSION_ACTIVE) || !session_id())
Anthony Hatzopoulos

9

Kiểm tra điều này :

<?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();
?>

Nguồn http://php.net


6

Sử dụng session_id () , nó trả về một chuỗi rỗng nếu không được đặt. Nó đáng tin cậy hơn là kiểm tra $_COOKIE.

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


5

Điều này sẽ làm việc cho tất cả các phiên bản PHP. Nó xác định phiên bản PHP, sau đó kiểm tra xem phiên có được bắt đầu hay không dựa trên phiên bản PHP. Sau đó, nếu phiên không được bắt đầu, nó bắt đầu nó.

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

Điều duy nhất bạn cần làm là:

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

Đây là cái tôi đã sử dụng trong những năm qua. Bất cứ ai khuyên không nên sử dụng cái này? Tất nhiên, thật tốt khi sử dụng kiểm tra nếu phiên đôi khi được bắt đầu - trong một số môi trường, apache có cài đặt tự động khởi động phiên, tải nhanh (chỉ bắt đầu phiên khi cần lần đầu tiên) hoặc đơn giản là đôi khi bạn chỉ cần thực hiện hack nhanh
K Kilian Lindberg

LÀ CÂU TRẢ LỜI CÙNG TRÊN (@miyuru)

2

Không chắc chắn về hiệu quả của giải pháp đó, nhưng đây là từ dự án làm việc Điều này cũng được sử dụng nếu bạn cần xác định ngôn ngữ mặc định

   /**
    * 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

@ trước khi một lệnh gọi hàm ngăn chặn mọi lỗi có thể được báo cáo trong khi gọi hàm.

Thêm một @trướcsession_start cho PHP để tránh in thông báo lỗi.

Ví dụ:

Sử dụng session_start()sau khi bạn đã in một cái gì đó lên trình duyệt dẫn đến lỗi, do đó PHP sẽ hiển thị một cái gì đó như "tiêu đề không thể được gửi: bắt đầu từ (dòng 12)",@session_start() vẫn sẽ thất bại trong trường hợp này, nhưng thông báo lỗi không được in màn.

Trước khi bao gồm các tệp hoặc chuyển hướng đến trang mới, hãy sử dụng exit() chức năng, nếu không nó sẽ báo lỗi.

Mã này có thể được sử dụng trong mọi trường hợp:


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

1

Trên PHP 5.3, nó hoạt động với tôi:

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

Sau đó bạn có. Nếu bạn không đặt câu lệnh không tại nếu bắt đầu phiên sẽ bắt đầu bất kỳ cách nào tôi không biết tại sao.


1

Phản hồi DỰA TRÊN Phản hồi @Meliza Ramos (xem phản hồi đầu tiên) và http://php.net/manual/en/feft.phpversion.php ,

HÀNH ĐỘNG:

  • định nghĩa PHP_VERSION_ID nếu không tồn tại
  • xác định chức năng để kiểm tra phiên bản dựa trên PHP_VERSION_ID
  • xác định hàm để openSession () an toàn

chỉ sử dụng 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();
    }
}

Trên thực tế, bây giờ đã quá muộn để giải thích nó ở đây vì nó đã được giải quyết. Đây là tệp .inc của một trong những dự án của tôi nơi bạn định cấu hình menu cho nhà hàng bằng cách chọn một món ăn và loại bỏ / thêm hoặc thay đổi thứ tự. Máy chủ tôi đang làm việc không có phiên bản thực tế nên tôi đã làm cho nó linh hoạt hơn. Tùy thuộc vào các tác giả muốn sử dụng và dùng thử.


1

Đoạn mã này có phù hợp với bạn không?

if (!count($_SESSION)>0) {
    session_start();
}

0

Bạn nên sắp xếp lại mã của mình để bạn gọi session_start() chính xác một lần cho mỗi lần thực hiện trang.


4
gọi nó chính xác một lần trên mỗi trang thực thi có thể không được mong muốn trong một số trường hợp.
Timo Huovinen

Nếu bạn đang giết phiên để tạo lại nó, thì chắc chắn, nhưng đó là một trường hợp đặc biệt. Nói chung, ứng dụng nên có mã được chạy ngay từ đầu một lần, đó là nơi session_start () đi.
SamT

1
ví dụ: một ứng dụng lưu trữ các phiên trên một tệp và cần tải 2 yêu cầu dữ liệu chậm đồng thời, không có yêu cầu nào trong số này cần phiên, nhưng một yêu cầu sẽ chặn phiên khác vì session_start khóa tệp phiên.
Timo Huovinen

Chính xác. @YuriKolovsky nói đúng. Câu hỏi của Alex là thích hợp bởi vì những trường hợp này có thể xảy ra, và chúng không phải là hiếm.
Paulo Coghi - Tái lập Monica

14
-1, Hầu hết các trang web đều được điều khiển bởi CMS và có những thứ như chủ đề và plugin, thường được viết bởi các bên khác nhau, không bao giờ biết liệu mã của nhau có bắt đầu phiên hay không. Hàm ý rằng đây chỉ là một vấn đề tổ chức mã là sai.
Jimbo Jonny

0
session_start();
if(!empty($_SESSION['user']))
{     
  //code;
}
else
{
    header("location:index.php");
}

0

PHP_VERSION_ID có sẵn kể từ PHP 5.2.7, vì vậy hãy kiểm tra cái này trước và nếu cần, hãy tạo nó. session_statuscó sẵn kể từ phiên bản PHP 5.4, vì vậy chúng tôi cũng phải kiểm tra điều này:

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

Dựa trên thực tế của tôi, trước khi truy cập, $_SESSION[]bạn cần gọisession_start mỗi lần để sử dụng tập lệnh. Xem liên kết dưới đây để xem hướng dẫn.

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

Đối với tôi ít nhất session_startlà khó hiểu như một cái tên. A session_loadcó thể rõ ràng hơn.


0

tôi đã kết thúc với việc kiểm tra tình trạng php 5,4 trở lên

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

0

Bạn có thể sử dụng giải pháp sau đây để kiểm tra xem phiên PHP đã bắt đầu chưa:

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

Câu trả lời hợp lệ chi tiết hơn.
Clément Prévost

0

Đây là những gì tôi sử dụng để xác định nếu một phiên đã bắt đầu. Bằng cách sử dụng sản phẩm nào và rỗng như sau:

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

-3

Thay thế session_start();bằng:

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

nó chứa lỗi mã và sẽ chỉ hoạt động, nếu cùng một tệp sẽ được bao gồm nhiều lần, nhưng không bao gồm trong một bao đóng.
BananaAcid
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.