Warum sollte SESSION im Cache gespeichert werden
Was PHP betrifft, wird die von der Sprache selbst unterstützte Sitzung in Form einer Datei auf einer Festplatte gespeichert und in einem angegebenen Ordner gespeichert. Der gespeicherte Pfad kann in der Konfigurationsdatei festgelegt oder die Funktion verwendet werden session_save_path() im Programm einrichten, aber es gibt Nachteile,
Die erste besteht darin, sie im Dateisystem zu speichern, was ineffizient ist. Solange die Sitzung verwendet wird, wird die angegebene Sitzungs-ID aus mehreren Dateien durchsucht, was sehr ineffizient ist.
Das zweite Problem besteht darin, dass bei Verwendung mehrerer Server das Problem des Sitzungsverlusts auftreten kann (eigentlich wird die Sitzung auf anderen Servern gespeichert).
Natürlich kann das Speichern im Cache das oben genannte Problem lösen. Wenn Sie die PHP-eigene Sitzungsfunktion verwenden, können Sie die Funktion session_set_save_handler() verwenden, um den Sitzungsverarbeitungsprozess einfach neu zu steuern. Wenn Sie die Sitzungsserienfunktionen nicht verwenden, können Sie auch selbst eine ähnliche Sitzungsfunktion schreiben. Dies ist das Projekt, an dem ich gerade arbeite. Es berechnet den Hash als Sitzungs-ID basierend auf der Mitte und dem Login Jedes Mal, wenn es angefordert wird, muss die Sitzungs-ID hinzugefügt werden, um gültig zu sein (dies ist nicht erforderlich, wenn Sie sich zum ersten Mal anmelden. Die Sitzungs-ID wird zu diesem Zeitpunkt erstellt und an den Client zurückgegeben. Dies ist auch sehr praktisch.) prägnant und effizient. Natürlich spreche ich in diesem Artikel hauptsächlich über die „Manipulation von Dingen“ in PHPs eigener SESSION.
SITZUNG im Cache gespeichert
PHP speichert den Cache in Redis. Sie können die Verarbeitung und Speicherung der Sitzung natürlich auch mit der Funktion ini_set() ändern Ich werde es hier verwenden. Auf diese Weise wird natürlich empfohlen, Konfigurationsdateien in einer Produktionsumgebung zu verwenden.
<?<span>php </span><span>ini_set</span>("session.save_handler", "redis"<span>); </span><span>ini_set</span>("session.save_path", "tcp://localhost:6379"<span>); </span><span>session_start</span><span>(); </span><span>header</span>("Content-type:text/html;charset=utf-8"<span>); </span><span>if</span>(<span>isset</span>(<span>$_SESSION</span>['view'<span>])){ </span><span>$_SESSION</span>['view'] = <span>$_SESSION</span>['view'] + 1<span>; }</span><span>else</span><span>{ </span><span>$_SESSION</span>['view'] = 1<span>; } </span><span>echo</span> "【view】{<span>$_SESSION</span>['view']}";
Hier ist die session.save_handler-Methode auf redis eingestellt, und session.save_path ist die Adresse und der Port von redis. Nach dem Festlegen werden Sie feststellen, dass die in redis generierte sessionId dieselbe ist wie vom Browser angefordert
Ist es nicht sehr praktisch? Sie müssen nur die Konfigurationsdatei ändern, um die Sitzung in Redis zu speichern. Ich möchte hier jedoch darüber sprechen, wie Sie die Sitzung mit dem Programm verarbeiten und in Redis oder DB speichern können. Werfen wir einen Blick darauf.
Schreiben Sie die Sitzungsverarbeitungsfunktion selbst über die von PHP bereitgestellte Schnittstelle neu
Hier können Sie sich zunächst die Funktion session_set_save_handler in PHP 5.4 ansehen und die SessionHandlerInterface-Schnittstelle direkt implementieren. Beim Umschreiben gibt es hauptsächlich die folgenden Methoden
open(string $savePath, string $sessionName); //open ähnelt einem Konstruktor und wird beim Starten einer Sitzung aufgerufen, beispielsweise nach Verwendung der Funktion session_start()
close(); //Ähnlich wie der Destruktor einer Klasse wird er nach dem Aufruf der Schreibfunktion aufgerufen
wird auch nach session_write_close() ausgeführt.read(string $sessionId); //Wird beim Lesen der Sitzung aufgerufen
write(string $sessionId, string $data); //Wird beim Speichern von Daten aufgerufen
destory($sessionId); //Beim Zerstören der Sitzung (session_destory() oder session_regenerate_id()) wird
aufgerufengc($lifeTime); //Müllbereinigungsfunktion, abgelaufene Daten bereinigen
Die Hauptsache ist, diese Methoden entsprechend den verschiedenen Speichertreibern zu implementieren. Ich habe zwei Treiber zum Speichern von Sitzungen implementiert ganz einfach. Bequemlichkeit ist einfach.
Das Folgende ist meine Redis-Implementierung (DB ähnelt Redis, es gibt weniger Redis-Code, gepostet):
Ich habe die Schnittstellenmethode verwendet, die die Erweiterung erleichtert. Ich wollte an diesem Tag memcached verwenden, also füge es einfach direkt hinzu
<?<span>php </span><span>include_once</span> __DIR__."/interfaceSession.php"<span>; </span><span>/*</span><span>* * 以db的方式存储session </span><span>*/</span> <span>class</span> redisSession <span>implements</span><span> interfaceSession{ </span><span>/*</span><span>* * 保存session的数据库表的信息 </span><span>*/</span> <span>private</span> <span>$_options</span> = <span>array</span><span>( </span>'handler' => <span>null</span>, <span>//</span><span>数据库连接句柄</span> 'host' => <span>null</span>, 'port' => <span>null</span>, 'lifeTime' => <span>null</span>,<span> ); </span><span>/*</span><span>* * 构造函数 * @param $options 设置信息数组 </span><span>*/</span> <span>public</span> <span>function</span> __construct(<span>$options</span>=<span>array</span><span>()){ </span><span>if</span>(!<span>class_exists</span>("redis", <span>false</span><span>)){ </span><span>die</span>("必须安装redis扩展"<span>); } </span><span>if</span>(!<span>isset</span>(<span>$options</span>['lifeTime']) || <span>$options</span>['lifeTime'] <= 0<span>){ </span><span>$options</span>['lifeTime'] = <span>ini_get</span>('session.gc_maxlifetime'<span>); } </span><span>$this</span>->_options = <span>array_merge</span>(<span>$this</span>->_options, <span>$options</span><span>); } </span><span>/*</span><span>* * 开始使用该驱动的session </span><span>*/</span> <span>public</span> <span>function</span><span> begin(){ </span><span>if</span>(<span>$this</span>->_options['host'] === <span>null</span> || <span>$this</span>->_options['port'] === <span>null</span> || <span>$this</span>->_options['lifeTime'] === <span>null</span><span> ){ </span><span>return</span> <span>false</span><span>; } </span><span>//</span><span>设置session处理函数</span> <span>session_set_save_handler</span><span>( </span><span>array</span>(<span>$this</span>, 'open'), <span>array</span>(<span>$this</span>, 'close'), <span>array</span>(<span>$this</span>, 'read'), <span>array</span>(<span>$this</span>, 'write'), <span>array</span>(<span>$this</span>, 'destory'), <span>array</span>(<span>$this</span>, 'gc'<span>) ); } </span><span>/*</span><span>* * 自动开始回话或者session_start()开始回话后第一个调用的函数 * 类似于构造函数的作用 * @param $savePath 默认的保存路径 * @param $sessionName 默认的参数名,PHPSESSID </span><span>*/</span> <span>public</span> <span>function</span> open(<span>$savePath</span>, <span>$sessionName</span><span>){ </span><span>if</span>(<span>is_resource</span>(<span>$this</span>->_options['handler'])) <span>return</span> <span>true</span><span>; </span><span>//</span><span>连接redis</span> <span>$redisHandle</span> = <span>new</span><span> Redis(); </span><span>$redisHandle</span>->connect(<span>$this</span>->_options['host'], <span>$this</span>->_options['port'<span>]); </span><span>if</span>(!<span>$redisHandle</span><span>){ </span><span>return</span> <span>false</span><span>; } </span><span>$this</span>->_options['handler'] = <span>$redisHandle</span><span>; </span><span>$this</span>->gc(<span>null</span><span>); </span><span>return</span> <span>true</span><span>; } </span><span>/*</span><span>* * 类似于析构函数,在write之后调用或者session_write_close()函数之后调用 </span><span>*/</span> <span>public</span> <span>function</span><span> close(){ </span><span>return</span> <span>$this</span>->_options['handler']-><span>close(); } </span><span>/*</span><span>* * 读取session信息 * @param $sessionId 通过该Id唯一确定对应的session数据 * @return session信息/空串 </span><span>*/</span> <span>public</span> <span>function</span> read(<span>$sessionId</span><span>){ </span><span>return</span> <span>$this</span>->_options['handler']->get(<span>$sessionId</span><span>); } </span><span>/*</span><span>* * 写入或者修改session数据 * @param $sessionId 要写入数据的session对应的id * @param $sessionData 要写入的数据,已经序列化过了 </span><span>*/</span> <span>public</span> <span>function</span> write(<span>$sessionId</span>, <span>$sessionData</span><span>){ </span><span>return</span> <span>$this</span>->_options['handler']->setex(<span>$sessionId</span>, <span>$this</span>->_options['lifeTime'], <span>$sessionData</span><span>); } </span><span>/*</span><span>* * 主动销毁session会话 * @param $sessionId 要销毁的会话的唯一id </span><span>*/</span> <span>public</span> <span>function</span> destory(<span>$sessionId</span><span>){ </span><span>return</span> <span>$this</span>->_options['handler']->delete(<span>$sessionId</span>) >= 1 ? <span>true</span> : <span>false</span><span>; } </span><span>/*</span><span>* * 清理绘画中的过期数据 * @param 有效期 </span><span>*/</span> <span>public</span> <span>function</span> gc(<span>$lifeTime</span><span>){ </span><span>//</span><span>获取所有sessionid,让过期的释放掉</span> <span>$this</span>->_options['handler']->keys("*"<span>); </span><span>return</span> <span>true</span><span>; } }</span>
Schauen Sie sich das einfache Fabrikmuster an
<span>class</span><span> session { </span><span>/*</span><span>* * 驱动程序句柄保存 </span><span>*/</span> <span>private</span> <span>static</span> <span>$_handler</span> = <span>null</span><span>; </span><span>/*</span><span>* * 创建session驱动程序 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span> getSession(<span>$type</span>, <span>$options</span><span>){ </span><span>//</span><span>单例</span> <span>if</span>(<span>isset</span>(<span>$handler</span><span>)){ </span><span>return</span> self::<span>$_handler</span><span>; } </span><span>switch</span> (<span>$type</span><span>) { </span><span>case</span> 'db': <span>//</span><span>数据库驱动session类型</span> <span>include_once</span> __DIR__."/driver/dbSession.php"<span>; </span><span>$handler</span> = <span>new</span> dbSession(<span>$options</span><span>); </span><span>break</span><span>; </span><span>case</span> 'redis': <span>//</span><span>redis驱动session类型</span> <span>include_once</span> __DIR__."/driver/redisSession.php"<span>; </span><span>$handler</span> = <span>new</span> redisSession(<span>$options</span><span>); </span><span>break</span><span>; </span><span>default</span>: <span>return</span> <span>false</span><span>; </span><span>break</span><span>; } </span><span>return</span> self::<span>$_handler</span> = <span>$handler</span><span>; } }</span>
Der Aufruf ist auch sehr einfach,
session::getSession('redis',<span>array</span><span>( </span>'host' => "localhost", 'port' => "6379",<span> ))</span>-><span>begin(); </span><span>session_start</span>();
Auch die Datenbankversion ist sehr einfach zu konfigurieren. Bei Bedarf können Sie die Vollversion und Demo
hier herunterladenDas Urheberrecht dieses Artikels liegt beim Autor (luluyrt@163.com). Nach dem Nachdruck des Artikels müssen der Autor und der Originaltext-Link angegeben werden an einer offensichtlichen Stelle auf der Artikelseite, andernfalls behalten wir uns die Geltendmachung gesetzlicher Haftungsrechte vor.
Das Obige führt die Sitzung in Cache (Redis) und DB ein, einschließlich des Inhalts. Ich hoffe, dass es für Freunde hilfreich ist, die sich für PHP-Tutorials interessieren.