首页 后端开发 PHP问题 php 实现类似于pyhon中的Construct库的功能(三)实现if-else功能

php 实现类似于pyhon中的Construct库的功能(三)实现if-else功能

Aug 19, 2019 pm 04:48 PM

引言

在文章《php 实现类似于pyhon中的Construct库的功能(一) 基本设计思路》介绍了用php解析二进制数据的基本思路

在文章《php 实现类似于pyhon中的Construct库的功能(二)实现适配器功能》说明了如何实现适配器功能。

以上两篇都是对静态数据结构进行解析。接下来要逐步实现动态数据结构的解析。也就是说数据结构的定义与上下文有关,要在数据解析时才能真正确定。

推荐相关PHP视频教程:https://www.php.cn/course/list/29/type/2.html

这一次要实现的是if-else功能。

基本思路

1,修改词法分析规则,使其可以接受if,else关键字

2,修改语法分析规则,使其可以接受if,else语句

3,修改编码器,生成可运行的php目标代码

其中主要的工作内容是修改语法分析规则文件。

实现内容

准备解析的结构体定义文件

struct student
{
  char name[2];
  int num;
  if(num.value==1 ){
  	int age;
  }else{
  	char addr[3];
  } 
  
};
登录后复制

为了聚焦在if-else功能的实现上,这次只定义了一个结构体 student。与以前的静态结构体定义最大的不同,在于如下定义

  if(num.value==1 ){
  	int age;
  }else{
  	char addr[3];
  }
登录后复制

如果解析过程中,num字段的值为1则定义一个age字段,否则定义一个addr字段。

词法规则文件改动不大,增加对if,else关键字的匹配就可以了

		['/^if\b/','_if'		,'i'],
		['/^else\b/','_else'	,'e'],
登录后复制

语法规则文件需改动的地方比较多

首先,增加一个符号移进时的处理函数。在前面介绍的处理函数都是在归约时被调用,但对于更复杂的情形,有必要在移进时也进行处理。

先看一下script_parser.php中的移进处理的基本操作

//移进
	private function shift($token){

		//处理记号栈
		$this->tokenStack= $this->tokenStack.$token[0];
		
		if($this->debugMode){
			echo I('srcline:'),$token[2],I(' shifted :'),$this->tokenStack,"\n";
		}
		
		//处理语法栈,栈中元素为[记号名,记号值,起始位置,结束位置,[附加信息]]
		array_push($this->syntaxStack, [$token[0],$token[1],$this->tokenIndex-1,$this->tokenIndex-1,[]]);

		//调用规则处理中的移进处理函数
		$extra=$this->rulesHandler->handleShift($token[0],$this->syntaxStack,$this->coder);

		//在栈中保存附加信息
		$this->syntaxStack[count($this->syntaxStack)-1][TokenExtraIndex]=$extra;
						
	}
登录后复制

其中放置了一个钩子函数的调用

//调用规则处理中的移进处理函数
		$extra=$this->rulesHandler->handleShift($token[0],$this->syntaxStack,$this->coder);
登录后复制

在语法规则处理的基类中定义了一个空的 handleShift 方法。
我们需要做的就是在语法规则处理类中重载 handleShift 方法。

//处理移进,返回附加信息数组
function handleShift($tokenName,$stack,$coder){

	if($tokenName=='_if'){
		//插入一个空行,空行所在的序号存入附加信息数组,以后可以替换为正确的内容
		return [$coder->pushLine('')];
	}

	if($tokenName=='_else'){
		//插入一个空行,空行所在的序号存入附加信息数组,以后可以替换为正确的内容
		return [$coder->pushLine('')];
	}	
	return [];
}
登录后复制

从以上代码可以看出,在编译过程中,如果发生了if 或 else的移进操作,则在要生成的目标代码中插入一个空白行,并且将这个空白行的地址保存起来,在对if-else语句进行归约时用最终确定的内容替换空白行。

为什么要这么做呢?

