预览模式: 普通 | 列表

1.用include_once加载文件
function test_include() {
    $time_start = microtime_float();
    for ($i = 0; $i < 100; $i++) {
        include_once('py_dic.php');
    }
    $time_end = microtime_float();

    printf("total time: %s%s", $time_end - $time_start, l);
}

test_include();

循环100次,用include_once
total time: 0.037981986999512

2.用include加载文件
function test_include() {
    $time_start = microtime_float();
    for ($i = 0; $i < 100; $i++) {
        include('py_dic.php');
    }
    $time_end = microtime_float();

    printf("total time: %s%s", $time_end - $time_start, l);
}

test_include();

循环100次,用include
total time: 3.7502920627594

3.总结
用include_once加载文件时同样的文件只加载一次,所以速度比较快,而如果用include,则需要每次加载同一个文件,增加了IO操作,所以速度就慢一些,用include_once的速度大概是用include的速度的98位,3.7502920627594 / 0.037981986999512 = 98.7387011。

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 2534

PHP中func_get_args的用法

1.函数的动态参数
<?php
$cacheServerConfig = array('host' => 'localhost', 'port' => 11211);
function getCacheObj() {
    $a = func_get_args();
    var_dump($a);

    if (is_array($a[0])) {
        $cacheServerConfig = $a[0];   
    } else {
        $cacheServerConfig = $GLOBALS['cacheServerConfig'];
    }
    
    if (!is_array($cacheServerConfig)) {
        die("Parameter \$cacheServerConfig must be an array!");
    }
    
    if (is_array($a[0])) {
        array_shift($a);
    }
    
    var_dump($a);
    Util::loadLib('cache/Cache.class');
    
    $cache = Cache::factory($cacheServerConfig, $a[0], $a[1], $a[2], $a[3], $a[4]);
    
    return $cache;
}
getCacheObj($cacheServerConfig, '1616', 'hao123');
getCacheObj('a', 'b', 'c');
?>

输出如下:
array(3) {
  [0]=>
  array(2) {
    ["host"]=>
    string(9) "localhost"
    ["port"]=>
    int(11211)
  }
  [1]=>
  string(4) "1616"
  [2]=>
  string(6) "hao123"
}
array(2) {
  [0]=>
  string(4) "1616"
  [1]=>
  string(6) "hao123"
}
array(3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
}
array(3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
}

测试一主要演示的是PHP中函数动态参数的用法,函数定义的时候是没有任何参数的,调用的时候想传什么参数就传什么参数,想传多少参数就传多少参数,完全由你自己来控制。

2.函数的默认参数
function testArgs($type = 'memcached') {
    $numargs = func_num_args();
    echo "Number of arguments: $numargs\n";

    echo "type: $type\n";
    $a = func_get_args();
    var_dump($a);
}
testArgs();
testArgs('kt');

输出如下:
Number of arguments: 0
type: memcached
array(0) {
}
Number of arguments: 1
type: kt
array(1) {
  [0]=>
  string(2) "kt"
}

从以上的输出可以说明一个问题,当函数有默认参数,且在调用时不传递此参数时,函数func_get_args里面是不包含默认参数的,但是直接输出此参数时是有值的。

3.注意问题
func_get_arg, func_get_args, func_num_args这三个函数不能直接作为函数的参数。

注: 因为本函数依赖于当前域来决定参数细节,因此不能用作函数参数。如果必须要传递这个值,将结果赋给一个变量,然后传递该变量。

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1912

PHP技巧总结

1.判断方法是否存在
class Util {
    function test() {
        return 'ok';
    }
}

if (method_exists('Util', 'test')) {
    echo 'Util::test():' . Util::test();
} else {
    echo 'Util::test() not exists';
}

输出:
Util::test():ok

函数method_exists的定义中第一个参数可以是个对象,也可以是字符串,此时可以传入类的名称直接判断方法是否存在。
bool method_exists ( mixed $object , string $method_name )

object 
An object instance or a class name 

method_name 
The method name 


2.关于变量值自增的问题
a.测试一
$loginFailedCount = 1;
$currentFailedCount = empty($loginFailedCount) ? 1 : $loginFailedCount++;
echo "currentFailedCount: $currentFailedCount, loginFailedCount: $loginFailedCount";

输出:
currentFailedCount: 1, loginFailedCount: 2

$a++, 返回 $a,然后将 $a 的值加一。同理$loginFailedCount++返回变量$loginFailedCount的值,然后将变量$loginFailedCount加1,所以变量$currentFailedCount的值为1,$loginFailedCount的值为2

b.测试二
$loginFailedCount = 1;
$currentFailedCount = empty($loginFailedCount) ? 1 : $loginFailedCount += 1;
echo "currentFailedCount: $currentFailedCount";

输出:
currentFailedCount: 2

3.关于函数的定义与传值的问题
function testFunction($a = '') {
    echo __FUNCTION__ . ' 测试定义函数时定义一个参数,调用时传多于一个参数: ' . $a;
}
testFunction(3, 4);

输出:
testFunction 测试定义函数时定义一个参数,调用时传多于一个参数: 3

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1753

PHP中全局变量的一个问题

class testGlobal {
    public function __construct() {
        include_once(dirname(__FILE__) . "/config.inc.php");        
    }

    public function getMetaDataById() {
        global $db;

        echo "db: $db\n";
    }
}
$obj = new testGlobal();
$obj->getMetaDataById();

