手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表Tag:php

重写PHP的fgetcsv函数

内容来自虫少侠的enjoyphp.com,因为很多时候我们都使用了fgetcsv,只是我们有时候都还在使用file,再explode处理,相反却忽略了这个系统函数,然而,用虫少侠的话来说,这个函数还是有BUG的,主要是在处理中文上,因此就有了这个函数:

function fgetcsv_reg(& $handle, $length = null, $d = ',', $e = '"') {
    $d = preg_quote($d);
    $e = preg_quote($e);
    $_line = "";
    $eof=false;
    while ($eof != true) {
        $_line .= (empty ($length) ? fgets($handle) : fgets($handle, $length));
        $itemcnt = preg_match_all('/' . $e . '/', $_line, $dummy);
        if ($itemcnt % 2 == 0)
            $eof = true;
    }
    $_csv_line = preg_replace('/(?: |[ ])?$/', $d, trim($_line));
    $_csv_pattern = '/(' . $e . '[^' . $e . ']*(?:' . $e . $e . '[^' . $e . ']*)*' . $e . '|[^' . $d . ']*)' . $d . '/';
    preg_match_all($_csv_pattern, $_csv_line, $_csv_matches);
    $_csv_data = $_csv_matches[1];
    for ($_csv_i = 0; $_csv_i < count($_csv_data); $_csv_i++) {
        $_csv_data[$_csv_i] = preg_replace('/^' . $e . '(.*)' . $e . '$/s', '$1', $_csv_data[$_csv_i]);
        $_csv_data[$_csv_i] = str_replace($e . $e, $e, $_csv_data[$_csv_i]);
    }
    return empty ($_line) ? false : $_csv_data;
}

原文来自:http://www.enjoyphp.com/2009/lamp/php-lamp/php-fgetcsv/

 

Tags: fgetcsv

scala是什么

前两天一直在说scala,有几个朋友问我什么 是Scala,每次让他们翻一下google也太累了,所以我就贴在博客上,当然这也是找出来的东西,我没有能力写这么多。

我个人还是认为,不管怎么样,WEB、winform、console(shell)三种编程效果的程序语言最好都要熟悉一种,不管是为了将来的职业发展还是工作应用,都会有很大的方便。
OK,开始介绍:

Scala是一门现代的多范式编程语言,志在以简练、优雅及类型安全的方式来表达常用编程模式。它平滑地集成了面向对象和函数语言的特性。

  • Scala是面向对象的:Scala是一个纯面向对象语言,在某种意义上来讲所有数值都是对象。对象的类型和 行为是由class和trait来描述的。Class的抽象可由子类化和一种灵活的基于mixin的组合机制(它可作为多重继承的简单替代方案)来扩展。
  • Scala是函数式的: Scala还是一个函数式语言,在某种意义上来讲所有函数都是数值。Scala为定义匿名函数提供了一种轻量级的语法,它支持高阶(higher- order)函数、允许函数嵌套、支持局部套用(currying)。Scala的case类及其内置支持的模式匹配模型代数类型在许多函数式编程语言中 都被使用。
  • Scala是静态类型的:Scala配备了一套富有表现力的类型系统,该抽象概念以一种安全的和一致的方式被 使用。
  • Scala是可扩展的:Scala的设计承认了实践事实,领域特定应用开发通常需要领域特定语言扩展。 Scala提供了一个独特的语言组合机制,这可以更加容易地以类库的形式增加新的语言结构:
    • 任何方式可以被用作中缀(infix)或后缀(postfix)操作符
    • 闭包按照所期望的类型(目标类型)自动地被构造
    两者结合使用可方便地定义新语句,无需扩展语法,也无需使用类似宏的元编程工具。
  • Scala可与Java和.NET进行互操作:Scala 设计时就考虑了与流行编程环境良好交互,如Java 2运行时环境(JRE)和 .NET框架(CLR)。特别是与主流面向对象语言,如Java和C#尽量无缝交互。Scala有像Java和C#一样的编译模型(独立编译,动态装载 类),允许访问成千上万的高质量类库。

来源:http://www.oschina.net/p/scala

Tags: scala, java

PHP 技巧:file_get_contents的超时处理

话说,从PHP5开始,file_get_content已经支持context了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_contents其实也可以POST数据,关于这个,我在通过file_get_contents来 Post数据的实例也有所介绍。

今天说的这篇是讲超时的,确实在跨服务器提交的时候,不可避免的会遇到超时的情况,这个时候怎么办?set_time_limit是没有用的,只有用context中的timeout时间来控制。相反,我们不是要抑止,而是要管理。比如在超时返回错误后,进行一次尝试,就象js中的settimeout那样,对函数重新处理。错误超过3次或者5次后,我们就确实的认为无法连接服务器而彻底放弃。这,是一个好办法,应该值得推荐使用。其实。不全是file_get_contents,只要支持context的都应该加上,避免超时浪费时间。这样可以被支持的函数大致有:fsocketopen(该函数的最后一个参数。好象比较推荐在读stream的时候,使用stream_time_out函数进行控制),fopen(也是从PHP5开始加入context支持),file(PHP5加入支持),curl(curl有自已的变量CURLOPT_TIMEOUT)等 。

