Thoroughly figure out what a session is?

Before talking about what a session is, let's talk about why a session occurs and what is the mechanism for it? We know that when we open a web page with a browser, we use the HTTP protocol. The HTTP protocol is stateless, which means that this request has nothing to do with the previous request, does not know each other, and is not related. But the benefit of this statelessness is fast.

So it will bring a problem that I want several requested pages to be related, for example: I am logged in in www.a.com/login.php, I also hope that in www.a.com/index.php It is the login status, but these are 2 different pages, that is, 2 different HTTP requests. These 2 HTTP requests are stateless, that is, unrelated, so they cannot be simply read in index.php Until it has been logged in login.php!

What do you do? It is impossible for me to log in to both of these pages. Or use the stupid method to query the database on these two pages. If there is a login status, it is judged that it is logged in. Although this method of querying the database is feasible, it is not a problem to query the database every time, which will cause pressure on the database.

So it is this kind of appeal. At this time, a new way of storing data on the client side appeared: cookie. A cookie stores a small amount of information on the user's own computer. It is global under a domain name. As long as its storage path is set under the domain name www.a.com, then when the user accesses it with a browser, php The information in the cookie can be read from any page on this domain. So it is a good solution that I log in on the www.a.com/login.php page, and I can also get this login information at www.a.com/index.php. At the same time, there is no need to repeatedly query the database.

Although this solution is very good, it is also very fast and convenient, but because the cookie exists on the user side, and the size of its own storage is also limited, the most important thing is that the cookie can be visible to the user and can be modified at will, which is very insecure. So how to be safe and easy to read information globally? So, at this time, a new storage session mechanism: session was born.

Well, session was born. From the above description, it is to solve the association of two HTTP requests in one session, so that they can be connected, so that two pages can read and find this global session information . Session information exists on the server side, so it also solves the security problem very well.

The running mechanism of the session and how is it saved?

Since it is also a way of storing data in the service area, it must also exist somewhere on the server. Indeed, it exists in the /tmp directory of the server, which we will talk about later.

Let's first talk about its operating mechanism and how it is allocated. We mainly use the mechanism of session in PHP, in fact, various languages ​​are similar.

If we need to use session at this time, what should we do first? The first step is to open the session:

session_start();

This is a function with no return value, neither an error nor a success. Its role is to open the session and randomly generate a unique 32-bit session_id, similar to this:
4c83638b3b0dbf65583181c2f89168ec

The entire mechanism of the session is also based on this session_id, which is used to distinguish which requests are made by one person. Why has to be this way? Because HTTP is stateless and irrelevant, a page may be visited by hundreds or thousands of people, and each person's user name is different, so how does the server distinguish between Xiao Wang's visit this time and Xiao Wang's visit that time what about? So there is a unique session_id to bind a user. A user is a session_id in a session, so that thousands of people visit, the server can also distinguish who is visiting.

Let's do an experiment and see if this is the case:

We enter the following code in the a.php page under the php.iyangyi.com domain name:

session_start(); echo "SID: ".SID."<br>"; echo "session_id(): ".session_id()."<br>"; echo "COOKIE: ".$_COOKIE["PHPSESSID"];

Let's visit the a.php page and see what can be output?


We see that there is actually a warning. Let's look at them one by one. First of all, the constant SID, we did not assign a value to it, it can actually output, and secondly, the session_id() system method is to output the session_id generated this time. Finally $_COOKIE['PHPSESSIID'] has no value, which we will talk about next.

OK, let's refresh the page again, what can we see?


Strange things happened. SID has no value, $_COOKIE['PHPSESSID'] has value. Moreover, 2 refreshes, session_id is the same

: bjvlo4p38cfqkr1hr7pe924ts3, in fact, as long as the webpage is not closed, how to refresh is the same:

Now that we see that there is value in COOKIE, let's open firebug to see what it is:

And the expiration time of this PHPSESSID is the session, what does it mean? That is, as long as the browser is not closed, it will not exist, and as soon as the browser is closed, it will expire and disappear.

Ok, let's close the browser and reopen the a.php page to see if there is any change:


Look, it's back to the way it was when it was first opened.

OK, it's time to solve the puzzle:

每次我们访问一个页面,如果有开启session,也就是有session_start() 时,就会自动生成一个session_id 来标注是这次会话的唯一ID,同时也会自动往cookie里写入一个名字为PHPSESSID的变量,它的值正是session_id,当这次会话没结束,再次访问的时候,服务器会去读取这个PHPSESSID的cookie是否有值有没过期,如果能够读取到,则继续用这个session_id,如果没有,就会新生成一个session_id,同时生成PHPSESSID这个cookie。由于默认生成的这个PHPSESSID cookie是会话,也就是说关闭浏览器就会过期掉,所以,下次重新浏览时,会重新生成一个session_id。

好,这个是session_id,就用来标识绑定一个用户的,既然session_id生成了。那么当我们往session里面写入数据,是如何保存的,答案是保存在服务器的临时目录里,根据php.ini的配置,我机子上的这个session是存在D:\wamp\tmp 目录里的。我们先说是存在这个目录下,然后待会将如何修改。

那么它是怎么存的呢?

同样也是用到session_id。session_id是32位的,服务器会用 sess_前缀 + session_id 的形式存在这个临时目录下,比如上面这个例子:


所以,每一次生成的session_id都会生成一个这样的文件,用来保存这次会话的session信息。

我们往session里写入些数据,来看看session是怎么往这个文件里写数据的,我们同样在a.php页面继续加上写入session的语句:

 

$_SESSION['hello'] = 123;

$_SESSION['word'] = 456;

然后,我刷新页面,由于我并没有关闭页面,就这是说这次会话还没结束,那么肯定还会是同样的session_id : bjvlo4p38cfqkr1hr7pe924ts3

然后,我们 用编辑器打开它的存储文件sess_bgg20mcl86drbt3j08jg5h5h17这个文件,看看里面是啥?

hello|i:123;word|i:456;

是序列化的数据,我们肉眼也能读出来。当我们往$_SESSION全局变量里写数据时,它会自动往这个文件里写入。读取session的时候,也会根据session_id 找到这个文件,然后读取需要的session变量。

这个sess文件不会随着客户端的PHPSESSID过期,也一起过期掉,它会一直存在,出息GC扫描到它过期或者使用session_destroy()函数摧毁,我们在下面讲到session·回收的时候会说到。

我们大致总结下:

HTTP请求一个页面后,如果用到开启session,会去读cookie中的PHPSESSID是否有,如果没有,则会新生成一个session_id,先存入cookie中的PHPSESSID中,再生成一个sess_前缀文件。当有写入$_SESSION的时候,就会往sess_文件里序列化写入数据。当读取的session变量的时候,先会读取cookie中的PHPSESSID,获得session_id,然后再去找这个sess_sessionid文件,来获取对应的数据。由于默认的PHPSESSID是临时的会话,在浏览器关闭后,会消失,所以,我们重新访问的时候,会新生成session_id和sess_这个文件。

好。session生成和保存将清楚了。我们再来看前面提到的几个变量:

echo "SID: ".SID."<br>";

echo "session_id(): ".session_id()."<br>";

echo "COOKIE: ".$_COOKIE["PHPSESSID"];

SID 是一个系统常量,SID包含着会话名以及会话 ID 的常量,格式为 "name=ID",或者如果会话 ID 已经在适cookie 中设定时则为空字符串,第一次显示的时候输出的是SID的值,当你刷新的时候,因为已经在cookie中存在,所以显示的是一个空字符串。

session_id() 函数用来返回当前会话的session_id,它会去读取cookie中的name,也就是PHPSESSID值。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324853547&siteId=291194637