邢栋博客

邢栋博客,Action博客,记录工作和生活中的点点滴滴

php xhprof扩展的安装和测试使用
xhprof的安装和测试使用
安装
wegt http://pecl.php.net/get/xhprof-0.9.4.tgz
tar zxvf xhprof-0.9.4.tgz

cd xhprof-0.9.4/extension/
/alidata/server/php/bin/phpize //我的php的安装目录是/alidata/server/php
./configure --with-php-config=/alidata/server/php/bin/php-config
make && make install
然后打开php的配置文件
vim /alidata/server/php/etc/php.ini
加入以下代码
extension=xhprof.so
xhprof.output_dir=/tmp/xhprof

重启php
killall php-fpm
php-fpm

然后执行php -m 就可以看到xhprof 这个模块
或者执行 php --ri xhprof 也可以
会看到
xhprof
xhprof => 0.9.2
CPU num => 1

xhprof 自带了一个测试的例子
把expmple/simple.php(只复制simple.php文件),xhprof_html/,xhprof_lib/ 拷贝到你的程序目录下
打开simple.php
将xhprof_enable()改为
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY)
让它也显示cpu和内存信息

将最后一段echo一行修改为:
echo '<a href="/xhprof_html/index.php?run='.$run_id.'&source=xhprof_foo" target="_blank">count</a>';
然后运行此php文件

XHProf输出说明
1. Inclusive Time : 包括子函数所有执行时间。
2. Exclusive Time/Self Time : 函数执行本身花费的时间,不包括子树执行时间。
3. Wall Time : 花去了的时间或挂钟时间。
4. CPU Time : 用户耗的时间+ 内核耗的时间
5. Inclusive CPU : 包括子函数一起所占用的CPU
6. Exclusive CPU : 函数自身所占用的CPU

php vld扩展测试抑制符@性能

vld php Opcode查看扩展
安装vld扩展

下载 http://pecl.php.net/package/vld

# tar zxvf vld-0.13.0.tgz  
# cd ./vld-0.11.1  
# /alidata/server/php/bin/phpize                
# ./configure --with-php-config=/alidata/server/php/bin/php-config --enable-vld  
# make && make install  

修改php.ini加入
extension=vld.so

重启php-fpm nginx

新建php文件 
<?php
phpinfo();
?>
可以看到vld扩展

新建一个ceshi.php
<?php
file_get_contents('xingdong365');
//@file_get_contents('xingdong365');
?>

执行php -dvld.active=1 -dvld.execute=0 ceshi.php
<?php
//file_get_contents('xingdong365');
@file_get_contents('xingdong365');
?>

如图所示
QQ截图20151011125843.png
可见使用@抑制符会产生额外开销


