1. 程式人生 > >PHP函式原始碼之SESSION實現機制

PHP函式原始碼之SESSION實現機制

Session是以擴充套件的形式嵌入到PHP核心的,所以我們可以把Session當成擴充套件來看待。

一般擴充套件被載入到PHP會經過下面幾個過程

  1. #define PHP_MINIT_FUNCTION      ZEND_MODULE_STARTUP_D       // 初始化module時執行 
  2. #define PHP_MSHUTDOWN_FUNCTION  ZEND_MODULE_SHUTDOWN_D      // 當module被解除安裝時執行
  3. #define PHP_RINIT_FUNCTION      ZEND_MODULE_ACTIVATE_D      // 當一個REQUEST請求初始化時執行
  4. #define PHP_RSHUTDOWN_FUNCTION  ZEND_MODULE_DEACTIVATE_D    // 當一個REQUEST請求結束時執行  
  5. #define PHP_MINFO_FUNCTION      ZEND_MODULE_INFO_D          // 這個是設定phpinfo中這個模組的資訊
  6. #define PHP_GINIT_FUNCTION      ZEND_GINIT_FUNCTION         // 初始化全域性變數時 
  7. #define PHP_GSHUTDOWN_FUNCTION  ZEND_GSHUTDOWN_FUNCTION     // 釋放全域性變數時
具體的執行順序跟PHP的生命週期相同
MINIT -> RINIT ->RSHUTDOWN -> MSHUTDOWN

1. SESSION模組的初始化  PHP_MINIT_FUNCTION

對於Session而言,PHP_MINIT_FUNCTION主要完成的初始化工作包括(注:不同版本的PHP具體處理過程並不完全相同,如PHP 5.4+提供了SessionHandlerInterface,這樣可以通過session_set_save_handler ( SessionHandlerInterface $sessionhandler )的方式自定義Session的處理機制,而不必像之前一樣使用冗長的bool

session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )):

(1).  註冊$_SESSION超全域性變數:

  1. zend_register_auto_global("_SESSION"sizeof("_SESSION")-1, NULL TSRMLS_CC);    
就是說,$_SESSION超全域性變數實際上是在session的MINIT階段被註冊的。

相關閱讀 :PHP語言中的超級全域性變數(Superglobals) http://www.walu.cc/phpbook/12.5.md

(2).  讀取ini檔案中的相關配置。

  1. REGISTER_INI_ENTRIES();    

 REGISTER_INI_ENTRIES();實際上是一個巨集定義:

#define REGISTER_INI_ENTRIES() zend_register_ini_entries(ini_entries, module_number TSRMLS_CC)