下面开始看原文吧:http://xinsync.xju.edu.cn/index.php/archives/6840。

因为要用php去向我的虚拟主机管理系统发送开通空间等的请求,需要Post传值,由于开通空间过程很慢,同时需要延时处理。以下找到了一下 file_get_contents的超时处理,网上有人用2个方法解决:

在使用file_get_contents函数的时候,经常会出现超时的情况,在这里要通过查看一下错误提示,看看是哪种错误,比较常见的是读取超 时,这种情况大家可以通过一些方法来尽量的避免或者解决。这里就简单介绍两种:

一、增加超时的时间限制

这里需要注意:set_time_limit只是设置你的PHP程序的超时时间,而不是file_get_contents函数读取URL的超时时 间。
我一开始以为set_time_limit也能影响到file_get_contents,后来经测试,是无效的。真正的修改 file_get_contents延时可以用resource $context的timeout参数:

PHP代码
  1. $opts = array(  
  2.     'http'=>array(  
  3.         'method'=>"GET",  
  4.         'timeout'=>60,  
  5.     )  
  6. );  
  7.    
  8. $context = stream_context_create($opts);  
  9.    
  10. $html =file_get_contents('http://www.example.com', false, $context);  
  11. fpassthru($fp);  
二、一次有延时的话那就多试几次

有时候失败是因为网络等因素造成,没有解决办法,但是可以修改程序,失败时重试几次,仍然失败就放弃,因为file_get_contents()如果失 败将返回 FALSE,所以可以下面这样编写代码:
PHP代码
  1. $cnt=0;  
  2. while($cnt < 3 && ($str=@file_get_contents('http...'))===FALSE) $cnt++;  