因为 if 语句中,if 或else的块语句先完成归约,整个if语句在此之后才完成归约。而目标代码的生成是边归约边生成,所以要先为if 或else抢占一个位置。

下而是if-else的语法规则处理函数

// if          {{{

function _ifStatement_0_ifStatement_else_blockStatement($stack,$coder){	

	//取出_else 记号中保存的空白行所在的地址,替换为正确的内容
	$t1= $this->topItem($stack,2);
	$lineIndex=$t1[TokenExtraIndex][0];

	$content='else{';

	$coder->resetLine($lineIndex,$content);	

	$coder->pushLine('}');	

	return $this->pass($stack,3);
}

function _ifStatement_0_if_wholeExpression_blockStatement($stack,$coder){
	
	//取出_if 记号中保存的空白行所在的地址,替换为正确的内容
	$t1= $this->topItem($stack,3);
	$lineIndex=$t1[TokenExtraIndex][0];

	$t2= $this->topItem($stack,2);
	$condtionExp=$t2[TokenValueIndex];

	$content='if'.$condtionExp.'{';

	$coder->resetLine($lineIndex,$content);	

	$coder->pushLine('}');

	return $this->pass($stack,3);
}

//  if        }}}
登录后复制

着重分析一下if语句的处理,处理函数如下所示

function _ifStatement_0_if_wholeExpression_blockStatement($stack,$coder){
	
	//取出_if 记号中保存的空白行所在的地址,替换为正确的内容
	$t1= $this->topItem($stack,3);
	$lineIndex=$t1[TokenExtraIndex][0];

	$t2= $this->topItem($stack,2);
	$condtionExp=$t2[TokenValueIndex];

	$content='if'.$condtionExp.'{';

	$coder->resetLine($lineIndex,$content);	

	$coder->pushLine('}');

	return $this->pass($stack,3);
}
登录后复制

以下语句

$t1= $this->topItem($stack,3);
登录后复制
登录后复制

的含义是从当前语法栈的栈顶取出元素,第2个参数3 表明是从栈顶计数,取第三个元素。计数时从1开始

_ifStatement_0_if_wholeExpression_blockStatement

所包含的语法规则就是:

当栈顶出现了_if, _wholeExpression, _blockStatement 三个符号是,这三个符号就可以归约为 _ifStatement_0 是一个分隔串,分隔语法规则的左部与右部。

在ados脚本语言中采用了一种设计技巧,就是以产生式(语法规则)做为函数的名称,语法规则与语法规则处理函数合二为一。

这样做的好处是不用分别维护语法规则与语法规则处理函数,不用时刻保持两者的同步。

$t1= $this->topItem($stack,3);
登录后复制
登录后复制

取出的是_if 这个符号在语法栈中对应的内容。前面已经介绍过,在_if 符号移进时,插入了一个空白行,在符加信息数组中保存了这个空白行的地址。这时将其取出来。

$t2= $this->topItem($stack,2);
$condtionExp=$t2[TokenValueIndex];
登录后复制

_wholeExpression 对应的语法栈元素中取出相应的条件表达式,组成一个完整的内容后替换先前的空白行。

请留意,这时if语句块内容已经写入到目标代码中。
接下来补上一个if语句块的结束标记 ‘}’ 就OK了。

接下来实现对 属性运算符 . 的处理,在例子中就是对

num.value
登录后复制

这种形式的表达式的处理

语法规则处理函数如下

function _term_0_term_dot_iden($stack,$coder){  
		
	$t1= $this->topItem($stack,3);
	$obj = $t1[TokenValueIndex];
	$t2= $this->topItem($stack,1);
	$var = $t2[TokenValueIndex];
	$exp = '$'.$obj.'[\''.$var.'\']';

	return [$exp,[]];
}
登录后复制

从例子来看,源代码是 num.value ,最终得到的目标代码是 $num[‘value’]
也就是将类C的源代码变成了php代码

接下来还得实现对 比较运算符 == 的处理:

function _wholeExpression_0_wholeExpression_bieq_expression($stack,$coder){
	
	return $this->biOpertors($stack,3,'==',1,$coder);
}

//二元操作符的通用处理函数
function biOpertors($stack,$op1Index,$op,$op2Index,$coder){

	$t1= $this->topItem($stack,$op1Index);
	$exp1=$t1[TokenValueIndex];

	$t2= $this->topItem($stack,$op2Index);
	$exp2=$t2[TokenValueIndex];

	$s=$exp1.$op.$exp2;
	return [$s,[]];
}
登录后复制

下面是完整的语法规则处理文件的内容

0){
		return intval($extraArray[0]);
	}else{
		return 0;
	}
}
//二元操作符的通用处理函数
function biOpertors($stack,$op1Index,$op,$op2Index,$coder){
	$t1= $this->topItem($stack,$op1Index);
	$exp1=$t1[TokenValueIndex];
	$t2= $this->topItem($stack,$op2Index);
	$exp2=$t2[TokenValueIndex];
	$s=$exp1.$op.$exp2;
	return [$s,[]];
}
//处理移进,返回附加信息数组
function handleShift($tokenName,$stack,$coder){

	if($tokenName=='_if'){
		//插入一个空行,空行所在的序号存入附加信息数组,以后可以替换为正确的内容
		return [$coder->pushLine('')];
	}

	if($tokenName=='_else'){
		//插入一个空行,空行所在的序号存入附加信息数组,以后可以替换为正确的内容
		return [$coder->pushLine('')];
	}	
	return [];
}
//语法规则处理函数名由规则右边部分与规则左边部分拼接而成
//语法规则定义的先后决定了归约时匹配的顺序,要根据实际的语法安排
//如果不熟悉语法,随意调整语法规则的先后次序将有可能导致语法错误
// struct list  {{{
function _structList_0_structList_struct($stack,$coder){
	$coder->pushBlockTail();
	return ['#',[]];
}
function _structList_0_struct($stack,$coder){	
	$coder->pushBlockTail();
	return ['#',[]];
}
// struct list  }}}
// struct   {{{
function _struct_0_structName_blockStatement_semi($stack,$coder){
	$t1= $this->topItem($stack,3);
	$structName = 	$t1[TokenValueIndex];
	$t2= $this->topItem($stack,2);
	$extraArray=$t2[TokenExtraIndex];
	return [$structName,$extraArray];
}
// struct   }}}
// struct name     {{{
function _structName_0_strukey_iden($stack,$coder){  
	$t1= $this->topItem($stack,1);
	$structName = 	$t1[TokenValueIndex];
	$coder->pushBlockHeader($structName);	
	return $this->pass($stack,1);
}
// struct name     }}}
// blockStatement    {{{
function _blockStatement_0_lcb_statementList_rcb($stack,$coder){
	return $this->pass($stack,2);
}
// blockStatement    }}}
// statement list  {{{
function _statementList_0_statementList_statement($stack,$coder){	
	return $this->pass($stack,1);
}
function _statementList_0_statement($stack,$coder){
	//此处0表示statementList是上一级节点,要做特殊处理
	return $this->pass($stack,1);
}
// statement list  }}}
// statement       {{{
function _statement_0_wholeExpression_semi($stack,$coder){
	$t1= $this->topItem($stack,2);
	$elementName = 	$t1[TokenValueIndex];	
	$coder->pushCheckBody($elementName);	
	return $this->pass($stack,2);
}
function _statement_0_ifStatement($stack,$coder){
	return $this->pass($stack,1);
}
// statement        }}}
// if          {{{
function _ifStatement_0_ifStatement_else_blockStatement($stack,$coder){	
	//取出_else 记号中保存的空白行所在的地址,替换为正确的内容
	$t1= $this->topItem($stack,2);
	$lineIndex=$t1[TokenExtraIndex][0];
	$content='else{';
	$coder->resetLine($lineIndex,$content);	
	$coder->pushLine('}');	
	return $this->pass($stack,3);
}
function _ifStatement_0_if_wholeExpression_blockStatement($stack,$coder){
	//取出_if 记号中保存的空白行所在的地址,替换为正确的内容
	$t1= $this->topItem($stack,3);
	$lineIndex=$t1[TokenExtraIndex][0];
	$t2= $this->topItem($stack,2);
	$condtionExp=$t2[TokenValueIndex];
	$content='if'.$condtionExp.'{';
	$coder->resetLine($lineIndex,$content);	
	$coder->pushLine('}');
	return $this->pass($stack,3);
}
//  if        }}}
// function expression {{{
//函数表达式
function _term_0_funcTerm($stack,$coder){  
	$t1= $this->topItem($stack,1);
	$funcName=$t1[TokenValueIndex];
	$paraArray=$t1[TokenExtraIndex]; 
	$paras = implode(",", $paraArray);
	$exp = $funcName.'('.$paras.')';	
	return [$exp,[]];
}
function _funcTerm_0_funcExpLp_rp($stack,$coder){  
	return $this->pass($stack,2);
}
function _funcTerm_0_funcExpLeft_rp($stack,$coder){  
	return $this->pass($stack,2);
}
function _funcExpLeft_0_funcExpLeft_comma_expression($stack,$coder){  		
	$t1= $this->topItem($stack,3);
	$t2= $this->topItem($stack,1);
	//函数的参数列表存放在附加信息中
	$paraArray=$t1[TokenExtraIndex]; 
	array_push($paraArray, $t2[TokenValueIndex]);
	return [$t1[TokenValueIndex],$paraArray];
}
function _funcExpLeft_0_funcExpLp_expression($stack,$coder){  
	$t1= $this->topItem($stack,2);
	$t2= $this->topItem($stack,1);
	//函数的参数列表存放在附加信息中
	$paraArray=$t1[TokenExtraIndex]; 
	array_push($paraArray, $t2[TokenValueIndex]);
	return [$t1[TokenValueIndex],$paraArray];
}
function _funcExpLp_0_iden_lp($stack,$coder){  
	return $this->pass($stack,2);
}
// function expression }}}
// whole Expression  {{{
function _wholeExpression_0_wholeExpression_bieq_expression($stack,$coder){	
	return $this->biOpertors($stack,3,'==',1,$coder);
}
function _wholeExpression_0_expression($stack,$coder){	
	return $this->pass($stack,1);
}
// whole Expression      }}}
//    Expression         {{{
//表达式可以进行管道运算
function _expression_0_expression_pipe_factor($stack,$coder){
	$t1= $this->topItem($stack,1);
	$handlerName = 	$t1[TokenValueIndex];
	$t2= $this->topItem($stack,3);
	$elementName = 	$t2[TokenValueIndex];
	$coder->pushPipeBody($handlerName,$elementName);	
	return $this->pass($stack,3);
}
function _expression_0_double_factor($stack,$coder){	
	$t1= $this->topItem($stack,1);
	$elementName = 	$t1[TokenValueIndex];
	$parseFuncName = 'parseDouble';	
	$coder->pushParseBody($parseFuncName,$elementName);		
	return $this->pass($stack,1);
}
function _expression_0_float_factor($stack,$coder){	
	$t1= $this->topItem($stack,1);
	$elementName = 	$t1[TokenValueIndex];
	$parseFuncName = 'parseFloat';	
	$coder->pushParseBody($parseFuncName,$elementName);		
	return $this->pass($stack,1);
}
function _expression_0_char_factor($stack,$coder){
	$t1= $this->topItem($stack,1);
	$elementName = 	$t1[TokenValueIndex];
	$size = $this->elementSize($t1[TokenExtraIndex]);	
	$parseFuncName = 'parseFixStr';	
	$coder->pushParseBody($parseFuncName,$elementName,$size);		
	return $this->pass($stack,1);
}
function _expression_0_int_factor($stack,$coder){	
	$t1= $this->topItem($stack,1);
	$elementName = 	$t1[TokenValueIndex];
	$parseFuncName = 'parseInt';	
	$coder->pushParseBody($parseFuncName,$elementName,4);		
	return $this->pass($stack,1);
}
function _expression_0_factor($stack,$coder){	
	return $this->pass($stack,1);
}
//   Expression         }}}
// factor       {{{
function _factor_0_term($stack,$coder){
	
	return $this->pass($stack,1);
}

