PHP API文档管理系统

https://github.com/ares333/php-doc-system.git

关于

项目已经大量用在生产环境。

API文档编写是非常重要的一项工作,但是编写维护非常麻烦,本项目解决的问题是以最轻松的方式维护n个接口,每个接口n个版本, 尤其适合大量接口的使用情境。

原理是解析固定格式的txt文件实时全自动生成文档,txt文件大量使用继承、递归、前缀、替换等等。

需求

PHP: >=5.3

ext-yaf: >=2.3.3

安装

composer create-project ares333/api-doc
  1. php ini: yaf.use_namespace = 1
  2. 绑定public目录为web服务器的入口
  3. Enjoy!

特性

  1. 无需数据库,可以用svn记录版本。
  2. 编写非常简便,所有枯燥的工作全部由机器完成。
  3. 支持非常多的自定义语法。
  4. 以非常便捷的方式实现继承、加前缀、后缀等各种高级功能。

Demo

http://demo-apidoc.phpdr.net
用户名:admin
密码:admin

联系我们

QQ群:424844502

PHP RSA加密解密

Android或IOS需要的公鈅格式可能需要转换。

<?php
class Rsa {
	private $private;
	private $public;
	function __construct($private, $public = null) {
		$this->private = $private;
		$this->public = $public;
	}
	private function getPrivateKey() {
		return openssl_pkey_get_private ( $this->private );
	}
	private function getPublicKey() {
		return openssl_pkey_get_public ( $this->public );
	}
	function publicEncrypt($data) {
		if (! is_string ( $data )) {
			user_error ( 'data must be string', E_USER_WARNING );
			return;
		}
		return openssl_public_encrypt ( $data, $encrypted, $this->getPublicKey () ) ? base64_encode ( $encrypted ) : null;
	}
	function publicDecrypt($encrypted) {
		if (! is_string ( $encrypted )) {
			user_error ( 'encrypted must be string', E_USER_WARNING );
			return;
		}
		return (openssl_public_decrypt ( base64_decode ( $encrypted ), $decrypted, $this->getPublicKey () )) ? $decrypted : null;
	}
	function privateEncrypt($data) {
		if (! is_string ( $data )) {
			user_error ( 'data must be string', E_USER_WARNING );
			return;
		}
		return openssl_private_encrypt ( $data, $encrypted, $this->getPrivateKey () ) ? base64_encode ( $encrypted ) : null;
	}
	function privateDecrypt($encrypted) {
		if (! is_string ( $encrypted )) {
			user_error ( 'encrypted must be string', E_USER_WARNING );
			return;
		}
		return (openssl_private_decrypt ( base64_decode ( $encrypted ), $decrypted, $this->getPrivateKey () )) ? $decrypted : null;
	}
}

base64通过http传输的时候需要处理一下,$data = rawurldecode ( urlencode ( $_GET['data'] ) );

下载:Rsa

php控制tor

<?php
/**
 * only be use in linux command line
 *
 * @author admin@phpdr.net
 */
class Tor {
	private $controlPassword = 'tor321';
	private $tor;
	function __construct($port) {
		settype ( $port, 'integer' );
		if (php_sapi_name () == 'cli') {
			$ports = $this->scan ();
			if (in_array ( $port, $ports )) {
				$this->tor = '127.0.0.1:' . $port;
			} else {
				user_error ( 'Tor port not found, port=' . $port, E_USER_WARNING );
			}
		} else {
			user_error ( __CLASS__ . " can only be used under php command line", E_USER_ERROR );
		}
	}

	/**
	 * restart tor, get new ip immediately
	 */
	function restart() {
		$port = explode ( ':', $this->tor );
		$port = $port [1];
		`tor-client stop $port`;
		`tor-client start $port`;
	}

	/**
	 * scan tor clinet
	 * --SocksPort 10090 --SocksListenAddress 127.0.0.1 --ControlPort 10091
	 */
	private function scan() {
		$lines = `ps aux|grep 'tor.\+--SocksPort [0-9]\+'`;
		$ports = array ();
		if (! empty ( $lines )) {
			$lines = explode ( "\n", $lines );
			foreach ( $lines as $v ) {
				$v = trim ( $v );
				if (! empty ( $v )) {
					preg_match ( '/--SocksPort (\d+)/', $v, $v );
					$port = $v [1];
					if (is_numeric ( $port )) {
						$ports [] = ( integer ) $port;
					} else {
						user_error ( 'tor port is invlaid, port=' . $port, E_USER_WARNING );
					}
				}
			}
			$ports = array_slice ( array_unique ( $ports ), 0 );
		}
		return $ports;
	}

	/**
	 * get a new ip use tor control port
	 *
	 * @param string $ip
	 * @param int $port
	 *        	control port
	 * @param string $authCode
	 *        	should be wraped by single quotes
	 * @return boolean
	 */
	function switchIp() {
		list ( $ip, $port ) = explode ( ':', $this->tor );
		$r = false;
		$fp = fsockopen ( $ip, $port, $errno, $errstr, 3 );
		if (! $fp) {
			user_error ( "can't connect to tor control, ip=$ip, port=$port", E_USER_WARNING );
		} else {
			fputs ( $fp, "AUTHENTICATE \"{$this->pass}\"\r\n" );
			$response = fread ( $fp, 1024 );
			list ( $code, $text ) = explode ( ' ', $response, 2 );
			if ($code != '250') {
				user_error ( "authentication failed", E_USER_WARNING );
			} else {
				// send the request to for new identity
				fputs ( $fp, "signal NEWNYM\r\n" );
				$response = fread ( $fp, 1024 );
				list ( $code, $text ) = explode ( ' ', $response, 2 );
				if ($code != '250') {
					user_error ( "signal failed", E_USER_WARNING );
				} else {
					$r = true;
				}
			}
			fclose ( $fp );
		}
		return $r;
	}

