Table of Contents
2. [代码]CLS_SCACHER   
3. [代码]CLS_ECACHER    
4. [代码]get_departments.php  
5. [代码]get_users.php  
6. [代码]get_users_complex.php  
Home php教程 PHP源码 使用etag和文件缓存降低服务器数据库压力

使用etag和文件缓存降低服务器数据库压力

May 23, 2016 pm 04:38 PM
php

使用php5.3+,使用了一些自定义的内容,不过都一看便知
比如常量ROOT、DIR_CACHE等
核心使用的有
diehere(输出json字符串,并die),err_a(组合错误信息),makedir(连续创建目录)
其余的都根据实际使用的情况来

终于debug完成了……新增one_key方法,一键完成输出,完美……
departments初次查询170ms
之后仅16ms,越复杂效果越好啊

高复杂测试get_users_complex.php
初次108.0 KB  985ms
第二次16ms,哈哈哈,
清空etag(未清空data)读取,接收数据125ms                        

1. [代码]DEF.inc.php    

	define('ROOT',dirname(__FILE__));

	define('CLS_SCACHER','/inc/SCACHER.cls.php');
	define('CLS_ECACHER','/inc/ECACHER.cls.php');

	define('DIR_CACHE','/cache/');	//用于缓存判断的目录


function run_sql($sql){
	static $db;
	if(!$db){
		$db=getdb();
	}
	return mysql_query($sql,$db);
}

function getdb(){
	static $mydb;
	if(!$mydb){
		$mydb=dbconnection();
	}
	return $mydb;
}

function dbconnection(&$var=0){
	
	if($var==0||!is_array($var)){$var=array();}
	if(!isset($var['dbhost']) || !is_string($var['dbhost'])){	$var['dbhost']=constant('DBHOST');}
	if(!isset($var['dbuser']) || !is_string($var['dbuser'])){	$var['dbuser']=constant('DBUSER');}
	if(!isset($var['dbpsw']) || !is_string($var['dbpsw'])){$var['dbpsw']=constant('DBPSW');}
	$db=mysql_connect($var['dbhost'],$var['dbuser'],$var['dbpsw']) or die();
	if(!$db){return 0;}
	mysql_select_db(constant('DBNAME'),$db) or die();//echo('db enter here');
	mysql_query("SET NAMES 'UTF8'");
	return $db;
}

