Put session into cache (redis), DB, sessionredis
Why should SESSION be saved in cache
As far as PHP is concerned, the session supported by the language itself is saved to a disk file in the form of a file and saved in a specified folder. The saved path can be set in the configuration file or use the function session_save_path() in the program. Set it up, but there are drawbacks to doing so,
<p>第一就是保存到文件系统中,效率低,只要有用到session就会从好多个文件中查找指定的sessionid,效率很低。</p> <p>第二就是当用到多台服务器的时候可能会出现,session丢失问题(其实是保存在了其他服务器上)。</p>
Of course, saving in the cache can solve the above problem. If you use PHP's own session function, you can use the session_set_save_handler() function to easily re-control the session processing process. If you don't use PHP's session series functions, you can write a similar session function yourself. It's also possible. This is the project I'm working on now. It will calculate the hash as the sessionId based on the user's mid and login time. Every time it is requested, The sessionId must be added to be legal (it is not needed when logging in for the first time, the sessionId will be created at this time and returned to the client). This is also very convenient, concise and efficient. Of course, what I am mainly talking about in this article is "manipulating things" in PHP's own SESSION.
SESSION saved in cache
PHP saves the cache to redis. You can use the configuration file to modify the processing and saving of the session. Of course, you can also use the ini_set() function in the program to modify it. This is very convenient for testing. I will use it here. In this way, of course, it is recommended to use configuration files in a production environment.
<?<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']}";
Here the session.save_handler method is set to redis, and session.save_path is the address and port of redis. After setting, refresh, and then look back at redis. You will find that the sessionId generated in redis is the same as the one requested by the browser.
open(string $savePath, string $sessionName); //open is similar to a constructor and will be called when starting a session, such as after using the session_start() function
close(); //Similar to the destructor of a class, it is called after the write function is called.
will also be executed after session_write_close()read(string $sessionId); //Called when reading session
write(string $sessionId, string $data); //Called when saving data
destory($sessionId); //When destroying the session (session_destory() or session_regenerate_id()),
will be calledgc($lifeTime); //Garbage cleaning function, clean up expired data
The main thing is to implement these methods. You can set different specific methods according to different storage drivers. I have implemented two drivers for saving sessions, mysql database and redis. If necessary, you can expand it yourself. The expansion is very easy. Convenience is easy.
The following is my redis implementation (db is similar to redis, redis code is less, posted):
I used the interface method, which makes it easier to expand. I wanted to use memcached that day, so just add it directly
<?<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>
Take a look at the simple factory pattern
<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>
The call is also very simple,
session::getSession('redis',<span>array</span><span>( </span>'host' => "localhost", 'port' => "6379",<span> ))</span>-><span>begin(); </span><span>session_start</span>();
The database version is also very simple to configure. If necessary, you can download the full version and demo
here
The copyright of this article belongs to the author iforever (luluyrt@163.com). Any form of reprinting is prohibited without the author's consent. After reprinting the article, the author and the original text link must be given in an obvious position on the article page, otherwise we will reserve the right to pursue it. Legal liability rights.

ThesecrettokeepingaPHP-poweredwebsiterunningsmoothlyunderheavyloadinvolvesseveralkeystrategies:1)ImplementopcodecachingwithOPcachetoreducescriptexecutiontime,2)UsedatabasequerycachingwithRedistolessendatabaseload,3)LeverageCDNslikeCloudflareforservin

You should care about DependencyInjection(DI) because it makes your code clearer and easier to maintain. 1) DI makes it more modular by decoupling classes, 2) improves the convenience of testing and code flexibility, 3) Use DI containers to manage complex dependencies, but pay attention to performance impact and circular dependencies, 4) The best practice is to rely on abstract interfaces to achieve loose coupling.

Yes,optimizingaPHPapplicationispossibleandessential.1)ImplementcachingusingAPCutoreducedatabaseload.2)Optimizedatabaseswithindexing,efficientqueries,andconnectionpooling.3)Enhancecodewithbuilt-infunctions,avoidingglobalvariables,andusingopcodecaching

ThekeystrategiestosignificantlyboostPHPapplicationperformanceare:1)UseopcodecachinglikeOPcachetoreduceexecutiontime,2)Optimizedatabaseinteractionswithpreparedstatementsandproperindexing,3)ConfigurewebserverslikeNginxwithPHP-FPMforbetterperformance,4)

APHPDependencyInjectionContainerisatoolthatmanagesclassdependencies,enhancingcodemodularity,testability,andmaintainability.Itactsasacentralhubforcreatingandinjectingdependencies,thusreducingtightcouplingandeasingunittesting.

Select DependencyInjection (DI) for large applications, ServiceLocator is suitable for small projects or prototypes. 1) DI improves the testability and modularity of the code through constructor injection. 2) ServiceLocator obtains services through center registration, which is convenient but may lead to an increase in code coupling.

PHPapplicationscanbeoptimizedforspeedandefficiencyby:1)enablingopcacheinphp.ini,2)usingpreparedstatementswithPDOfordatabasequeries,3)replacingloopswitharray_filterandarray_mapfordataprocessing,4)configuringNginxasareverseproxy,5)implementingcachingwi

PHPemailvalidationinvolvesthreesteps:1)Formatvalidationusingregularexpressionstochecktheemailformat;2)DNSvalidationtoensurethedomainhasavalidMXrecord;3)SMTPvalidation,themostthoroughmethod,whichchecksifthemailboxexistsbyconnectingtotheSMTPserver.Impl


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 Linux new version
SublimeText3 Linux latest version

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Notepad++7.3.1
Easy-to-use and free code editor
