php语言

PHP前端开发中的性能

时间:2023-03-28 05:03:08 php语言 我要投稿
  • 相关推荐

PHP前端开发中的性能

  有平常心,就会有最佳的发挥;怀自信心,便能跨越每一个障碍。。以下是小编为大家搜索整理的PHP前端开发中的性能,希望能给大家带来帮助!更多精彩内容请及时关注我们应届毕业生考试网!

  在我们平时的php开发中,一个大的项目经过长时间的积累以后你会发现性能越来越慢,而性能到底消耗在了什么地方,常常是一个令人头疼的问题,function a()调用了多少次,function b()又消耗了多少时间,我们到底怎么查找是哪个蛀虫拉慢了我们的程序运行速度呢?在这里给大家介绍一款工具xdebug,相信很多人已经听说过了,希望借助这个工具我们可以起到简单分析php程序性能瓶颈的问题。

  A)假设1,假设用户目录在/home/ad

  B)假设2,假设php目录在/home/ad/php

  1、xdebug简介与安装

  Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况。

  1)下载xdebug

  xdebug的官方下载地址为:http://xdebug.org/download.php

  最新版本为:Xdebug 2.1.0

  2)xdebug的安装

1
2
3
4
5
6
7
8
cd /home/ad
wget  http://xdebug.org/files/xdebug-2.1.0.tgz
tar -zxvf xdebug-2.1.0.tgz
cd xdebug-2.1.0
/home/ad/php/bin/phpize
./configure --enable-xdebug --with-php-config=/home/ad/php/bin/php-config
make
make install

  安装完以后会提示你扩展安装到了哪个目录,类似 /home/ad/php/lib/php/extensions/no-debug-non-zts-20060613/

  假设你的php.ini放在 /home/ad/php/lib/php.ini

  加上

1
2
3
4
5
6
7
8
9
[xdebug]
zend_extension = "/home/ad/php/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so"
xdebug.auto_trace = on
xdebug.auto_profile = on
xdebug.collect_params = on
xdebug.collect_return = on
xdebug.profiler_enable = on
xdebug.trace_output_dir = "/home/ad/xdebug_log"
xdebug.profiler_output_dir = "/home/ad/xdebug_log"

  重启apache

  去/home/ad/xdebug_log下看看是不是日志已经出来了

  2、xdebug参数简介

  zend_extension 加载xdebug扩展

  xdebug.auto_trace 自动打开打开函数调用监测

  xdebug.auto_profile 自动打开性能监测

  xdebug.trace_output_dir 设定函数调用监测信息的输出文件的路径。

  xdebug.profiler_output_dir 设定效能监测信息输出文件的路径。

  xdebug.collect_params 打开收集“函数参数”的功能。将函数调用的参数值列入函数过程调用的监测信息中。

  xdebug.collect_return 打开收集“函数返回值”的功能。将函数的返回值列入函数过程调用的监测信息中。

  3、示例程序与日志收集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
function a()
{
    echo "aaa";   
}
function b()
{
    a();
    sleep(1);
    a();
    sleep(1);
    a();   
}
b();
?>

  4、日志分析工具wincachegrind

  http://sourceforge.net/projects/wincachegrind/

  不用安装直接双击就可以打开了

  我们用它打开刚才收集的日志cachegrind.out.***

  前端开发中的性能那点事(二)巧用curl 并发减少后端访问时间

  前言:

  在我们平时的程序中难免出现同时访问几个接口的情况,平时我们用curl进行访问的时候,一般都是单个、顺序访问,假如有3个接口,每个接口耗时500毫秒那么我们三个接口就要花费1500毫秒了,这个问题太头疼了严重影响了页面访问速度,有没有可能并发访问来提高速度呢?今天就简单的说一下,利用curl并发来提高页面访问速度,

  希望大家多指导。

  1、老的curl访问方式以及耗时统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
function curl_fetch($url, $timeout=3){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($ch);
    $errno = curl_errno($ch);
    if ($errno>0) {
        $data = false;
    }
    curl_close($ch);
    return $data;
}
function microtime_float()
{
   list($usec, $sec) = explode(" ", microtime());
   return ((float)$usec + (float)$sec);
}
$url_arr=array(
     "taobao"=>"http://www.taobao.com",
     "sohu"=>"http://www.sohu.com",
     "sina"=>"http://www.sina.com.cn",
     );
 $time_start = microtime_float();
 $data=array();
 foreach ($url_arr as $key=>$val)
 {
     $data[$key]=curl_fetch($val);
 }
 $time_end = microtime_float();
 $time = $time_end - $time_start;
 echo "耗时:{$time}";
