DIYism schooner能逆风行驶的纵帆船是生命的极好象征,贝努利效应正是化逆为顺的经典!--呆仁 收藏本站 涂鸦本站 来信本站 跟我MSN 跟我QQ GTalk 思想农业天文生物文化饮食娱乐硬件健康语言心理网络物理政治个人编程软件工具 php学习笔记
javascript学习笔记
flash学习笔记
css学习笔记
xsl学习笔记
sql学习笔记
ubuntu安装配置
centos安装配置
damnsmall安装配置
python学习笔记
呓语录
(k94f)
============================================================================================
linux里安装php:
cd /usr/local/php
tar zxvf php-5.1.6.tar.gz
cd php-5.1.6
./configure --prefix=/usr/local/php \
--with-apxs2=/usr/local/apache2/bin/apxs \     #生成libphp5.so文件
--enable-sockets \
--with-config-file-path=/usr/local/php \设置配置文件路径
--with-mysql=/usr/local/mysql \ #添加mysql扩展
--enable-so #不能去掉, 否则启动apache报undefined symbol: php_escape_html_entities
make      #php编译较耗时
make install
cp php.ini-dist /usr/local/php/php.ini
cd ..
rm php-5.1.6.tar.gz
添加扩展:
cd /usr/local/php/php-5.1.6/ext/mbstring
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install
cp modules/mbstring.so /usr/local/php/ext/mbstring.so
将php.ini里
extension_dir = "./"改成extension_dir = /usr/local/php/ext
extension=php_mbstring.dll去掉注释改成extension=mbstring.so
/etc/rc.d/init.d/httpd -k restart
=============================================================================================
windows apache下使用mod_rewrite, 在httpd.conf里:
LoadModule rewrite_module modules/mod_rewrite.so #D:\ProgXP\Apache Group\Apache2\modules下编译好的各个so可以直接用
NameVirtualHost 192.168.100.118:80   #如果局域网IP不固定, 这里可用主机名如"kexianbin:80"
   #如果局域网IP不固定, 这里可用主机名(如果上面IP这里必IP, 上面*这里必*)
ServerName root.diy
DocumentRoot E:\www\PHPApps\ROOT
RewriteEngine on
RewriteRule ^/(.+)/$ /open_url.php?username=$1

