PHP API文档管理系统

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

API文档编写是非常重要的一项工作,但是编写维护非常麻烦,本项目的解决的问题是以最轻松的方式维护n个接口,每个接口n个版本。原理是解析固定格式的txt文件实时全自动生成文档,大量使用继承、递归、前缀、替换等等。

安装

  1. composer install
  2. 绑定www服务器的入口目录为本项目的public目录
  3. 现在应该可以访问了

特性

  1. 无需数据库。
  2. 编写非常简便,所有枯燥的工作全部由机器完成。
  3. 支持非常多的格式。
  4. 以非常便捷的方式实现继承,加前缀,后缀等等各种高级功能。

Demo

http://doc.phpdr.net
用户名:admin
密码:admin

用法

语法说明文件查看doc/Api.txt
Demo使用的数据文件在app/data/doc/api
看Demo和文档基本就会用

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 数据库

<?php
/**
 *
 * @author admin@phpdr.net
 *
 */
class ChunZhenIp {
	private $file;
	function __construct($dataFile) {
		$this->file = $dataFile;
	}
	/**
	 * parse ip address from QQ Chunzhen IP data file
	 *
	 * @param mixed $ip
	 */
	function parse($ip) {
		if (! preg_match ( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $ip )) {
			user_error ( 'wrong ip', E_USER_WARNING );
			return false;
		}
		$fd = fopen ( $this->file, 'rb' );
		if ($fd) {
			$ip = explode ( '.', $ip );
			$ipNum = $ip [0] * 16777216 + $ip [1] * 65536 + $ip [2] * 256 + $ip [3];
			// get start and end position
			$DataBegin = fread ( $fd, 4 );
			$DataEnd = fread ( $fd, 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 use dichotomy algorithm
			while ( $ip1num > $ipNum || $ip2num < $ipNum ) {
				$Middle = intval ( ($EndNum + $BeginNum) / 2 );
				// excursion the pointer to index position and read 4 bytes
				fseek ( $fd, $ipbegin + 7 * $Middle );
				$ipData1 = fread ( $fd, 4 );
				if (strlen ( $ipData1 ) < 4) {
					fclose ( $fd );
					return '- System Error';
				}
				// convert to long, plush 2^32 if is negative
				$ip1num = implode ( '', unpack ( 'L', $ipData1 ) );
				if ($ip1num < 0)
					$ip1num += pow ( 2, 32 );
					// if greater than ip then change the end position and go to next loop
				if ($ip1num > $ipNum) {
					$EndNum = $Middle;
					continue;
				}
				// fetch next index after current fetched
				$DataSeek = fread ( $fd, 3 );
				if (strlen ( $DataSeek ) < 3) {
					fclose ( $fd );
					return '- System Error';
				}
				$DataSeek = implode ( '', unpack ( 'L', $DataSeek . chr ( 0 ) ) );
				fseek ( $fd, $DataSeek );
				$ipData2 = fread ( $fd, 4 );
				if (strlen ( $ipData2 ) < 4) {
					fclose ( $fd );
					return '- System Error';
				}
				$ip2num = implode ( '', unpack ( 'L', $ipData2 ) );
				if ($ip2num < 0)
					$ip2num += pow ( 2, 32 );
					// return unknow if not found
				if ($ip2num < $ipNum) {
					if ($Middle == $BeginNum) {
						fclose ( $fd );
						return '- Unknown';
					}
					$BeginNum = $Middle;
				}
			}
			// don't understand code bellow yet...
			$ipFlag = fread ( $fd, 1 );
			if ($ipFlag == chr ( 1 )) {
				$ipSeek = fread ( $fd, 3 );
				if (strlen ( $ipSeek ) < 3) {
					fclose ( $fd );
					return '- System Error';
				}
				$ipSeek = implode ( '', unpack ( 'L', $ipSeek . chr ( 0 ) ) );
				fseek ( $fd, $ipSeek );
				$ipFlag = fread ( $fd, 1 );
			}
			if ($ipFlag == chr ( 2 )) {
				$AddrSeek = fread ( $fd, 3 );
				if (strlen ( $AddrSeek ) < 3) {
					fclose ( $fd );
					return '- System Error';
				}
				$ipFlag = fread ( $fd, 1 );
				if ($ipFlag == chr ( 2 )) {
					$AddrSeek2 = fread ( $fd, 3 );
					if (strlen ( $AddrSeek2 ) < 3) {
						fclose ( $fd );
						return '- System Error';
					}
					$AddrSeek2 = implode ( '', unpack ( 'L', $AddrSeek2 . chr ( 0 ) ) );
					fseek ( $fd, $AddrSeek2 );
				} else {
					fseek ( $fd, - 1, SEEK_CUR );
				}
				while ( ($char = fread ( $fd, 1 )) != chr ( 0 ) )
					$ipAddr2 .= $char;
				$AddrSeek = implode ( '', unpack ( 'L', $AddrSeek . chr ( 0 ) ) );
				fseek ( $fd, $AddrSeek );
				while ( ($char = fread ( $fd, 1 )) != chr ( 0 ) )
					$ipAddr1 .= $char;
			} else {
				fseek ( $fd, - 1, SEEK_CUR );
				while ( ($char = fread ( $fd, 1 )) != chr ( 0 ) )
					$ipAddr1 .= $char;
				$ipFlag = fread ( $fd, 1 );
				if ($ipFlag == chr ( 2 )) {
					$AddrSeek2 = fread ( $fd, 3 );
					if (strlen ( $AddrSeek2 ) < 3) {
						fclose ( $fd );
						return '- System Error';
					}
					$AddrSeek2 = implode ( '', unpack ( 'L', $AddrSeek2 . chr ( 0 ) ) );
					fseek ( $fd, $AddrSeek2 );
				} else {
					fseek ( $fd, - 1, SEEK_CUR );
				}
				while ( ($char = fread ( $fd, 1 )) != chr ( 0 ) )
					$ipAddr2 .= $char;
			}
			fclose ( $fd );
			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;
		}
	}
}

下载:ChunZhenIP