php 数据调试 by debug_backtrace

/**
 * 返回函数操作链表
 *
 * @param int $level
 *        	返回多少级
 * @param int $start
 *        	跳过原来多少级
 * @param boolean $gettree
 *        	是否按树的形式返回
 * @return array
 */
function backtracelist($level = 3, $start = 0, $gettree = false) {
	$backtrace = debug_backtrace ();
	$btlist = array ();
	if ($backtrace) {
		$level = $level + $start;
		foreach ( $backtrace as $i => $bt ) {
			if ($i < $start) {
				continue;
			}
			if ($i >= $level) {
				break;
			}
			$args = '';
			foreach ( $bt ['args'] as $a ) {
				if (! empty ( $args )) {
					$args .= ', ';
				}
				switch (gettype ( $a )) {
					case 'integer' :
					case 'double' :
						$args .= $a;
						break;
					case 'string' :
						$a = htmlspecialchars ( substr ( $a, 0, 64 ) ) . ((strlen ( $a ) > 64) ? '...' : '');
						$args .= ""$a"";
						break;
					case 'array' :
						$args .= 'Array(' . count ( $a ) . ')';
						break;
					case 'object' :
						$args .= 'Object(' . get_class ( $a ) . ')';
						break;
					case 'resource' :
						$args .= 'Resource(' . strstr ( $a, '#' ) . ')';
						break;
					case 'boolean' :
						$args .= $a ? 'True' : 'False';
						break;
					case 'NULL' :
						$args .= 'Null';
						break;
					default :
						$args .= 'Unknown';
				}
			}
			$params = array (
					"line" => $bt ['line'],
					"file" => $bt ['file'],
					"class" => $bt ['class'],
					"type" => $bt ['type'],
					"function" => $bt ['function'],
					"args" => $args,
					"next" => $params 
			);
			$btitem = array (
					'file' => "{$bt['line']} - {$bt['file']}",
					'call' => "{$bt['class']}{$bt['type']}{$bt['function']}($args)" 
			);
			if ($bt ['args']) {
				$btitem ['args'] = $bt ['args'];
			}
			$btlist [] = $btitem;
		}
	}
	if ($gettree) {
		return $params;
	}
	return $btlist;
}

 

 

/**
 * 通过在 $_GET[GDDEBUG_LEVEL]=1
 * 可以动态调整 gddebug 时 backtracelist 打印出来的层数,方便数据调试
 */
defined ( 'GDDEBUG_LEVEL' ) or define ( 'GDDEBUG_LEVEL', 'GDDEBUG_LEVEL' );

 

/**
 *
 * @author caihaibin
 *         数据打印工具,用来打印各种数据进行调试
 *         字符串为 string(1) "a"
 *         数字为 int(1)
 *         NULL 为 NULL
 *         数组为 Array(
 *         'a'=>'test'
 *         )
 *         对像为 Object xxxx
 *        
 *         另补充数据 debug_backtrace 层级调试,可以方便跟踪数据所在位置 ,具体看 backtracelist()
 *         可以通过 $_GET [GDDEBUG_LEVEL] 指定对应显示层级
 *         再将返回结果插入数据库,可以通过数据库进行数据调试
 */
function gddebug() {
	echo "rn<pre>";
	if (isset ( $_GET [GDDEBUG_LEVEL] )) {
		$level = $_GET [GDDEBUG_LEVEL];
	} else {
		$level = 0;
	}
	$btlist = backtracelist ( $level, 1 );
	if (! empty ( $btlist )) {
		echo "backtracelist:rn";
		foreach ( $btlist as &$btitem ) {
			if (isset ( $btitem ['args'] ))
				$btitem ['args'] = preg_replace ( '/n/ms', "n            ", print_r ( $btitem ['args'], true ) );
		}
		echo htmlspecialchars ( print_r ( $btlist, true ) ) . "rn";
	}
	$arrays = func_get_args ();
	echo "args:rn";
	foreach ( $arrays as $value ) {
		if (is_array ( $value ) || is_object ( $value )) {
			echo htmlspecialchars ( print_r ( $value, true ) ) . "rn";
		} elseif (is_string ( $value )) {
			echo "string(" . strlen ( $value ) . ") "" . htmlspecialchars ( $value ) . ""rn";
		} else {
			var_dump ( $value );
		}
	}
	echo "</pre>";
}

 