因此,實際上是呼叫zend_register_ini_entries(ini_entries, module_number TSRMLS_CC)。關於ini檔案的解析和配置,已經超出了本文的範疇,可以參考這篇文章:http://www.cnblogs.com/driftcloudy/p/4011954.html 。

   擴充套件中讀取和設定ini的相關配置位於PHP_INI_BEGIN和PHP_INI_END巨集之間。對於session而言,實際上包括:

  1. /* {{{ PHP_INI 
  2.  */
  3. PHP_INI_BEGIN()  
  4.     STD_PHP_INI_ENTRY("session.save_path",          "",          PHP_INI_ALL, OnUpdateSaveDir,save_path,          php_ps_globals,    ps_globals)  
  5.     STD_PHP_INI_ENTRY("session.name",               "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name,       php_ps_globals,    ps_globals)  
  6.     PHP_INI_ENTRY("session.save_handler",           "files",     PHP_INI_ALL, OnUpdateSaveHandler)  
  7.     STD_PHP_INI_BOOLEAN("session.auto_start",       "0",         PHP_INI_PERDIR, OnUpdateBool,   auto_start,         php_ps_globals,    ps_globals)  
  8.     STD_PHP_INI_ENTRY("session.gc_probability",     "1",         PHP_INI_ALL, OnUpdateLong,   gc_probability,     php_ps_globals,    ps_globals)  
  9.     STD_PHP_INI_ENTRY("session.gc_divisor",         "100",       PHP_INI_ALL, OnUpdateLong,   gc_divisor,         php_ps_globals,    ps_globals)  
  10.     STD_PHP_INI_ENTRY("session.gc_maxlifetime",     "1440",      PHP_INI_ALL, OnUpdateLong,   gc_maxlifetime,     php_ps_globals,    ps_globals)  
  11.     PHP_INI_ENTRY("session.serialize_handler",      "php",       PHP_INI_ALL, OnUpdateSerializer)  
  12.     STD_PHP_INI_ENTRY("session.cookie_lifetime",    "0",         PHP_INI_ALL, OnUpdateLong,   cookie_lifetime,    php_ps_globals,    ps_globals)  
  13.     STD_PHP_INI_ENTRY("session.cookie_path",        "/",         PHP_INI_ALL, OnUpdateString, cookie_path,        php_ps_globals,    ps_globals)  
  14.     STD_PHP_INI_ENTRY("session.cookie_domain",      "",          PHP_INI_ALL, OnUpdateString, cookie_domain,      php_ps_globals,    ps_globals)  
  15.     STD_PHP_INI_BOOLEAN("session.cookie_secure",    "",          PHP_INI_ALL, OnUpdateBool,   cookie_secure,      php_ps_globals,    ps_globals)  
  16.     STD_PHP_INI_BOOLEAN("session.cookie_httponly",  "",          PHP_INI_ALL, OnUpdateBool,   cookie_httponly,    php_ps_globals,    ps_globals)  
  17.     STD_PHP_INI_BOOLEAN("session.use_cookies",      "1",         PHP_INI_ALL, OnUpdateBool,   use_cookies,        php_ps_globals,    ps_globals)  
  18.     STD_PHP_INI_BOOLEAN("session.use_only_cookies""1",         PHP_INI_ALL, OnUpdateBool,   use_only_cookies,   php_ps_globals,    ps_globals)  
  19.     STD_PHP_INI_BOOLEAN("session.use_strict_mode",  "0",         PHP_INI_ALL, OnUpdateBool,   use_strict_mode,    php_ps_globals,    ps_globals)  
  20.     STD_PHP_INI_ENTRY("session.referer_check",      "",          PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals,    ps_globals)  
  21. #if HAVE_DEV_URANDOM
  22.     STD_PHP_INI_ENTRY("session.entropy_file",       "/dev/urandom",          PHP_INI_ALL, OnUpdateString, entropy_file,       php_ps_globals,    ps_globals)  
  23.     STD_PHP_INI_ENTRY("session.entropy_length",     "32",         PHP_INI_ALL, OnUpdateLong,   entropy_length,     php_ps_globals,    ps_globals)  
  24. #elif HAVE_DEV_ARANDOM
  25.     STD_PHP_INI_ENTRY("session.entropy_file",       "/dev/arandom",          PHP_INI_ALL, OnUpdateString, entropy_file,       php_ps_globals,    ps_globals)  
  26.     STD_PHP_INI_ENTRY("session.entropy_length",     "32",         PHP_INI_ALL, OnUpdateLong,   entropy_length,     php_ps_globals,    ps_globals)  
  27. #else
  28.     STD_PHP_INI_ENTRY("session.entropy_file",       "",          PHP_INI_ALL, OnUpdateString, entropy_file,       php_ps_globals,    ps_globals)  
  29.     STD_PHP_INI_ENTRY("session.entropy_length",     "0",         PHP_INI_ALL, OnUpdateLong,   entropy_length,     php_ps_globals,    ps_globals)  
  30. #endif
  31.     STD_PHP_INI_ENTRY("session.cache_limiter",      "nocache",   PHP_INI_ALL, OnUpdateString, cache_limiter,      php_ps_globals,    ps_globals)  
  32.     STD_PHP_INI_ENTRY("session.cache_expire",       "180",       PHP_INI_ALL, OnUpdateLong,   cache_expire,       php_ps_globals,    ps_globals)  
  33.     PHP_INI_ENTRY("session.use_trans_sid",          "0",         PHP_INI_ALL, OnUpdateTransSid)  
  34.     PHP_INI_ENTRY("session.hash_function",          "0",         PHP_INI_ALL, OnUpdateHashFunc)  
  35.     STD_PHP_INI_ENTRY("session.hash_bits_per_character""4",    PHP_INI_ALL, OnUpdateLong,   hash_bits_per_character, php_ps_globals, ps_globals)  
  36.     /* Upload progress */
  37.     STD_PHP_INI_BOOLEAN("session.upload_progress.enabled",  
  38.                                                     "1",     ZEND_INI_PERDIR, OnUpdateBool,        rfc1867_enabled, php_ps_globals, ps_globals)  
  39.     STD_PHP_INI_BOOLEAN("session.upload_progress.cleanup",  
  40.                                                     "1",     ZEND_INI_PERDIR, OnUpdateBool,        rfc1867_cleanup, php_ps_globals, ps_globals)  
  41.     STD_PHP_INI_ENTRY("session.upload_progress.prefix",  
  42.                                          "upload_progress_", ZEND_INI_PERDIR, OnUpdateSmartStr,      rfc1867_prefix,  php_ps_globals, ps_globals)  
  43.     STD_PHP_INI_ENTRY("session.upload_progress.name",  
  44.                               "PHP_SESSION_UPLOAD_PROGRESS", ZEND_INI_PERDIR, OnUpdateSmartStr,      rfc1867_name,    php_ps_globals, ps_globals)  
  45.     STD_PHP_INI_ENTRY("session.upload_progress.freq",  "1%", ZEND_INI_PERDIR, OnUpdateRfc1867Freq, rfc1867_freq,    php_ps_globals, ps_globals)  
  46.     STD_PHP_INI_ENTRY("session.upload_progress.min_freq",  
  47.                                                        "1",  ZEND_INI_PERDIR, OnUpdateReal,        rfc1867_min_freq,php_ps_globals, ps_globals)  
  48.     /* Commented out until future discussion */
  49.     /* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */
  50. PHP_INI_END()  
  51. /* }}} */
如果在ini檔案中沒有配置相關的引數項,在session的MINIT階段,引數會被初始化為預設的值。

(3).  註冊SessionHandlerSessionHandlerInterface這兩個Class

自php 5.4起,php提供了SessionHandlerSessionHandlerInterface這兩個Class, 因此還需要對這兩個Class做相關的初始化工作。這是通過:

INIT_CLASS_ENTRY(ce, PS_IFACE_NAME, php_session_iface_functions);

INIT_CLASS_ENTRY(ce, PS_CLASS_NAME, php_session_class_functions);

來實現的,有興趣的同學可以檢視具體的實現過程,這裡不再贅述。

2. session請求時的準備RINIT   PHP_RINIT_FUNCTION

  1. static PHP_RINIT_FUNCTION(session) /* {{{ */
  2. {  
  3.     return php_rinit_session(PS(auto_start) TSRMLS_CC);  
  4. }  
  5. /* ******************************** 
  6.    * Module Setup and Destruction * 
  7.    ******************************** */
  8. staticint php_rinit_session(zend_bool auto_start TSRMLS_DC) /* {{{ */
  9. {// 初始化session相關的全域性變數
  10.     php_rinit_session_globals(TSRMLS_C);  
  11. // 根據ini的配置查詢session.save_handler,從而確定是使用files還是user( 或者是其他的擴充套件方式)來處理session:
  12.     if (PS(mod) == NULL) {  
  13.         char *value;  
  14.         value = zend_ini_string("session.save_handler"sizeof("session.save_handler"), 0);  
  15.         if (value) {  
  16. 相關推薦

    PHP函式原始碼SESSION實現機制

    Session是以擴充套件的形式嵌入到PHP核心的,所以我們可以把Session當成擴充套件來看待。 一般擴充套件被載入到PHP會經過下面幾個過程 #define PHP_MINIT_FUNCTION      ZEND_MODULE_STARTU

    PHP函式原始碼VLD實現原理

    vld功能的實現要依賴 Zend引擎初始化(zend_startup)的時候 將zend_execute和zend_compile_file定義為函式指標的功勞了   預設的 zend_execute指向execute zend_compile_file指向comp

    [06] Session實現機制以及和Cookie的區別

    但是 session存儲 請求 pri com 無法 體驗 -c data 1、為什麽有Session和Cookie根據早期的HTTP協議,每次request-reponse時,都要重新建立TCP連接。TCP連接每次都重新建立,所以服務器無法知道上次請求和本次請求是否來自於

    spark源碼系列累加器實現機制及自定義累加器

    大數據 spark一,基本概念 累加器是Spark的一種變量,顧名思義該變量只能增加。有以下特點: 1,累加器只能在Driver端構建及並只能是Driver讀取結果,Task只能累加。 2,累加器不會改變Spark Lazy計算的特點。只會在Job觸發的時候進行相關累加操作。 3,現有累加器的類型。相信有很

    Spring事務實現原始碼事務實現以及Connection的繫結與獲取

    PlatformTransactionManager是spring事務的高階抽象,事務的實現需要藉助PlatformTransactionManager完成,該管理主要方法如下: 當我們在使用事務的時候,需要呼叫如下方法獲取一個事務狀態物件。 TransactionS

    Hibernate 快取 Session 實現(一)

    首先以查詢學生為例,模擬一個快取的機制 public class Test { public static void main(String[] args) throws Exception { MyClassDao myClassDao = new

    TornadoSession實現

    Tornado框架中,預設執行Handler的get/post等方法之前預設會執行 initialize方法,所以可以通過自定義的方式使得所有請求在處理前執行操作 import tornado.ioloop import tornado.web import time import ha

    Dubbo系列SPI實現機制(五)

    private String createAdaptiveExtensionClassCode() { StringBuilder codeBuidler = new StringBuilder(); Method[] methods = type.getMethods(); boolean

    ES學習筆記-Translog實現機制的理解

    就是 文件 實時 應用場景 Lucene 索引操作 解決 模擬 結果 ES作為一個NoSQL,典型的應用場景就是存儲數據。即用戶可以通過api添加數據到es中。由於Lucene內部的實現, 每次添加的數據並不是實時落盤的。而是在內存中維護著索引信息,直到緩沖區滿了或者顯式的

    php原始碼路第四章第一節( 函式的內部結構)

    函式是一種可以在任何被需要的時候執行的程式碼塊。它不僅僅包括使用者自定義的函式,還包括程式語言實現的庫函式。 使用者定義的函式 如下所示手冊中的展示函式用途的虛擬碼 funct

    android 原始碼剖析------Window的內部實現機制(新增、刪除、更新)

    今天,在做專案的過程中,實現了一個浮動視窗的功能,大致思路是這樣的:通過例項化一個ImageButton並給這個Button設定監聽,然後將這個Button傳遞給WindowManager的addView方法,在ListView滑動過程中,通過監聽ListView的滑動狀態,利用WindowManager

    從Spring-Session原始碼Session機制實現細節

    作者:徐靖峰原文:https://www.cnkirito.moe/2018/04/17/spr

    php分布式redis實現session共享

    code handler database auth 內容 cnblogs markdown pat edi 方法一:找到配置文件php.ini,修改為下面內容,保存並重啟服務 session.save_handler = redis session.save_path =

    PHP會話控制失效時間與過期回收機制

    gutops session生命周期 php會話控制 session過期回收機制 sessions失效時間 PHP會話控制之失效時間與過期回收機制 session的生命周期 從session的初始化開始,直到註銷的這段時間稱之為sesssion生命周期。 設置session生命周期再php

    php session實現原理分析

    keep enc accep referer zip image time -s accept http://www.jb51.net/article/77726.htm 第一次會話時會有Set-Cookie響應頭返回,設置上PHPSESSID cookie Cache

    php編程kindeditor上傳圖片加水印實現

    php 圖片加水印 對於如何在圖片上添加水印是許多技術人員遇到的一個難題,那大家都見過微信公眾號及一些其他技術平臺是可以實現這個功能的,但是對於源碼是如何實現的,卻沒有頭緒,那麽今天就為大家介紹一下關於kindeditor上傳圖片加水印的方法,看完之後相信各位技術人員就知道了。第一步:修改upload

    php編程短信發送接口調用流程的實現

    短信發送 PHP 對於一個交互型網站來說,需要用戶來登錄註冊使用,那麽一般網站的技術人員肯定需要實現註冊時的短信發送功能,但是這個功能很多技術人員發現在添加的過程中有許多問題,要麽是無法接收,要麽就是時間慢等等原因,對於這個問題,下面就跟大家說一下如何快速有效的實現。   本文主要講解的是如何利用m.

    php編程如何調用支付寶支付接口的實現

    支付寶 支付接口 對於任何一款軟件來說,支付功能都是核心的,那麽目前的主流支付接口主要是支付寶、微信和銀聯卡,而大多數開發技術人員對於如何調用支付寶的支付接口還存在很大的困擾,今天就來跟大家分享一下如何正確調用支付寶支付接口的實現,代碼如下所示:public function zfbpay1(){re

    微軟與開源幹貨對比篇_PHP和 ASP.NET在 Session實現和管理機制上差異

    ima 影響 前言 很難 刪除 定性 缺點 重新編譯 state 微軟與開源幹貨對比篇_PHP和 ASP.NET在 Session實現和管理機制上差異 前言:由於開發人員要靠工具吃飯,可能和開發工具、語言、環境呆的時間比和老婆孩子親人在一起的時間還多,所以每個人或多或少對自

    PHP JS CSS session實現驗證碼功能

    驗證碼 ges ron oss art tex lse 個數 bcd PHP JS CSS session實現驗證碼功能 頁面<?php//校驗驗證碼if (isset($_POST["authcode"])) {session_start();