function PR($v){
	if(isset($v)){
		echo(&#39;<pre class="brush:php;toolbar:false">&#39;);
		print_r($v);
		echo(&#39;
'); } } function rs_2_array($rs){ //this is a function used to make the code clear and less //i am tired to code same code to get the arry result //thought it is not much //redlz2500@2008-06-24 $t=array(); try { while($row=mysql_fetch_array($rs,MYSQL_ASSOC)){ $t[]=$row; } return $t; }catch (Exception $e) { } return $t; } /* * 功能:连续建目录 * $dir 目录字符串 */ function makedir($dir,$mode = '0777') { //notice: the $dir will not set the code style & //as maybe call by $str.$str1 //the var can not be reference if(!isset($dir)){return 0;} //echo('
**********intomakedir*************
'.$dir); $dir = str_replace( "\\", "/", $dir ); $mdir = ""; foreach( explode( "/", $dir ) as $val ) { $mdir .= $val."/"; if( $val == ".." || $val == "." ) continue; if( ! file_exists( $mdir ) ) { if(!@mkdir( $mdir, $mode )){ echo "创建目录 [".$mdir."]失败."; exit; } } } return true; }
Copy after login

2. [代码]CLS_SCACHER

<?php
/*
//超级简单的文件缓存类,用于ECACHE的数据缓存支持
//使用ROOT.DIR_CACHE作为基本目录,下面再是path划分小目录,category和name组合为缓存文件的名称
//不包括时间有效期,若需使用时间有效判定,使用CLS_CACHER类
//属性配置调用scacher方法
//set($v)直接设置$v的值到缓存
//get()和del()无参数,含义自明
//主要用于CLS_ECACHER的底层支持
//redlz2500@20151022
*/
	
	class scacher{
		protected $fullpath=&#39;&#39;;
		protected $path=&#39;&#39;;	//在ROOT.DIR_CACHE目录下的,左右无目录分隔符
		protected $category=&#39;default&#39;;	//缓存下的分类
		protected $name=&#39;mycache&#39;;	//文件标识名称
		
		public function __construct($opt){
			$this->scacher($opt);
		}
		
		public function scacher($opt=[]){
			$flag=false;
			if($opt[&#39;category&#39;] && is_string($opt[&#39;category&#39;]) && ($this->category!=$opt[&#39;category&#39;]) ){
				$this->category=$opt[&#39;category&#39;];
				$flag=true;
			}
			if($opt[&#39;name&#39;] && is_string($opt[&#39;name&#39;]) && ($this->name!=$opt[&#39;name&#39;])){
				$this->name=$opt[&#39;name&#39;];
				$flag=true;
			}
			if($opt[&#39;path&#39;] && is_string($opt[&#39;path&#39;]) && ($this->pat!=$opt[&#39;path&#39;])){
				$this->path=$opt[&#39;path&#39;];
				$flag=true;
			}
			if($flag){
				if($this->path){
					$this->fullpath=ROOT.DIR_CACHE.$this->path.&#39;/&#39;;
				}else{
					$this->fullpath=ROOT.DIR_CACHE;
				}
				if(!file_exists($this->fullpath)){
					makedir($this->fullpath);
					if(!file_exists($this->fullpath)){
						throw new Exception(&#39;errSCACHER配置失败 当前调用参数:&#39;.$this->category.&#39;.&#39;.$this->name);
					}
				}
			}
		}
		
		public function set($v){
			$fp=fopen($this->fullpath . $this->category .&#39;.&#39;. $this->name,&#39;w&#39;);
			if (!fwrite($fp,$v)) {
				return [&#39;success&#39;=>false,&#39;error&#39;=>err_a(&#39;errSCACHER_1&#39;,&#39;数据写入失败,请稍后重试。<br/>重试无效请联系管理员。<br/>当前调用参数:&#39;.$this->category.&#39;.&#39;.$this->name)];
			}  
			@fclose($fp);
			return [&#39;success&#39;=>true];
		}
		public function get(){
			$f=$this->fullpath . $this->category .&#39;.&#39;. $this->name;
			if(file_exists($f)){
				$res=@file_get_contents($f);
				if(!$res){
					$res=&#39;&#39;;
				}
				return [&#39;success&#39;=>true,&#39;data&#39;=>$res];
			}else{
				return [&#39;success&#39;=>false,&#39;data&#39;=>&#39;&#39;,&#39;error&#39;=>err_a(&#39;errSCACHER_3&#39;,&#39;未找到缓存。<br/>当前调用参数:&#39;.$this->category.&#39;.&#39;.$this->name)];
			}
		}
		public function del(){
			$f=$this->fullpath . $this->category .&#39;.&#39;. $this->name;
			if(file_exists($f)){
				@unlink($f);
				if(file_exists($f)){
					return [&#39;success&#39;=>false,&#39;error&#39;=>err_a(&#39;errSCACHER_2&#39;,&#39;数据处理异常,请稍后重试。<br/>重试无效请联系管理员。<br/>当前调用参数:&#39;.$this->category.&#39;.&#39;.$this->name)];
				}
			}else{
				return [&#39;success&#39;=>true];
			}
		}
	}
?>
Copy after login

3. [代码]CLS_ECACHER

<?php
/*
//基于CLS_CACHER的缓存机制,包括etag参数以及其余的数据,主要用于单个的json数据缓存
//主要目的为在服务器端给json方式做缓存,模式如下:
//核心的detail缓存由后台互动生成(也可以由前台生成,方法摆在这里自己组合)
//1、查询端query.php
//	调用etag_chk,相同则 发送304header(默认允许)
//		不同则调用data_get方法,取出缓存,如果取出缓存失败,则前台处理,不重新生成缓存(也可以生成,但是需重新包括缓存生成方法)
//2、数据生成页面trigger.php
//	触发数据重新生成机制 ,生成新的缓存,并更新etag信息,这样做在触发频繁的情况下可能引起大量无必要的数据库操作,
//可在此时修改触发方式,或者触发的时候仅清空数据,但是并不重新生成缓存,而在前台实际调用的时候才执行缓存生成操作
//A、或者是在查询段负责生成数据,触发端负责清空缓存
//	ecacher重设参数
//	mode_etag mode_data在两种模式下切换,内部方法
//	etag_chk	检查浏览器是否一致,一致的话 发送304(默认允许)
//	etag_create	生成新的etag并缓存
//	data_get	获取缓存的data
//	data_create	调用外部定义的方法以及参数生成缓存并重设etag,注意,虽然重设了etag,但是并不会重新发送200
//	clear	清空数据,传入数组
//第一次生成数据的时候可能不正确,未处理	已经解决redlz2500@20151022
//v1.1新增one_key方法
//v1.2增加catch-control输出。某个页面一直无法输出304,检查服务器返回catch-control:no-catch……查不出原因,直接重写了……
//v1.3增加force参数,用于强制输出catch-control控制,默认false,为true强制输出自己的catch-control,以避免和php自己的session_cache_limiter冲突
//redlz2500@20151022
*/

	define(&#39;DEF_ECACHE_PERFECT&#39;,&#39;0001&#39;);	//浏览器发送了匹配的etag,完美,返回304
	define(&#39;DEF_ECACHE_BROWSER_NULL&#39;,&#39;0010&#39;);	//浏览器未发送etag
	define(&#39;DEF_ECACHE_ETAG_NULL&#39;,&#39;0100&#39;);	//本地的etag记录为空(可能是数据真空期)
	define(&#39;DEF_ECACHE_ETAG_CREATED&#39;,&#39;1000&#39;);//etag成功生成

	require_once(ROOT.CLS_SCACHER);//使用scacher类
	
	class ecacher{
		protected $path=&#39;&#39;;
		protected $category=&#39;default&#39;;	//当前类别的分类
		protected $name=&#39;myname&#39;;		//模板名称
		//以上三个是scacher类的定义,方式与ecacher相同,缓存位置由ecacher来控制
		protected $force_cache=false;
		protected $auto_send_etag_header=true;	//是否自动发送header信息

		protected $create_fn=&#39;&#39;;	//没有数据的时候生成数据的回调函数,返回数据由data_create处理,仅支持字符串
		protected $create_par;		//生成数据的时候需要传送的参数,按参数先后顺序组合为array传送,不是数组则自动将其转换为数组
		
		protected $scacher;
		
		public function __construct($opt){
			$this->scacher=new scacher([]);		//scacher实例,路径由scacher来控制
			$this->ecacher($opt);
		}
		
		public function __destruct(){
			
		}
		
		function ecacher($opt){
			if(is_array($opt)){
				if($opt[&#39;force_cache&#39;]){
					$this->force_cache=true;
				}else{
					if(isset($opt[&#39;force_cache&#39;])){
						$this->force_cache=false;
					}
				}
				if($opt[&#39;path&#39;] && is_string($opt[&#39;path&#39;])){
					$this->path=$opt[&#39;path&#39;];
				}
				if($opt[&#39;category&#39;] && is_string($opt[&#39;category&#39;])){
					$this->category=$opt[&#39;category&#39;];
				}
				if($opt[&#39;name&#39;] && is_string($opt[&#39;name&#39;])){
					$this->name=$opt[&#39;name&#39;];
				}
				if(isset($opt[&#39;auto_send_etag_header&#39;])){
					$this->auto_send_etag_header=$opt[&#39;auto_send_etag_header&#39;];
				}
				if($opt[&#39;create_fn&#39;] && is_string($opt[&#39;create_fn&#39;])){
					$this->create_fn=$opt[&#39;create_fn&#39;];
				}
				if($opt[&#39;create_par&#39;]){
					if(is_array($opt[&#39;create_par&#39;])){
						$this->create_par=$opt[&#39;create_par&#39;];
					}else{
						$this->create_par=[$opt[&#39;create_par&#39;]];
					}
				}else{
					$this->create_par=[];
				}
				$this->scacher->scacher($opt);//更新的数据写入(好吧,其实并没有什么卵用)(好吧,可以提前判断缓存路径有没有效)
			}
		}
		
		private function mode_etag(){
			$this->scacher->scacher([&#39;name&#39;=>$this->name.&#39;.etag&#39;]);
		}
		private function mode_data(){
			$this->scacher->scacher([&#39;name&#39;=>$this->name.&#39;.&#39;]);
		}
		public function etag_chk(){
			$this->mode_etag();//设置etag模式
			$etag=$this->scacher->get();
			echo_debug(&#39;test etag&#39;);
			echo_debug($etag);
			if($etag[&#39;success&#39;]){
				$etag=$etag[&#39;data&#39;];
			}else{
				return $etag;
			}
			$s_etag=$_SERVER[&#39;HTTP_IF_NONE_MATCH&#39;];
			echo_debug(&#39;etag from browse&#39;);
			echo_debug($s_etag);
			if($etag){
				if($s_etag==$etag){
					if($this->auto_send_etag_header){
						if($this->force_cache){
							header(&#39;Cache-Control: max-age=0&#39;);
							header(&#39;Expires: &#39;.gmdate(&#39;D, d M Y H:i:s&#39;, time() + SERVER_TIME_SHIFT + 10 ) . &#39; GMT&#39; );
						}
						header(&#39;Etag:&#39;.$etag,true,304);
						die();//必须die,否则还会继续执行下去。
					}else{
						return [	&#39;etag&#39;=>$etag,	&#39;statue&#39;=>DEF_ECACHE_PERFECT	];
					}
				}else{
					if($this->auto_send_etag_header){
						if($this->force_cache){
							header(&#39;Cache-Control: max-age=0&#39;);
							header(&#39;Expires: &#39;.gmdate(&#39;D, d M Y H:i:s&#39;, time() + SERVER_TIME_SHIFT + 10 ) . &#39; GMT&#39; );
						}
						header(&#39;Etag:&#39;.$etag);
					}
					return [	&#39;etag&#39;=>$etag,	&#39;statue&#39;=>DEF_ECACHE_BROWSER_NULL	];
				}
			}else{
				return [
					&#39;etag&#39;=>&#39;&#39;,
					&#39;statue&#39;=>DEF_ECACHE_ETAG_NULL
				];
			}
		}
		
		public function etag_create($auto=false){
			$etag=md5($this->category.&#39;:&#39;.$this->name.&#39;:&#39;.time().&#39;:&#39;.ranstr());
			$this->mode_etag();
			$this->scacher->set($etag);
			if($auto){
				if($this->force_cache){
					header(&#39;Cache-Control: max-age=0&#39;);
					header(&#39;Expires: &#39;.gmdate(&#39;D, d M Y H:i:s&#39;, time() + SERVER_TIME_SHIFT + 10 ) . &#39; GMT&#39; );
				}
				header(&#39;Etag:&#39;.$etag);
			}
			echo_debug(&#39;etag create finish:&#39;.$etag);
			return [
				&#39;success&#39;=>true,
				&#39;etag&#39;=>$etag,
				&#39;status&#39;=>DEF_ECACHE_ETAG_CREATED
			];
		}
		
		public function data_get(){
			//PR(&#39;begin get data&#39;);BR();
			$this->mode_data();
			$data=$this->scacher->get();
			if($data[&#39;success&#39;]){
				echo_debug(&#39;orgin data is:&#39;);
				echo_debug($data[&#39;data&#39;]);
				$data[&#39;data&#39;]=unserialize($data[&#39;data&#39;]);
			}else{
				echo_debug(&#39;not success:&#39;);
				echo_debug($data);
				$data[&#39;data&#39;]=&#39;&#39;;
			}
			echo_debug();
			echo_debug(&#39;the data is:&#39;);
			echo_debug($data);
			return $data;
		}
		public function data_create($auto_etag=false){
			if(!$this->create_fn){
				throw new Exception(&#39;<ECACHER>未传递数据生成函数<br/>当前参数:&#39;.$this->category.&#39;.&#39;.$this->name);		//这样的错误时不允许的,因此直接抛出错误
				die();
			}
			$data=call_user_func_array($this->create_fn,$this->create_par);
			//生成数据的处理
			if($data===false){
				throw new Exception(&#39;<ECACHER>生成数据失败<br/>当前参数:&#39;.$this->category.&#39;.&#39;.$this->name);		//无法,只有不返回false了
				die();
			}
			//PR($data);
			$s_data=serialize($data);
			$this->mode_data();
			$res=$this->scacher->set($s_data);
			if(!$res[&#39;success&#39;]){	return $res;	}
			if($auto_etag){
				$res=$this->etag_create();
				if(!$res[&#39;success&#39;]){	return $res;	}
			}
			return [&#39;success&#39;=>true,&#39;data&#39;=>$data];
		}
		
		public function clear($p=[&#39;etag&#39;,&#39;data&#39;]){
			if(in_array(&#39;both&#39;,$p)){
				$p=[&#39;etag&#39;,&#39;data&#39;];
			}
			if(in_array(&#39;etag&#39;,$p)){
				$this->mode_data();
				$res=$this->scacher->del();
				if(!$res[&#39;success&#39;]){	return $res;	}
			}
			if(in_array(&#39;etag&#39;,$p)){
				$this->mode_etag();
				$res=$this->scacher->del();
				if(!$res[&#39;success&#39;]){	return $res;	}
			}
			return [&#39;success&#39;=>true];
		}
		
		public function one_key(){
			$r=$this->etag_chk();
			if(!$r[&#39;etag&#39;]){
				echo_debug(&#39;the etag is null,should be rebuild&#39;);
				echo_debug($r);
				$this->etag_create(&#39;auto&#39;);
			}
			$res=$this->data_get();
			if($res[&#39;success&#39;]){
				//PR($res);
				if($res[&#39;data&#39;]){
					diehere($res);
				}
			}
			echo_debug(&#39;recreate data&#39;);
			
			$data=$this->data_create();
			diehere($data);
		}
	}
?>
Copy after login

4. [代码]get_departments.php

<?php
//实在受不了每次的数据的读取咯,所以按照以下的方式进行处理:
//对于部门,因为内容不算很多,120多个的样子,有效部门90个的样子,因此将其一次性进行处理,使用这个东西来创造,使用缓存机制
//如果数据没有变化的,就读取缓存,如果有变化的,就发送数据
//redlz2500@20151022
	define(&#39;IN_SERVER&#39;,1);
	require(&#39;../../../DEF.inc.php&#39;);
	require(ROOT.CLS_ECACHER);
	
	//define(&#39;ECHO_DEBUG&#39;,0);
	//define(&#39;ECHO_DEBUG&#39;,1);
	
	$e=new ecacher([
		&#39;create_fn&#39;=>&#39;get_departments&#39;,
		&#39;path&#39;=>&#39;json&#39;,&#39;category&#39;=>&#39;common&#39;,&#39;name&#39;=>&#39;department&#39;
	]);
	
	$e->one_key();
	
	die();
function get_departments(){
	$sql=&#39;select `depid` as `id`,`name`,`father`,`departcode` as `code` from `department` where `father` !=0&#39;;
	
	$rs=run_sql($sql);
	$data=[];
	require_once(ROOT.INC_MAIL);
	while($row=mysql_geta($rs)){
		$address=get_dep_mail_address($row[&#39;id&#39;]);
		$fullname=explode(&#39;.&#39;,$address);
		$fullname=array_reverse($fullname);
		$fullname=implode(&#39;.&#39;,$fullname);
		$row[&#39;fullname&#39;]=$fullname;
		$data[]=$row;
	}
	return $data;
}
?>
Copy after login

5. [代码]get_users.php

<?php
//本来想一次性全部读取,想到数量还是有点儿大,还是按照部门来读取好了
//redlz2500@20151022
	define(&#39;IN_SERVER&#39;,1);
	require(&#39;../../../DEF.inc.php&#39;);
	require(ROOT.CLS_ECACHER);
	
	$par=$_POST;
	$par=$_GET;
	$res[&#39;success&#39;]=false;
	if(!$par[&#39;depid&#39;]){
		$res[&#39;error&#39;]=err_a(&#39;errU038&#39;,&#39;参数缺失&#39;);
		diehere($res);
	}
	if(!isDecimalNumber($par[&#39;depid&#39;])){
		$res[&#39;error&#39;]=err_a(&#39;errU039&#39;,&#39;参数错误&#39;);
		diehere($res);
	}
	$e=new ecacher([
		&#39;create_fn&#39;=>&#39;get_users&#39;,
		&#39;create_par&#39;=>$par[&#39;depid&#39;],
		&#39;path&#39;=>&#39;json&#39;,&#39;category&#39;=>&#39;common&#39;,&#39;name&#39;=>&#39;users_in_&#39;.$par[&#39;depid&#39;]]);
	
	$e->one_key();
	
function get_users($depid){
	$sql=&#39;select `uid`,`name`,`login`,`depid` from `user` where `register` = 1 and `depid` = &#39;.$depid;
	$rs=run_sql($sql);
	$rs=rs_2_array($rs);
	return $rs;
}

?>
Copy after login

6. [代码]get_users_complex.php

<?php
//本来想一次性全部读取,想到数量还是有点儿大,还是按照部门来读取好了
//redlz2500@20151022
	define(&#39;IN_SERVER&#39;,1);
	require(&#39;../../../DEF.inc.php&#39;);
	require(ROOT.CLS_ECACHER);
	
	$res[&#39;success&#39;]=false;

	$e=new ecacher([
		&#39;create_fn&#39;=>&#39;get_users&#39;,
		&#39;create_par&#39;=>$par[&#39;depid&#39;],
		&#39;path&#39;=>&#39;json&#39;,&#39;category&#39;=>&#39;common&#39;,&#39;name&#39;=>&#39;users_all&#39;]);
	
	$e->one_key();
	
function get_users(){
	$sql=&#39;select `uid`,`name`,`login`,`depid` from `user` where `register` = 1 &#39;;
	$rs=run_sql($sql);
	require_once(ROOT.INC_MAIL);
	$data=[];
	while($row=mysql_geta($rs)){
		$addr=_get_user_mail_address($row[&#39;login&#39;]);
		$row[&#39;addr&#39;]=$addr;
		$data[]=$row;
	}
	return $data;
}

?>
Copy after login

                   

                   

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

7 PHP Functions I Regret I Didn't Know Before 7 PHP Functions I Regret I Didn't Know Before Nov 13, 2024 am 09:42 AM

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

See all articles