dodgepudding/wechat-php-sdk 添加登录验证码识别

其实有时间优化下,调整代码到 snoopy.class.php 用起来会方便点

Wechatext::getCode

	/**
	 * @添加验证码抓取.
	 */
	public function getCode() {
		$filename = $this->_cookiename;
		if (file_exists ( $filename )) {
			$mtime = filemtime ( $filename );
			if ($mtime < time () - $this->_cookieexpired)
				$data = '';
			else
				$data = file_get_contents ( $filename );
		} else
			$data = '';
		$send_snoopy = new Snoopy ();
		$send_snoopy->rawheaders ['Cookie'] = $data;
		$send_snoopy->maxredirs = 0;
		$url = "https://mp.weixin.qq.com/cgi-bin/verifycode?username=" . $this->_account . "&r=1406270984491";
		$send_snoopy->fetch ( $url );
		$cookie = '';
		foreach ( $send_snoopy->headers as $key => $value ) {
			$value = trim ( $value );
			if (preg_match ( '/^set-cookie:[s]+([^=]+)=([^;]+)/i', $value, $match ))
				$cookie .= $match [1] . '=' . $match [2] . '; ';
		}
		$this->saveCookie ( $this->_cookiename, $cookie );
		header ( 'Content-Type: image/jpeg' );
		echo $send_snoopy->results;
		exit ();
	}

补充验证码自动识别工具(不是做广告….)

http://www.uuwise.com/

注:微信对登录次数太多的ip做登录限制,会导致该ip的公众号无法登录。。慎玩。

php get java properties fix(utf-8)

$properties = parse_properties ( 'prop.properties' );
var_export ( $properties );
function unicode2utf8($str) {
	if (! $str)
		return $str;
	$decode = json_decode ( $str );
	if ($decode)
		return $decode;
	$str = '["' . $str . '"]';
	$decode = json_decode ( $str );
	if (count ( $decode ) == 1) {
		return $decode [0];
	}
	return $str;
}
function parse_properties($propertiespath) {
	$txtProperties = file_get_contents ( $propertiespath );
	$result = array ();
	$lines = split ( "n", $txtProperties );
	$key = "";
	$isWaitingOtherLine = false;
	foreach ( $lines as $i => $line ) {
		if (empty ( $line ) || (! $isWaitingOtherLine && strpos ( $line, "#" ) === 0))
			continue;

		if (! $isWaitingOtherLine) {
			$key = substr ( $line, 0, strpos ( $line, '=' ) );
			$value = substr ( $line, strpos ( $line, '=' ) + 1, strlen ( $line ) );
		} else {
			$value .= $line;
		}
		/* Check if ends with single '' */
		if (strrpos ( $value, "" ) === strlen ( $value ) - strlen ( "" )) {
			$value = substr ( $value, 0, strlen ( $value ) - 1 ) . "n";
			$isWaitingOtherLine = true;
		} else {
			$isWaitingOtherLine = false;
		}
		$value = trim ( $value );
		$value = preg_replace ( "/(\uw{4})/e", "unicode2utf8('1')", $value );
		$value = preg_replace ( "/\\/", "", $value );
		$value = preg_replace ( "/\:/", ":", $value );
		$result [$key] = $value;
		unset ( $lines [$i] );
	}
	return $result;
}

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

探究 Zend Guard 加密&解密

参考:http://zhainan.org/post-1667.html

解密:黑刀  http://www.tmd.me/2008/read.php/50.htm

补充:

zend guard 6.0的费用不低,在接连5.0~5.5被轻松反编译的现在。估计6.0也是早晚的事。觉得还是干扰名比较好。

但是基于维护不方便性,比如原来的项目已经部署上线的情况下。不可能进行重新生成。和覆盖。这块需要继续探究解决方案。

做为单一小脚本和核心功能模块处理的情况下仍推荐用变量名干扰。这样用5.0即可,且支持的5.2的环境比较多。

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

 

CURL_MULTI 工具类

参考:http://techbbs.zol.com.cn/1/9_3371.html

<?php
/**
 * $results = CurlMulti::cmcheck ( array (
 * 		"http://www.maranellowebfashion.com/prodotti/immagini/scarpa_donna_elisabetta_franchi_sa7962052_rosa_212/1.jpg",
 * 		"http://www.maranellowebfashion.com/prodotti/immagini/scarpa_donna_elisabetta_franchi_sa7962052_rosa_212/222.jpg",
 * 		"http://www.maranellowebfashion.com/prodotti/immagini/scarpa_donna_elisabetta_franchi_sa7962052_rosa_212/3.jpg" 
 * 	) );
 * $results = CurlMulti::cmfetch($results);
 * @author caihaibin
 */
class CurlMulti {
	static $urls = null;
	static $able_urls=null;
	static $resourcs = null;
	static $resoponses = null;
	static $nobody = false;
	static $mh = null;
	static function cminit($urls) {
		self::$resourcs = array ();
		self::$resoponses = array ();
		self::$urls = $urls;
		self::$mh = curl_multi_init ();
		foreach ( $urls as $url ) {
			$ch = curl_init ();
			curl_setopt ( $ch, CURLOPT_URL, $url );
			curl_setopt ( $ch, CURLOPT_HEADER, 0 );
			// 执行不打印
			curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); // return the image
			if (self::$nobody)
				curl_setopt ( $ch, CURLOPT_NOBODY, 1 );
			curl_multi_add_handle ( self::$mh, $ch );
			self::$resourcs [] = $ch;
		}
	}
	static function cmcheck($urls = array()) {
		self::$nobody = true;
		self::$able_urls = array();
		self::cminit ( $urls );
		$active = null;
		// 执行批处理句柄
		do {
			$mrc = curl_multi_exec ( self::$mh, $active );
		} while ( $mrc == CURLM_CALL_MULTI_PERFORM );

		while ( $active && $mrc == CURLM_OK ) {
			if (curl_multi_select ( self::$mh ) != - 1) {
				do {
					$mrc = curl_multi_exec ( self::$mh, $active );
				} while ( $mrc == CURLM_CALL_MULTI_PERFORM );

				if ($mhinfo = curl_multi_info_read ( self::$mh )) {
					// 意味着该连接正常结束
					// 8. 从curl句柄获取信息
					$chinfo = curl_getinfo ( $mhinfo ['handle'] );
					// 9. 死链么?
					if (! $chinfo ['http_code']) {
// 						$chinfo ['url'];
						// 10. 404了?
					} else if ($chinfo ['http_code'] == 404) {
// 						$chinfo ['url'];
						// 11. 还能用
					} else {
						$able_urls[]=$chinfo ['url'];
					}
					// 12. 移除句柄
					curl_multi_remove_handle ( self::$mh, $mhinfo ['handle'] );
					curl_close ( $mhinfo ['handle'] );
					// 13. 加入新URL,干活
					do {
						$mrc = curl_multi_exec ( self::$mh, $active );
					} while ( $mrc == CURLM_CALL_MULTI_PERFORM );
				}
			}
		}
		curl_multi_close ( self::$mh );
		return $able_urls;
	}
	static function cmfetch($urls = array()) {
		self::$nobody = false;
		self::cminit ( $urls );
		$active = null;
		// 执行批处理句柄
		do {
			$mrc = curl_multi_exec ( self::$mh, $active );
		} while ( $mrc == CURLM_CALL_MULTI_PERFORM );

		while ( $active && $mrc == CURLM_OK ) {

			if (curl_multi_select ( self::$mh ) != - 1) {

				do {
					$mrc = curl_multi_exec ( self::$mh, $active );
				} while ( $mrc == CURLM_CALL_MULTI_PERFORM );

			}

		}
		self::cmdestroy ();
		return self::$resoponses;
	}
	static function getContents() {
		return self::$resoponses;
	}
	static function cmdestroy() {
		foreach ( self::$resourcs as &$rs ) {
			self::$resoponses [] = curl_multi_getcontent ( $rs );
			curl_multi_remove_handle ( self::$mh, $rs );
		}
		curl_multi_close ( self::$mh );
	}
}

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

