0

0

Golang写了一个帮助调试的代理程序,PHP实现了一个类用于输出调

php中文网

php中文网

发布时间:2016-06-06 19:33:04

|

1206人浏览过

|

来源于php中文网

原创

1.有时,我们想看到对于同一个URL请求多次,输出的调试信息的变化。 2.或者当你调试的脚本需要重定向到其他脚本,然后又重定向回来,你希望能看到这些脚本的调试输出信息。 3.当你的脚本通过CURL请求一个自己设计的API时,你想输出这个API的一些调试信息。 那

1.有时,我们想看到对于同一个URL请求多次,输出的调试信息的变化。
2.或者当你调试的脚本需要重定向到其他脚本,然后又重定向回来,你希望能看到这些脚本的调试输出信息。
3.当你的脚本通过CURL请求一个自己设计的API时,你想输出这个API的一些调试信息。

那么这个代理程序将能够帮到你,但它现在只能简单的输出一些调试信息,它仍需要完善。
详细介绍:https://github.com/yangxikun/proxy-debug/blob/master/README_zh-CN.md
目前仅支持linux,因为使用到了shell的字符颜色功能

源码与演示:源码出处

TURF(开源)权限管理系统
TURF(开源)权限管理系统

TURF(开源)权限定制管理系统(以下简称“TURF系统”),是蓝水工作室推出的一套基于软件边界设计理念研发的具有可定制性的权限管理系统。TURF系统充分考虑了易用性,将配置、设定等操作进行了图形化设计,完全在web界面实现,程序员只需在所要控制的程序中简单调用一个函数,即可实现严格的程序权限管控,管控力度除可达到文件级别外,还可达到代码级别,即可精确控制到

下载
<?php
/**
 * PD
 * ProxyDebug
 *
 * @author    kun <yangrokety@gmail.com>
 * @copyright 2014 kun
 * @license   http://www.php.net/license/3_01.txt  PHP License 3.01
 * @version   1.0
 * @link      https://github.com/yangxikun/tag-parse
 * @since     1.0
 */
/**
* PD
*
* @author    rokety <yangrokety@gmail.com>
* @license   http://www.php.net/license/3_01.txt  PHP License 3.01
* @version   1.0
* @link
* @since     1.0
*/
class PD
{
    protected static $debugItemCount = 0;
    protected static $debugGroupCount = 0;
    protected static $group = array();
    protected static $start;
    protected static $offset = 0;
    protected static $varNameString = null;

    /**
     * getVarName
     * get the variable name
     *
     * @access protected
     * @static
     *
     * @return string
     */
    protected static function getVarName()
    {
        if (self::$varNameString === null) {
            $trace = debug_backtrace();
            $line = file($trace[3]['file']);
            self::$varNameString = $line[$trace[3]['line']-1];
        }

        preg_match(
            '~\$([\w\d_]+)~',
            self::$varNameString,
            $matches,
            PREG_OFFSET_CAPTURE,
            self::$offset
        );

        if (!isset($matches[1])) {
            throw new Exception('Error Params, should use $variable as params', 1);
        }
        self::$offset = $matches[1][1];

        return $matches[1][0];
    }

    /**
     * func
     *
     * @param string $type debug type(info, warn, error)
     * @param mixed  $arg  debug variable
     *
     * @access protected
     * @static
     *
     * @return null
     */
    protected static function func($type, $arg)
    {
        if (self::$start) {
            self::$group[] = array(
                "category"=>$type,
                "type"=>gettype($arg),
                "name"=>self::getVarName(),
                "value"=>$arg
            );
        } else {
            self::$debugItemCount++;
            header(
                'Proxy_debug_item_'.self::$debugItemCount.': '
                .json_encode(
                    ["category"=>$type,
                    "type"=>gettype($arg),
                    "name"=>self::getVarName(),
                    "value"=>$arg]
                )
            );
            header('Proxy_debug_item_count: '.self::$debugItemCount);
        }
    }