?>

  耗时:0.614秒

  2、curl并发访问方式以及耗时统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
function curl_multi_fetch($urlarr=array()){
    $result=$res=$ch=array();
    $nch = 0;
    $mh = curl_multi_init();
    foreach ($urlarr as $nk => $url) {
        $timeout=2;
        $ch[$nch] = curl_init();
        curl_setopt_array($ch[$nch], array(
        CURLOPT_URL => $url,
        CURLOPT_HEADER => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $timeout,
        ));
        curl_multi_add_handle($mh, $ch[$nch]);
        ++$nch;
    }
    /* wait for performing request */
    do {
        $mrc = curl_multi_exec($mh, $running);
    } while (CURLM_CALL_MULTI_PERFORM == $mrc);
  
    while ($running && $mrc == CURLM_OK) {
        // wait for network
        if (curl_multi_select($mh, 0.5) > -1) {
            // pull in new data;
            do {
                $mrc = curl_multi_exec($mh, $running);
            } while (CURLM_CALL_MULTI_PERFORM == $mrc);
        }
    }
  
    if ($mrc != CURLM_OK) {
        error_log("CURL Data Error");
    }
  
    /* get data */
    $nch = 0;
    foreach ($urlarr as $moudle=>$node) {
        if (($err = curl_error($ch[$nch])) == '') {
            $res[$nch]=curl_multi_getcontent($ch[$nch]);
            $result[$moudle]=$res[$nch];
        }
        else
        {
            error_log("curl error");
        }
        curl_multi_remove_handle($mh,$ch[$nch]);
        curl_close($ch[$nch]);
        ++$nch;
    }
    curl_multi_close($mh);
    return  $result;
}
$url_arr=array(
     "taobao"=>"http://www.taobao.com",
     "sohu"=>"http://www.sohu.com",
     "sina"=>"http://www.sina.com.cn",
     );
function microtime_float()
{
   list($usec, $sec) = explode(" ", microtime());
   return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
$data=curl_multi_fetch($url_arr);
$time_end = microtime_float();
$time = $time_end - $time_start;
 echo "耗时:{$time}";
?>

  耗时:0.316秒

  帅气吧整个页面访问后端接口的时间节省了一半

  3、curl相关参数

  来自:http://cn2.php.net/manual/en/ref.curl.php

  curl_close — Close a cURL session

  curl_copy_handle — Copy a cURL handle along with all of its preferences

  curl_errno — Return the last error number

  curl_error — Return a string containing the last error for the current session

  curl_exec — Perform a cURL session

  curl_getinfo — Get information regarding a specific transfer

  curl_init — Initialize a cURL session

  curl_multi_add_handle — Add a normal cURL handle to a cURL multi handle

  curl_multi_close — Close a set of cURL handles

  curl_multi_exec — Run the sub-connections of the current cURL handle

  curl_multi_getcontent — Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set

  curl_multi_info_read — Get information about the current transfers

  curl_multi_init — Returns a new cURL multi handle

  curl_multi_remove_handle — Remove a multi handle from a set of cURL handles

  curl_multi_select — Wait for activity on any curl_multi connection

  curl_setopt_array — Set multiple options for a cURL transfer

  curl_setopt — Set an option for a cURL transfer

  curl_version — Gets cURL version information

  前端开发中的性能那点事(三)php的opcode缓存

  前言:由php的运行机制决定,其实php在运行阶段我们也是可以进行缓存的从而提高程序运行效率,这就是我们常说的opcode缓存。

  1、简述php的运行机制

  (因为本文是写opcode缓存的所以这里只是简要概述,后边会专门写一篇揭秘php运行机制的。)

  a).php文件通过浏览器过来

  b)请求交给SAPI,随后SAPI层将控制权转给PHP

  c)zend_language_scanner对代码进行扫描,对php代码进行词法分析转换成一系列的tokens array

  d)zend_language_parser将c步骤产生的一系列tokens处理掉空格等无用的代码以后转换成一系列表达式

  e)经过compiler阶段生成opcode返回zend_op_array指针

  f)zend_vm_execute根据传入的zend_op_array指针,执行opcode并将结果返回输出

  2、opcode简介

  Opcode是operation code(操作码)的简称,其实就是第一小节c)、d)、e)步骤产生的一种中间码,

  opcode是一个四元组,(opcode, op1, op2, result),它们分别代表操作码,第一操作数,第二操作数,结果。

  如:

1
2
3
<?php
echo "taobao search blog";
?>

  对应的tokens

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Array
(
    [0] => Array
        (
            [0] => 367
            [1] => <?php
            [2] => 1
        )
  
    [1] => Array
        (
            [0] => 316
            [1] => echo
            [2] => 1
        )
  
    [2] => Array
        (
            [0] => 370
            [1] =>
            [2] => 1
        )
  
    [3] => Array
        (
            [0] => 315
            [1] => "taobao search blog"
            [2] => 1
        )
  
    [4] => ;
    [5] => Array
        (
            [0] => 370
            [1] =>
            [2] => 1
        )
  
    [6] => Array
        (
            [0] => 369
            [1] => ?>
            [2] => 1
        )
  
)

  对应的opcode就是

1
2
3
4
5
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   ECHO                                                     'taobao+search+blog'
   4     1    > RETURN                                                   1
         2*   > ZEND_HANDLE_EXCEPTION

  3、使用apc对opcode缓存

  a)假设php路径为/home/ad/php

  对opcode进行缓存的软件很多(apc、eAcclerator、Xcache、Zend Platform),这里主要介绍apc

  APC提供两种缓存功能,即缓存Opcode(目标文件),我们称之为apc_compiler_cache。同时它还提供一些接口用于PHP开发人员将用户数据驻留在内存中,我们称之为apc_user_cache。我们这里主要讨论apc_compiler_cache的配置。

  下载地址:http://pecl.php.net/package/APC

  最新版本为APC-3.1.6.tgz

1
2
3
4
5
6
7
wget http://pecl.php.net/get/APC-3.1.6.tgz
tar -zxvf APC-3.1.6.tgz
cd APC-3.1.6
/home/ad/php/bin/phpize
./configure --enable-apc --enable-apc-mmap  --with-php-config=/home/ad/php/bin/php-config
make
make install

  编辑php.ini

  添加apc的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
[apc]
extension=apc.so
apc.enabled=1
apc.shm_segments = 1
apc.shm_size = 128
apc.ttl = 0
apc.user_ttl = 7200
apc.num_files_hint = 1000
apc.write_lock=1
apc.stat = 0
apc.max_file_size=1M
apc.filters = a.php,b.php
apc.cache_by_default=1

  重新apache就ok啦

  4、常用参数的解析

  apc.enabled 开启apc 设置为0关闭,1为开启

  apc.shm_segments 共享内存块数

  apc.shm_size 共享内存大小,但是是M

  那么显然共享内存的总数就是apc.shm_segments*apc.shm_size

  apc.num_files_hint 允许多少个opcode被缓存

  apc.stat 为1的时候会自动检查opcode对应的php文件是否有更新,有更新的话会自动更新。设置为0的话就不会去检查了这样会提高apc的效率,但是要使php的修改生效的话就必须重启apache了,或者使用函数apc_cache_clear()来清空缓存

  apc.ttl opcode缓存的过期时间,设置为0表示不过期,如果不为0会检查两次请求之间的时间,如果时间大于设置值那么会更新opcode缓存

  apc.write_lock 表示多个进程同时更新一份opcode缓存的时候那么只让最先的一个生效,可以有效避免写冲突

  apc.max_file_size 超过设置值大小的文件不被缓存

  apc.filters 需要特例的文件,多个文件用逗号(,)相隔

  apc.filters 与 apc.cache_by_default结合使用,

  当apc.cache_by_default为1时apc.filters文件不被缓存,当apc.cache_by_default为0时仅apc.filters文件被缓存

【PHP前端开发中的性能】相关文章:

PHP开发CS结构的技巧11-09

PHP常用开发工具分析06-27

PHP中的trait是什么04-12

为什么选php语言开发制作全站11-10

PHP中的Division by zero报错处理技巧02-23

PHP常量介绍04-21

PHP变量介绍02-28

PHP的基本作用03-17

php环境搭建06-11

PHP基本语法04-29