自备 PHP 工具函数

获取ip

    function getip() {

        if (isset ( $_SERVER )) {

            if (isset ( $_SERVER ['HTTP_X_FORWARDED_FOR'] )) {

                $aIps = explode ( ',', $_SERVER ['HTTP_X_FORWARDED_FOR'] );

                foreach ( $aIps as $sIp ) {

                    $sIp = trim ( $sIp );

                    if ($sIp != 'unknown') {

                        $sRealIp = $sIp;

                        break;

                    }

                }

            } elseif (isset ( $_SERVER ['HTTP_CLIENT_IP'] )) {

                $sRealIp = $_SERVER ['HTTP_CLIENT_IP'];

            } else {

                if (isset ( $_SERVER ['REMOTE_ADDR'] )) {

                    $sRealIp = $_SERVER ['REMOTE_ADDR'];

                } else {

                    $sRealIp = '0.0.0.0';

                }

            }

        } else {

            if (getenv ( 'HTTP_X_FORWARDED_FOR' )) {

                $sRealIp = getenv ( 'HTTP_X_FORWARDED_FOR' );

            } elseif (getenv ( 'HTTP_CLIENT_IP' )) {

                $sRealIp = getenv ( 'HTTP_CLIENT_IP' );

            } else {

                $sRealIp = getenv ( 'REMOTE_ADDR' );

            }

        }

        return $sRealIp;

    }

session 操作

<?php
/**
该类为session中用于操作session的各中处理
如果该类配置正常,在$_SESSION中的数据会以数据库的形式保存。
通过 session_id()操作可实现session的共享,使多应用可进行同步操作和登录。
这个是上次搞qq绑定时,保留下来的哈。不过网上多如牛毛。咱就不多说了。
*/
$aConfig = array (
		'session' => '1',
		'db' => array (
				'host' => 'localhost',
				'user' => 'root',
				'pass' => '',
				'name' => 'test' 
		) 
);
new session ( $aConfig );

class session {
	/*
	 * 数据库接口
	 */
	private $oDB;
	function __construct($aConfig) {
		session_cache_limiter ( 'private, must-revalidate' );

		session_cache_expire ( 1800 );

		@ini_set ( 'session.cookie_lifetime', 0 );

		@ini_set ( 'session.cookie_httponly', TRUE );

		@ini_set ( 'session.use_cookies', 1 );

		@ini_set ( 'session.use_only_cookies', 1 );

		@ini_set ( 'session.use_trans_sid', 0 );

		@ini_set ( 'session.gc_probability', 1 );

		@ini_set ( 'session.gc_divisor', 1 );

		@ini_set ( 'session.gc_maxlifetime', 1800 );

		if ($aConfig ["session"] == 1) {
			$this->oDB = mysql_connect ( $aConfig ["db"] ["host"], $aConfig ["db"] ["user"], $aConfig ["db"] ["pass"] );
			mysql_select_db ( $aConfig ["db"] ["name"], $this->oDB );
			mysql_query ( "SET NAMES UTF8", $this->oDB );
			session_set_save_handler ( array (
					&$this,
					"open" 
			), array (
					&$this,
					"close" 
			), array (
					&$this,
					"read" 
			), array (
					&$this,
					"write" 
			), array (
					&$this,
					"destory" 
			), array (
					&$this,
					"gc" 
			) );

		} elseif ($aConfig ["session"] == 2) {
			@ini_set ( 'session.save_handler', 'memcache' );

			@ini_set ( "session.save_path", "tcp://" . $aConfig ["mem"] ["host"] . ":" . $aConfig ["mem"] ["port"] );
		}
		session_start ();
	}

