标签 php 下的文章

原文地址 : http://www.nowamagic.net/librarys/veda/detail/2407

以下文字并没有非常多的技术词汇,所以只要对PHP感兴趣的人都可以看看。

PHPer是草根吗?
从PHP诞生之日起,PHP就开始在Web应用方面为广大的程序员服务。同时,作为针对Web开发量身定制的脚本语言,PHP一直秉承简单、开源的思想,这也使得PHP得以快速的发展,并且大力地推动Web2.0的出现与发展。但是,长期以来,PHPer(PHP Programmers)被认为是处于草根阶层的程序员,被认为是技术含量少,层次低的程序员。这点在国内尤其突出。


- 阅读全部 -

背景

因当前开发功能需要用微信绑定第三方网站的用户表,然而微信订阅号没有 网页授权获取用户基本信息 的权限,于是就想到利用微信自动回复功能实现,点击自动回复的超链接跳转到第三方网站,这种方式有可能不当或者有其他更好的方式实现此功能,欢迎留言或者加QQ指出,具体实现如下:

步骤

// 在这里就不提微信接入及其他问题,只记录如何利用自动回复打开笫三方网站获取用户信息
// 因为在用户关注或者在给公众号文字消息的时候可以获取到用户的openid
// 于是就可以利用自动回复的功能
define("TOKEN", "token");
$echoStr = $_GET["echostr"];
//如果有$echoStr说明是对接
if (!empty($echoStr)) {
    //对接规则
    $signature = $_GET["signature"];
    $timestamp = $_GET["timestamp"];
    $nonce = $_GET["nonce"];
    $token = TOKEN;
    $tmpArr = array($token, $timestamp, $nonce);
    sort($tmpArr, SORT_STRING);
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );
    if( $tmpStr == $signature ){
        echo $echoStr;
    }else{
        echo "";
        exit;
    }
}else{
    responseMsg();
}

//用于回复用户消息
function responseMsg(){
    $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
    if (!empty($postStr)){
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        $fromUsername = $postObj->FromUserName;
        $toUsername = $postObj->ToUserName;
        $MsgT = $postObj->MsgType;
        $time = time();
        //如果用户发的text类型
        if($MsgT=="text"){
            $key = trim($postObj->Content);
            $fromUsername = $postObj->FromUserName;
            $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        </xml>"; 
            $msgType = "text";
            $answer = "<a href='http://www.baidu.com?openid=%s'>点击跳转</a>";
            // 如果有占位符就替换成openid
            $contentStr = strpos($answer, '%s') ? sprintf($answer,$fromUsername) : $answer;
            $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
            echo $resultStr;
            exit;
        }

        //如果用户发的event(事件)类型
        if($MsgT=="event"){
            $Event = $postObj->Event;
            if ($Event==subscribe) {
               $contentStr = "欢迎关注";
            }else{
                $contentStr = "希望您下次关注,但您收不到此条消息了";
            }

            $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        </xml>"; 
            $Title = $postObj->Title;
            $Description = $postObj->Description;
            $Url = $postObj->Url;
            $msgType = 'text';
            $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
            echo $resultStr;
            exit;
        }
    }else{
        echo "";
        exit;
    }
}

结果

点击自动回复超链接就可以把openid带到第三方网站,然后就可以利用openid查到用户的信息

PHP开发很多时候都要读取大文件,比如csv文件、text文件,或者一些日志文件。这些文件如果很大,比如几个G。这时,直接一次性把所有的内容读取到内存中计算不太现实。
使用生成器读取文件,可以第一次读取了第一行,第二次读取了第二行,以此类推,每次被加载到内存中的文字只有一行,可以大大的减小了内存的使用。

header("content-type:text/html;charset=utf-8");
function getLines($file) {
    $f = fopen($file, 'r');
    try {
        while ($line = fgets($f)) {
            yield $line;
        }
    } finally {
        fclose($f);
    }
}

foreach (getLines("sgland.log") as $n => $line) {
    //逐行内容
    echo $line . "</br>";
    //行数
    // var_dump($n);
}

microtime();  //返回当前 Unix 时间戳的微秒数:
$start = microtime(true);
$data = range(0, 1000000, 1);
foreach ($data as $val){
    echo $val;
}
$end = microtime(true);
echo  '耗时' . round($end - $start, 3) . '秒' . "\n";

memory_get_usage();  //返回当前分配给PHP脚本的内存量,单位是字节(byte)
echo '开始内存:'.memory_get_usage(), ''; 
$tmp = str_repeat('hello', 1000);   
echo '运行后内存:'.memory_get_usage(), '';  
unset($tmp);   
echo '回到正常内存:'.memory_get_usage(); 