    public static function __callStatic($name, $args)
    {
        $func = ['info'=>'I', 'warn'=>'W', 'error'=>'E'];
        if (isset($func[$name])) {
            self::$offset = 0;
            self::$varNameString = null;
            foreach ($args as $key => $arg) {
                self::func($func[$name], $arg);
            }
        } else {
            throw new Exception('Call to undefined method!', 1);
        }
    }

    /**
     * groupStart
     * start record a group
     *
     * @access public
     * @static
     *
     * @return null
     */
    public static function groupStart()
    {
        self::$start = true;
        self::$debugGroupCount++;
    }

    /**
     * groupEnd
     * stop record a group
     *
     * @access public
     * @static
     *
     * @return null
     */
    public static function groupEnd()
    {
        self::$start = false;
        header(
            'Proxy_debug_group_'
            .self::$debugGroupCount
            .': '.json_encode(self::$group)
        );
        header('Proxy_debug_group_count: '.self::$debugGroupCount);
        self::$group = array();
    }
}
//Proxy Debug
//This simple program is for helping developers debug through http header.
//For more detail, see README.md

package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
)

//color config
var color map[string]interface{}

//Parse config file
func readConfig() {
	config, err := os.Open("config.ini")
	if err != nil {
		log.Fatalln(err)
	}

	buf := bufio.NewReader(config)
	line, _ := buf.ReadString('\n')

	var jsonData interface{}
	err = json.Unmarshal([]byte(line), &jsonData)
	if err != nil {
		log.Fatalln(err)
	}
	var ok bool
	color, ok = jsonData.(map[string]interface{})
	if ok == false {
		log.Fatalln("Parse config file error, it must be a json string!")
	}
	for _, c := range color {
		if c.(float64) > 37 || c.(float64) < 30 {
			log.Fatalln("Config error!The valid value is 30-37.")
		}
	}
	item := [5]string{"url", "varName", "varType", "varValue", "group"}
	for _, i := range item {
		_, has := color[i]
		if has == false {
			log.Fatalln("Losing configuration:", i)
		}
	}
}