//  factor        }}}

//   term    {{{
function _term_0_lp_wholeExpression_rp($stack,$coder){
	
	$t1= $this->topItem($stack,2);
	$s='('.$t1[TokenValueIndex].')';
	return [$s,[]];
}
function _term_0_term_dot_iden($stack,$coder){  
		
	$t1= $this->topItem($stack,3);
	$obj = $t1[TokenValueIndex];
	$t2= $this->topItem($stack,1);
	$var = $t2[TokenValueIndex];
	$exp = '$'.$obj.'[\''.$var.'\']';

	return [$exp,[]];
}
function _term_0_iden($stack,$coder){
	$t1= $this->topItem($stack,1);
	//未指定数据长度时将长度值设为0 
	$valLen = 	'0';	
	$t2= $this->topItem($stack,2);
	return [$t1[TokenValueIndex],[$valLen]];	
}
function _term_0_num($stack,$coder){
	return $this->pass($stack,1);
}
function _term_0_array($stack,$coder){
	return $this->pass($stack,1);
}
//   term     }}}
// array 	  {{{
function _array_0_arrayLb_num_rb($stack,$coder){
	$t1= $this->topItem($stack,2);
	$valLen = 	$t1[TokenValueIndex];	
	
	$t2= $this->topItem($stack,3);
	//将数据长度放入附加信息 
	return [$t2[TokenValueIndex],[$valLen]];		
}
function _arrayLb_0_iden_lb($stack,$coder){  
	return $this->pass($stack,2);
}
// array 	   }}}
}// end of class
登录后复制