<?php
    function geturl($url){
            $headerArray =array("Content-type:application/json;","Accept:application/json");
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($url,CURLOPT_HTTPHEADER,$headerArray);
            $output = curl_exec($ch);
            curl_close($ch);
            $output = json_decode($output,true);
            return $output;
    }
    function posturl($url,$data){
            $data  = json_encode($data);    
            $headerArray =array("Content-type:application/json;charset='utf-8'","Accept:application/json");
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $output = curl_exec($curl);
            curl_close($curl);
            return json_decode($output,true);
    }
    function puturl($url,$data){
        $data = json_encode($data);
        $ch = curl_init(); //初始化CURL句柄 
        curl_setopt($ch, CURLOPT_URL, $url); //设置请求的URL
        curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); //设为TRUE把curl_exec()结果转化为字串,而不是直接输出 
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST,"PUT"); //设置请求方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//设置提交的字符串
        $output = curl_exec($ch);
        curl_close($ch);
        return json_decode($output,true);
    }
    function delurl($url,$data){
        $data  = json_encode($data);
        $ch = curl_init();
        curl_setopt ($ch,CURLOPT_URL,$put_url);
        curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, "DELETE");   
        curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
        $output = curl_exec($ch);
        curl_close($ch);
        $output = json_decode($output,true);
    }
    function patchurl($url,$data){
        $data  = json_encode($data);
        $ch = curl_init();
        curl_setopt ($ch,CURLOPT_URL,$url);
        curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, "PATCH");  
        curl_setopt($ch, CURLOPT_POSTFIELDS,$data);     //20170611修改接口,用/id的方式传递,直接写在url中了
        $output = curl_exec($ch);
        curl_close($ch);
        $output = json_decode($output);
        return $output;
    }
?>

<?php 
    static public function unlimitedForLevel($cate,$html='|—',$pid=0,$level=0){
        //建立空数组存储结果
        $arr = array();
        //循环$cate,如果这级的pid等于上一级的cid,就先压入数组,再找当前的下一级
        foreach ($cate as $v) {
            //查找当前分类是否有子分类
            if ($v['parent_id'] == $pid) {
                $v['level'] = $level + 1;
                $v['html'] = str_repeat($html, $level);

                $arr[] = $v;
                //递归合并数组
                $arr = array_merge($arr,self::unlimitedForLevel($cate,$html,$v['id'],$level+1));
            }
        }
        return $arr;
    }

    //静态方法获取多维数组递归结果
    static public function unlimitedForMore($cate,$name='child',$pid=0){
        $arr = array();
        foreach ($cate as $v) {
            if ($v['parent_id'] == $pid) {
                $v[$name] = self::unlimitedForMore($cate,$name,$v['id']);
                $arr[] = $v;
            }
        }
        return $arr;
    }

    //递归获取父函数
    static public function getParents($cate,$cid){
        $arr = array();
        foreach ($cate as $v) {
            if ($v['id'] == $cid) {
                $arr[] = $v;
                $arr = array_merge(self::getParents($cate,$v['parent_id']),$arr);
            }
        }
        return $arr;
    }

 ?>

php自带函数file_exists判断文件是否存在,is_dir判断文件夹是否存在

如:

//当/www/index.php 都实际存在时
$file='index.php';
$dir='/www/';
if(file_exists($dir.$file)){
    echo '文件'.$file.'存在';
}else{
    echo '文件'.$file.'不存在';
}
if(is_dir($dir)){
    echo '目录'.$dir.'存在';
}else{
    echo '目录'.$dir.'不存在';
}

用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则 不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说echo是语言结构,不是真正的函数,故把函数加 上了双引号)。

1、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。

2、$row[’id’] 的速度是$row[id]的7倍。

3、echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2。

4、在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替。

5、注销那些不用的变量尤其是大数组,以便释放内存。

6、尽量避免使用__get,__set,__autoload。

7、require_once()代价昂贵。

8、include文件时尽量使用绝对路径,因为它避免了PHP去include_path里查找文件的速度,解析操作系统路径所需的时间会更少。

9、如果你想知道脚本开始执行(译注:即服务器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。

10、函数代替正则表达式完成相同功能。

11、str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍。

12、如果一个字符串替换函数,可接受数组或字符作为参数,并且参数长度不太长,那么可以考虑额外写一段替换代码,使得每次传递参数是一个字符,而不是只写一行代码接受数组作为查询和替换的参数。

13、使用选择分支语句(译注:即switch case)好于使用多个if,else if语句。

14、用@屏蔽错误消息的做法非常低效,极其低效。

15、打开apache的mod_deflate模块,可以提高网页的浏览速度。

16、数据库连接当使用完毕时应关掉,不要用长连接。

17、错误消息代价昂贵。

18、在方法中递增局部变量,速度是最快的。几乎与在函数中调用局部变量的速度相当。

19、递增一个全局变量要比递增一个局部变量慢2倍。

20、递增一个对象属性(如:$this->prop++)要比递增一个局部变量慢3倍。

function decodeUnicode($str)
{
    return preg_replace_callback('/\\\\u([0-9a-f]{4})/i',
    create_function(
        '$matches',
        'return mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UCS-2BE");'
        ),
        $str);
}