伪静态页面规则(所谓的搜索引擎优化):
RewriteRule ^/forum/([^/]+)/([^/]+)/([^/]+)$ /forum.php?forumId=$1&sortId=$2&forumPage=$3
=============================================================================================
ob_implicit_flush(1);不让服务器缓存输出, 而是直接输出到客户端
要输出缓冲, 必须同时flush();ob_flush();
要输出大文件:ini_set('max_execution_time','3600');//set_time_limit(0);表不限时长
输出页面比较大时可以在代码第一行加上"ob_start('ob_gzhandler');", 这样浏览器支持压缩通讯时就自动采用压缩通讯以加速,
或在php.ini里改成"zlib.output_compression = On", 或者在apache.conf里LoadModule deflate_module mod_deflate.so,
不要同时使用, 否则报conflicts警告
如果有mod_deflate而想临时在单个php里禁用压缩传输, 这个也没用:apache_setenv('no-gzip', '1');
=============================================================================================
在什么地方重开session就在什么地方恢复所有session变量,前面同名变量的值将
被覆盖,GET、POST过来的变量在重开session之前,因而其重名变量肯定会被覆盖
=================================================================
用户session锁住导致其它页面无法打开(不论linux还是windows服务器):
test.php:
session_start();
for ($i=0;$i<10;++$i)
    {sleep(1);
     echo 'hell
'; } test1.php: session_start(); echo 'hello'; 访问test.php, 将导致当前用户在10秒内无法看到test1.php的输出(其它用户没有问题). 可以在test.php里循环之前session_write_close()以避免问题. ================================================================= 放在双引号里的字串变量会被自动解析, 相当于用"."串上这个变量, 并不对其内"\"再次转义, 如echo "return $Supplier_out[0][name];";得到的是"return Array[name];" 这不是我们所期望的,所以需要纯字串时最好还是使用单引号, 需要解析字串内变量时统一加{}: echo "{$username},welcolm"; mysql_query("select * from tb1 where id='{$sql_safe($userid)}'");//注意$sql_safe='sql_safe'; 有时候需要直接使用大段字串(不用处理单引号或双引号): $str= @<<= @<<= 注意:如果字串内有"{$aVar='string';"或"$aVar['jack']"会触发语法错误, "@<<0) {$doc_before=ob_get_contents(); ob_end_clean(); } ob_start(); //wirte doc below: ?> Example \nof $kk /*jkj*/ spanning 'multiple' lines using "heredoc" syntax. 0) {ob_start($ob_before[0]); echo $doc_before; } return $doc; } $doc1=segment_doc1(); echo htmlspecialchars($doc1); 不过doc内的""还是会产生冲突, 最可靠的做法还是读文件 ================================================================= 调试的时候,可以用 <<
";'), $status); 比如找出执行时间比较长的sql语句: $t1=time().substr(microtime(),2,6); mysql_query($query_string,$this->link_id); $t2=time().substr(microtime(),2,6); if (isset($_GET['debug'])) {$_SESSION['debug']=$_GET['debug']; } if ($_SESSION['debug']) #需要预先session_start(); {if (($t3=(float)$t2-(float)$t1)>1000) //需要跟踪指定语句时加: || strpos($query_string, "SELECT area_name FROM area_code")!==false {ob_start();debug_print_backtrace();$tmp=strtr(ob_get_contents(),array("\n"=>'
'));ob_clean(); register_shutdown_function('var_export', $query_string.':'.$t3.'(too long)
'.$tmp.'
'); } else {register_shutdown_function('var_export', $query_string.':'.$t3.'
'); } } ================================================================= 用DBG调试器来debug(发现错误)和profile(发现性能问题): 在测试服务器上编译对应php版本的DBG服务端(从http://dd.cron.ru/dbg/下载最新版binary即可) 生成dbg.so放到php.ini里extension_dir指定位置,并设置php.ini: extension=dbg.so [debugger] debugger.enabled = true debugger.profiler_enabled = true debugger.JIT_host = 10.1.134.19 #程序员所在机器IP debugger.JIT_port = 7869 在程序员机器的phpedit安装目录里的dbg listener也要从http://dd.cron.ru/dbg/下载对应DBG服务端的版本 在程序员机器的phpedit启动的php dbg listener里设置: bind address: 10.1.134.19 #程序员所在机器IP port: 7869 code page: 简体中文GB2312 #程序员机器操作系统编码页 breakpoint on script start: yes 在程序员机器的phpedit里Debug\Debug Setting里设置HTTP(SAPI or remote CGI): Lauch debug session in web browser: yes HTTP Server root URL: http:// Local Root directory: E:\download\cvsroot #程序员工作目录(可以是本机, 也可以是测试服务器ftp) Remote Root directory: /www #测试服务器web root目录 在程序员机器网页浏览器里启动phpedit调试: http:///index.php?DBGSESSID=1@10.1.134.19:7869 #用DBGSESSID=0来临时停止调试 (DBGSESSID后的三个参数不要写掉了, 否则会导致apache死掉) (不能跟eAccelerator扩展同时启用, 否则profiler失效) ================================================================= 有时实在没有办法将测试服务器跟生产服务器同步准现场, 只能在生产服务器上测试时, 可以在保证代码没有错误的前提下用判断PHPSESSID是否你正在调试会话的方法来打印调试结果 欲构建准现场测试服务器, 需要能回滚测试数据, 然后才能快速同步生产服务器上的数据 ================================================================= 采用php.ini-dist反而比php.ini-recommended速度快 在输出报表这样比较大的文件时,需要设置php.ini里的output_buffering = On, 否则客户端会不断刷屏,而且输出结果也不正确. ================================================================= 为使mssql_query("select getdate()")返回标准格式日期: php.ini中mssql节内mssql.datetimeconvert默认是On要改为Off ================================================================= 判断一个传回数组中的元素个数最好用is_array($aArr)?count($aArr):0,因为如果传回的不是数组count也会为1 要注意,定义传出结果数组的函数时,要在添加数组元素的循环前面定义空数组,要不然传出结果不是空数组,而是空变量 判断一个变量是否数字索引数组最好用is_array && is_numeric(key($arr)),因为如果传回字串则isset($arr[0])为真 ================================================================= header("Cache-Control:no-cache");点击"转到"一次就删除了缓存文件. flickr的架构师认为需要写全这些: 让一个php在10年内浏览器上不失效: 和rewrite配置里: RewriteEngine on RewriteRule ^/(.*.)v[0-9.]+.(css|js|gif|png|jpg)$ /$1$2 [L] 让一个静态文件在10年内浏览器上不失效: RewriteEngine on RewriteRule ^/(.*.)v[0-9.]+.(css|js|gif|png|jpg)$ /$1$2 [L,E=VERSIONED_FILE:1] Header add "Expires" "Mon, 28 Jul 2014 23:30:00 GMT" env=VERSIONED_FILE Header add "Cache-Control" "max-age=315360000" env=VERSIONED_FILE 基本意思就是能在需要时改变URL里文件名来触发一个10年不失效文件的再次下载 ========================================================== php中接收所有post或get的字串都自动进行了转义处理('变成\',"变成\",\变成\\,null变成\x00), 以确保串到sql或其它字串中不发生语法错误, (magic_quotes_gpc默认开启,所有GET,POST,COOKIE数据都自动addslashes()了) 比如一个搜索函数,既可能使用外面传进来的参数也可能使用内部代码中的参数, 则不应该在这个函数内使用addslashes或mysql_real_escape_string, 而是在内部代码每个调用这个函数的地方使用addslashes, 这非常麻烦,而且这些数据传出来显示在网页上时如果出现在链接或value等字串内时也会有麻烦, 因而最好办法是根本就不让这样的数据进入数据库,在各种表单提交的地方拦住或过滤掉它们, 比如"


=============================================================================================== 用php执行外部命令时shell_exec('cd /');只对该行php有效, 用echo shell_exec('cd /;pwd');可看出, 要用chdir('/');才能让后面的php语句里也有效. 用sudo crontab -e在cron任务表里添加(每三分钟访问一次网页): */2 * * * * /usr/bin/wget -q -O /dev/null http://192.168.0.1/up_ip.php 可以这样用php执行命令行: (先用sudo visudo -f /etc/sudoers里加上:www-data ALL=(ALL) NOPASSWD:/etc/init.d/proftpd restart) shell_exec('sudo /etc/init.d/proftpd restart'); shell_exec最方便(四种方式的all lines都不是命令行里真正返回的all lines): (apache账户没有权限的shell命令不会有stdout或stderr, 因而加" 2>&1"也没用 事实上所有文件输出符号都无效, 即使输出到子命令或从子命令输出:shell_exec("wc -l <(echo -e 'kk\\nkk')"); 改成这样就行了:shell_exec("echo -e 'kk\\nkk' | wc -l"); 一个完整的例子:echo shell_exec("echo -e 'he\\nl\\nlo' | (tmp=\$(array('pipe', 'r'), 1=>array('pipe', 'w'), 2=>array('pipe', 'w')), $pipes); fwrite($pipes[0], 'h\\nel\\nlo');fclose($pipes[0]); $stdout=stream_get_contents($pipes[1]);fclose($pipes[1]); $stderr=stream_get_contents($pipes[2]);fclose($pipes[2]); $rtn=proc_close($proc); echo 'stdout:'.htmlspecialchars($stdout).'
'; echo 'stderr:'.htmlspecialchars($stderr).'
'; echo 'return:'.htmlspecialchars($rtn).'
'; ) ○string shell_exec ( string cmd )(PHP 4, PHP 5) (all lines)(command) Execute command via shell ○string exec ( string command [, array &output [, int &return_var]] )(PHP 3, PHP 4, PHP 5) (last line)(command)(append every line,without trailing whitespace,\n etc)(return status) Execute command via shell ○string system ( string command [, int &return_var] )(PHP 3, PHP 4, PHP 5) (last line or FALSE on failure)(command)(return status) Execute command via shell and display the output(automatically flush web server buffer each line) ○void passthru ( string command [, int &return_var] )(PHP 3, PHP 4, PHP 5) (null)(command)(return status) Execute command via shell and display raw output(ie. binary data) =============================================================================================== 把用sqlyog从mysql导出的csv文件当作数据库来查询(好处是能跨表查询及排序): (awk 3.1.4开始regular expression matching支持utf-8字符) $fields_ori=array('KeyID','Keyword','ChannelID','CategoryID','ChlScore','CatScore','ApvChannelID','ApvCategoryID','AccountID','CampaignID','BatchNum','AdgroupID','ApproveMethod','Type','AddTime','LastChangeTime'); $fields=array_flip(array_merge(array(''), $fields_ori));//first blank element for awk index $order=''; $arr_order=array('1'=>'', '2'=>'r'); $arr_order_char=array('1'=>'', '2'=>'n'); $order.=$items['order_keyword']?"-k{$fields['Keyword']},{$fields['Keyword']}{$arr_order_char[$items['order_keyword']]}{$arr_order[$items['order_keyword']]} ":''; $order.=$items['order_addtime']?"-k{$fields['AddTime']},{$fields['AddTime']}{$arr_order_char[$items['order_addtime']]}{$arr_order[$items['order_addtime']]} ":''; $order=$order?"| sort -t\$'\\t' ".$order:''; $limit=''; $start=$items['pg_size']*($items['pg_no']-1); $limit="NR>=".($start+1)." && NR<".($start+1+$items['pg_size']);//index start from 1, so added 1 $where=''; $where.="\${$fields['Keyword']} ~ /".preg_to_ereg(stripslashes($items['search_keyword']))."/ && "; $where.="\${$fields['BatchNum']} == \"{$batch_id}\" && "; $where=$where?substr($where, 0, -3):''; $table="kw_{$data['ChannelID']}_*"; $cmd="cd ../../keyword_search/;awk 'BEGIN {FS=\"\\t\";IGNORECASE=1} {$where}' {$table} {$order} | awk '{$limit} {print} {++count} END {print count}'";//exit($cmd); //reset FS because default field seperator is space and tab $out=shell_exec($cmd); $out=explode("\n", substr($out, 0, -1)); $total_count=array_pop($out); array_walk($out, create_function('&$v, $k, $arrIn', '$v=array_combine($arrIn, explode("\t", $v));'), $fields_ori); return array('total'=>$total_count, 'data'=>$out); 其中转换preg为ereg的函数: function preg_to_ereg($reg) {//convert preg in grep command to ereg in awk return strtr($reg, array('\S'=>'[^[:space:]]', '\s'=>'[[:space:]]', '\D'=>'[^[:digit:]]', '\d'=>'[[:digit:]]', '\b'=>'\y', '\''=>'\\47' ) ); } =============================================================================================== ie等浏览器不能自动识别php传出的xml文件的头部(被当做htm来处理了),必须发头消息: header('Content-type: text/xml; charset=utf-8'); 头消息比头部更早到达客户端, 有优先权 =============================================================================================== 函数传址的写法: $the_array=array(); $name_element_parent='channel__item category="column_headline"__item category="marquee"__item category="link"__0__link'; function &path2ele($path_full, &$array_root) {$ref_rtn=&$array_root; $path_exp=explode('__', $path_full); for ($i=0,$cnt=count($path_exp)-1;$i<$cnt;++$i) {$ref_rtn=&$ref_rtn[html_entity_decode($path_exp[$i+1])]; } return $ref_rtn; } $ele=&path2ele($name_element_parent, $the_array); $ele='jack'; var_export($the_array); =============================================================================================== 返回提交页面并刷新数据: header('Location: ' . $_SERVER['HTTP_REFERER']); 解出来源页面url: $url_ref=parse_url($_SERVER['HTTP_REFERER']); 注意:在Apache里, 送出"HTTP/1.1 302 Found"后会送出cookie然后再跳转(可以用输出js跳转而不用header的方法来解决), 而奇怪的IIS, 送出"HTTP/1.1 302 Object Moved"后立即跳转而不会送cookie(包括session cookie) =============================================================================================== array_merge:后面数组的相同字串索引的元素会覆盖前面数组里的对应元素但相同数字索引元素不覆盖而是重新排队索引(作用于第一层元素), array_merge_recursive:则将相同字串索引的元素累并到以该字串素引的一个下级数组元素里但相同数字索引元素不累并而是重新排队索引(作用于任意层), +:后面数组的相同索引(字串或数字)的元素不覆盖前面数组里的对应元素(丢弃),前面数组没有该索引的元素合并进来(只作用于第一层元素). 欲往一个数组的头部插入带索引的元素, 用array_unshift不行(自动建索引), 用array_merge也不行(破坏数字索引), 用"+"才行. 有时explode一个字串, 为免数量不够而到后面用isset检查, 可以先用空array来补(非空不会被覆盖): $tmp=explode(',', $v)+array('', '', '', ''); =============================================================================================== (服务器要装上libxslt(for linux):ftp://xmlsoft.org/libxslt/libxslt-1.1.20.tar.gz或启用php_xsl.dll(for windows)) 将xml和xsl转成html: $url=(($_GET['trg']=='http://www.xmnext.com/')?'http://www.xmnext.com/main/ui/index.xml':$_GET['trg']); $xml = new DOMDocument; $xml->load($url); //载入XSL文件 $xsl = new DOMDocument; $xsl->load(str_replace('.xml','.xsl', $url)); //转换为HTML $proc = new XSLTProcessor; $proc->importStyleSheet($xsl); // 加载xsl echo strtr($proc->transformToXML($xml), array(''=>'','
'=>'
')); 要注意所有的"
"都被转成了"
", 在ie下的xhtml里
被错误地解析成了两个换行, 所有要在写文件前把"
"都替换"
" =============================================================================================== 如果一批function是有规律的话, 可以通过eval来批量声明function =============================================================================================== 对象复制: $aObject=clone $bObject;直接赋值的话是传址的:$aObject=$bObject; 函数的参数如果是对象则也是传址的. =============================================================================================== 可以直接创建一个对象: $aObject=(object)array('host'=>'smtp.163.com', 'user_name'=>'kexianbin@163.com'); =============================================================================================== $aObject->aEle='aFun'; 可以这样调用变名函数:call_user_func_array($aObject->aEle, array($p1,$p2,...)); 而不能直接$aObject->aEle($p1,$p2,...), 这样调的是$aObject的aEle()这个method 还有这种用法: $aName='aEle'; echo $aObject->$aName;等价于echo $aObject->aEle; =============================================================================================== class里面const,static元素都是属于class的而不是属于object的, 用"aClass::"访问; public元素(默认)都是属于object的, 用"aObject->"访问 =============================================================================================== class内元素不能直接赋值为对象, 而要在初始化中赋值: class aClass {var $aObject; function aClass() {$this->aObject=(object)array('host'=>'smtp.163.com','user_name'=>'disuse@163.com'); } } =============================================================================================== //让method在class内外皆可用 kk','$this->bb')) {if ($use!=array('$this->kk','$this->bb')) {eval('global '.$use[0].';'); eval('global '.$use[1].';'); } $out=$in.'hell'.eval('return '.$use[0].';').eval('return '.$use[1].';'); } } $aObj=new aClass; $aObj->aFun('ren',$out); echo $out;?>

=============================================================================================== //可以直接建立只有属性的object,不可能直接建立含method的object,因为method是属于class的,而stdClass不可能修改 //可以近似实现: $aObject=(object)array('aEle'=>'kkk', 'bEle'=>'ccc', 'aFun'=>create_function('$a,$b', 'return $a+$b;')); $aFunName=$aObject->aFun;echo $aFunName(25, 36); 不允许直接: $aObject->aFun(25, 36);那是在调aFun这个方法而不是属性作函数名. //或echo call_user_func_array($aObject->aFun, array(25, 36)); //或者echo ${!${''}=$aObject->aFun}(25, 36); =============================================================================================== 动态按需载入class文件(class1.php, class2.php): =============================================================================================== //mb_detect_encoding并不能准确测出编码: echo mb_detect_encoding('联通','ASCII,CP936,UTF-8',1);//必须这样顺序'ASCII,CP936,UTF-8' echo mb_detect_encoding('虹口','ASCII,CP936,UTF-8',1);//必须这样顺序'ASCII,CP936,UTF-8' 判断是否utf-8编码应该用这个函数: function is_utf8($string) {return preg_match('%^(?: [\x09\x0A\x0D\x20-\x7E] # ASCII | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 )*$%xs', $string ); } 匹配utf-8汉字: php里不能使用\u4e00-\u9fa5的写法([u4e00-u9fa5]想当于0-u所有的数字字母),应该这样写: preg_match_all('/[\xe4-\xe9][\x80-\xbf]{2}/',$str,$mchs); 匹配gbk汉字(这并不可靠,如'判刑'中'判'字后半和"刑"字前半刚好是gbk的"行"字,下面的"手的"中间刚好是"值"字,等等): preg_match_all('/[\x81-\xFE][\x40-\x7E\x80-\xFE]/',$str,$mchs); 匹配gbk中指定个数多字节字符或单字节字符(转码及用u修饰符): $tmp=preg_replace(array('/(.{15})('.mb_convert_encoding($keyword,'UTF-8','GBK').')(.{15})/u'),array(']]>\1=0x00 && ord($str{$i})<=0x80) {$rtn.=$str{$i}; } else if (ord($str{$i})>=0x81 && ord($str{$i})<=0xfe) {if (ord($str{$i+1})>=0x40 && ord($str{$i+1})<=0x7e || ord($str{$i+1})>=0x80 && ord($str{$i+1})<=0xfe) {$rtn=$rtn.$str{$i}.$str{$i+1}; $i=$i+1; } } } return $rtn; } =============================================================================================== 仔细研究《编码对照表》,你会发现unicode编码中的汉字编码区间是连续的,位于4E00和9FA0之间,用《进制转换页面》把16进制转换成2进制: 4E00 : 0100 1110 0000 0000 9FA0 : 1001 1111 1010 0000 上面的二进制编码就是要写入1110 ____ 10__ ____ 10__ ____的16个空位,就像: 1110 0100 1011 1000 1000 0000 : E4 B8 80 1110 1001 1011 1110 1010 0000 : E9 BE A0 精确拆分的结果如下: 第一段:E4 B8 80 到 E4 BF BF 第二段:E5 80 80 到 E8 BF BF 第三段:E9 80 80 到 E9 BE A0 正则: \xe4\xb8[\x80-\xff]| \xe4[\xb9-\xbe][\x00-\xff]| \xe4\xbf[\x00-\xbf]| \xe5\x80[\x80-\xff]| [\xe5-\xe8][\x81-\xbe][\x00-\xff]| \xe8\xbf[\x00-\xbf]| \xe9\x80[\x80-\xff]| \xe9[\x81-\xbd][\x00-\xff]| \xe9\xbe[\x00-\xa0] 正则合并: (?:\xe4\xb8|[\xe5\xe9]\x80)[\x80-\xff]| (?:\xe4[\xb9-\xbe]|[\xe5-\xe8][\x81-\xbe]|\xe9[\x81-\xbd])[\x00-\xff]| [\xe4\xe8]\xbf[\x00-\xbf]| \xe9\xbe[\x00-\xa0] 粗糙正则: [\xe4-\xe9][\x80-\xbf]{2} =============================================================================================== 当心GBK下多字节替换: echo strtr('夏季出手的希望',array('值'=>'hell'));//将得到奇怪的"夏季出蔴ell南M" echo preg_replace(array('/值/'),array('hell'),'夏季出手的希望');//将得到"夏季出蔴ell南M" 由于没有对应的多字节操作,进行类似操作时可以将要替换的字串和关键字都先转为utf-8再用strtr: $mbc='mb_convert_encoding'; echo $mbc(strtr($mbc('夏季出手的希望','utf-8','gbk'),array($mbc('季','utf-8','gbk')=>'hell')),'gbk','utf-8'); echo $mbc(preg_replace(array('/'.$mbc('季','utf-8','gbk').'/u'),array('hell'),$mbc('夏季出手的希望','utf-8','gbk')),'gbk','utf-8'); 写成函数: function gbk_strtr($content,$arr_tr,$num=-1,$uft8=0) {$arr_tr_utf8=array(); foreach ($arr_tr as $k=>$v) {$k='/'.mb_convert_encoding($k,'utf-8','gbk').'/u'; $arr_tr_utf8[$k]=mb_convert_encoding($v,'utf-8','gbk'); } $content_tmp=mb_convert_encoding($content,'utf-8','gbk'); $content_tmp=preg_replace(array_keys($arr_tr_utf8),array_values($arr_tr_utf8),$content_tmp,$num); return $uft8?$content_tmp:mb_convert_encoding($content_tmp,'gbk','utf-8'); } 对应关系: (editplus里)unicode big endian = (php里)ucs-2 ~= utf-16 (editplus里)unicode = (php里)ucs-2le ~= utf-16le =============================================================================================== 在一系列循环出来的select,紧跟每个select后用js给select赋值(避免第一个select时尚不是数组的问题): =============================================================================================== left join两个表select出来的fields可能重名, 这样处理: $r=mysql_query('select * from registration left join reg on reg.email=registration.email '.$whr); $n=mysql_num_fields(mysql_list_fields($DBname,"registration")); for ($i=0;$i$host_n_prd_id,'{2}'=>$_COOKIE['pauserid']) ))); 如sql串日期比较: strtr( "select user.userid, {md_1_date}, {md_2_date},'".$date_edition."' from userwant left join user on userwant.userid=user.userid where card_state=2 and (({md_1_date} - INTERVAL 3 MONTH) <'".$date_edition."' and ({md_1_date} + INTERVAL 3 MONTH)>'".$date_edition."' or ({md_2_date} - INTERVAL 3 MONTH) <'".$date_edition."' and ({md_2_date} + INTERVAL 1 MONTH)>'".$date_edition."' ) group by userwant.userid ", array('{md_1_date}'=>"DATE_FORMAT(CONCAT(userwant.md_1_year,'-',userwant.md_1_month,'-','1'),'%Y-%m-%d')", '{md_2_date}'=>"DATE_FORMAT(CONCAT(userwant.md_2_year,'-',userwant.md_2_month,'-','1'),'%Y-%m-%d')" ) ); =============================================================================================== 这个跨域的test.js.php的header不会往浏览器的任何域下种上phpsessid, 反过来浏览器上任何域的cookie也不会上到test.js.php, 只有本域的js.php才会种上phpsessid, 但test.js.php的内容js里可以往thissite种下cookie, 也能用js取得thissite的cookie送回othersite. =============================================================================================== 常用的逗号字段插入: mysql_query("update 17wan_user set list_invite_me=CONCAT(list_invite_me,CASE WHEN FIND_IN_SET('".$_SESSION['id']."',list_invite_me)>0 THEN '' ELSE CASE WHEN list_invite_me>'' THEN ',".$_SESSION['id']."' ELSE '".$_SESSION['id']."' END END) where id='".$_GET['id']."'"); =============================================================================================== 在正则替换前先行处理(用到了'/e'修饰符,"\0"代表完整匹配): echo preg_replace(array('/dd/i','/jj(.*?)kk/e'),array('hell','"a".chr(\1)."c"'), 'jj65kk456DD');//\1传进去的是数字 //"chr(\\1)"才等同于'chr(\1)'的写法 还可以用自定义函数处理复杂情形(比如进行第二层正则替换): echo preg_replace(array('/dd/i','/jj(.*?)kk/e'),array('hell','"a".myfun("\1")."c"'), 'jj65kk456DD');//"\1"传进去的是字串 传进去的字串可能需要将所有的"\'"替换成"'", 因为最外层的单引号的原因(见whole_code()里的实现) 使用/e修饰符时要避免直接处理用户输入变量, 否则可能遭到类似eval注入攻击 要在替换里面加序号/行号之类: $cnt=0; echo preg_replace(array('/kk/e'), array('"pp".($cnt++)'), 'aaakkbbbbkkeeeekkdddd'); '?'作数量符之限定符(或非贪婪模式)时, 指不贪婪第一个边界字符后面的字符. =============================================================================================== 可以用preg_match($str_preg, $str)===false;来判断正则表达式不合法. preg_grep('/'.$str_preg.'/i', file($file_path, FILE_IGNORE_NEW_LINES)); 相当于linux下的"grep -iP {$str_preg} {$file_path}"命令行, grep是global regular expression print的缩写. =============================================================================================== preg_replace或preg_match里"."默认是只不包括新行符\n(不同于[\S]是不包含\x20,\r,\n,\f,\t), 加上修饰符/s后才相当于[\S\s]: preg_match('/\r\n\r\n(.*?)\r\n\r\n/s',$str,$match); 或者: preg_match('/\r\n\r\n([\S\s]*?)\r\n\r\n/',$str,$match); /m修饰符用来控制"^"和"$"是作为全文头/全文尾还是句头/句尾 "\b"直接使用指word boudary(非字母数字下划)等价于在前"(?<=\W|^)"和在后"(?=\W|$)", 即不占用匹配位置, 在"[\b]"里使用指backspace等价于"\x08". =============================================================================================== 将preg正则表达式(没有addslashes过的)转成msyql里可用: function preg_to_mysql($reg) {//convert perl_reg(preg_match) to mysql_reg(rlike/regexp) return strtr($reg, array('\W'=>'[^[:alnum:]_]', '\w'=>'[[:alnum:]_]', '\S'=>'[^[:space:]]', '\s'=>'[[:space:]]', '\D'=>'[^[:digit:]]', '\d'=>'[[:digit:]]', '\b'=>'(^|[^[:alnum:]_]|$)', '\\'=>'\\\\', '\''=>'\\\'' ) ); } =============================================================================================== 常用检查(电邮,邮编,身份证,手机,姓名,链接,数值): preg_match('/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z]{2,4}$/', $_POST['email']) preg_match('/^\d{6}$/',$_POST['zip']) preg_match('/^\d{15}(\d{2}[A-Za-z0-9])?$/', $_POST['id_card']) preg_match('/^1\d{10}$/', $_POST['cellphone']) preg_match('/^['.chr(0xa1).'-'.chr(0xff).']+$/', $_POST['real_name'])//GBK preg_match('/^(?:[\xe4-\xe9][\x80-\xbf]{2})+$/', $_POST['real_name'])//UTF-8 preg_match("/^https?:\/\/([\w-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6}(:\d{1,5})?(\/.*)?$/i",$url); preg_match("/^[0-9]+([\.][0-9]+)?$/", $float); =============================================================================================== "(...)"既是匹配子板也是分支定界,"(?:...)"只是分支定界,例: 'the white queen'匹配/((red|white) (king|queen))/, 得到\1是white queen, \2是white, \3是queen 'the white queen'匹配/((?:red|white) (king|queen))/, 得到\1是white queen, \2是queen "(?=...)"表示局部匹配后再扩展检查,符合才选入(用在前面的是"(?<=...)"), 例: 'JavaScript,hello,jack'匹配/(JavaScript(?=,hello)),jack/, 得到\1是JavaScript,jack "(?!...)"表示局部匹配后再扩展检查,不符合才选入(用在前面的是"(?'\"',"\r"=>'\r',"\n"=>'\n')).'");'; 调用: 内容: js_pxy.php可以用这个取代(注意要用串行方式): =============================================================================================== 获得http报头: $fp = fopen($url, 'r'); $meta_data = stream_get_meta_data($fp); $head = $meta_data['wrapper_data']; /* 如果是fsockopen()好像不怎么好用, 要直接用fgets来得到报头 */ /* PHP4.3.0之前可以直接用$http_response_header(对于不返回指针的file_get_contents()也可以用这个) */ =============================================================================================== 可以这样匹配query字串: preg_match('/(^|&|\?)keyword=(.*?)(&|$)/',$url['query'],$match); 但不能: preg_match('/[^|&|\?]keyword=(.*?)[&|$]/',$url['query'],$match); 匹配出来的字串要解码: rawurldecode($match[2]) =============================================================================================== 稍微精简的分页页码: 0){?>上一页   0){?>      下一页 =============================================================================================== 一个跨域传递cookie的方法(比如在通行证中用到): 客户在一个域登录时,将cookie放到一个文件中: $hash=md5(serialize($_COOKIE));//用来作为保存cookie 数据的文件名 $data=base64_encode(serialize($_COOKIE));//要保存的cookie数据 $h=fopen($hash,"wb+"); fwrite($h,$data); 然后跳转到另一个域时把文件名传过去?hash=, 解出cookie再种上: foreach (unserialize(base64_decode(file_get_contents("http://otherdomain".$_GET['hash']))) as $k => $v) {setcookie($k,$v); } 用跨域的js应该也可以实现: =============================================================================================== 如果一个函数内的两个缺省参数的缺省需要是不确定的, 不能使用一般的缺省值设置方法, 而是要传NULL值, 然后在函数内部代码赋予缺省值: function aFun($a, $b, $c, $d) {if ($c===NULL){$c='...';} if ($d===NULL){$d='...';} ... } aFun('...','...',NULL,'jack'); 也可以不定义所有不确定的参数,而通过func_get_args()获得: function aFun($aPar) {return count(func_get_args()).$aPar; } echo aFun('a','b','c'); 给函数少传参数会报错, 但是给函数多传参数即使里面不处理也没问题. =============================================================================================== 给图片补白并调整尺寸的函数: function img_pad($file_src,$file_trg,$width_trg,$height_trg,$color_pad) {$type_img=function_exists('exif_imagetype')? exif_imagetype($file_src): array_shift(array_slice(getimagesize($file_src),2,1)); switch ($type_img) {case IMAGETYPE_JPEG: $img_src = imagecreatefromjpeg($file_src); break; case IMAGETYPE_BMP: $img_src = imagecreatefromwbmp($file_src); break; case IMAGETYPE_GIF: $img_src = imagecreatefromgif($file_src); break; case IMAGETYPE_PNG: $img_src = imagecreatefrompng($file_src); break; } if(!is_resource($img_src)){return false;} $img_trg = imagecreatetruecolor($width_trg, $height_trg); imagefill($img_trg,$width_trg/2,$height_trg/2,$color_pad); list($width_orig, $height_orig) = getimagesize($file_src); if ($width_orig/$height_orig<$width_trg/$height_trg) {$ratio = $height_trg/$height_orig; } else {$ratio = $width_trg/$width_orig; } imagecopyresampled($img_trg, $img_src, ($width_trg-$width_orig*$ratio)/2, ($height_trg-$height_orig*$ratio)/2, 0, 0, $width_orig*$ratio, $height_orig*$ratio, $width_orig, $height_orig ); return imagejpeg($img_trg, $file_trg, 100); } 使用: img_pad('upload/'.$_COOKIE['userid'].'.m.jpg','upload/'.$_COOKIE['userid'].'.s.jpg',50,50,0xFFFFFF); =============================================================================================== ""来解决), "?>"紧后的回车不输出到html:
=============================================================================================== 有时想将数组的索引直接用做变量名, 这样:'x'.base64_encode(<索引>)是不行的, 因为base64里还有"/","+","="三个字符非法 要转换:'x'.strtr(base64_encode(<索引>),array('+'=>'¢','/'=>'£','='=>'¥')),做成函数叫inv2val(), 转回的时候:base64_decode(strtr(substr(<变量名>,1),array('¢'=>'+','£'=>'/','¥'=>'='))),做成函数叫val2inv() =============================================================================================== 每次随机生成图片验证码的数字并种在服务器端的session变量里,提交核对时也要清除这个session变量,以防用url过滤作弊 =============================================================================================== 字符编码转换(还可以用iconv,也可用自己写的utf82gb,但mb_convert_encoding在php5中已是默认扩展): mb_convert_encoding($file, 'UTF-8', 'GBK');//从GBK到UTF-8 =============================================================================================== 获得插入的最后一行数据的id:mysql_insert_id(), PDO里是$pdo->lastInsertId(); ==================================================================================== 取得域名指向的ip很简单:gethostbyname('diyism.com'); =============================================================================================== 用xml_rss配置文件及下面的xsl_raw模板文件来装配php程序: 模板: echo "you are "; ?> you are ">" width="131" height="105" style="border:none;"/>
函数: function xsl2php($path) {$xsl_text=array(''. ''. ''. '', ''. '' ); $xml = new DOMDocument; $xml->load($path); $content_xsl = file_get_contents(str_replace('.xml','.xsl', $path)); $content_xsl = preg_replace(array('/<\/?xsl:[\S\s]*?>/'), array(']]>\0'; $xsl = new DOMDocument; $xsl->loadXML($xsl_text[0].$content_xsl.$xsl_text[1]); $proc = new XSLTProcessor; $proc->importStyleSheet($xsl); return $proc->transformToXML($xml); } ====================================================================================== 防范合法用户的攻击: 没有任何办法可以防范用户修改浏览器缓存的本站页面后提交非法数据, 所以安全要求高的页面必须在服务器 接收端也进行数据合法性检查 =============================================================================================== 防范钓鱼攻击: 像银行这种网站的数据接收端(包括get,post)是可以通过检查$_SERVER['HTTP_REFERER']来避免钓鱼攻击的(一个合法 用户被诱骗从非法网站点击了向银行网站提交的表单),因为非法网站无法同时提交伪造的$_SERVER['HTTP_REFERER']和合法 用户的session:要么提交了合法用户的session却没伪造referer,要么伪造了referer却提交不了合法用户的session, 但是非法网站可以多绕一圈,先把鱼钓到不检查session的银行网站页面,再通过对该页面伪造js自动二次提交数据到真正的 接收端,所以银行网站即使不需检查session的普通页面(比如首页)也要防范提交数据对页面的影响,最好不允许普通页面接收 数据(包括url里get方式以及cookie) =============================================================================================== 简易html模板方法(需要在php 5.3里): (因为直接采用php函数进行模板操作, 所以不需要像smarty那样将smarty模板语言转php语言再缓存): (注意, 在$if()内的判断条件里的变量需要用双引号引起来, 因为: $s='substr';$k='abcdefg';echo "{$s("{$k}", 0, 4)}";得到'abcd', 而 $s='substr';$k='abcdefg';echo "{$s('{$k}', 0, 4)}";得到'{$k}'. ) (注意, 所有明文html里的双引号都要写成""", 否则模板eval时出错, 如果php 5.3正式版支持nowdoc嵌套于heredoc内(现在的5.3.0.beta1只支持nowdoc嵌在双引号内), 就不需要转"了, 我提了47516的bug后, PHP 5.3.0RC2已经支持nowdoc嵌套于heredoc内了) my_tpl.php: test.tpl: {$company} 职员:

{$foreach($info,<<<'FUN' 信息:{$if("{$name}"=='jack',"姓名:{$name}电话:{$tel}",'保密')}
FUN )}
{$foreach($info,<<<'FUN' 姓名:{$name}电话:{$tel}
FUN )}
"会员":{$if("{$flag}"=='1','是的呀',$if("{$flag}"=='0','不是',''))}

{$my_tpl($dat,'footer.tpl')} footer.tpl: Bye, {$company} test.php: 'kexianbin','tel'=>'7894'); $d['info'][1]=array('name'=>'jack','tel'=>'7411'); $d['flag']='1'; echo my_tpl($d,'test.tpl'); ?> =============================================================================================== 有时候偷懒, 想直接在双引号字串内使用函数: echo "123{${!${''}=substr}('abc',2,1)}456"; =============================================================================================== 不管大小写的字串比较:strtolower(aStr)!=strtolower(bStr) =============================================================================================== 去掉所有js\css\html\注释\空白,转换html实体: //依赖chr_utf8函数 function strip_all($str) {$search = array ("']*?>.*?'si", // remove javascript "']*?>.*?'si", // remove css "'<[/!]*?[^<>]*?>'si", // remove html tags "'

??您的网址:(可能:)呆元:2387年08月21日(19-09-25)访客总人次:433220(自k5a1)??
Copyleft 2364-2378 DIYism
Powered by Ubuntu Server & ZPC-GX
全民备TOR 安全上网