	/**
	 *
	 * @param number $port
	 *        	tor port
	 * @return mixed
	 */
	function getProxy() {
		$r = array (
				CURLOPT_PROXYTYPE => CURLPROXY_SOCKS5,
				CURLOPT_PROXY => $this->tor
		);
		return $r;
	}
}

下载:Tor

PHP解析 QQ 纯真 IP 数据库(qqip)

<?php
/**
 * parse ip use http://www.cz88.net database
 */
class QQIp
{

    protected $fp;

    function __construct($file)
    {
        if (! is_file($file)) {
            user_error('file is not found, file=' . $file, E_USER_ERROR);
        }
        $this->fp = fopen($file, 'rb');
        if (! is_resource($this->fp)) {
            user_error('can not open file, file=' . $file, E_USER_ERROR);
        }
    }

    /**
     *
     * @param string $ip
     */
    function parse($ip)
    {
        $fp = $this->fp;
        $ip = explode('.', $ip);
        $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
        // get start position and end position from db
        $DataBegin = fread($fp, 4);
        $DataEnd = fread($fp, 4);
        $ipbegin = implode('', unpack('L', $DataBegin));
        if ($ipbegin < 0)
            $ipbegin += pow(2, 32);
        $ipend = implode('', unpack('L', $DataEnd));
        if ($ipend < 0)
            $ipend += pow(2, 32);
        $ipAllNum = ($ipend - $ipbegin) / 7 + 1;
        $BeginNum = 0;
        $EndNum = $ipAllNum;
        $ip1num = null;
        $ip2num = null;
        // find ip from index use dichotomy
        while ($ip1num > $ipNum || $ip2num < $ipNum) {
            $Middle = intval(($EndNum + $BeginNum) / 2);
            // set the pointer to index position and read 4 byte
            fseek($fp, $ipbegin + 7 * $Middle);
            $ipData1 = fread($fp, 4);
            if (strlen($ipData1) < 4) {
                fclose($fp);
                return '- System Error';
            }
            // convert value to long.Add 2^32 if value is negative
            $ip1num = implode('', unpack('L', $ipData1));
            if ($ip1num < 0)
                $ip1num += pow(2, 32);
            // change end position if value greate than ip address
            if ($ip1num > $ipNum) {
                $EndNum = $Middle;
                continue;
            }
            // get next index
            $DataSeek = fread($fp, 3);
            if (strlen($DataSeek) < 3) {
                fclose($fp);
                return '- System Error';
            }
            $DataSeek = implode('', unpack('L', $DataSeek . chr(0)));
            fseek($fp, $DataSeek);
            $ipData2 = fread($fp, 4);
            if (strlen($ipData2) < 4) {
                fclose($fp);
                return '- System Error';
            }
            $ip2num = implode('', unpack('L', $ipData2));
            if ($ip2num < 0)
                $ip2num += pow(2, 32);
            // not found
            if ($ip2num < $ipNum) {
                if ($Middle == $BeginNum) {
                    fclose($fp);
                    return '- Unknown';
                }
                $BeginNum = $Middle;
            }
        }
        $ipFlag = fread($fp, 1);
        if ($ipFlag == chr(1)) {
            $ipSeek = fread($fp, 3);
            if (strlen($ipSeek) < 3) {
                fclose($fp);
                return '- System Error';
            }
            $ipSeek = implode('', unpack('L', $ipSeek . chr(0)));
            fseek($fp, $ipSeek);
            $ipFlag = fread($fp, 1);
        }
        if ($ipFlag == chr(2)) {
            $AddrSeek = fread($fp, 3);
            if (strlen($AddrSeek) < 3) {
                fclose($fp);
                return '- System Error';
            }
            $ipFlag = fread($fp, 1);
            if ($ipFlag == chr(2)) {
                $AddrSeek2 = fread($fp, 3);
                if (strlen($AddrSeek2) < 3) {
                    fclose($fp);
                    return '- System Error';
                }
                $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0)));
                fseek($fp, $AddrSeek2);
            } else {
                fseek($fp, - 1, SEEK_CUR);
            }
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr2 .= $char;
            $AddrSeek = implode('', unpack('L', $AddrSeek . chr(0)));
            fseek($fp, $AddrSeek);
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr1 .= $char;
        } else {
            fseek($fp, - 1, SEEK_CUR);
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr1 .= $char;
            $ipFlag = fread($fp, 1);
            if ($ipFlag == chr(2)) {
                $AddrSeek2 = fread($fp, 3);
                if (strlen($AddrSeek2) < 3) {
                    fclose($fp);
                    return '- System Error';
                }
                $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0)));
                fseek($fp, $AddrSeek2);
            } else {
                fseek($fp, - 1, SEEK_CUR);
            }
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr2 .= $char;
        }
        fclose($fp);
        if (preg_match('/http/i', $ipAddr2)) {
            $ipAddr2 = '';
        }
        $ipaddr = "$ipAddr1 $ipAddr2";
        $ipaddr = preg_replace('/CZ88\.NET/is', '', $ipaddr);
        $ipaddr = preg_replace('/^\s*/is', '', $ipaddr);
        $ipaddr = preg_replace('/\s*$/is', '', $ipaddr);
        if (preg_match('/http/i', $ipaddr) || $ipaddr == '') {
            $ipaddr = '- Unknown';
        }
        $ipaddr = mb_convert_encoding($ipaddr, 'utf-8', 'GBK');
        return $ipaddr;
    }

    function __destruct()
    {
        fclose($this->fp);
    }
}

下载:QQIp.php