func main() {
	var port int = 8888

	if len(os.Args) == 1 {
		fmt.Println("Listening in default port:8888")
	} else if os.Args[1] == "--help" {
		fmt.Println("usage: proxy [-p port]")
		return
	} else if len(os.Args) != 3 || os.Args[1] != "-p" {
		log.Fatalln("Error arguments!Just support '-p port'.")
	} else {
		port, err := strconv.Atoi(os.Args[2])
		if err != nil && port > 65535 || port < 1024 {
			log.Fatalln("Error port, it should be 1024-65535, default is 8888.")
		}
	}

	readConfig()

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		r.RequestURI = ""
		resp, err := http.DefaultClient.Do(r)
		if err != nil {
			http.NotFound(w, r)
			return
		}
		defer resp.Body.Close()

		//Get the debugging information form http header
		caterory := map[string]int{"I": 34, "W": 33, "E": 31}
		format := "\t \033[%dm-%s\033[%vm %s\033[%vm%s\033[%vm%s\n"
		debugItem := make(map[string]map[string]interface{})
		debugItemIndex := make([]string, 0, 5)
		var jsonData interface{}

		v, okDebugItem := resp.Header["Proxy_debug_item_count"]
		if okDebugItem {
			count, _ := strconv.Atoi(v[0])
			for i := 1; i <= count; i++ {
				index := "Proxy_debug_item_" + strconv.Itoa(i)
				vv, ok := resp.Header[index]
				if ok {
					err = json.Unmarshal([]byte(vv[0]), &jsonData)
					if err != nil {
						continue
					}
					data, ok := jsonData.(map[string]interface{})
					if ok == false {
						continue
					}
					debugItemIndex = append(debugItemIndex, index)
					debugItem[index] = data
				}
			}
		}

		debugGroup := make(map[string]interface{})
		debugGroupIndex := make([]string, 0, 5)

		v, okDebugGroup := resp.Header["Proxy_debug_group_count"]
		if okDebugGroup {
			count, _ := strconv.Atoi(v[0])
			for i := 1; i <= count; i++ {
				index := "Proxy_debug_group_" + strconv.Itoa(i)
				vv, ok := resp.Header[index]
				if ok {
					err = json.Unmarshal([]byte(vv[0]), &jsonData)
					if err != nil {
						continue
					}
					debugGroup[index] = jsonData
					debugGroupIndex = append(debugGroupIndex, index)
				}
			}
		}

		//response to browser
		for k, v := range resp.Header {
			for _, vv := range v {
				w.Header().Add(k, vv)
			}
		}
		for _, c := range resp.Cookies() {
			w.Header().Add("Set-Cookie", c.Raw)
		}
		w.WriteHeader(resp.StatusCode)
		result, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			http.NotFound(w, r)
			return
		}
		w.Write(result)

		//output debugging information
		if okDebugItem {
			fmt.Printf("\033[%vm%v\n", color["url"], r.URL)

			var maxLenName, maxLenType int = 0, 0
			for _, vm := range debugItem {
				v := vm["name"].(string)
				if len(v) > maxLenName {
					maxLenName = len(v)
				}
				v = vm["type"].(string)
				if len(v) > maxLenType {
					maxLenType = len(v)
				}
			}

			for _, i := range debugItemIndex {
				n := debugItem[i]["name"].(string)
				t := debugItem[i]["type"].(string)
				c := debugItem[i]["category"].(string)
				fmt.Printf(
					format,
					caterory[c],
					c,
					color["varName"],
					n+strings.Repeat(" ", maxLenName-len(n)+1),
					color["varType"],
					t+strings.Repeat(" ", maxLenType-len(t)+1),
					color["varValue"],
					strings.Replace(fmt.Sprint(debugItem[i]["value"]), "map", "", 1))
			}
		}

		if okDebugGroup {
			if okDebugItem == false {
				fmt.Printf("\033[%vm%v\n", color["url"], r.URL)
			}
			maxLenName := make([]int, len(debugGroupIndex))
			maxLenType := make([]int, len(debugGroupIndex))
			k := 0
			for _, vm := range debugGroup {
				for _, vv := range vm.([]interface{}) {
					vk, ok := vv.(map[string]interface{})
					if ok == false {
						continue
					}
					v := vk["name"].(string)
					if len(v) > maxLenName[k] {
						maxLenName[k] = len(v)
					}
					v = vk["type"].(string)
					if len(v) > maxLenType[k] {
						maxLenType[k] = len(v)
					}
				}
				k++
			}

			k = 0
			for _, i := range debugGroupIndex {
				fmt.Printf("\t\033[%vm=Group %v=\n", color["group"], k+1)
				for _, v := range debugGroup[i].([]interface{}) {
					vk, ok := v.(map[string]interface{})
					if ok == false {
						continue
					}
					n := vk["name"].(string)
					t := vk["type"].(string)
					c := vk["category"].(string)
					fmt.Printf(
						format,
						caterory[c],
						c,
						color["varName"],
						n+strings.Repeat(" ", maxLenName[k]-len(n)+1),
						color["varType"],
						t+strings.Repeat(" ", maxLenType[k]-len(t)+1),
						color["varValue"],
						strings.Replace(fmt.Sprint(vk["value"]), "map", "", 1))
				}
				k++
				fmt.Printf("\t\033[%vm=GROUP=\n", color["group"])
			}
		}
	})
	http.ListenAndServe(":"+strconv.Itoa(port), nil)
}
Golang写了一个帮助调试的代理程序,PHP实现了一个类用于输出调
PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

705

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

233

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

117

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

22

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

61

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

30

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

669

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

58

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
golang socket 编程
golang socket 编程

共2课时 | 0.1万人学习

nginx浅谈
nginx浅谈

共15课时 | 0.9万人学习

golang和swoole核心底层分析
golang和swoole核心底层分析

共3课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号