下面是改进过后的编码器的内容

<?php
/*!
 * structwkr编码器,
 *
 * 45022300@qq.com
 * Version 0.9.0
 *
 * Copyright 2019, Zhu Hui
 * Released under the MIT license
 */

namespace Ados;

require_once __SCRIPTCORE__.&#39;coder/base_coder.php&#39;;
require_once __STRUCT_PARSE_TEMP__.&#39;templateReplaceFuncs.php&#39;;


class StructwkrCoder extends BaseCoder{

	public function __construct($engine)
	{
		if($engine){ 
			$this->engine = $engine;
		}else{ 
			exit(&#39;the engine is not valid in StructwkrCoder construct.&#39;);
		}
	}

	//编译得到的最终结果
	public function codeLines(){
		if(count($this->codeLines)<1){
			return &#39;&#39;;
		}
		$script=&#39;&#39;;		
		for ($i=0;$i< count($this->codeLines);$i+=1) {
			$script.=$this->codeLines[$i];
		}	
		return $script;
	}	

	//输出编译后的结果
	public function printCodeLines(){
		echo $this->codeLines();	
	}

	//添加一个块解析函数头
	public function pushLine($content){		
		array_push($this->codeLines, $content);
		$lineIndex=$this->lineIndex;
		$this->lineIndex+=1;
		return $lineIndex;		
	}

	//重置一行的内容
	public function resetLine($lineIndex,$line){

		$this->codeLines[$lineIndex]=$line;
	}

	//添加一个块解析函数头
	public function pushBlockHeader($structName){
		$structName=ucfirst($structName);
		$content = makeBlockHeader($structName);		
		return $this->pushLine($content);		
	}

	//添加一个块解析函数体
	public function pushParseBody($parseFuncName,$filedName=&#39;&#39;,$filedSize=0){
		$content = makeParseBody($parseFuncName,$filedName,$filedSize);
		return $this->pushLine($content);
	}

	//添加一个管道处理
	public function pushPipeBody($handler,$filedName=&#39;&#39;){
		$content = makePipeBody($handler,$filedName);		
		return $this->pushLine($content);
	}

	//添加一个检查结果值的body
	public function pushCheckBody($filedName=&#39;&#39;){
		$content = makeCheckBody($filedName);
		return $this->pushLine($content);
	}

	//添加一个块解析类的tail
	public function pushBlockTail(){
		$content = makeblockTail();
		return $this->pushLine($content);
	}	

}
登录后复制

实现结果

自动生成的测试文件如下

<?php

namespace Ados;

//加载常量定义文件
require_once &#39;const.php&#39;;
require_once __STRUCT_PARSE_TEMP__.&#39;templateBuidinFuncs.php&#39;;
require_once __STRUCT_PARSE_ADAPTER__.&#39;int2str.adapter.php&#39;;
require_once __STRUCT_PARSE_ADAPTER__.&#39;intoffset.adapter.php&#39;;

$context[&#39;pos&#39;]=0;
$context[&#39;data&#39;]="\x41\x43\x01\x00\x00\x00\x02\x00\x00\x00\x41\x42\x43\x41\x42\x01\x00\x00\x00\x41\x42\x43";

$expRes = Student::parse($context);
$context[&#39;pos&#39;]+=$expRes[&#39;size&#39;];
print_r($expRes);

/*
$expRes = Teacher::parse($context);
$context[&#39;pos&#39;]+=$expRes[&#39;size&#39;];
print_r($expRes);
*/



class Student{

	static function parse($context,$size=0){
		$valueArray=[];
		$totalSize = 0;
	
		$name = parseFixStr($context,2);
	
		if($name[&#39;error&#39;]==0){
			$filed = &#39;name&#39;;
			if($filed){
				$valueArray[$filed]=$name[&#39;value&#39;];
			}else{
				$valueArray[]=$name[&#39;value&#39;];
			}		
			$context[&#39;pos&#39;]+=$name[&#39;size&#39;];
			$totalSize+= $name[&#39;size&#39;];
		}else{
			return [&#39;value&#39;=>False,&#39;size&#39;=>0,&#39;error&#39;=>$name[&#39;error&#39;],&#39;msg&#39;=>$name[&#39;msg&#39;]];
		}
	
		$num = parseInt($context,4);
	
		if($num[&#39;error&#39;]==0){
			$filed = &#39;num&#39;;
			if($filed){
				$valueArray[$filed]=$num[&#39;value&#39;];
			}else{
				$valueArray[]=$num[&#39;value&#39;];
			}		
			$context[&#39;pos&#39;]+=$num[&#39;size&#39;];
			$totalSize+= $num[&#39;size&#39;];
		}else{
			return [&#39;value&#39;=>False,&#39;size&#39;=>0,&#39;error&#39;=>$num[&#39;error&#39;],&#39;msg&#39;=>$num[&#39;msg&#39;]];
		}
	if($num[&#39;value&#39;]==1){
		$age = parseInt($context,4);
	
		if($age[&#39;error&#39;]==0){
			$filed = &#39;age&#39;;
			if($filed){
				$valueArray[$filed]=$age[&#39;value&#39;];
			}else{
				$valueArray[]=$age[&#39;value&#39;];
			}		
			$context[&#39;pos&#39;]+=$age[&#39;size&#39;];
			$totalSize+= $age[&#39;size&#39;];
		}else{
			return [&#39;value&#39;=>False,&#39;size&#39;=>0,&#39;error&#39;=>$age[&#39;error&#39;],&#39;msg&#39;=>$age[&#39;msg&#39;]];
		}
	}else{
		$addr = parseFixStr($context,3);
	
		if($addr[&#39;error&#39;]==0){
			$filed = &#39;addr&#39;;
			if($filed){
				$valueArray[$filed]=$addr[&#39;value&#39;];
			}else{
				$valueArray[]=$addr[&#39;value&#39;];
			}		
			$context[&#39;pos&#39;]+=$addr[&#39;size&#39;];
			$totalSize+= $addr[&#39;size&#39;];
		}else{
			return [&#39;value&#39;=>False,&#39;size&#39;=>0,&#39;error&#39;=>$addr[&#39;error&#39;],&#39;msg&#39;=>$addr[&#39;msg&#39;]];
		}
	}
		return [&#39;value&#39;=>$valueArray,&#39;size&#39;=>$totalSize,&#39;error&#39;=>0,&#39;msg&#39;=>&#39;ok&#39;];
	}
}	
登录后复制

运行测试文件的结果

Array
(
    [value] => Array
        (
            [name] => AC
            [num] => 1
            [age] => 2
        )

    [size] => 10
    [error] => 0
    [msg] => ok
)
登录后复制

对比测试数据

$context[&#39;data&#39;]="\x41\x43\x01\x00\x00\x00\x02\x00\x00\x00\x41\x42\x43\x41\x42\x01\x00\x00\x00\x41\x42\x43";
登录后复制

由于字段 num的值为1,所以接下来产生了一个age字段,而并没有产生addr字段。

结论:if-else功能已经实现并通过了验证。

更多相关问题请访问PHP中文网:https://www.php.cn/

以上是php 实现类似于pyhon中的Construct库的功能(三)实现if-else功能的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP 8 JIT(即时)汇编:它如何提高性能。 PHP 8 JIT(即时)汇编:它如何提高性能。 Mar 25, 2025 am 10:37 AM

PHP 8的JIT编译通过将代码经常汇编为机器代码,从而增强了性能,从而使应用程序有益于大量计算并减少执行时间。

OWASP前10 php:描述并减轻常见漏洞。 OWASP前10 php:描述并减轻常见漏洞。 Mar 26, 2025 pm 04:13 PM

本文讨论了OWASP在PHP和缓解策略中的十大漏洞。关键问题包括注射,验证损坏和XSS,并提供用于监视和保护PHP应用程序的推荐工具。

PHP安全文件上传:防止与文件相关的漏洞。 PHP安全文件上传:防止与文件相关的漏洞。 Mar 26, 2025 pm 04:18 PM

本文讨论了确保PHP文件上传的确保,以防止诸如代码注入之类的漏洞。它专注于文件类型验证,安全存储和错误处理以增强应用程序安全性。

PHP身份验证&amp;授权:安全实施。 PHP身份验证&amp;授权:安全实施。 Mar 25, 2025 pm 03:06 PM

本文讨论了在PHP中实施强大的身份验证和授权,以防止未经授权的访问,详细说明最佳实践并推荐安全增强工具。

PHP加密:对称与非对称加密。 PHP加密:对称与非对称加密。 Mar 25, 2025 pm 03:12 PM

本文讨论了PHP中的对称和不对称加密,并比较了它们的适用性,性能和安全差异。对称加密速度更快,适合大量数据,而不对称的键交换则使用。

如何使用PHP从数据库中检索数据? 如何使用PHP从数据库中检索数据? Mar 20, 2025 pm 04:57 PM

文章讨论了使用PHP从数据库中检索数据,涵盖步骤,安全措施,优化技术和解决方案的常见错误。

PHP CSRF保护:如何防止CSRF攻击。 PHP CSRF保护:如何防止CSRF攻击。 Mar 25, 2025 pm 03:05 PM

本文讨论了防止PHP中CSRF攻击的策略,包括使用CSRF代币,同一站点cookie和适当的会话管理。

mysqli_query()和mysqli_fetch_assoc()的目的是什么? mysqli_query()和mysqli_fetch_assoc()的目的是什么? Mar 20, 2025 pm 04:55 PM

本文讨论了MySQLI_QUERY()和MySQLI_Fetch_Assoc()在PHP中的MySQL数据库交互中的功能。它解释了他们的角色,差异,并提供了它们使用的实际例子。主要论点侧重于usin的好处

See all articles