上面的代码没有任何输出,奇怪,问题出在哪儿呢?后来想想,原来是全局变量的问题在捣鬼。

在__construct里面加入一行global $db就解决问题啦。

也就是说,虽然在__construct里面包含了配置文件,但是配置文件里面的变量只对__construct有效,要想让配置文件里面的变量在其它的函数里面也有效,需要声明此变量为全局变量,同时在调用此变量的方法(getMetaDataById)里面也要声明此变量为全局变量。
同时有个问题要注意,global $db必须定义在include_once之前,否则在方法getMetaDataById里面是取不到变量$db的值的。
class testGlobal {
    public function __construct() {
        global $db;

        include_once(dirname(__FILE__) . "/config.inc.php");        
    }

    public function getMetaDataById() {
        global $db;

        echo "db: $db\n";
    }
}
$obj = new testGlobal();
$obj->getMetaDataById();

输出:
db: Test db obj

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1909

PHP正则验证中文

1.测试一
$str = '中文测试'; 
if (preg_match_all("/^([\x81-\xfe][\x40-\xfe])+$/", $str, $match)) {
    echo '全部是汉字';    
} else {
    echo '不全是汉字';
}

当$str = '中文测试'; 时输出"全部是汉字";
当$str = '中a文3测试'; 时输出"不全是汉字";

应用说明:当某个地方要求用户输入的内容必须全部是中文时,这个就派上用场了。

2.测试二
$str = '中a文3测试'; 
if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $str, $match)) {
    echo '含有汉字';    
} else {
    echo '不含有汉字';
}

当$str = '中a文3测试'; 时输出"含有汉字";
当$str = 'a345'; 时输出"不含有汉字";

应用说明:当某个地方要求用户输入的内容中必须含有中文时(而不一定全部是中文),这个就派上用场了。

经测试,上述变量$str的内容与utf8还是gbk编码无关,判断结果均是一样的。

Tags: php 正则表达式

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 2898

PHP中多线程抓取网页

用php自带的curl功能实现的多线程下载工具,比file_get_contents,以及linux自带的命令行curl、wget效率高多了。

大家如果觉得好,就拿去直接用吧。

/**
 * @param mixed string or array,参数$urlArray是要抓取的网页(或文件,下同)的网址,可以是单个网址,也可以是多个网址组成的数组。
 */
function multiDownload($urlArray) {
    if (empty($urlArray)) return false;
    
    $isStr = false;
    if (is_string($urlArray)) {
        $urlArray = array($urlArray);
        $isStr = true;
    }
    
    self::log(sprintf("%s Multi thread download begin...", __METHOD__));
    
    $mh = curl_multi_init(); //curl_multi_init --  Returns a new cURL multi handle
    $curlArray = array(); 

    foreach ($urlArray as $i => $url) { 
        self::log(sprintf("%s Download url: |%s|...", __METHOD__, $url));

        $curlArray[$i] = curl_init($url); 

        curl_setopt($curlArray[$i], CURLOPT_RETURNTRANSFER, true); //设置为true表示返回抓取的内容,而不是直接输出到浏览器上。TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly

        curl_setopt($curlArray[$i], CURLOPT_AUTOREFERER, true); //自动设置referer。TRUE to automatically set the Referer: field in requests where it follows a Location: redirect.

        curl_setopt($curlArray[$i], CURLOPT_FOLLOWLOCATION, true); //跟踪url的跳转,比如301, 302等

        curl_setopt($curlArray[$i], CURLOPT_MAXREDIRS, 2); //跟踪最大的跳转次数

        curl_setopt($curlArray[$i], CURLOPT_HEADER, 0); //TRUE to include the header in the output. 

        curl_setopt($curlArray[$i], CURLOPT_ENCODING, ""); //接受的编码类型,The contents of the "Accept-Encoding: " header. This enables decoding of the response. Supported encodings are "identity", "deflate", and "gzip". If an empty string, "", is set, a header containing all supported encoding types is sent. 

        curl_setopt($curlArray[$i], CURLOPT_CONNECTTIMEOUT, 5); //连接超时时间         

        curl_multi_add_handle($mh, $curlArray[$i]); //curl_multi_add_handle --  Add a normal cURL handle to a cURL multi handle 
    }
     
    $running = NULL;
    $count = 0;
    do { 
        //10秒钟没退出,就超时退出
        if ($count++>100) break; 
        usleep(100000); 
        curl_multi_exec($mh, $running); //curl_multi_exec --  Run the sub-connections of the current cURL handle 
    } while($running > 0);
    
    $content = array(); 
    foreach ($urlArray as $i => $url) {
        $content[$url] = curl_multi_getcontent($curlArray[$i]); //curl_multi_getcontent --  Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set
    } 
    
    //curl_multi_remove_handle --  Remove a multi handle from a set of cURL handles
    foreach ($urlArray as $i => $url){ 
        curl_multi_remove_handle($mh, $curlArray[$i]); 
    }
    
    //curl_multi_close --  Close a set of cURL handles 
    curl_multi_close($mh);
    
    self::log(sprintf("%s Multi thread download end...", __METHOD__));
    
    //如果参数$urlArray是字符串,则将返回值也转换为字符串
    if ($isStr) $content = implode('', $content);
    
    return $content;
}

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1932

 广告位

↑返回顶部↑