


PHP implementiert Funktionen ähnlich der Construct-Bibliothek in Python (2) Implementierung der Adapterfunktion
Einführung
Im vorherigen Artikel „PHP implementiert Funktionen ähnlich der Construct-Bibliothek in Python (2) Implementieren von Adapterfunktionen“ wurde die Verwendung von PHP zum Parsen von Binärdaten vorgestellt Grundgedanke. Als nächstes sind zwei Aufgaben zu erledigen.
1. Im vorherigen Artikel wurde die Analysefunktion verwendet, aber jetzt wurde sie in eine Analyseklasse geändert und die Analysemethode ist in der Klasse enthalten.
2. Fügen Sie beim Definieren der Strukturdatenelemente die Adapterfunktion hinzu und verwenden Sie den Pipe-Operator |, um die Datenelemente und den Adapter zu verbinden, um die Datentransformation zu realisieren.
Empfohlenes PHP-Video-Tutorial: https://www.php.cn/course/list/29/type/2.html
Grundlegende Ideen
1, ändern Sie die lexikalischen Analyseregeln, damit sie Pipe-Operatoren akzeptieren können|
2, ändern Sie die Syntaxanalyseregeln, damit sie Adapteraufrufe akzeptieren können
3. Verwenden Sie die PHP-Sprache, um die Adapterfunktion zu implementieren
Implementierungsinhalt
Zu analysierende Strukturdefinitionsdatei
struct student { char name[2]; int num|IntOffset(100); int age; char addr[3]; }; struct teacher { char name[2]; int num|Int2str; char addr[3]; };
Der größte Unterschied zur Strukturdefinition im vorherigen Artikel besteht darin, dass die folgenden zwei Sätze
int num|IntOffset(100); int num|Int2str; };
zwei Adapter über Pipelines aufrufen IntOffset(100)
einen Offset um 100 basierend auf dem Originalwert bedeuten und Int2str das Original konvertieren ganzzahliger Wert in eine Zeichenfolge
Werfen wir einen Blick auf die spezifische Implementierung dieser beiden Adapter
<?php //将整数值偏移一个定值 namespace Ados; class IntOffset { public function __construct($offset) { $this->offset = $offset; } function parse($obj){ if(is_array($obj)){ return array_map(function($value) { return $value + $this->offset; },$obj); } return $obj+ $this->offset; } function build($obj){ throw new \Exception("Int2str build method not implements"); } } class Int2str { function parse($obj){ if(is_array($obj)){ return array_map(function($value) { return ''.$value; },$obj); } return ''.$obj; } function build($obj){ throw new \Exception("Int2str build method not implements"); } }
Um sich auf das Parsen von Binärdaten zu konzentrieren, wird nur die Methode parse
implementiert. aber die Methode build
ist noch nicht implementiert.
Dementsprechend sollte auch die Vorlagendatei angepasst werden
<?php //用于进行替换的模板文本 /*blockHeader{{*/ class structName{ static function parse($context,$size=0){ $valueArray=[]; $totalSize = 0; /*blockHeader}}*/ /*parseBody{{*/ $expRes = parseByte($context,$filedSize); /*parseBody}}*/ /*pipeBody{{*/ $expRes['value'] = (new Adapter())->parse($expRes['value']); /*pipeBody}}*/ /*checkBody{{*/ if($expRes['error']==0){ $filed = '$filedName'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } /*checkBody}}*/ /*blockTail{{*/ return ['value'=>$valueArray,'size'=>$totalSize,'error'=>0,'msg'=>'ok']; } } /*blockTail}}*/
Die lexikalische Regeldatei hat sich nicht viel geändert, fügen Sie einfach die Übereinstimmung der Pipeline-Operatoren hinzu
['/^\|/','_pipe' ,'|'],
Grammatikregeldatei Die Änderungen sind relativ groß, da es notwendig ist, diese Art von Aussage analysieren zu können
int num|IntOffset(100);
Der Inhalt der geänderten Grammatikregeldatei ist wie folgt:
<?php /*! * structwkr的语法规则处理器 * 45022300@qq.com * Version 0.9.0 * * Copyright 2019, Zhu Hui * Released under the MIT license */ namespace Ados; require_once 'const.php'; require_once __SCRIPTCORE__.'syntax_rule/base_rules_handler.php'; class StructwkrRulesHandler extends BaseRulesHandler{ //语法分析的起始记号,归约到最后得到就是若干个结构体定义的列表 function startToken(){ return '_structList'; } //求出放在附加信息中的数组长度 function elementSize($extraArray){ if(count($extraArray)>0){ return intval($extraArray[0]); }else{ return 0; } } //语法规则处理函数名由规则右边部分与规则左边部分拼接而成 //语法规则定义的先后决定了归约时匹配的顺序,要根据实际的语法安排 //如果不熟悉语法,随意调整语法规则的先后次序将有可能导致语法错误 // 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_expression_semi($stack,$coder){ $t1= $this->topItem($stack,2); $elementName = $t1[TokenValueIndex]; $coder->pushCheckBody($elementName); return $this->pass($stack,2); } // statement }}} // 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 }}} // Expression {{{ //表达式可以进行管道运算 function _expression_0_expression_pipe_factor($stack,$coder){ $t1= $this->topItem($stack,1); $handlerName = $t1[TokenValueIndex]; $coder->pushPipeBody($handlerName); 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_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
Der Encoder muss ebenfalls angepasst werden entsprechend wird der Pipeline-Vorgang hinzugefügt
<?php /*! * structwkr编码器, * * 45022300@qq.com * Version 0.9.0 * * Copyright 2019, Zhu Hui * Released under the MIT license */ namespace Ados; require_once __SCRIPTCORE__.'coder/base_coder.php'; require_once __STRUCT_PARSE_TEMP__.'templateReplaceFuncs.php'; class StructwkrCoder extends BaseCoder{ public function __construct($engine) { if($engine){ $this->engine = $engine; }else{ exit('the engine is not valid in StructwkrCoder construct.'); } } //编译得到的最终结果 public function codeLines(){ if(count($this->codeLines)<1){ return ''; } $script=''; for ($i=0;$i< count($this->codeLines);$i+=1) { $script.=$this->codeLines[$i]; } return $script; } //输出编译后的结果 public function printCodeLines(){ echo $this->codeLines(); } //添加一个块解析函数头 public function pushBlockHeader($structName){ $structName=ucfirst($structName); $content = makeBlockHeader($structName); array_push($this->codeLines, $content); $lineIndex=$this->lineIndex; $this->lineIndex+=1; return $lineIndex; } //添加一个块解析函数体 public function pushParseBody($parseFuncName,$filedName='',$filedSize=0){ $content = makeParseBody($parseFuncName,$filedName,$filedSize); array_push($this->codeLines, $content); $lineIndex=$this->lineIndex; $this->lineIndex+=1; return $lineIndex; } //添加一个管道处理 public function pushPipeBody($handler){ $content = makePipeBody($handler); array_push($this->codeLines, $content); $lineIndex=$this->lineIndex; $this->lineIndex+=1; return $lineIndex; } //添加一个检查结果值的body public function pushCheckBody($filedName=''){ $content = makeCheckBody($filedName); array_push($this->codeLines, $content); $lineIndex=$this->lineIndex; $this->lineIndex+=1; return $lineIndex; } //添加一个块解析类的tail public function pushBlockTail(){ $content = makeblockTail(); array_push($this->codeLines, $content); $lineIndex=$this->lineIndex; $this->lineIndex+=1; return $lineIndex; } }
Ergebnisse erzielen
Die automatisch generierte Testdatei lautet wie folgt
<?php namespace Ados; //加载常量定义文件 require_once 'const.php'; require_once __STRUCT_PARSE_TEMP__.'templateBuidinFuncs.php'; require_once __STRUCT_PARSE_ADAPTER__.'int2str.adapter.php'; require_once __STRUCT_PARSE_ADAPTER__.'intoffset.adapter.php'; $context['pos']=0; $context['data']="\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['pos']+=$expRes['size']; print_r($expRes); $expRes = Teacher::parse($context); $context['pos']+=$expRes['size']; print_r($expRes); class Student{ static function parse($context,$size=0){ $valueArray=[]; $totalSize = 0; $expRes = parseFixStr($context,2); if($expRes['error']==0){ $filed = 'name'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } $expRes = parseInt($context,4); $expRes['value'] = (new IntOffset(100))->parse($expRes['value']); if($expRes['error']==0){ $filed = 'num'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } $expRes = parseInt($context,4); if($expRes['error']==0){ $filed = 'age'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } $expRes = parseFixStr($context,3); if($expRes['error']==0){ $filed = 'addr'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } return ['value'=>$valueArray,'size'=>$totalSize,'error'=>0,'msg'=>'ok']; } } class Teacher{ static function parse($context,$size=0){ $valueArray=[]; $totalSize = 0; $expRes = parseFixStr($context,2); if($expRes['error']==0){ $filed = 'name'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } $expRes = parseInt($context,4); $expRes['value'] = (new Int2str)->parse($expRes['value']); if($expRes['error']==0){ $filed = 'num'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } $expRes = parseFixStr($context,3); if($expRes['error']==0){ $filed = 'addr'; if($filed){ $valueArray[$filed]=$expRes['value']; }else{ $valueArray[]=$expRes['value']; } $context['pos']+=$expRes['size']; $totalSize+= $expRes['size']; }else{ return ['value'=>False,'size'=>0,'error'=>$expRes['error'],'msg'=>$expRes['msg']]; } return ['value'=>$valueArray,'size'=>$totalSize,'error'=>0,'msg'=>'ok']; } }
Die Ergebnisse der Ausführung die Testdatei
Array ( [value] => Array ( [name] => AC [num] => 101 [age] => 2 [addr] => ABC ) [size] => 13 [error] => 0 [msg] => ok ) Array ( [value] => Array ( [name] => AB [num] => 1 [addr] => ABC ) [size] => 9 [error] => 0 [msg] => ok )
Vergleichen Sie die Testdaten
$context['data']="\x41\x43\x01\x00\x00\x00\x02\x00\x00\x00\x41\x42\x43\x41\x42\x01\x00\x00\x00\x41\x42\x43";
Wenn kein Adapter hinzugefügt wird
Das Ergebnis des Num-Felds der ersten Struktur sollte sein:[num] => 1
Jetzt wird der Adapter hinzugefügtint num|IntOffset(100);
Das Ergebnis wird also:
[num] => 101
Die Adapterfunktion wurde implementiert und verifiziert.
Für weitere verwandte Fragen besuchen Sie bitte die entsprechenden Video-Tutorials auf der chinesischen PHP-Website: https://www.php.cn/
Das obige ist der detaillierte Inhalt vonPHP implementiert Funktionen ähnlich der Construct-Bibliothek in Python (2) Implementierung der Adapterfunktion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Die JIT -Kompilierung von PHP 8 verbessert die Leistung, indem häufig ausgeführte Code in den Maschinencode zusammengestellt wird, um Anwendungen mit schweren Berechnungen zugute und die Ausführungszeiten zu reduzieren.

In dem Artikel werden OWASP Top 10 Schwachstellen in PHP- und Minderungsstrategien erörtert. Zu den wichtigsten Problemen gehören die Injektion, die kaputte Authentifizierung und XSS mit empfohlenen Tools zur Überwachung und Sicherung von PHP -Anwendungen.

In dem Artikel wird das Sicherung von PHP -Dateien -Uploads erläutert, um Schwachstellen wie die Code -Injektion zu verhindern. Es konzentriert sich auf die Dateitypvalidierung, den sicheren Speicher und die Fehlerbehandlung, um die Anwendungssicherheit zu verbessern.

In dem Artikel wird die Implementierung einer robusten Authentifizierung und Autorisierung in PHP erörtert, um den nicht autorisierten Zugriff zu verhindern, Best Practices zu beschreiben und sicherheitsrelevante Tools zu empfehlen.

In dem Artikel wird die symmetrische und asymmetrische Verschlüsselung in PHP erörtert und ihre Eignung, Leistung und Sicherheitsunterschiede verglichen. Die symmetrische Verschlüsselung ist schneller und für Massendaten geeignet, während asymmetrisch für den sicheren Schlüsselaustausch verwendet wird.

In Artikel wird das Abrufen von Daten aus Datenbanken mithilfe von PHP, die Schritte, Sicherheitsmaßnahmen, Optimierungstechniken und gemeinsame Fehler bei Lösungen erfasst.

In dem Artikel werden Strategien erörtert, um CSRF-Angriffe in PHP zu verhindern, einschließlich der Verwendung von CSRF-Token, selben Cookies und ordnungsgemäßem Sitzungsmanagement.

In dem Artikel werden die Funktionen von MySQLI_Query () und MySQLI_Fetch_assoc () in PHP für MySQL -Datenbankinteraktionen erörtert. Es erklärt ihre Rollen, Unterschiede und liefert ein praktisches Beispiel für ihre Verwendung. Das Hauptargument konzentriert sich auf die Vorteile von usin