以上方法对付超时已经OK了。那么Post呢?细心点有人发现了’method’=>”GET”, 对!是不是能设置成post呢?百度找了下相关资料,还真可以!而且有人写出了山寨版的post传值函数,如下:
PHP代码
  1. function Post($url$post = null)  
  2. {  
  3.     $context = array();  
  4.    
  5.     if (is_array($post)) {  
  6.         ksort($post);  
  7.    
  8.         $context['http'] = array (  
  9.             'timeout'=>60,  
  10.             'method' => 'POST',  
  11.             'content' => http_build_query($post'''&'),  
  12.          );  
  13.     }  
  14.    
  15.     return file_get_contents($url, false, stream_context_create($context));  
  16. }  
  17.    
  18. $data = array (  
  19.     'name' => 'test',  
  20.     'email' => 'test@gmail.com',  
  21.     'submit' => 'submit',  
  22.  );  
  23.    
  24.  echo Post('http://www.example.com'$data);  

OK , 上面函数完美了,既解决了超时控制又解决了Post传值。再配合康盛的改良版RC4加密解密算法,做一个安全性很高的webservice就简单多了。

通过以上函数的组合,终于实现了PHP和我的ASP版虚拟主机管理软件的通信。.net相信也很容易了,因为已经有了.net版本的 authcode类。未来再做一个java版的就天下大同了。

--EOF--

我只能说这样的处理好是好,只是还得注意文件头的Set_time_out,否则整个文件都得超时了。呵呵

 

 

Tags: settimelimit, timeout, filegetcontents, context

一次糟糕的测试

关于飞信,我上次写过学着写PHP飞信,然而今天晚上我把上文中测试的内容重现时却发现,现实有点残酷。我用curl的时候,速度居然没有fsocketopen快?我于是多次测试,然而,我却得到了一些令人沮丧的结果

【$postData,$postLength,都不提供。。。】

1、curl,利用curl来post

平均【大约 1.8~1.9秒】
  1. $ch = curl_init();  
  2. $chOptions = array(  
  3.     CURLOPT_URL => "http://nav.fetion.com.cn/nav/getsystemconfig.aspx",  
  4.     CURLOPT_HTTP_VERSION => 'HTTP/1.0',  
  5.     CURLOPT_USERAGENT => sprintf('IIC2.0/pc %s' , self::FETION_CLIENT_VERSION),  
  6.     CURLOPT_ENCODING => 'gzip,deflate',  
  7.     CURLOPT_HTTPHEADER => array('Content-Type: text/xml; charset=utf-8'),  
  8.     CURLOPT_POST => 1,  
  9.     CURLOPT_POSTFIELDS => $postData ,  
  10.     CURLOPT_RETURNTRANSFER => 1,  
  11.     CURLOPT_HEADER => 0  
  12. );  
  13. curl_setopt_array($ch$chOptions);  
  14. $res = curl_exec($ch);  

 2、fsocketopen,同样POST数据

平均【大约 0.8~0.9秒】
  1. $headers=<<<eot  
  2. POST /nav/getsystemconfig.aspx HTTP/1.0  
  3. User-Agent: IIC2.0/pc 3.1.0480  
  4. Accept-Encoding: deflate, gzip  
  5. Host: nav.fetion.com.cn:80  
  6. Content-Length: {$postLength}  
  7.   
  8. {$postData}  
  9. eot;  
  10. fwrite($fp,$headers);  
  11. $received=fread($fp,1024);  
  12. fclose($fp);  

3、stream,利用文件流

平均【大约 1.3~1.4秒】
  1. $opts = array (  
  2.     'http' => array (  
  3.         'method' => 'POST',  
  4.         'header'=> "Content-type: application/x-www-form-urlencoded" .  
  5.                    "Content-Length: " . $postLength . "",  
  6.         'content' => $postData  
  7.     ),  
  8. );  
  9. $context = stream_context_create($opts);  
  10. //$received = file_get_contents('http://nav.fetion.com.cn/nav/getsystemconfig.aspx', false, $context , 0 ,1024);  
  11. $fp = fopen('http://nav.fetion.com.cn/nav/getsystemconfig.aspx','r',false,$context);  
  12. if($fp){  
  13.     $received = fgets($fp, 512);  //在这里我用了三种测试,fgets,fread,stream_get_contents
  14.     fclose($fp);  
  15. }  

在这里我用了两种方式,一种是file_get_contents还有一种是fopen,file_get_contents的方法被我注释了。。。

在这三种中,我发现真的只有fsocketopen后然后fread是最快的。

真让我沮丧。。因为第三种方法中file_get_contens也可以指定读取的长度。但PHPRPC作者andot却认为,file_get_contents把头已经读回来了。我想,file_get_contents其实已经把数据读回来了,虽然是指定了长度,但其实只是读回来后再截取的。

唉。看来,不得不用fsocketopen了。。不知道除此之外有没有什么好办法。

php中addslashes() ,mysql_real_escape_string() 和mysql_escape_string() 的区别

以前还真没有关注过这面的事情。自己在写的时候都是用了一个很简单的函数

PHP代码
  1. <?php  
  2. function escape($str){  
  3.     if(function_exists('mysql_escape_string')){  
  4.          return mysql_escape_string($str);  
  5.     }elseif( function_exists(...real_escape...)){  
  6.        //real_escape  
  7.     }else{  
  8.         if(MAGIC_QUOTER ....判断){  
  9.              return $str  
  10.         }else{  
  11.             return addslashes($str);  
  12.         }  
  13.     }  
  14. }  

但是这篇文章却告诉我,原来这三个函数的功能各有不同,前两个我当然知道,但如果没有加载mysql库,这两个功能是都用不上的,当然,现在有PDO的prepare然后setParam当然是很方便,mysqli函数也有这种功能。如果没有呢?怎么办?下面这篇文章告诉你上面三个函数的区别
来源:http://www.akii.org/2009-08/php-in-the-addslashes-mysql_real_escape_string-and-mysql_escape_string-the-difference-between/

SQL注入攻击是黑客攻击网站最常用的手段。如果你的站点没有使用严格的用户输入检验,那么常容易遭到SQL注入攻击。SQL注入攻击通常通过给站点数据库提交不良的数据或查询语句来实现,很可能使数据库中的纪录遭到暴露,更改或被删除。

为了防止SQL注入攻击,PHP自带一个功能可以对输入的字符串进行处理,可以在较底层对输入进行安全上的初步处理,也即Magic Quotes。(php.ini magic_quotes_gpc)。如果magic_quotes_gpc选项启用,那么输入的字符串中的单引号,双引号和其它一些字符前将会被自动加 上反斜杠\。

但Magic Quotes并不是一个很通用的解决方案,没能屏蔽所有有潜在危险的字符,并且在许多服务器上Magic Quotes并没有被启用。所以,我们还需要使用其它多种方法来防止SQL注入。

许多数据库本身就提供这种输入数据处理功能。例如PHP的MySQL操作函数中有addslashes()、 mysql_real_escape_string()、mysql_escape_string()等函数,可将特殊字符和可能引起数据库操作出错的字 符转义。那么这三个功能函数之间有什么却别呢?下面我们就来详细讲述下。

虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在 于黑客 可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会 被看作是单引号,所以addslashes无法成功拦截。

当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。

另外对于php手册中get_magic_quotes_gpc的举例:
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST[‘lastname’]);
} else {
$lastname = $_POST[‘lastname’];
}
最好对magic_quotes_gpc已经开放的情况下,还是对$_POST[’lastname’]进行检查一下。

再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别:
mysql_real_escape_string 必须在(PHP 4 >= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ,两者的区别是:mysql_real_escape_string 考虑到连接的当前字符集,而mysql_escape_string 不考虑。

总结一下:

* addslashes() 是强行加\;
* mysql_real_escape_string()  会判断字符集,但是对PHP版本有要求;
* mysql_escape_string不考虑连接的当前字符集。

Tags: mysql, addslashes