linux编译php7后找不到php.ini
今天在编译php7后竟然没有找到 php.ini这个配置文件
最后解决办法
执行
/server/php7/bin/php --ini
显示
Configuration File (php.ini) Path: /server/php7/lib/
Loaded Configuration File:         (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

php.ini位置修改方法如下:
编辑php时
./configure --prefix=/server/php7/ --with-config-file-path=/etc  --disable-fileinfo
就是加上 --with-config-file-path=/etc

然后在源码中找到php.ini-development 和 php.ini-production
拷贝php.ini-development  到etc 目录下为 php.ini
cp php.ini-development /etc/php.ini

php二分法查找键值
之前面试遇到过好几回这个问题,现在归置一下

1.递归,也可用来做插值查找


<?php
//search函数 其中$array为数组,$k为要找的值,$low为查找范围的最小键值,$high为查找范围的最大键值
function seekKey($array, $k, $low=0, $high=0){ 
//判断是否为第一次调用
    if(count($array)!=0 && $high == 0){
        $high = count($array);
    }
    if($low <= $high){//如果还存在剩余的数组元素 
        $mid = intval(($low+$high)/2);//取$low和$high的中间值
        if ($array[$mid] == $k){//如果找到则返回
            return $mid; 
        }elseif ($k < $array[$mid]){//如果没有找到,则继续查找 
            return seekKey($array, $k, $low, $mid-1); 
        }else{ 
            return seekKey($array, $k, $mid+1, $high); 
        } 
    } 
    return -1; 
} 
$array = array(4,5,7,8,9,10);//测试search函数
echo seekKey($array, 9);//调用search函数并输出查找结果
2.while



<?php

    $arr = array(1,2,3,4,5,6,7,8,9,10);
    function search($data,$num){
        $count = count($data);
        $high = $count-1;
        $low = 0;
        while($high >= $low){
            $mid = intval(($high+$low)/2);
            if($data[$mid] > $num){
                $high = $mid-1;
            }elseif($data[$mid] < $num){
                $low  = $mid+1;
            }else{
                return $mid;
            }
        }
        return -1;
    }

    $res = search($arr,4);

    var_dump($res);






php几个常用的关于路径的函数
getcwd — 取得当前工作目录 
<?php
$a = getcwd();
var_dump($a);//string 'D:\wamp\www\ceshi' (length=17)
?>
__FILE__
<?php
echo __FILE__;//'D:\wamp\www\ceshi\ceshi.php'
?>
pathinfo — 返回文件路径的信息
<?php
$a = pathinfo(__FILE__);
var_dump($a);
/*array (size=4)
'dirname' => string 'D:\wamp\www\ceshi' (length=17)
'basename' => string 'ceshi.php' (length=9)
'extension' => string 'php' (length=3)
'filename' => string 'ceshi' (length=5)*/
?>

dirname — 返回路径中的目录部分 
<?php
$a = dirname(__FILE__);
var_dump($a);//string 'D:\wamp\www\ceshi' (length=17)
?>

basename — 返回路径中的文件名部分 
<?php
$a = basename(__FILE__);
var_dump($a);//string 'ceshi.php' (length=9)
?>

realpath — 返回规范化的绝对路径名 
//在 Windows 上, realpath() 会将 unix 风格的路径改成 Windows 风格的
<?php
 echo  realpath ( '/windows/system32' );//C:\WINDOWS\System32
 ?> 
php内存管理之引用计数
<?php
$a = 'Hello World';
$b = $a;
unset($a);  
?>

第一条语句执行后,PHP创建了$a这个变量,并为它申请了12B的内存来存放"hello world"这个字符串. 紧接着把$a赋给了$b,并释放掉$a;
PHP变量的名称和值在内核中是保存在两个不同的地方的,值是通过一个与名字毫无关系的zval结构来保存,而这个变量的名字a则保存在符号表里,两者之间通过指针联系着.
现在我们检查$a和$b两个变量,他们的值指向了"hello world"这个字符串在内存中的位置. zval的四个成员value、type、is_ref__gc、refcount__gc,
当一个变量被第一次创建的时候,它对应的zval结构体的refcount__gc成员的值会被初始化为1,理由很简单,因为只有这个变量自己在用它。但是当你把这个变量赋值给别的变量时,refcount__gc属性便会加1变成2,因为现在有两个变量在用这个zval结构了! 
这个时候当我们再用unset删除$a的时候,它删除符号表里的$a的信息,然后清理它的值部分,这时它发现$a的值对应的zval结构的refcount值是2,也就是有另外一个变量在一起用着这个zval,所以unset只需把这个zval的refcount减去1就行了!

写时复制机制
<?php
$a = 1;
$b = $a;
$b += 5;
?>
从代码逻辑来看,我们希望语句执行后$a仍然是1,而$b则需要变成6。我们知道在第二句完成后内核通过让$a和$b共享一个zval结构来达到节省内存的目的,但是现在第三句来了,这时$b的改变应该怎样在内核中实现呢? 答案非常简单,内核首先查看refcount__gc属性,如果它大于1则为这个变化的变量从原zval结构中复制出一份新的专属与$b的zval来,并改变其值。
现在$b变量拥有了自己的zval,并且可以自由的修改它的值了。

Change on Write
<?php
    $a = 1;
    $b = &$a;
    $b += 5;
?>
我们都知道$a的值也变成6了。当我们更改$b的值时,内核发现$b是$a的一个用户端引用,也就是所它可以直接改变$b对应的zval的值,而无需再为它生成一个新的不同与$a的zval。因为他知道$a和$b都想得到这次变化! 但是内核是怎么知道这一切的呢?简单的讲,它是通过zval的is_ref__gc成员来获取这些信息的。这个成员只有两个值,就像开关的开与关一样。它的这两个状态代表着它是否是一个用户在PHP语言中定义的引用。在第一条语句($a = 1;)执行完毕后,$a对应的zval的refcount__gc等于1,is_ref__gc等于0;。 当第二条语句执行后($b = &$a;),refcount__gc属性向往常一样增长为2,而且is_ref__gc属性也同时变为了1! 最后,在执行第三条语句的时候,内核再次检查$b的zval以确定是否需要复制出一份新的zval结构来,这次不需要复制,因为我们刚才上面的get_var_and_separate函数其实是个简化版,并且少写了一个条件:
/* 如果这个zval在php语言中是通过引用的形式存在的,或者它的refcount小于2,则不许要复制。*/
if ((*varval)->is_ref || (*varval)->refcount < 2) {
    return *varval;
}   
这一次,尽管它的refcount等于2,但是因为它的is_ref等于1,所以也不会被复制。内核会直接的修改这个zval的值


Separation Anxiety
<?php
$a = 1;
$b = $a;
$c = &$a; 
?>
03fig03.jpg

<?php
$a = 1;
$b = &$a;
$c = $a; 
?>

03fig02.jpg


PS:http://www.walu.cc/phpbook/3.2.md


php获取网页头部信息相关
php获取网页头部信息相关

php设置头部
<?php
    header("HTTP/1.0 404 Not Found");
    //header("HTTP/1.0 204 No Response");
?>

php通过内置函数获取头部信息
<?php
//$header = get_headers('http://xingdong365.com');
$header = get_headers('http://xingdong365.com',1);//会解析相应的信息并设定数组的键名
echo "<pre>";
print_r($header);
echo "</pre>";
?>

php通过curl获取头部信息

<?php
var_dump(get_header('http://xingdong365.com'));
function get_header($url){
$ch  = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY,true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch, CURLOPT_AUTOREFERER,true);
$header = curl_exec($ch);
return $header;
}
?>