	function open($session_save_path, $session_name) {
		return true;
	}

	function close() {
		return true;
	}

	function write($key, $value) {
		$query = mysql_query ( "select * from `sessions` where `sessionkey`='" . $key . "'", $this->oDB );
		if (mysql_num_rows ( $query ) == 0) {
			mysql_query ( "insert into `sessions` set `sessionkey`='" . $key . "',`sessionvalue`='" . $value . "',`sessionip`='" . getip () . "', `sessionexpiry` ='" . date ( "Y-m-d H:i:s", strtotime ( "+1800 seconds" ) ) . "'", $this->oDB );
		} else {
			mysql_query ( "update `sessions` set `sessionvalue`='" . $value . "',`sessionip`='" . getIp () . "',`sessionexpiry`='" . date ( "Y-m-d H:i:s", strtotime ( "+1800 seconds" ) ) . "' where `sessionkey`='" . $key . "'", $this->oDB );
		}
	}

	function read($key) {
		$Query = mysql_query ( "select `sessionvalue` from `sessions` where `sessionkey`='" . $key . "' and `sessionexpiry`>'" . date ( "Y-m-d H:i:s" ) . "' and `sessionip`='" . getIp () . "'", $this->oDB );
		$aValue = mysql_fetch_assoc ( $Query );
		if (empty ( $aValue )) {
			return NULL;
		}
		return $aValue ["sessionvalue"];
	}

	function gc() {
		return mysql_query ( "delete from `sessions` where `sessionexpiry`<='" . date ( "Y-m-d H:i:s" ) . "'", $this->oDB );
	}

	function destory($key) {
		return mysql_query ( "delete from `sessions` where `sessionkey`='" . $key . "'", $this->oDB );
	}
}

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

 

php excel 导出常见问题

1.php 多功能导出工具 phpexcel

2.简单导出数据,采用table 加修改后缀的方式 ^_^

2.1 导出数据格式,解决excel格式自动化,显示异常,加样式

style=’text-align:center;vnd.ms-excel.numberformat:@’

但是注意,对于大文本,请不要加,不然会显示一堆#########

2.2导出文件头相关参数

导出相关代码,解决ie6 zip多文件异常问题

function file_down($filepath, $filename = '') {
	if (! $filename)
		$filename = basename ( $filepath );
	if ($this->is_ie ())
		$filename = rawurlencode ( $filename );
	$filetype = fileext ( $filename );
	$filesize = sprintf ( "%u", filesize ( $filepath ) );
	if (ob_get_length () !== false)
		@ob_end_clean ();
	header ( 'Pragma: public' );
	header ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
	header ( 'Cache-Control: no-store, no-cache, must-revalidate' );
	header ( 'Cache-Control: pre-check=0, post-check=0, max-age=0' );
	header ( 'Content-Transfer-Encoding: binary' );
	header ( 'Content-Encoding: none' );
	header ( 'Content-type: ' . $filetype );
	header ( 'Content-Disposition: attachment; filename="' . $filename . '"' );
	header ( 'Content-length: ' . $filesize );
	readfile ( $filepath );
	exit ();
}

 

2.3 iconv 转换过成中,数据丢失或没有数据输出 //IGNORE 标志,跳过异常

iconv ( 'UTF-8', 'GBK//IGNORE',$string);

 

3.导出大数据解决(其实这个是因为服务器的内存限制,导出中,字符串的拼接又过大,导致内存溢出)

$out=fopen($path,"a+");//拼接

fwite($out,$data);//一点一点输出成文件

fclose($out);

 

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827