Jump to content
新域网络技术论坛

Search the Community

Showing results for tags 'PHP'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • 论坛服务
    • 公告栏
  • 技术讨论
    • IPB相关讨论
    • PHP技术探讨
    • FREEBSD讨论
    • 其它技术
    • 软件分享
  • 业余无线电
    • 使用指南
    • 设备讨论

Blogs

There are no results to display.

Product Groups

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


位置


兴趣


呼号

Found 30 results

  1. 使用场景模拟,例如:登录过程中,有很多相关日志、积分或者某些活动参加部分解耦,将这些相关联模块采用观察者模式,用户登录时添加这些观察者,通知一次,观察者们会自动调用相关的方法处理。避免登录模块中掺杂过多的其他方面的代码。 /** * 事件产生类 * Class EventGenerator */ abstract class EventGenerator { private $ObServers = []; //增加观察者 public function add(ObServer $ObServer) { $this->ObServers[] = $ObServer; } //事件通知 public function notify($msg = '') { foreach ($this->ObServers as $ObServer) { $ObServer->update($msg); } } } /** * 观察者接口类 * Interface ObServer */ interface ObServer { public function update($event_info = null); } /** * 观察者1 */ class ObServer1 implements ObServer { public function update($event_info = null) { var_dump($event_info); echo "观察者1 收到执行通知 执行完毕!\n"; } } /** * 观察者1 */ class ObServer2 implements ObServer { public function update($event_info = null) { var_dump($event_info); echo "观察者2 收到执行通知 执行完毕!\n"; } } /** * 事件 * Class Event */ class Event extends EventGenerator { /** * 触发事件 */ public function trigger() { //通知观察者 $this->notify(mt_rand(1, 10)); } } //创建一个事件 $event = new Event(); //为事件增加旁观者 $event->add(new ObServer1()); $event->add(new ObServer2()); //执行事件 通知旁观者 $event->trigger(); sleep(1); $event->trigger();
  2. 这个问题原来是C++的版本,目前在学习Java中,问题就用Java描述吧。 看代码:将变量a 和 b的值交换后输出。当然实际情况下,肯定不允许这样的情况发生,如果可以传指参的话,直接使用指参就可以了,比如PHP里可以直接使用 function doSwap(&$a, &$b) {...} 就可以了,我查了一下JAVA是没有指参的,所以不能这么处理。代码中还有部分不是太理解,逻辑是理解了,等后续再看吧。 public class Main { public static void main(String[] args) { Integer a, b; a = 1; b = 2; System.out.printf("a = %d, b = %d\n", a, b); try { doSwap(a, b); } catch (Exception e) { System.out.println(e.toString()); } System.out.printf("a = %d, b = %d\n", a, b); } private static void doSwap(Integer a, Integer b) throws Exception { // 请在这里实现交换过程 } } 我这里先给出一个PHP版本的解法,不使用Class的情况是可以实现的,如果限制在Class环境中,暂时还没想到实现方式,PHP中没有内存操作的概。: $a = 10; $b = 20; echo "a:{$a} b:{$b}\n"; doSwap($a, $b); echo "a:{$a} b:{$b}\n"; function doSwap($a, $b) { /* 请实现交换两个变量 预期结果: a:1 b:2 a:2 b:1 */ global $a, $b; $c = $a; $a = $b; $b = $c; } 看一下JAVA的实现方式,你没看错,就这个操作需要这么长的代码: import java.lang.reflect.Field; public class Main { public static void main(String[] args) { Integer a, b; a = 1; b = 2; System.out.printf("a = %d, b = %d\n", a, b); try { doSwap(a, b); } catch (Exception e) { System.out.println(e.toString()); } System.out.printf("a = %d, b = %d\n", a, b); } private static void doSwap(Integer a, Integer b) throws java.lang.Exception { // 请在这里实现交换过程 int c = a; Integer cInteger = new Integer(c); Class<? extends Integer> aClass = a.getClass(); Field avalue = aClass.getDeclaredField("value"); avalue.setAccessible(true); avalue.set(a, b); Class<? extends Integer> bClass = b.getClass(); Field bvalue = bClass.getDeclaredField("value"); bvalue.setAccessible(true); bvalue.set(b, cInteger); } }
  3. 从PHP5.3开始phar模块已经默认编译在里面了,直接使用就可以了。 使用前需要把php.ini中的只读权限去掉, [Phar] ; http://php.net/phar.readonly ;phar.readonly = On phar.readonly = Off 然后新建一个PHP文件 if (class_exists('\Phar')) { $phar = new \Phar('demo.phar', 0, 'demo.phar'); $phar->buildFromDirectory(__DIR__ . '/a1/'); $phar->setStub($phar->createDefaultStub('demo.php', 'index.php')); $phar->compressFiles(Phar::GZ); } else { exit('no Phar module'); } 然后运行一下这个新的文件,指定目录下的所有文件(包括其他资源文件,是所有文件)都会被打包到phar文件中,运行时这些文件都可以直接被PHP代码调用 。如果没有错误的话,当前目录会产生一个指定的phar文件。然后就可以随便把它放到哪个目录下调用了。
  4. 顺便把安装方式也一并添加一下吧。 报错如下: Warning: Invalid argument supplied for foreach() in Command.php on line 249 Warning: Invalid argument supplied for foreach() in /usr/local/share/pear/PEAR/Command.php on line 249 curl -O http://pear.php.net/go-pear.phar php go-pear.phar 一般安装在: /usr/local/bin/pecl ee `which pecl` 到最后一行,把-n 去掉就可以了。
  5. 很多情况下,用户频繁请求文件,会带走很多流量,其实有的时候根本没必要请求,怎么办呢?通过rewrite把所有的请求集中管理起来,判断有没有缓存,没缓存强制设置缓存,另外检查本地修改时间,如果已经修改直接更新,就是不知道上传到服务器上去的文件修改时间会不会一起改变,待测试! /* RewriteEngine on #RewriteBase /Test/ RewriteCond %{REQUEST_FILENAME} ^.*?\.(css|js|jpg|png)$ RewriteRule ^(.*)$ p304.php/$1 [QSA,PT,L] */ //静态文件尝试使用304方式优化 //缓存时间10年 $cache_time = 315360000; $root = $_SERVER['DOCUMENT_ROOT']; $file = $_SERVER['REQUEST_URI']; if (isset($_SERVER['REDIRECT_URL'])) { $file = $_SERVER['REDIRECT_URL']; }else{ $f = explode('?',$file); $file = $f[0]; } if (file_exists($root.$file)) { $is304 = false; if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) { $lt = strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]); $ft = filemtime($root.$file); if ($ft <= $lt) $is304 = true; } if ($is304) { header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified'); header("Cache-Control: max-age=$cache_time"); }else{ header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cache_time) . " GMT"); header("Cache-Control: max-age=$cache_time"); echo(file_get_contents($root . $file)); } }else{ header($_SERVER["SERVER_PROTOCOL"].' 404 Not Found'); }
  6. python里有个结巴分词工具,看着还不错,我们PHP上能够尝试用它么? 先来分词py脚本 : # -*- coding: UTF-8 -*- import sys import jieba import json str = "" for i in range(1, len(sys.argv)): str += sys.argv[i]+' ' if (str == ""): str = "他来到了网易杭研大厦" t = "jieba V"+jieba.__version__ out = {"TITLE":t} seg_list = jieba.cut(str, cut_all=True) #print("Full Mode: " + "/ ".join(seg_list)) # 全模式 out['FULL'] = "||".join(seg_list) seg_list = jieba.cut(str, cut_all=False) #print("Default Mode: " + "/ ".join(seg_list)) # 精确模式 out['DEF'] = "||".join(seg_list) #seg_list = jieba.cut(str) # 默认是精确模式 #print(", ".join(seg_list)) seg_list = jieba.cut_for_search(str) # 搜索引擎模式 #print(", ".join(seg_list)) out['SEARCH'] = "||".join(seg_list) print json.dumps(out) 再来PHP脚本: <?php //路径请自行定义 $script = '/usr/local/www/apache24/data/py/tst.py'; $str = "我家住在黄土高坡"; if (isset($_REQUEST['str'])) $str = $_REQUEST['str']; header('Content-Type:application/json;charset:UTF-8'); system("python {$script} {$str}"); 现在只有一个问题,运行速度有点慢,同样的文字,python端只需要0.2秒,但PHP请求需要2-3秒。。看样子后续还是要改成直接用python返回相应请求。
  7. 之前一直用PHPED的断点调试功能,它是采用的PHPDBG,没有合适的远程调试IDE。前期也一直在使用PHPStorm,与PHPED的大部分功能都很相像。当时唯一没搞出来的就是断点调试,经过一番摸索终于实现了。PHPStorm与PHPED相比的优点有以下几点: 1. 风格多变,可以有很多种不同类型的风格切换,虽然PHPED也有,但是变化不如它多,当然这也不是一个多大的优势 2. 支持其他扩展名解析为PHP文件(PHPED中不能实现) 3. 自带格式化代码功能,包括json/PHP/xml/html……(PHPED中需要用插件才能实现,并且不能同步这么多) 与PHPED相比感觉不如意的地方: 1. 代码提示中注释部分一直没有PHPED人性化 2. 各种配置较多,不如PHPED容易使用(也不能算什么缺点吧,毕竟功能多) 好了废话不多说了,两种情况,一种Windows,php.ini 配置文件如下: [Xdebug] zend_extension="F:\PHP\ext\php_xdebug-2.5.5-5.6-vc11-x86_64.dll" xdebug.profiler_enable=on xdebug.trace_output_dir="F:\PHP\xdebug" xdebug.profiler_output_dir="F:\PHP\xdebug" xdebug.remote_enable=on xdebug.remote_handler=dbgp xdebug.remote_host=0.0.0.0 xdebug.remote_port=9001 xdebug.idekey=PHPSTORM xdebug.remote_connect_back=1 freebsd中的php.ini [Xdebug] xdebug.remote_enable=on xdebug.remote_handler=dbgp xdebug.remote_host=0.0.0.0 xdebug.remote_port=9001 xdebug.idekey=PHPSTORM xdebug.remote_connect_back=1 PHP端的配置大概就是这样,然后看IDE中的配置吧。 安装浏览器插件:详见官网 https://confluence.jetbrains.com/display/PhpStorm/Browser+Debugging+Extensions 安装完后把IDE Key设置成和PHP端设置的一样,上面的配置中都是 PHPSTORM Languages & Frameworks / PHP / Debug Xdebug Debug Port: 9001 Languages & Frameworks / PHP / Debug / DBGp Proxy IDE Key: PHPSTORM HOST: 服务器或者本地IP Port:服务器端口,一般是80 Languages & Frameworks / PHP / Servers 添加一个服务器 HOST:服务器或者本地IP Port:服务器端口 Debugger: Xdebug Use path mappings: 将本地路径与服务器上的路径对应设置一下 保存就可以了。
  8. 日常开发中经常需要按照一定的规则将类文件放在指定目录,正常情况下需要include或require一堆文件,非常的不方便,一般来说可以使用spl_autoload_register进行自动加载,大型项目开发时还会用到namespace,特意整理了一份支持几种方式的自动调用。 /** * 根命名空间自动加载类 * 支持命名空间及正常方式加载类 * @since 2017-09-07 * @author Jamers */ namespace { @session_start(); if (!defined("ROOT")) { define("ROOT",dirname(__FILE__).DIRECTORY_SEPARATOR); } if (defined('STDIN')) chdir(dirname(__FILE__)); function autoload($cls) { $base = 'class'.DIRECTORY_SEPARATOR; if (strtolower($cls)=='smarty') { $file = ROOT.'libs/Smarty-3.1.30/Smarty.class.php'; }else{ $a = explode('\\',$cls); $a[count($a)-1] = 'Cls_'.ucfirst($a[count($a)-1]); $file = ROOT.$base.implode(DIRECTORY_SEPARATOR,$a).'.php'; } if (file_exists($file)) { include_once($file); }else{ try { $err = 'Can\'t found '.$file; throw new Exception($err); }catch(Exception $e){ exit($e->getFile().':'.$e->getLine().'<br><br> "'.$e->getMessage().'"<br><br><b>Track:</b><br>'.$e->getTraceAsString()); } } return true; } spl_autoload_register('autoload'); }
  9. 这是普通匹配的,PHP中能够使用: '%<(?<tag>[\w]+)([^>]*)>(.*?)</\k<tag>>%i' 这是递归匹配的,使用了正则的平衡组,PHP5.6的版本中还不运行,我测试了一下在C# .net中是支持的,希望PHP7.0的时候能够支持这种正则吧。 <(?<tag>[\w]+)([^>]*)>(.*?)((?<rept><\k<tag>([^>]*)|</\k<tag>>(?<-rept>)|.*?)*)</\k<tag>> 测试字符串: <a><b>test<b></a> <div>info1<div>info2</div></div> 匹配结果: Match 1: <a><b>test<b></a> 0 17 Group "tag": a 1 1 Group 1: 2 0 Group 2: 3 0 Group 3: <b>test<b> 3 10 Group "rept": 13 0 Group 4 did not participate in the match Match 2: <div>info1<div>info2</div></div> 19 32 Group "tag": div 20 3 Group 1: 23 0 Group 2: 24 0 Group 3: info1<div>info2</div> 24 21 Group "rept": 45 0 Group 4: 33 0
  10. 由于目前PHP上各类系统都良焉不齐,安全问题频发,个人又经常无法清楚所有的上传WebShell问题,导致安全问题频发,我们采用更为粗暴有效的方式进行限制,让上传到upload目录下的所有PHP文件都不能运行,就达到相应的目的了。如果有其他类型的文件也可同样处理。我服务器上有N多站点,只要在httpd.conf中添加这些内容,可以防范Apache下所有的站点安全。 <Directory ~ "/.*/upload"> #匹配所有名为upload的目录 <Files ~ "\.php$"> #匹配后缀是 .php 的文件 Order allow,deny Deny from all </Files> </Directory> <Directory ~ "/.*/uploadfile"> #匹配所有名为uploadfile的目录 <Files ~ "\.php$"> #匹配后缀是 .php 的文件 Order allow,deny Deny from all </Files> </Directory>
  11. 刚好有windows下连接sql server的需求,使用CI3.1.2框架进行连接,发现不管怎么样都无法连接,实在没办法,用底层函数连接试一下吧。 <?php $serverName = "127.0.0.1"; $connectionInfo = array( "Database"=>"gurms", "UID"=>"gurms", "PWD"=>"gurms"); $conn = sqlsrv_connect( $serverName, $connectionInfo); if( $conn ) { echo "Connection established.<br />"; }else{ echo "Connection could not be established.<br />"; die( print_r( sqlsrv_errors(), true)); } ?> 得到的结果是:
  12. PHP5开始导入自动加载(autoload)功能,闲来无事测试一下,以便日后使用,留下测试代码。 t1.php <?php function aload($c) { var_dump($c); if (file_exists($c.'.class.php')) { include_once($c.'.class.php'); return true; }else{ return true; } } spl_autoload_register('aload'); $t = new test(); echo $t->test1('Jamers'); $d = new TB(); var_dump($d); ?> test.class.php <?php class test { function test1($t) { return "Res:{$t}"; } } ?> 运行结果: string(4) "test" Res:Jamersstring(2) "TB" <br /> <b>Fatal error</b>: Class 'TB' not found in <b>test\t1.php</b> on line <b>16</b><br />
  13. 最近看到可以测试PHPED 14.0,之前一直在用PHPED 9.0,感觉各方面都还行,升到最新看看是否有什么变化吧。 安装完毕,打开原来做的项目,居然发现,从5.0以后解决得非常好的中文支持问题,在14.0上居然又出现半个字的情况,中文无法显示完整。其它变化也没多看,因为对于中文支持不好,我肯定接受不了。速度换回PHPED 9.0. 想想一个这么大的软件,居然会越搞越差。。难以理解。 如果哪位想使用PHPED的话,不建议使用14.0,9.0就很好!
  14. 我们有的时候要执行一个较长时间的查询动作,让客户端去等好象不太现实,让服务器去执行吧,到时候去取最终的结果就可以了。 调用方式: ajax('http://www.xxx.xxx/index.php?test=1'); ajax('http://www.xxx.xxx/index.php','post','123456'); 执行到这条语句的时候会延迟1ms,然后继续执行后面的代码,不会对用户造成影响。需要注意的是,这些代码是由服务端执行的,所以SESSION之类的操作无效,建议采用文件或数据库等第三方方式存储数据。否则可能造成功能无法实现,切记! function ajax($url,$mode='get',$data='') { $ch = curl_init(); // set URL and other appropriate options curl_setopt($ch, CURLOPT_URL,$url); if (strtolower($mode)=='post') { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_TIMEOUT_MS,1); // grab URL, and print curl_exec($ch); curl_close($ch); return true; }
  15. ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9/10/11,chrome,firefox,Safari等),底层依赖轻量级的Canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。 支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)、雷达图(填充雷达图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等12类图表,同时提供标题,详情气泡、图例、值域、数据区域、时间轴、工具箱等7个可交互组件,支持多图表、组件的联动和混搭展现。 由于它功能强大,生成的图表可以用惊艳来形容,无奈数据项太多,无法用程序完全生成option配置串,所以我写了这个模块直接把图表数据作为参数传入,并配置扩展设置 $opt,生成图表的类型三个参数传进去,就能得到option配置串,你安全可以生成出来后直接到网站进行预览,看是否配置正确。这里说明一下color模块是我写的一个自动生成多种颜色的模块,不是必须的,可以将这个去掉。$opt参数为扩展设置数组,具体请参照示例和官方网站的说明,大概思路就是option串里就是一个数组,自己设置键值和内容。 包括原先的思路也在类代码中特意没有删除,可以供参考。 DEMO代码如下: <?php include_once('cls_echarts.php'); //$dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99)); //$dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99),'X1'=>array('D1'=>100,'D2'=>200,'D3'=>150,'D4'=>190),'Y1'=>array('D1'=>99,'D2'=>80,'D3'=>88,'D4'=>100)); $dary = array('Num1'=>500,'Num2'=>300,'Label1'=>134,'Label2'=>338,'laebl3'=>115); $opt = array('series'=>array('radius'=>array('50%','70%'))); echo "<pre>"; echo (echarts::build_option($dary,$opt,'pie')); echo "</pre>"; ?> <?php /** * @see color */ include_once('cls_color.php'); /** * 生成echart图标的option参数,用以显示图形化数据 * @example include_once('cls_echarts.php'); //$dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99)); $dary = array('Num1'=>500,'Num2'=>300,'Label1'=>134,'Label2'=>338,'laebl3'=>115); $opt = array('series'=>array('radius'=>array('50%','70%'))); echo "<pre>"; echo (echarts::build_option($dary,$opt,'pie')); echo "</pre>"; * * @author Jamers 2015.11.26 * @since 1.0.0 初版完成 2015.11.26 */ class echarts { /** * 默认option数据数组 * * @var array */ static $def = array( 'tooltip' => array('trigger'=>'axis'), 'calculable' => true, ); /** * echarts图表类型遍历 值为magicType值 * * @var mixed */ static $type = array( 'line'=>'line,bar', //折线图 'bar'=>'line,bar', //柱形图 'scatter' => '', //散点图 'k' => '', //K线图 'pie' => 'pie,funnel',//饼图 'radar' => '', //雷达图 'chord' => 'force,chord', //和弦图 'force' => 'force,chord', //力导向图 'map' => '', //地图 'gauge' => '', //仪表盘 'funnel'=> '', //漏斗图 'heatmap' => '', //热力图 'eventRiver' => '', //事件河流图 'venn' => '', //韦恩图 'treemap' => '', //矩形图 'tree' => '', //树图 'wordCloud' => '', //字符云 ); /** * 单组数据类型 * * @var array */ static $single = array('pie','funnel','venn','treemap','map'); /** * 需要添加花括号的键值 * * @var mixed */ static $na = array('value'); /** * 需要添加方括号的键值 * * @var mixed */ static $ab = array('series'); /** * 默认toolbox样式 * * @var mixed */ static $toolbox = array( 'toolbox' => array( 'show' => true, 'feature' => array( 'mark' => array('show'=>true,), 'dataView' => array('show'=>true,'readOnly'=>false), 'restore' => array('show'=>true), 'saveAsImage' => array('show'=>true), ), ) ); /** * 需要使用中括号隔离的字段([]) * 默认使用花括号({}) * @since 2015.11.26 启用新算法,此处作废 * * @var mixed */ //static $bracket = array('data'=>'','series'=>'','xAxis'=>'','yAxis'=>'','center'=>'','color'=>'','type'=>'magicType'); /** * 需要添加花括号的字段 * @since 2015.11.26 启用新算法,此处作废 * * @var array */ //static $abracket = array('xAxis','yAxis'); /** * 实在没办法规避,用死方法,直接不加引号 * @since 2015.11.26 启用新算法,此处作废 * * @var array */ //static $nquote = array('series'); /** * 生成图表数据 * * @param mixed $dary 数据数组 标题=>数值 * @param boolean $single 单一数组(True饼图,False折线图) * * @example $dary = array('Num1'=>500,'Num2'=>300,'Label1'=>134,'Label2'=>338,'laebl3'=>115); * @example $dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99)); * @return array */ static function general_data($dary,$single=true) { $c = color::general_hex_color(count($dary)); $o = $l = array(); $l = array_keys($dary); //图例数组 //图例标题 if ($single) { //单组数据 foreach($dary as $k=>$v) { //$o[] = "{value:{$v}, name:'{$k}'}"; $o[] = array('value'=>$v,'name'=>$k); } return array('l'=>$l,'d'=>$o,'c'=>$c); }else{ //多组数据 $x = array(); $y = array(); foreach ($dary as $k => $v) { foreach ($v as $m => $n) { if (!isset($x[$m])) $x[$m] = $m; $y[$k][$m] = $n; } } $o = array(); foreach ($y as $k => $v) { foreach ($x as $m => $n) { $o[$k][$m] = $y[$k][$m]; } } $yy = array(); foreach($o as $k=>$v) { //$yy[$k]='['.implode(',',$v).']'; $yy[$k] = array_values($v); } return array( 'c'=>$c, 'l' => $l, 'x' => array_values($x), 'y' => $yy, ); } } /** * 数组内容中增加引号方便implode * * @param mixed $ary */ static function addquote($ary) { $r = array(); foreach ($ary as $k => $v) { $r[$k] = "'{$v}'"; } return $r; } /** * 新的数组构造函数,原build_array停用 2015.11.25 * * @param array $data 数据数组 * @param boolean $addkey 是否增加主键,暂时未使用 * @param int $dep 数组深度 */ static function build_data($data,$addkey=true,$dep=0) { $havekeys = false; $r = array(); if (is_array($data)) { foreach ($data as $k=>$v) { $a1='{';$a2='}'; $keys = (is_numeric($k)||!$addkey?'':"{$k}:"); //非字母数字添加双引号 preg_match('%[^a-z0-9/\\\\\s\t]*%i',$k,$x); //var_dump($x); if ($keys && $x[0]) $keys = '"'.$k.'":'; //TODO: 中文keys要加双引号未处理 geoCoord if (!$havekeys && $keys) $havekeys = true; $t = ''; if (is_array($v)) { $b1=$b2=''; if (!is_numeric($k) && in_array($k,self::$na)) {$a1='[';$a2=']';$b1='{';$b2='}';} //if (!is_numeric($k)&& in_array($k,self::$ab)) { // $DAT = self::build_data(array_values($v),$addkey,$dep+1); //}else{ $DAT = self::build_data($v,$addkey,$dep+1); //} //var_dump($DATA); if ((!$DAT['k'])) {$a1='[';$a2=']';} if (!is_numeric($k)&& in_array($k,self::$ab)) {$a1 = ($a1=='['?$a1:'['.$a1);$a2 = ($a2==']'?$a2:$a2.']');} $t1 = "{$b1}{$keys}{$a1}".$DAT['d']."{$a2}{$b2}"; //echo $t1; $r[] = $t1; }else if (is_bool($v)) { if ($v) { $t = 'true'; }else{ $t = 'false'; } }else if (is_string($v)) { $t = "'{$v}'"; }else{ $t = $v; } if ($t) $r[] = "{$keys}{$t}"; } } if ($dep>0) { $a1='';$a2=''; }else{ $a1='[';$a2=']'; } if ($dep==0) { $a1='{';$a2='}'; return $a1.implode(',',$r).$a2; }else{ if (!$data) $havekeys = true; return array('d'=>$a1.implode(',',$r).$a2,'k'=>$havekeys); } } /** * 将数组编译成js结构 * * @param mixed $ary * @param boolean $addkey 是否添加主键 * @param string $par 父键 */ /* static function build_array($ary,$addkey=true,$par='') { $r = array(); if (is_array($ary)) { foreach ($ary as $k=>$v) { $addkey = ($addkey && (!is_numeric($k))); $keys = ($addkey?"{$k}:":""); if (is_array($v)) { if (array_key_exists($k,self::$bracket)) { $a1 = $a2 = ''; //if ($k=='series') var_dump($v); if (in_array($k,self::$abracket) || (isset($v['type']) && isset($v['data']))) { $a1 = '{';$a2='}'; } $r[] = "{$keys}[{$a1}".self::build_array($v,$addkey,$k)."{$a2}]"; }else{ $r[] = "{$keys}{".self::build_array($v,$addkey,$k)."}"; } }else{ if (is_bool($v)) { if ($v) { $t = 'true'; }else{ $t = 'false'; } } else if (is_string($v)) { $nb = true; if (in_array($par,self::$nquote)) $nb = false; //if ((array_key_exists($k,self::$bracket))||(array_key_exists($par,self::$bracket))) { if ((array_key_exists($k,self::$bracket))) { //if ((array_key_exists($k,self::$bracket))) { //echo "par:{$par},k:{$k},bracket:".self::$bracket[$k]."<br>\r\n"; if (isset(self::$bracket[$par])&&(!self::$bracket[$par])&&(!self::$bracket[$k])) { $nb = false; }else if ($par==self::$bracket[$k]) { $nb = false; }else{ $nb = true; } } if ($nb) { $t = "'{$v}'"; }else{ $t = $v; } }else { $t = $v; } $r[] = "{$keys}{$t}"; } } return implode(',',$r); } return ''; } */ /** * 生成option配置串 * * @param mixed $data * @param array $opt 自定义值,合并进最终option * @param string $type 图表类型 */ static function build_option($data,$opt=array(),$type='bar') { //如果无类型默认BAR if (!isset(self::$type[$type])) $type='bar'; //$opt = array_merge_recursive($data,self::$def); $box = self::$toolbox; if (self::$type[$type]) { //有magictype设置 $mt = explode(',',self::$type[$type]); /* $tt = array(); foreach ($mt as $v) { $tt[] = "'{$v}'"; }*/ //$box['toolbox']['feature']['magicType'] = array('show'=>true,'type'=>'['.implode(',',$tt).']', $box['toolbox']['feature']['magicType'] = array('show'=>true,'type'=>$mt, 'option'=>array('funnel'=>array('x'=>'25%','width'=>'50%','funnelAlign'=>'left','max'=>1548)) ); } //$opt = array_merge_recursive($opt,$box); $s = (in_array($type,self::$single)?true:false); //if ($s) $box['tooltip']['trigger']='item'; //var_dump($type); //Todo: 单数据还是复杂数据 $d = self::general_data($data,$s); $a = array( 'color' => $d['c'], 'legend' => array('data'=>$d['l']), ); if (isset($d['x'])) { $a['xAxis'] = array('type'=>'category','data'=>$d['x']); $a['yAxis'] = array('type'=>'value'); } $ed = array(); if (isset($d['d'])) { //单组数据 $ed['type'] = $type; //$ed['data'] = '['.implode(',',$d['d']).']'; $ed['data'] = $d['d']; } if (isset($d['y'])) { //有多组数据 //var_dump($d['y']); //$ed = $d['y']; foreach ($d['y'] as $k=>$v) { //var_dump($v); //$ed[] = "{name:'{$k}',type:'{$type}',data:{$v}}"; $ed[] = array('name'=>$k,'type'=>$type,'data'=>$v); } } $a['series'] = $ed; $opt = array_merge_recursive($a,$opt,$box,self::$def); if ($s) { $opt['tooltip']['trigger']='item'; } //var_dump($opt); //$r = "option = {".self::build_array($opt)."};"; $r = "option = ".self::build_data($opt).";"; return $r; } } ?>
  16. curl有个功能可以直接交由后台处理访问链接,我在Windows下默认curl都有AsynchDNS功能的,在FREEBSD下发现居然是关闭的。直接造成访问链接前要等DNS查询到后才能够进行访问,直接等10秒左右哪受得了?所以想办法开启这个功能! 折腾了二三个小时,查阅资料无数,由于我使用的是Ports安装的,根本没有相应的选项可以设置,所以一抹黑。 后来直接先把curl升到最新版本把ares选上,然后再重装php55-curl,安装完成后自然就开启AsynchDNS的功能了。 备忘!自己注意PHP版本。以下是我服务器上的路径仅供参考。 curl /usr/ports/ftp/curl php模块 /usr/ports/ftp/php55-curl
  17. 包括协议,端口以及路径。 function getcururl() { $http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://'; $self = $_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']; return $http_type.$self; }
  18. 有的时候我们在网页源码中发现,有一大串编码的图片,比如下面的编码,我们能不能自己这样做呢?注意图片尽量小一点,否则太长可能会有反效果,因为这种类型的图片浏览器是不会缓存的,显示一次加载一次,太大的话增加自己网站的流出量也增加访问者的流量支出,一般情况下尽量不要超过20K,当然这个本身没有限制,即使你拿20M的图片编码也是可以的,土豪或者无视访客体验的可以无视之, :D <img width="20" height="20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAA81BMVEX///9VPnxWPXxWPXxWPXxWPXxWPXxWPXz///9hSYT6+vuFc6BXPn37+vz8+/z9/f2LeqWMe6aOfqiTg6uXiK5bQ4BZQX9iS4VdRYFdRYJfSINuWI5vWY9xXJF0YJR3Y5Z4ZZd5ZZd6Z5h9apq0qcW1qsW1q8a6sMqpnLyrn76tocCvpMGwpMJoUoprVYxeRoJjS4abjLGilLemmbrDutDFvdLPx9nX0eDa1OLb1uPd1+Td2OXe2eXh3Ofj3+nk4Orl4evp5u7u7PLv7fPx7/T08vb08/f19Pf29Pj39vn6+fuEcZ9YP35aQn/8/P1ZQH5fR4PINAOdAAAAB3RSTlMAIWWOw/P002ipnAAAAPhJREFUeF6NldWOhEAUBRvtRsfdfd3d3e3/v2ZPmGSWZNPDqScqqaSBSy4CGJbtSi2ubRkiwXRkBo6ZdJIApeEwoWMIS1JYwuZCW7hc6ApJkgrr+T/eW1V9uKXS5I5GXAjW2VAV9KFfSfgJpk+w4yXhwoqwl5AIGwp4RPgdK3XNHD2ETYiwe6nUa18f5jYSxle4vulw7/EtoCdzvqkPv3bn7M0eYbc7xFPXzqCrRCgH0Hsm/IjgTSb04W0i7EGjz+xw+wR6oZ1MnJ9TWrtToEx+4QfcZJ5X6tnhw+nhvqebdVhZUJX/oFcKvaTotUcvUnY188ue/n38AunzPPE8yg7bAAAAAElFTkSuQmCC" alt="Brand"> function base64_encode_image ($filename) { $type = array('jpg','png','gif','jpeg'); if (file_exists($filename)) { $a = pathinfo($filename); $ft = strtolower($a['extension']); if (in_array($ft,$type)) { $imgbinary = fread(fopen($filename, "r"), filesize($filename)); return 'data:image/' . $ft . ';base64,' . base64_encode($imgbinary); } } return ''; } echo '<img src="'.base64_encode_image ("a1.png").'"/>';
  19. 有的时候由于服务器无法修改设置,程序在服务器上运行有问题的时候一筹莫展,把下面的代码加到文件头部就可以看到错误信息了,什么?你是其它程序调用的看不到错误信息?没问题,也可以让你知道问题出在哪里! error_reporting(E_ALL); ini_set('display_errors', '1'); //将出错信息输出到一个文本文件 ini_set('error_log', dirname(__FILE__) . '/error_log.txt'); 普通调试上面二行用上就够了,如果是第三方调用中的错误可以三行加起来一起用,可以将错误信息保存成到文件里,让你运行完后,看错误日志,再去找原因。 今天在调试uploadify的时候,它可帮大忙了。因为脚本是swf调用的。
  20. 网上有很多这样的类,我也只是根据原有内容稍加修改,以适合我的要求。 文中内容出自:http://www.open-open.com/lib/view/open1378556584084.html 与上文中添加功能如下: 1. 修正目标生成缩略图目录指向功能,原代码无效 2. 增加前缀及后缀功能,用于自定义缩略图文件名 3. 修改少许参数类型 4. 使用完整路径以保证其它目录也可生成相应缩略图 附上代码: <?php /** * 功能:php生成缩略图片的类 * new ResizeImage('upload/abc.bmp', 120, 90, false, 'test/','aa|bc'); */ class ResizeImage{ /** * 缩略图生成类 * 来源:http://www.open-open.com/lib/view/open1378556584084.html * Modifyed by Jamers @ 2015.1.28 */ public $type;//图片类型 public $width;//实际宽度 public $height;//实际高度 public $add; //文件名前缀或后缀,默认前缀加t,用|分隔前缀后缀 public $resize_width;//改变后的宽度 public $resize_height;//改变后的高度 public $cut;//是否裁图 public $srcimg;//源图象 public $dstimg;//目标图象地址 public $im;//临时创建的图象 public $quality;//图片质量 //public $outimg; //输出的缩略图完整路径 /** * PHP生成缩略图类 * * @param string 图像文件 * @param interval 宽度 * @param interval 高度 * @param boolean 是否切图 * @param string 缩略图路径,用 /结尾 * @param string 前缀及后缀用 |分隔 * @param interval 图像品质 */ function resizeimage($img,$wid,$hei,$c,$dstpath='',$add='t|',$quality=100){ //$dstpath 为空时,默认为当前目录 $rp = pathinfo(realpath($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']))['dirname']; $this->srcimg=$img; $realpath = realpath($rp.'/'.$img); if ($realpath) $this->srcimg = $realpath; $this->resize_width=$wid; $this->resize_height=$hei; $this->cut=$c; $this->add = explode('|',$add); //0 前缀 1 后缀 $this->quality=$quality; $this->type=strtolower(substr(strrchr($this->srcimg,'.'),1));//图片的类型 $this->initi_img();//初始化图象 $this->dst_img($dstpath);//目标图象地址 @$this->width=imagesx($this->im); @$this->height=imagesy($this->im); $this->newimg();//生成图象 @ImageDestroy($this->im); } function newimg(){ $resize_ratio=($this->resize_width)/($this->resize_height);//改变后的图象的比例 @$ratio=($this->width)/($this->height);//实际图象的比例 if(($this->cut)==true){//裁图 if($img_func==='imagepng'&&(str_replace('.','',PHP_VERSION)>=512)){ //针对php版本大于5.12参数变化后的处理情况 $quality=9; } if($ratio>=$resize_ratio){//高度优先 $newimg=imagecreatetruecolor($this->resize_width,$this->resize_height); imagecopyresampled($newimg,$this->im,0,0,0,0,$this->resize_width,$this->resize_height,(($this->height)*$resize_ratio),$this->height); imagejpeg($newimg,$this->dstimg,$this->quality); } if($ratio<$resize_ratio){//宽度优先 $newimg=imagecreatetruecolor($this->resize_width,$this->resize_height); imagecopyresampled($newimg,$this->im,0,0,0,0,$this->resize_width,$this->resize_height,$this->width,(($this->width)/$resize_ratio)); imagejpeg($newimg,$this->dstimg,$this->quality); } }else{//不裁图 if($ratio>=$resize_ratio){ $newimg=imagecreatetruecolor($this->resize_width,($this->resize_width)/$ratio); imagecopyresampled($newimg,$this->im,0,0,0,0,$this->resize_width,($this->resize_width)/$ratio,$this->width,$this->height); imagejpeg($newimg,$this->dstimg,$this->quality); } if($ratio<$resize_ratio){ @$newimg=imagecreatetruecolor(($this->resize_height)*$ratio,$this->resize_height); @imagecopyresampled($newimg,$this->im,0,0,0,0,($this->resize_height)*$ratio,$this->resize_height,$this->width,$this->height); @imagejpeg($newimg,$this->dstimg,$this->quality); } } } function initi_img(){//初始化图象 if($this->type=='jpg' || $this->type=='jpeg'){ $this->im=imagecreatefromjpeg($this->srcimg); } if($this->type=='gif'){ $this->im=imagecreatefromgif($this->srcimg); } if($this->type=='png'){ $this->im=imagecreatefrompng($this->srcimg); } if($this->type=='wbm'){ @$this->im=imagecreatefromwbmp($this->srcimg); } if($this->type=='bmp'){ $this->im=$this->ImageCreateFromBMP($this->srcimg); } } function dst_img($dstpath){//图象目标地址 if ($dstpath=='') { //目标路径为空,当前目录 $dstpath = $this->srcimg; } $pa = pathinfo($this->srcimg); $dst = ($this->add[0]?$this->add[0].'_':'').$pa['filename'].($this->add[1]?'_'.$this->add[1]:'').'.'.$this->type; $dstpath = str_replace('\\','/',$dstpath); $dstpath = substr($dstpath,0,strrpos($dstpath,'/')); $this->dstimg=($dstpath?$dstpath.'/':'').$dst; //echo $this->dstimg; } function ImageCreateFromBMP($filename){ //自定义函数处理bmp图片 if(!$f1=fopen($filename,"rb")) return FALSE; $FILE=unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset",fread($f1,14)); if($FILE['file_type']!=19778) return FALSE; $BMP=unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'. '/Vcompression/Vsize_bitmap/Vhoriz_resolution'. '/Vvert_resolution/Vcolors_used/Vcolors_important',fread($f1,40)); $BMP['colors']=pow(2,$BMP['bits_per_pixel']); if($BMP['size_bitmap']==0)$BMP['size_bitmap']=$FILE['file_size']-$FILE['bitmap_offset']; $BMP['bytes_per_pixel']=$BMP['bits_per_pixel']/8; $BMP['bytes_per_pixel2']=ceil($BMP['bytes_per_pixel']); $BMP['decal']=($BMP['width']*$BMP['bytes_per_pixel']/4); $BMP['decal']-=floor($BMP['width']*$BMP['bytes_per_pixel']/4); $BMP['decal']=4-(4*$BMP['decal']); if($BMP['decal']==4)$BMP['decal']=0; $PALETTE=array(); if($BMP['colors']<16777216) { $PALETTE=unpack('V'.$BMP['colors'],fread($f1,$BMP['colors']*4)); } $IMG=fread($f1,$BMP['size_bitmap']); $VIDE=chr(0); $res=imagecreatetruecolor($BMP['width'],$BMP['height']); $P=0; $Y=$BMP['height']-1; while($Y>=0) { $X=0; while($X<$BMP['width']) { if($BMP['bits_per_pixel']==24) $COLOR=unpack("V",substr($IMG,$P,3).$VIDE); elseif($BMP['bits_per_pixel']==16) { $COLOR=unpack("n",substr($IMG,$P,2)); $COLOR[1]=$PALETTE[$COLOR[1]+1]; } elseif($BMP['bits_per_pixel']==8) { $COLOR=unpack("n",$VIDE.substr($IMG,$P,1)); $COLOR[1]=$PALETTE[$COLOR[1]+1]; } elseif($BMP['bits_per_pixel']==4) { $COLOR=unpack("n",$VIDE.substr($IMG,floor($P),1)); if(($P*2)%2==0)$COLOR[1]=($COLOR[1]>>4);else$COLOR[1]=($COLOR[1]&0x0F); $COLOR[1]=$PALETTE[$COLOR[1]+1]; } elseif($BMP['bits_per_pixel']==1) { $COLOR=unpack("n",$VIDE.substr($IMG,floor($P),1)); if(($P*8)%8==0)$COLOR[1]=$COLOR[1]>>7; elseif(($P*8)%8==1)$COLOR[1]=($COLOR[1]&0x40)>>6; elseif(($P*8)%8==2)$COLOR[1]=($COLOR[1]&0x20)>>5; elseif(($P*8)%8==3)$COLOR[1]=($COLOR[1]&0x10)>>4; elseif(($P*8)%8==4)$COLOR[1]=($COLOR[1]&0x8)>>3; elseif(($P*8)%8==5)$COLOR[1]=($COLOR[1]&0x4)>>2; elseif(($P*8)%8==6)$COLOR[1]=($COLOR[1]&0x2)>>1; elseif(($P*8)%8==7)$COLOR[1]=($COLOR[1]&0x1); $COLOR[1]=$PALETTE[$COLOR[1]+1]; } else return FALSE; imagesetpixel($res,$X,$Y,$COLOR[1]); $X++; $P+=$BMP['bytes_per_pixel']; } $Y--; $P+=$BMP['decal']; } fclose($f1); return $res; } } ?>
  21. 网络架构中常常要使用到子网掩码,手工计算相对麻烦,能不能让程序来计算出来呢? 目前代码生成的数据为可使用IP地址 <?php class cls_mask { /** * 子网掩码算法? * Jamers 2015.1.17 */ static function calc($ip) { $out = array(); $im = explode('/',$ip); $ia = explode('.',$im[0]); if (strpos($im[1],'.')===false) { $mv = intval($im[1]); }else{ $mv = self::getmaskval($im[1]); } $mask = self::getmask($mv); //默认C类 $count = 1; if ($mv<16) { //A类 $count = 3; }else if ($mv<24) { //B类 $count = 2; } $res = array(); $bin = array(); foreach($ia as $k=>$v) { $t = decbin(intval($v)); $t = str_repeat('0',8-strlen($t)).$t; $tmp = bindec($t) & intval($mask[$k]); $res[] = $tmp; $t = decbin($tmp); $t = str_repeat('0',8-strlen($t)).$t; $bin[] = $t; } //if ($mv<=) $start = str_repeat('0',32-$mv-1).'1'; $end = str_repeat('1',32-$mv-1).'0'; $flag = substr(implode('',$bin),0,$mv); $p = $mv-(4-$count)*8; $d = array(); if ($p) { $fp = substr($flag,0,-1*$p); $ss = 0; $se = bindec(str_repeat('1',$p)); for ($i=$ss;$i<=$se;$i++) { $aa = decbin($i); $add = str_repeat('0',$p-strlen($aa)).$aa; $ps = self::bintoip($fp.$add.$start); $pe = self::bintoip($fp.$add.$end); //echo "{$ps}-{$pe},(".self::getnums($ps,$pe).")<br>"; $d[] = "{$ps}-{$pe},(".self::getnums($ps,$pe).")"; } }else{ $ps = self::bintoip($flag.$start); $pe = self::bintoip($flag.$end); //echo "{$ps}-{$pe},(".self::getnums($ps,$pe).")<br>"; $d[] = "{$ps}-{$pe},(".self::getnums($ps,$pe).")"; } //echo "<br>{$count},{$p}<br>"; $list = implode('.',$res).'/'.implode('.',$mask).'('.$mv.')'; $out['list'] = $list; $out['data'] = $d; return $out; } static function bintoip($bin) { $ip = str_split($bin,8); $r = array(); foreach ($ip as $v) { $r[] = bindec($v); } return implode('.',$r); } static function getmask($n) { //根据子网掩码值取子网掩码 if ($n>32) $n = 32; $res = array(); $t = str_repeat('1',$n).str_repeat('0',32-$n); $tmp = str_split($t,8); foreach($tmp as $v) { $res[]=bindec($v); } return $res; } static function getmaskval($mask) { //取子网掩码值 $tmp = explode('.',$mask); $res = array(); foreach($tmp as $v) { $t = decbin(intval($v)); $t = str_repeat('0',8-strlen($t)).$t; $res[] = $t; } $t = implode('',$res); return strrpos($t,'1')+1; } static function getnums($ip1,$ip2) { /** * 取两个IP间的可用IP数 */ $n1 = self::getipval($ip1); $n2 = self::getipval($ip2); return abs($n1-$n2)+1; } static function getipval($ip) { /** * 将IP数值化 */ $r = explode('.',$ip); $val = 0; foreach($r as $k=>$v) { $val += $v*(pow(254,abs($k-3))); } return $val; } } $sp = '192.168.1.100/24'; if (isset($_REQUEST['i'])) $sp = $_REQUEST['i']; $pp = cls_mask::calc($sp); var_dump($pp); ?> $i = '192.168.1.0/29';的话返回结果如下: array(2) { ["list"]=> string(31) "192.168.1.0/255.255.255.248(29)" ["data"]=> array(32) { [0]=> string(27) "192.168.1.1-192.168.1.6,(6)" [1]=> string(28) "192.168.1.9-192.168.1.14,(6)" [2]=> string(29) "192.168.1.17-192.168.1.22,(6)" [3]=> string(29) "192.168.1.25-192.168.1.30,(6)" [4]=> string(29) "192.168.1.33-192.168.1.38,(6)" [5]=> string(29) "192.168.1.41-192.168.1.46,(6)" [6]=> string(29) "192.168.1.49-192.168.1.54,(6)" [7]=> string(29) "192.168.1.57-192.168.1.62,(6)" [8]=> string(29) "192.168.1.65-192.168.1.70,(6)" [9]=> string(29) "192.168.1.73-192.168.1.78,(6)" [10]=> string(29) "192.168.1.81-192.168.1.86,(6)" [11]=> string(29) "192.168.1.89-192.168.1.94,(6)" [12]=> string(30) "192.168.1.97-192.168.1.102,(6)" [13]=> string(31) "192.168.1.105-192.168.1.110,(6)" [14]=> string(31) "192.168.1.113-192.168.1.118,(6)" [15]=> string(31) "192.168.1.121-192.168.1.126,(6)" [16]=> string(31) "192.168.1.129-192.168.1.134,(6)" [17]=> string(31) "192.168.1.137-192.168.1.142,(6)" [18]=> string(31) "192.168.1.145-192.168.1.150,(6)" [19]=> string(31) "192.168.1.153-192.168.1.158,(6)" [20]=> string(31) "192.168.1.161-192.168.1.166,(6)" [21]=> string(31) "192.168.1.169-192.168.1.174,(6)" [22]=> string(31) "192.168.1.177-192.168.1.182,(6)" [23]=> string(31) "192.168.1.185-192.168.1.190,(6)" [24]=> string(31) "192.168.1.193-192.168.1.198,(6)" [25]=> string(31) "192.168.1.201-192.168.1.206,(6)" [26]=> string(31) "192.168.1.209-192.168.1.214,(6)" [27]=> string(31) "192.168.1.217-192.168.1.222,(6)" [28]=> string(31) "192.168.1.225-192.168.1.230,(6)" [29]=> string(31) "192.168.1.233-192.168.1.238,(6)" [30]=> string(31) "192.168.1.241-192.168.1.246,(6)" [31]=> string(31) "192.168.1.249-192.168.1.254,(6)" } }
  22. 最近想学习一下质数算法,拿了几个简单的方式去处理。 先看一下最最原始未通过任何优化的核心较验代码: function checkprime($val) { /** * 检测是否是质数,死模式 */ for ($i=2;$i<=sqrt($val);$i++) { if ($val%$i==0) { return false; } } return true; } //循环计算2-10000个质数,耗时0.07-0.09之间 从另一个地方取来的算法: function isPrime($n) {//TurkHackTeam AVP production if ($n <= 3) { return $n > 1; } else if ($n % 2 === 0 || $n % 3 === 0) { return false; } else { for ($i = 5; $i * $i <= $n; $i += 6) { if ($n % $i === 0 || $n % ($i + 2) === 0) { return false; } } return true; } } //循环计算2-10000 耗时0.02-0.04之间
  23. 翻资料找到以下内容,分享之。 //项目需要写了备忘 function xls_add($start,$add,$isy=0) { //起始单元表位置 增加字段 0 X向 1 Y向 $ru = '/([A-Z]{1,3})(\d{1,5})/si'; if (preg_match($ru,$start,$mat)) { if ($isy==0) { //X向 $mat[1] = cell_add($mat[1],$add); }elseif ($isy==1) { //Y向 $mat[2] = cell_add($mat[2],$add); } return $mat[1].$mat[2]; }else{ return $start; } } function cell_add($str,$add) { $ru0 = '/\d{1,5}/si'; $ru1 = '/[A-Z]{1,3}/si'; $str = strtoupper($str); if (!preg_match($ru0,$str) and !preg_match($ru1,$str)) return $str; if (preg_match($ru0,$str)) { //数字 return strval(intval($str)+$add); }else{ //字母 $tmp = 0; $all = 0; //'AA' = 26+1 BA = 26*2 +1 $len = strlen($str)-1; for ($i=$len;$i>=0;$i--) { $tmp = (ord($str[$i])-ORD('A')+1); $all += $tmp*pow(26,$len-$i); } $all += $add; $r = ''; for ($i= 2;$i>0;$i--) { if ($all > pow(26,$i)) { $tmp = floor($all/pow(26,$i)); $all -= $tmp*pow(26,$i); $r .= chr(ord('A')+$tmp-1); } } if ($all>0) $r .= chr(ord('A')+$all -1); return $r; }
  24. 最近整理硬盘,发现了许多年前做的东西,拿出来分享一下吧,如果能够用上就拿去用吧。里面有具体调用示例。 <?php /* 充值卡生成、验证模块 Jamers 2012.2.1 */ class prepay { var $keylen=10; //卡号总长度 var $passlen=10; //密码总长度 const KEY = '0123456789'; //卡号允许出现的字符串 const PASS = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ'; //密码字符串列表 const KEYCHK = 'E01A2C34FD567B89'; //检查卡号和密码匹配性 public function check($id,$pass) { if ($this->chk_key($id)) { //ID没问题 if (strtoupper(substr($pass,-2,1)) == $this->gen_fkey($id)) { //卡号较验正常 if (strtoupper(substr($pass,-1)) == $this->gen_pass_chk(substr($pass,0,strlen($pass)-1))) { return true; } } } return false; } //批量生成卡号和密码 public function batch_genstr($num,$prefix='W000000000') { $result = ''; $id = $prefix; for ($i=0;$i<$num;$i++) { $id = $this->gen_key($id); $pass = $this->gen_pass($id); $result .= $id.','.$pass.','; } $result = substr($result,0,strlen($result)-1); return $result; } public function batch_genary($num,$prefix='W000000000') { $result = array(); $id = $prefix; for ($i=0;$i<$num;$i++) { $id = $this->gen_key($id); $pass = $this->gen_pass($id); $result[$i] = $id.','.$pass; } return $result; } //生成密码,$pid为充值卡号 如果不写肯定错误 public function gen_pass($pid) { $result = ''; if ($this->chk_key($pid)) { //卡号正确 $result = $this->randit(self::PASS,$this->passlen-2); $result .= $this->gen_fkey($pid); //卡号较验 $result .= $this->gen_pass_chk($result); //总密较验 } return $result; } //生成卡号 密码位较验码 private function gen_fkey($key) { $value = 10; for ($i=0;$i<strlen($key);$i++) { $k = $i % 3; switch ($k) { case 0: $value +=ord($key[$i]); break; case 1: $value +=ord($key[$i])*2; break; case 2: $value -=ord($key[$i]); break; } } return substr(self::PASS,$value%strlen(self::PASS),1); } //生成密码较验码 private function gen_pass_chk($pass) { $value = 255; for ($i=0;$i<strlen($pass);$i++) { $k = $i % 2; if ($k == 0) { $value += ord($pass[$i]); }else{ $value -= ord($pass[$i])-30; } } return substr(self::PASS,$value%strlen(self::PASS),1); } public function gen_key($prefix='') { $result = ''; if ($prefix == '') { //没预定义卡号 $result = $this->randit(self::KEY,$this->keylen-1); }else{ //有上一个卡号 if (strlen($prefix)<$this->keylen) { //长度不够 $result = $prefix.$this->randit(self::KEY,$this->keylen-1-strlen($prefix)); }else{ $result = substr($prefix,0,$this->keylen-1); $result = $this->nextval($result); } } $result .= $this->gen_key_chk($result); return $result; } //生成下一个卡号 private function nextval($key) { $bit = strlen($key)-1; $tmp = substr($key,$bit,1); $pos = strpos(self::KEY,$tmp); if ($pos === false) return $key; if ($pos>=strlen(self::KEY)-1) { $result = $this->nextval(substr($key,0,$bit)).substr(self::KEY,0,1); }else{ $result = substr($key,0,$bit).substr(self::KEY,$pos+1,1); } return $result; } //生成卡号较验码 private function gen_key_chk($key) { $chkvalue = 151; for($i=0;$i<=strlen($key);$i++) { $chkvalue += ord(substr($key,$i,1))+3; } $chkvalue = $chkvalue % 100; //$test = $chkvalue%strlen(self::KEYCHK); //echo "(".$chkvalue.'%'.strval(strlen(self::KEYCHK)+1).'='.$test.")"; return substr(self::KEYCHK,$chkvalue%strlen(self::KEYCHK),1); } //验证卡号 private function chk_key($key){ if (strlen($key) != $this->keylen) { return false; }else{ $chk = substr($key,-1); $v = $this->gen_key_chk(substr($key,0,$this->keylen-1)); if ($chk != $v) return false; } return true; } //随机生成字符串 private function randit($strlist,$len) { $result = ''; while (strlen($result)<$len) { $result .= substr($strlist,mt_rand(0,strlen($strlist)),1); } return $result; } } $test = new prepay; $ary = $test->batch_genary(100); print_r($ary); if ($test->check('WG00000017','175833VTVC')) { echo 'True!'; }else{ echo 'False'; } /*$tmp = $test->gen_key('W000000000'); //$next = $test->nextval(substr($tmp,0,strlen($tmp)-1)); echo $tmp.'('.strlen($tmp).')<br><br>'; //echo "<br><br>{$next}<br>"; $pass = $test->gen_pass($tmp); echo "{$pass}(".strlen($pass).")"; $id = 'W000000018'; //$pass = 'TN9K3955JP'; $pass = 'TN9K3955JN'; $tmp = $test->check($id,$pass); echo "<br><br>卡号:{$id}<br>密码:{$pass}<br><br>"; if ($tmp) { echo "为有效卡号密码"; }else{ echo "无效数据!"; } */ /* W000000018(10) TN9K3955JP(10) if (isset($_REQUEST['key'])) { $key = $_REQUEST['key']; $tmp = $test->chk_key($key); if ($tmp) { echo "{$key}是合法的卡号"; }else{ echo "{$key}是错误的卡号"; } } */ ?>
  25. 我们平常能够使用到的防火墙大多是规则设置好后,然后就等人工分析相应日志后更新相应规则,这样就没有多少时效性,不能及时保证系统的安全。所以才萌发出搞个主动屏蔽的功能。 目前这套系统仅能够运行在启用ipfw的类*NIX或*BSD的系统中,当然PHP和mysql必不可少。另外程序只能够以root的身份在命令行状态进行执行,因为IPFW必须有root权限才能够操作。 系统原理为:定期执行相应程序分析指定日志文件(可以设置多个),从日志文件中挑出对系统不利的操作,一旦达到设定阀值后,即将指定IP临时屏蔽(按目前系统设定,那么接下来的24小时,此IP将无法访问本服务器),如果多次被屏蔽,将会被直接移至黑名单中,那样将永久屏蔽此IP的访问。具体可在config.php配置文件中修改。 以下帖出部分核心文件,完整的文件将在最下面提供下载。此程序仅供抛砖引玉,如果有更好的方案,可以一起探讨共同成长。如果此工具能够帮到一些朋友,我将不胜荣幸,如果有任何BUG之类的,也可以及时与我联系共同把此工具做好。 安装方式: 注意本程序仅供有足够unix操作经验的网友使用,权限方面的问题不多讲。 1. 首先没有conn.php,需要选执行一次 install.php,程序会自动生成conn.php 2. 待conn.php生成后,修改并创建相应mysql数据库及用户后再次运行install.php 3. 然后修改config.php,重要的是将各需要扫描的apache访问日志文件完整路径写上,原配置文件中的文件仅供测试使用 4. 修改crontab以root身份,每10到15分钟运行一下 php firewall.php ,这个时间可以根据自己的实际情况进行调整 5. 如果有需要加入白名单的IP地址以防止误封,可以手工在whitelist表中添加相应记录。 6. 如果事先有需要加入黑名单的IP地址也可以手工在blacklist表中添加相应记录 config.php <?php DEFINED('ROOT_DIR') || DEFINE('ROOT_DIR',dirname(__FILE__)); if (file_exists(ROOT_DIR.'/conn.php')) include_once(ROOT_DIR.'/conn.php'); class config { /** * 配置文件 Jamers 2015.1.5 */ static $dellogtime = -1; //删除数据时间 31*24*60*60 -1为不删除 static $blockvalue = 50; //屏蔽阀值,一天触发规则多少次 static $step = 1; //ID步行 static $white_start = 1100; //白名单起始ID static $white_set = 10; //白名单规则集 static $black_start = 1500; //黑名单起始ID static $black_set = 11; //黑名单规则集 static $temp_start = 10000; //临时屏蔽起始ID static $temp_set = 15; //临时屏蔽规则集 static $temp_durt = array(0 => 1,1 => 7,2 => -1); //临时屏蔽时间天数 -1为永久 static $ipfw = '/sbin/ipfw'; //IPFW完整路径,否则CRON无法执行 static $debug = false; //DEBUG标志 static $debug_out = 'debug.txt'; //DEBUG输出文件 static $list = array( 'data/bbs.zomew.net-access_log', ); //需要扫描的日志文件 static $filter = array( ' 404 ','%20and%20','%20or%20','/**/or/**/','phpinfo.php','act=phpinfo','phpmyadmin','%20union%20','select%20','><script>','=alert(', ); //需要过滤的内容 static $ignore = array( 'robots.txt','google=', ); //忽略列表数据,比如robots.txt //调用语句:cat 文件名 | grep -i "19/Dec/2014" | grep -i " 404 \|phpinfo.php" | grep -vi "robots.txt" } ?> cls_firewall.php 核心文件 <?php DEFINED('ROOT_DIR') || DEFINE('ROOT_DIR',dirname(__FILE__)); include_once(ROOT_DIR.'/config.php'); include_once(ROOT_DIR.'/cls_mysql.php'); class cls_firewall { /** * IPFW防火墙处理脚本,原设想自动根据apache日志屏蔽相应恶意访问IP * * Jamers 2015.1.5 */ public $vars=array(); public $DB; public $step = 1; private $dt,$ipfw,$debug,$debug_out; private $filter,$ignore; private $type = array('white','black','temp'); public $ids = array('white'=>1100,'black'=>1500,'temp'=>10000); public $sets = array('white'=>10,'black'=>11,'temp'=>15); public $qsql = array( 'white' => 'select ip from whitelist;', 'black' => 'select ip from blacklist;', 'temp' => 'select ip from blocked where stime+durt>=UNIX_TIMESTAMP()', ); public $output; //输出的语句 private $support; function __construct() { $this->step = config::$step; $this->ids['white'] = config::$white_start; $this->ids['black'] = config::$black_start; $this->ids['temp'] = config::$temp_start; $this->sets['white'] = config::$white_set; $this->sets['black'] = config::$black_set; $this->sets['temp'] = config::$temp_set; $this->dt = config::$dellogtime; $this->ipfw = config::$ipfw; $this->debug = false; $this->debug = config::$debug; $this->debug_out = config::$debug_out; $this->filter = implode('\\|',config::$filter); $this->ignore = implode('\\|',config::$ignore); $this->checksystem(); } private function checksystem() { $res = array(); $this->support = false; if (php_sapi_name()!='cli') return false; @exec('/usr/bin/uname',$res); //检测uname if ($this->debug) { $dd = var_export($res,true); $this->append($this->debug_out,'/usr/bin/uname'."\r\n".$dd."\r\n"); } if (count($res)>0) { $res = array(); @exec('/usr/bin/whoami',$res); //var_dump($res); if ($this->debug) { $dd = var_export($res,true); $this->append($this->debug_out,'/usr/bin/whoami'."\r\n".$dd."\r\n"); } if ($res[0]=='root') $this->support = true; } return $this->support; } function execute() { /** * 主调用程序,分析相应日志,并生成防火墙命令语句并执行 */ if (! $this->support) die('Your system is unable to support this program!this program need command line shell and root execute!'); //windows系统直接退出,不让玩! $this->loaddata(); //从日志文件中取得相应IP资料 //echo "1"; $this->delete_old_data(); //删除过期数据 //echo "2"; $t = $this->exec_filter(); //执行过滤语句 //var_dump($t); //echo date('Y-m-d H:i:s'); return date('Y-m-d H:i:s'); } function init_DB() { $this->DB = new cls_mysql($this->vars['dbhost'],$this->vars['dbuser'],$this->vars['dbpass'],$this->vars['dbname']); } private function checklist($ip) { /** * 检查是否在黑白名单中,在的话返回True */ $res = false; $sql = "select count(*) from ((select DISTINCT ip from whitelist) union (select DISTINCT ip from blacklist)) a where ip='{$ip}';"; $rs = $this->DB->getOne($sql,MYSQL_NUM); if (intval($rs[0])>0) $res = true; return $res; } private function loaddata() { /** * 读取日志数据 */ foreach (config::$list as $v) { $res = array(); $dstr = date('d/M/Y'); //$dstr = '19/Dec/2014'; //DEBUG专用 $p = '/^\s*(\d+)\s+([\d\.]+)$/'; $cmd = "/bin/cat {$v} | /usr/bin/grep -i '{$dstr}' | /usr/bin/grep -i '{$this->filter}' | /usr/bin/grep -vi '{$this->ignore}' | /usr/bin/awk '{print \$1}' | /usr/bin/sort | /usr/bin/uniq -c | /usr/bin/sort -nr "; if ($this->debug) $this->append($this->debug_out,$cmd); @exec($cmd,$res); if ($this->debug) { $dd = var_export($res,true); $this->append($this->debug_out,"\r\n".$dd."\r\n"); } foreach ($res as $v) { preg_match($p,$v,$t); $cc = 0; if (intval($t[1])>=config::$blockvalue) { //超过阀值,加入数据库,加入前先检查是否已有数据 //如果在黑名单中,应该就不会出现在这里了吧? $ip = trim($t[2]); $sql = "select count(id) from blocked where ip='{$ip}' and stime>UNIX_TIMESTAMP(DATE_FORMAT(now(),'%Y-%m-%d 0:0:0'))"; $rs = $this->DB->getOne($sql,MYSQL_NUM); if ($rs[0]<=0) { //当天没数据,加! if (! $this->checklist($ip)) { //检测是否在黑白名单中 $max = max(config::$temp_durt); $sql = "select count(id) from blocked where ip='{$ip}' and stime<UNIX_TIMESTAMP(DATE_FORMAT(now(),'%Y-%m-%d 0:0:0')) and stime>=UNIX_TIMESTAMP(DATE_FORMAT(DATE_SUB(now(),INTERVAL {$max} DAY),'%Y-%m-%d 0:0:0'))"; //N天内 $rs = array(); $rs = $this->DB->getOne($sql,MYSQL_NUM); if ($rs[0]>=0) { $cc = intval($rs[0]); } $ary = array('ip'=>$ip,'stime'=>time()); $ary['durt'] = config::$temp_durt[$cc]; if ($ary['durt']==-1) { $this->DB->do_insert('blacklist',array('ip'=>$ip,'addtime'=>time())); }else{ $ary['durt'] *= 24*60*60; $this->DB->do_insert('blocked',$ary); } } } } } } } private function delete_old_data() { /** * 删除过期数据 原设置为31天 * * @var mixed */ if ($this->dt >=0) { $sql = "delete from blocked where stime+durt+{$this->dt} < UNIX_TIMESTAMP();"; //echo $sql; $this->DB->execute($sql); } } private function buildall() { /** * 从数据库取所有IP数据,返回IPFW语句 * */ $res = ''; foreach ($this->type as $v) { $res .= "{$this->ipfw} delete set {$this->sets[$v]};"; $res .= $this->buildrule($v); } $this->output = $res; return $res; } private function exec_filter($len=1024) { //echo 'here!'; if ($this->output=='') $this->buildall(); if ($this->output=='') return 'NULL'; //var_dump($this->output); $str = $this->output; $res = array(); while (strlen($str)>0) { if (strlen($str)<=$len) { $res[] = $str; @exec($str); $str = ''; }else{ $tmp = substr($str,0,$len); $pos =strrpos($tmp,';'); $out = substr($tmp,0,$pos+1); $res[] = $out; @exec($out); $str = substr($str,$pos+1); } } if ($this->debug) { $dd = var_export($res,true); $this->append($this->debug_out,"exec_filter\r\n".$dd."\r\n"); } return $res; } private function buildrule($type) { /** * 生成相应ipfw语句 * * Jamers 2015.1.5 */ $res = ''; if (isset($this->qsql[$type])) { $sql = $this->qsql[$type]; $rs = $this->DB->getAll($sql,MYSQL_NUM); if ($rs) { foreach ($rs as $v) { $opt = strtolower($type)=='white'?'allow':'deny'; $res .= "{$this->ipfw} -q add {$this->ids[$type]} set {$this->sets[$type]} {$opt} ip from {$v[0]} to me;"; $this->ids[$type]+=$this->step; } return $res; }else{ return ''; } }else{ return ''; } } private function append($file,$str) { $fp = fopen($file,'a'); fwrite($fp,$str); fclose($fp); } } ?> firewall.php 调用主程序 <?php DEFINED('ROOT_DIR') || DEFINE('ROOT_DIR',dirname(__FILE__)); include_once(ROOT_DIR.'/cls_firewall.php'); $fw = new cls_firewall(); if (isset($INFO)) { $fw->vars = $INFO; $fw->init_DB(); }else{ die('system config error!'); } echo $fw->execute(); ?> firewall.rar
×
×
  • Create New...