php curl并发测试

test.php

<?php 

function multiCurl($res, $options=""){
    if(count($res)<=0) return False;
    $handles = array();
    if(!$options) // add default options
        $options = array(
            CURLOPT_HEADER=>0,
            CURLOPT_RETURNTRANSFER=>1,
            CURLOPT_TIMEOUT=>1,//超时时间
        );
    // add curl options to each handle
    foreach($res as $k=>$row){
        $ch{$k} = curl_init();
        $options[CURLOPT_URL] = $row['url'];
        $opt = curl_setopt_array($ch{$k}, $options);
        var_dump($opt);
        $handles[$k] = $ch{$k};
    }
    $mh = curl_multi_init();
    // add handles
    foreach($handles as $k => $handle){
        $err = curl_multi_add_handle($mh, $handle);            
    }
    $running_handles = null;
    do {
        curl_multi_exec($mh, $running_handles);
        curl_multi_select($mh);
    } while ($running_handles > 0);
        foreach($res as $k=>$row){
            $res[$k]['error'] = curl_error($handles[$k]);
            if(!empty($res[$k]['error']))
                $res[$k]['data']  = '';
            else
                $res[$k]['data']  = curl_multi_getcontent( $handles[$k] );  // get results

            // close current handler
            curl_multi_remove_handle($mh, $handles[$k] );
        }
        curl_multi_close($mh);
        return $res; // return response
}
$res = array( 
    "0"=>array("url"=>"http://localhost/curl/test1.php"), 
    "1"=>array("url"=>"http://localhost/curl/test2.php"), 
    "2"=>array("url"=>"http://localhost/curl/test3.php"), 

); 
echo "<pre>";
print_r( multiCurl($res)); 
echo "</pre>";
?> 

---------------------------------------------------------------------------

test1.php

<?php

    sleep(1);

    echo test1;

?>

test2.php

<?php

    sleep(2);

    echo test2;

?>

test3.php

<?php

    sleep(3);

    echo test3;

?>


优惠券
广告位-淘宝
最新微语