output_add_rewrite_var,output_reset_rewrite_var

解读output_add_rewrite_var函数
本文解析了PHP中output_add_rewrite_var函数的功能,该函数会在相对路径的URL中添加指定的参数,并在表单中增加相应的隐藏字段。同时介绍了output_reset_rewrite_var函数的作用。

今天在项目里面无意发现一个函数output_add_rewrite_var,这个函数很陌生,从来没有使用过,于是查阅了PHP官网的解释


此函数给URL重写机制添加名/值对。 这种名值对将被添加到URL(以GET参数的形式)和表单(以input隐藏域的形式),当透明URL重写用session.use_trans_sid 开启时同样可以添加到session ID。 要注意,绝对URL(http://example.com/..)不能被重写。


完全看不懂他在说些什么,于是看了下example


<?php
output_add_rewrite_var
('var''value');

// some links
echo '<a href="file.php">link</a>
<a href="http://example.com">link2</a>'
;

// a form
echo '<form action="script.php" method="post">
<input type="text" name="var2" />
</form>'
;

print_r(ob_list_handlers());
?>


输出

<a href="file.php?var=value">link</a>
<a href="http://example.com">link2</a>

<form action="script.php" method="post">
<input type="hidden" name="var" value="value" />
<input type="text" name="var2" />
</form>

Array
(
    [0] => URL-Rewriter
)
这个函数无非就是在href属性中添加了?var=value键值对(绝对路径不添加)在form表单里面添加了一个隐藏域而已,官网的解释是在让人无法理解。

而output_reset_rewrite_var函数相对就很好理解了reset故名思议就是重置操作,官网的解释和例子也比较好明白。


import tkinter as tk from tkinter import scrolledtext, ttk, messagebox import os import subprocess import sys import urllib.request import logging from datetime import datetime import tempfile import antlr4 from antlr4 import InputStream, CommonTokenStream, ParseTreeWalker class SimpleCLexer(antlr4.Lexer): def __init__(self, input=None): super().__init__(input) self.tokens = [] self._interp = None def getAllTokens(self): if not self.tokens: self.tokens = self.tokenize(self._input) return self.tokens def tokenize(self, input_str): # 简化的词法分析器实现 tokens = [] pos = 0 line = 1 column = 0 # 定义C语言的关键词和类型 keywords = { 'void', 'int', 'char', 'float', 'double', 'short', 'long', 'signed', 'unsigned', 'struct', 'union', 'enum', 'typedef', 'static', 'extern', 'auto', 'register', 'const', 'volatile', 'return', 'if', 'else', 'switch', 'case', 'default', 'for', 'while', 'do', 'break', 'continue', 'goto', 'sizeof' } types = {'U1', 'U2', 'U4', 'S1', 'S2', 'S4'} while pos < len(input_str): # 跳过空白字符 if input_str[pos] in ' \t': pos += 1 column += 1 continue # 处理换行 if input_str[pos] == '\n': line += 1 column = 0 pos += 1 continue # 处理注释 if input_str.startswith('//', pos): end = input_str.find('\n', pos) if end == -1: end = len(input_str) pos = end continue if input_str.startswith('/*', pos): end = input_str.find('*/', pos) if end == -1: end = len(input_str) else: end += 2 pos = end continue # 处理标识符 if input_str[pos].isalpha() or input_str[pos] == '_': start = pos pos += 1 while pos < len(input_str) and (input_str[pos].isalnum() or input_str[pos] == '_'): pos += 1 token_text = input_str[start:pos] token_type = 'IDENTIFIER' # 检查是否为关键字或类型 if token_text in keywords: token_type = 'KEYWORD' elif token_text in types: token_type = 'TYPE' tokens.append({ 'type': token_type, 'text': token_text, 'line': line, 'column': column }) column += (pos - start) continue # 处理数字 if input_str[pos].isdigit(): start = pos pos += 1 while pos < len(input_str) and (input_str[pos].isdigit() or input_str[pos] in '.xXabcdefABCDEF'): pos += 1 tokens.append({ 'type': 'NUMBER', 'text': input_str[start:pos], 'line': line, 'column': column }) column += (pos - start) continue # 处理字符串 if input_str[pos] == '"': start = pos pos += 1 while pos < len(input_str) and input_str[pos] != '"': if input_str[pos] == '\\' and pos + 1 < len(input_str): pos += 2 else: pos += 1 if pos < len(input_str) and input_str[pos] == '"': pos += 1 tokens.append({ 'type': 'STRING', 'text': input_str[start:pos], 'line': line, 'column': column }) column += (pos - start) continue # 处理字符 if input_str[pos] == "'": start = pos pos += 1 while pos < len(input_str) and input_str[pos] != "'": if input_str[pos] == '\\' and pos + 1 < len(input_str): pos += 2 else: pos += 1 if pos < len(input_str) and input_str[pos] == "'": pos += 1 tokens.append({ 'type': 'CHAR', 'text': input_str[start:pos], 'line': line, 'column': column }) column += (pos - start) continue # 处理运算符和标点符号 operators = { '(', ')', '{', '}', '[', ']', ';', ',', '.', '->', '++', '--', '&', '*', '+', '-', '~', '!', '/', '%', '<<', '>>', '<', '>', '<=', '>=', '==', '!=', '^', '|', '&&', '||', '?', ':', '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '&=', '^=', '|=', ',' } # 尝试匹配最长的运算符 matched = False for op_len in range(3, 0, -1): if pos + op_len <= len(input_str) and input_str[pos:pos+op_len] in operators: tokens.append({ 'type': 'OPERATOR', 'text': input_str[pos:pos+op_len], 'line': line, 'column': column }) pos += op_len column += op_len matched = True break if matched: continue # 无法识别的字符 tokens.append({ 'type': 'UNKNOWN', 'text': input_str[pos], 'line': line, 'column': column }) pos += 1 column += 1 return tokens class FunctionAnalyzer: def __init__(self): self.function_name = "" self.parameters = set() self.local_vars = [] self.global_vars = [] self.function_calls = [] self.current_function = None self.in_function = False self.in_global_scope = True self.variable_declarations = {} self.control_structures = {"if", "for", "while", "switch", "return", "else"} self.current_line = 0 self.macro_definitions = set() self.parameter_lines = {} self.type_aliases = {"U1", "U2", "U4", "S1", "S2", "S4"} self.in_function_body = False self.brace_depth = 0 self.recorded_globals = set() def analyze(self, tokens): self.tokens = tokens self.pos = 0 self.current_line = 0 # 第一步:识别宏定义(全大写标识符) self._identify_macros() # 第二步:分析函数体 while self.pos < len(self.tokens): token = self.tokens[self.pos] self.current_line = token['line'] # 检测函数定义 if token['text'] in {'void', 'int', 'char', 'float', 'double', 'U1', 'U2', 'U4', 'S1', 'S2', 'S4', 'static'}: if self._is_function_definition(): self._handle_function_definition() continue # 在函数体内检测变量声明 if self.in_function_body: if token['text'] in {'U1', 'U2', 'U4', 'S1', 'S2', 'S4', 'int', 'char', 'float', 'double'}: self._handle_variable_declaration() continue # 检测函数调用 if token['type'] == 'IDENTIFIER' and self.pos + 1 < len(self.tokens): next_token = self.tokens[self.pos + 1] if next_token['text'] == '(': self._handle_function_call() continue # 检测变量使用 if token['type'] == 'IDENTIFIER': self._handle_identifier_use(token) # 跟踪大括号深度 if token['text'] == '{': self.brace_depth += 1 if self.in_function and self.brace_depth == 1: self.in_function_body = True elif token['text'] == '}': self.brace_depth -= 1 if self.brace_depth == 0 and self.in_function: self.in_function = False self.in_function_body = False self.pos += 1 return self def _identify_macros(self): """识别宏定义(全大写标识符)""" for token in self.tokens: if token['type'] == 'IDENTIFIER' and token['text'].isupper(): self.macro_definitions.add(token['text']) def _is_function_definition(self): # 检查是否是函数定义 pos = self.pos depth = 0 found_name = False # 跳过可能的static修饰符 if self.tokens[pos]['text'] == 'static': pos += 1 # 检查返回类型 if self.tokens[pos]['text'] not in {'void', 'int', 'char', 'float', 'double', 'U1', 'U2', 'U4', 'S1', 'S2', 'S4'}: return False pos += 1 # 检查函数名 if pos < len(self.tokens) and self.tokens[pos]['type'] == 'IDENTIFIER': found_name = True pos += 1 else: return False # 检查左括号 if pos < len(self.tokens) and self.tokens[pos]['text'] == '(': depth = 1 pos += 1 else: return False # 检查参数列表和右括号 while pos < len(self.tokens) and depth > 0: token = self.tokens[pos] if token['text'] == '(': depth += 1 elif token['text'] == ')': depth -= 1 if depth == 0: # 检查后面是否是 { if pos + 1 < len(self.tokens) and self.tokens[pos + 1]['text'] == '{': return True return False pos += 1 return False def _handle_function_definition(self): # 跳过可能的static修饰符 if self.tokens[self.pos]['text'] == 'static': self.pos += 1 # 提取返回类型 return_type = self.tokens[self.pos]['text'] self.pos += 1 # 获取函数名 if self.pos < len(self.tokens) and self.tokens[self.pos]['type'] == 'IDENTIFIER': func_name = self.tokens[self.pos]['text'] self.pos += 1 # 跳过左括号 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '(': self.pos += 1 depth = 1 current_param = [] params = [] # 提取参数 while self.pos < len(self.tokens) and depth > 0: token = self.tokens[self.pos] if token['text'] == '(': depth += 1 elif token['text'] == ')': depth -= 1 if depth == 0: break elif token['text'] == ',' and depth == 1: # 参数结束 if current_param: # 提取参数名(最后一个标识符) param_name = None for t in reversed(current_param): if t['type'] == 'IDENTIFIER': param_name = t['text'] break if param_name: params.append(param_name) self.parameter_lines[param_name] = token['line'] current_param = [] self.pos += 1 continue current_param.append(token) self.pos += 1 # 处理最后一个参数 if current_param: param_name = None for t in reversed(current_param): if t['type'] == 'IDENTIFIER': param_name = t['text'] break if param_name: params.append(param_name) self.parameter_lines[param_name] = token['line'] # 记录参数 self.parameters = set(params) # 将参数视为已声明的变量 for param in params: self.variable_declarations[param] = True # 进入函数体 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '{': self.in_function = True self.in_function_body = False # 将在遇到第一个{时设置为True self.brace_depth = 0 self.current_function = func_name self.function_name = func_name self.pos += 1 def _handle_variable_declaration(self): # 提取类型 var_type = self.tokens[self.pos]['text'] self.pos += 1 # 获取变量名 var_names = [] while self.pos < len(self.tokens): token = self.tokens[self.pos] # 标识符 - 变量名 if token['type'] == 'IDENTIFIER': var_names.append(token['text']) self.pos += 1 # 逗号 - 多个变量声明 elif token['text'] == ',': self.pos += 1 continue # 结束声明 elif token['text'] == ';': self.pos += 1 break # 赋值 - 跳过赋值表达式 elif token['text'] == '=': self.pos += 1 # 跳过整个赋值表达式 depth = 0 while self.pos < len(self.tokens): t = self.tokens[self.pos] if t['text'] in {'(', '['}: depth += 1 elif t['text'] in {')', ']'}: depth -= 1 elif t['text'] in {',', ';'} and depth == 0: break self.pos += 1 # 数组声明 - 跳过数组大小 elif token['text'] == '[': self.pos += 1 depth = 1 while self.pos < len(self.tokens) and depth > 0: t = self.tokens[self.pos] if t['text'] == '[': depth += 1 elif t['text'] == ']': depth -= 1 self.pos += 1 else: self.pos += 1 # 添加到局部变量 for var_name in var_names: self.local_vars.append({ 'type': var_type, 'name': var_name, 'line': self.current_line }) self.variable_declarations[var_name] = True def _handle_function_call(self): # 提取函数名 func_name = self.tokens[self.pos]['text'] line = self.current_line self.pos += 2 # 跳过函数名和 '(' # 提取参数 params = [] depth = 1 current_param = [] while self.pos < len(self.tokens) and depth > 0: token = self.tokens[self.pos] if token['text'] == '(': depth += 1 elif token['text'] == ')': depth -= 1 if depth == 0: break elif token['text'] == ',' and depth == 1: params.append(''.join([t['text'] for t in current_param]).strip()) current_param = [] self.pos += 1 continue current_param.append(token) self.pos += 1 if current_param: params.append(''.join([t['text'] for t in current_param]).strip()) # 跳过 ')' 如果还在范围内 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == ')': self.pos += 1 # 确定返回类型 return_type = "unknown" if func_name.startswith("vd_"): return_type = "void" elif func_name.startswith(("u1_", "u2_", "u4_", "s1_", "s2_", "s4_")): prefix = func_name.split("_")[0] return_type = prefix.upper() # 添加到函数调用列表 self.function_calls.append({ 'name': func_name, 'return_type': return_type, 'type': "function", 'params': ", ".join(params), 'line': line }) def _handle_identifier_use(self, token): var_name = token['text'] line = token['line'] # 跳过宏定义(全大写) if var_name in self.macro_definitions: return # 跳过已声明的变量(局部变量) if var_name in self.variable_declarations: return # 跳过参数 if var_name in self.parameters: return # 跳过函数调用(函数名已经在函数调用处理中记录) for call in self.function_calls: if call['name'] == var_name: return # 跳过控制结构 if var_name in self.control_structures: return # 跳过类型别名 if var_name in self.type_aliases: return # 跳过已经记录过的全局变量 if var_name in self.recorded_globals: return # 添加到全局变量 self.global_vars.append({ 'name': var_name, 'line': line }) self.recorded_globals.add(var_name) class FunctionParserApp: def __init__(self, root): self.root = root self.root.title("C语言函数解析器 (内置解析器版)") self.root.geometry("900x700") self.setup_logging() # 创建输入区域 input_frame = tk.LabelFrame(root, text="输入C语言函数体", padx=5, pady=5) input_frame.pack(fill="both", expand=True, padx=10, pady=5) self.input_text = scrolledtext.ScrolledText(input_frame, width=100, height=20) self.input_text.pack(fill="both", expand=True, padx=5, pady=5) # 按钮区域 btn_frame = tk.Frame(root) btn_frame.pack(fill="x", padx=10, pady=5) # 解析按钮 parse_btn = tk.Button(btn_frame, text="解析函数", command=self.parse_function, bg="#4CAF50", fg="white") parse_btn.pack(side="left", padx=5) # 保存日志按钮 save_log_btn = tk.Button(btn_frame, text="保存日志", command=self.save_logs) save_log_btn.pack(side="right", padx=5) # 进度条 self.progress = ttk.Progressbar(btn_frame, orient="horizontal", length=300, mode="determinate") self.progress.pack(side="left", padx=10, fill="x", expand=True) # 创建输出区域 output_frame = tk.LabelFrame(root, text="解析结果", padx=5, pady=5) output_frame.pack(fill="both", expand=True, padx=10, pady=5) self.output_text = scrolledtext.ScrolledText(output_frame, width=100, height=15) self.output_text.pack(fill="both", expand=True, padx=5, pady=5) self.output_text.config(state=tk.DISABLED) # 日志区域 log_frame = tk.LabelFrame(root, text="日志信息", padx=5, pady=5) log_frame.pack(fill="both", expand=True, padx=10, pady=5) self.log_text = scrolledtext.ScrolledText(log_frame, width=100, height=8) self.log_text.pack(fill="both", expand=True, padx=5, pady=5) self.log_text.config(state=tk.DISABLED) # 添加示例按钮 example_btn = tk.Button(btn_frame, text="加载示例", command=self.load_example) example_btn.pack(side="right", padx=5) # 示例函数体 self.example_code = """static void Diag21_PID_C9(U1 u1_a_num) { U1 u1_t_cmplt; U1 u1_t_cnt; if((U1)DIAG_CNT_ZERO == u1_t_swrstcnt) /* Determine if a software reset is in progress */ { for(u1_t_cnt = (U1)DIAG21_ZERO; u1_t_cnt < (U1)DIAG21_PIDC9_FLAG; u1_t_cnt ++) { u1_t_cmplt = u1_g_InspSoftwareVersion(u4_g_cmd, &u4_g_data, (U1)TRUE); } vd_s_Diag21_U2ToU1(u2_g_buf, u1_g_data, (U1)DIAG21_PIDC9_FLAG); } else { /* Do Nothing */ } }""" def setup_logging(self): """配置日志系统""" self.log_filename = f"parser_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log" logging.basicConfig( filename=self.log_filename, level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) logging.info("应用程序启动") def log_to_gui(self, message, level="info"): """将日志信息显示在GUI中""" self.log_text.config(state=tk.NORMAL) timestamp = datetime.now().strftime("%H:%M:%S") self.log_text.insert(tk.END, f"[{timestamp}] {message}\n") self.log_text.see(tk.END) self.log_text.config(state=tk.DISABLED) if level == "info": logging.info(message) elif level == "warning": logging.warning(message) elif level == "error": logging.error(message) def save_logs(self): """保存日志到文件""" try: log_content = self.log_text.get("1.0", tk.END) filename = f"saved_log_{datetime.now().strftime('%H%M%S')}.txt" with open(filename, "w") as f: f.write(log_content) self.log_to_gui(f"日志已保存到: {filename}", "info") messagebox.showinfo("保存成功", f"日志已保存到:\n{filename}") except Exception as e: self.log_to_gui(f"保存日志失败: {str(e)}", "error") messagebox.showerror("保存失败", f"无法保存日志:\n{str(e)}") def update_progress(self, value): """更新进度条""" self.progress['value'] = value self.root.update_idletasks() def load_example(self): """加载示例函数体""" self.input_text.delete(1.0, tk.END) self.input_text.insert(tk.END, self.example_code) self.log_to_gui("已加载示例函数体") def parse_function(self): """使用内置解析器解析C语言函数体""" try: code = self.input_text.get(1.0, tk.END) if not code.strip(): self.log_to_gui("错误: 没有输入函数体", "error") messagebox.showerror("错误", "请输入要解析的C语言函数体") return self.log_to_gui("开始解析函数体...") self.output_text.config(state=tk.NORMAL) self.output_text.delete(1.0, tk.END) self.update_progress(0) # 使用内置词法分析器 self.log_to_gui("执行词法分析...") lexer = SimpleCLexer() tokens = lexer.tokenize(code) self.update_progress(30) # 使用内置语法分析器 self.log_to_gui("执行语法分析...") analyzer = FunctionAnalyzer() analyzer.analyze(tokens) self.update_progress(70) # 显示结果 self.log_to_gui("生成解析报告...") self.display_results( analyzer.local_vars, analyzer.global_vars, analyzer.function_calls, analyzer.function_name, analyzer.parameters ) self.update_progress(100) self.output_text.config(state=tk.DISABLED) self.log_to_gui("解析完成!") messagebox.showinfo("完成", "函数体解析成功完成!") except Exception as e: self.log_to_gui(f"解析错误: {str(e)}", "error") messagebox.showerror("解析错误", f"发生错误:\n{str(e)}") self.update_progress(0) def display_results(self, local_vars, global_vars, function_calls, func_name, func_params): """显示解析结果""" # 显示函数签名 if func_name: self.output_text.insert(tk.END, "=== 函数签名 ===\n") self.output_text.insert(tk.END, f"函数名: {func_name}\n") self.output_text.insert(tk.END, f"参数: {', '.join(func_params)}\n\n") else: self.output_text.insert(tk.END, "=== 函数签名 ===\n") self.output_text.insert(tk.END, "警告: 无法识别函数签名\n\n") self.log_to_gui("无法识别函数签名", "warning") # 显示局部变量 if local_vars: self.output_text.insert(tk.END, "=== 局部变量 ===\n") for var in local_vars: self.output_text.insert(tk.END, f"{var['type']} {var['name']} (行号: {var['line']})\n") self.log_to_gui(f"找到局部变量: {var['type']} {var['name']}") self.output_text.insert(tk.END, "\n") else: self.output_text.insert(tk.END, "未找到局部变量\n\n") self.log_to_gui("未找到局部变量", "warning") # 显示使用的全局变量 if global_vars: self.output_text.insert(tk.END, "=== 使用的全局变量 ===\n") for var in global_vars: self.output_text.insert(tk.END, f"{var['name']} (行号: {var['line']})\n") self.log_to_gui(f"找到全局变量: {var['name']}") self.output_text.insert(tk.END, "\n") else: self.output_text.insert(tk.END, "未使用全局变量\n\n") self.log_to_gui("未使用全局变量", "warning") # 显示函数调用 if function_calls: self.output_text.insert(tk.END, "=== 函数调用 ===\n") for func in function_calls: self.output_text.insert(tk.END, f"函数名: {func['name']} (行号: {func['line']})\n") self.output_text.insert(tk.END, f"返回类型: {func['return_type']}\n") self.output_text.insert(tk.END, f"函数类型: {func['type']}\n") self.output_text.insert(tk.END, f"参数: {func['params']}\n") self.output_text.insert(tk.END, "-" * 50 + "\n") self.log_to_gui(f"找到函数调用: {func['name']}") else: self.output_text.insert(tk.END, "未调用任何函数\n\n") self.log_to_gui("未调用任何函数", "warning") # 显示统计信息 self.output_text.insert(tk.END, "=== 解析统计 ===\n") self.output_text.insert(tk.END, f"局部变量数量: {len(local_vars)}\n") self.output_text.insert(tk.END, f"使用的全局变量数量: {len(global_vars)}\n") self.output_text.insert(tk.END, f"函数调用数量: {len(function_calls)}\n") self.output_text.insert(tk.END, "\n") if __name__ == "__main__": root = tk.Tk() app = FunctionParserApp(root) root.mainloop() === 函数签名 === 警告: 无法识别函数签名 未找到局部变量 === 使用的全局变量 === u1_t_cmplt (行号: 4) u1_t_cnt (行号: 5) u1_t_swrstcnt (行号: 7) === 函数调用 === 函数名: u1_g_InspSoftwareVersion (行号: 11) 返回类型: U1 函数类型: function 参数: u4_g_cmd, &u4_g_data, (U1)TRUE 函数名: vd_s_Diag21_U2ToU1 (行号: 13) 返回类型: void 函数类型: function 参数: u2_g_buf, u1_g_data, (U1)DIAG21_PIDC9_FLAG === 解析统计 === 局部变量数量: 0 使用的全局变量数量: 3 函数调用数量: 2 请修改上述问题,并且将每一步的解析结果都记录到日志,我会将记录的日志发给你,你找到原因并修改
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值