西安力洋网站建设

西安力洋网络
  • 9个必须知道的PHP函数和功能

  • 发布者:本站 发布时间:2010/6/30 10:08:30
  • 即使使用 PHP 多年,也会偶然发现一些未曾了解的函数和功能。其中有些是非常有用的,但没有得到充分利用。并不是所有人都会从头到尾一页一页地阅读手册和函数参考!

    1、任意参数数目的函数

    你可能已经知道,PHP 允许定义可选参数的函数。但也有完全允许任意数目的函数参数的方法。以下是可选参数的例子:

    以下为引用的内容:

    // function with 2 optional arguments
    function foo($arg1 = '', $arg2 = '') {

     echo "arg1: $arg1\n";
     echo "arg2: $arg2\n";

    }

    foo('hello','world');
    /* prints:
    arg1: hello
    arg2: world
    */

    foo();
    /* prints:
    arg1:
    arg2:
    */

    现在让我们看看如何建立能够接受任何参数数目的函数。这一次需要使用 func_get_args() 函数:

    以下为引用的内容:

    // yes, the argument list can be empty
    function foo() {

     // returns an array of all passed arguments
     $args = func_get_args();

     foreach ($args as $k => $v) {
      echo "arg".($k+1).": $v\n";
     }

    }

    foo();
    /* prints nothing */

    foo('hello');
    /* prints
    arg1: hello
    */

    foo('hello', 'world', 'again');
    /* prints
    arg1: hello
    arg2: world
    arg3: again
    */

    2、使用 Glob() 查找文件

    许多 PHP 函数具有长描述性的名称。然而可能会很难说出 glob() 函数能做的事情,除非你已经通过多次使用并熟悉了它。可以把它看作是比 scandir() 函数更强大的版本,可以按照某种模式搜索文件。

    以下为引用的内容:

    // get all php files
    $files = glob('*.php');

    print_r($files);
    /* output looks like:
    Array
    (
        [0] => phptest.php
        [1] => pi.php
        [2] => post_output.php
        [3] => test.php
    )
    */

    你可以像这样获得多个文件:

    以下为引用的内容:

    // get all php files AND txt files
    $files = glob('*.{php,txt}', GLOB_BRACE);

    print_r($files);
    /* output looks like:
    Array
    (
        [0] => phptest.php
        [1] => pi.php
        [2] => post_output.php
        [3] => test.php
        [4] => log.txt
        [5] => test.txt
    )
    */

    请注意,这些文件其实是可以返回一个路径,这取决于查询条件:

    以下为引用的内容:

    $files = glob('../images/a*.jpg');

    print_r($files);
    /* output looks like:
    Array
    (
        [0] => ../images/apple.jpg
        [1] => ../images/art.jpg
    )
    */

    如果你想获得每个文件的完整路径,你可以调用 realpath() 函数:

    以下为引用的内容:

    $files = glob('../images/a*.jpg');

    // applies the function to each array element
    $files = array_map('realpath',$files);

    print_r($files);
    /* output looks like:
    Array
    (
        [0] => C:\wamp\www\images\apple.jpg
        [1] => C:\wamp\www\images\art.jpg
    )
    */

    3、内存使用信息

    通过侦测脚本的内存使用情况,有利于代码的优化。PHP 提供了一个垃圾收集器和一个非常复杂的内存管理器。脚本执行时所使用的内存量,有升有跌。为了得到当前的内存使用情况,我们可以使用 memory_get_usage() 函数。如果需要获得任意时间点的最高内存使用量,则可以使用 memory_limit() 函数。

    以下为引用的内容:

    echo "Initial: ".memory_get_usage()." bytes \n";
    /* prints
    Initial: 361400 bytes
    */

    // let's use up some memory
    for ($i = 0; $i < 100000; $i++) {
     $array []= md5($i);
    }

    // let's remove half of the array
    for ($i = 0; $i < 100000; $i++) {
     unset($array[$i]);
    }

    echo "Final: ".memory_get_usage()." bytes \n";
    /* prints
    Final: 885912 bytes
    */

    echo "Peak: ".memory_get_peak_usage()." bytes \n";
    /* prints
    Peak: 13687072 bytes
    */

    4、CPU 使用信息

    为此,我们要利用 getrusage() 函数。请记住这个函数不适用于 Windows 平台。

    以下为引用的内容:

    print_r(getrusage());
    /* prints
    Array
    (
        [ru_oublock] => 0
        [ru_inblock] => 0
        [ru_msgsnd] => 2
        [ru_msgrcv] => 3
        [ru_maxrss] => 12692
        [ru_ixrss] => 764
        [ru_idrss] => 3864
        [ru_minflt] => 94
        [ru_majflt] => 0
        [ru_nsignals] => 1
        [ru_nvcsw] => 67
        [ru_nivcsw] => 4
        [ru_nswap] => 0
        [ru_utime.tv_usec] => 0
        [ru_utime.tv_sec] => 0
        [ru_stime.tv_usec] => 6269
        [ru_stime.tv_sec] => 0
    )

    */这可能看起来有点神秘,除非你已经有系统管理员权限。以下是每个值的具体说明(你不需要记住这些):

    以下为引用的内容:

    ru_oublock: block output operations
    ru_inblock: block input operations
    ru_msgsnd: messages sent
    ru_msgrcv: messages received
    ru_maxrss: maximum resident set size
    ru_ixrss: integral shared memory size
    ru_idrss: integral unshared data size
    ru_minflt: page reclaims
    ru_majflt: page faults
    ru_nsignals: signals received
    ru_nvcsw: voluntary context switches
    ru_nivcsw: involuntary context switches
    ru_nswap: swaps
    ru_utime.tv_usec: user time used (microseconds)
    ru_utime.tv_sec: user time used (seconds)
    ru_stime.tv_usec: system time used (microseconds)
    ru_stime.tv_sec: system time used (seconds)

    要知道脚本消耗多少 CPU 功率,我们需要看看 ‘user time’ 和 ’system time’ 两个参数的值。秒和微秒部分默认是单独提供的。你可以除以 100 万微秒,并加上秒的参数值,得到一个十进制的总秒数。让我们来看一个例子:

    以下为引用的内容:

    // sleep for 3 seconds (non-busy)
    sleep(3);

    $data = getrusage();
    echo "User time: ".
     ($data['ru_utime.tv_sec'] +
     $data['ru_utime.tv_usec'] / 1000000);
    echo "System time: ".
     ($data['ru_stime.tv_sec'] +
     $data['ru_stime.tv_usec'] / 1000000);

    /* prints
    User time: 0.011552
    System time: 0
    */

    尽管脚本运行用了大约 3 秒钟,CPU 使用率却非常非常低。因为在睡眠运行的过程中,该脚本实际上不消耗 CPU 资源。还有许多其他的任务,可能需要一段时间,但不占用类似等待磁盘操作等 CPU 时间。因此正如你所看到的,CPU 使用率和运行时间的实际长度并不总是相同的。下面是一个例子:

    以下为引用的内容:

    // loop 10 million times (busy)
    for($i=0;$i<10000000;$i++) {

    }

    $data = getrusage();
    echo "User time: ".
     ($data['ru_utime.tv_sec'] +
     $data['ru_utime.tv_usec'] / 1000000);
    echo "System time: ".
     ($data['ru_stime.tv_sec'] +
     $data['ru_stime.tv_usec'] / 1000000);

    /* prints
    User time: 1.424592
    System time: 0.004204
    */

    这花了大约 1.4 秒的 CPU 时间,但几乎都是用户时间,因为没有系统调用。系统时间是指花费在执行程序的系统调用时的 CPU 开销。下面是一个例子:

    以下为引用的内容:

    $start = microtime(true);
    // keep calling microtime for about 3 seconds
    while(microtime(true) - $start < 3) {

    }

    $data = getrusage();
    echo "User time: ".
     ($data['ru_utime.tv_sec'] +
     $data['ru_utime.tv_usec'] / 1000000);
    echo "System time: ".
     ($data['ru_stime.tv_sec'] +
     $data['ru_stime.tv_usec'] / 1000000);

    /* prints
    User time: 1.088171
    System time: 1.675315
    */

    现在我们有相当多的系统时间占用。这是因为脚本多次调用 microtime() 函数,该函数需要向操作系统发出请求,以获取所需时间。你也可能会注意到运行时间加起来不到 3 秒。这是因为有可能在服务器上同时存在其他进程,并且脚本没有 100% 使用 CPU 的整个 3 秒持续时间。

    5、魔术常量

    PHP 提供了获取当前行号 (__LINE__)、文件路径 (__FILE__)、目录路径 (__DIR__)、函数名 (__FUNCTION__)、类名 (__CLASS__)、方法名 (__METHOD__) 和命名空间 (__NAMESPACE__) 等有用的魔术常量。在这篇文章中不作一一介绍,但是我将告诉你一些用例。当包含其他脚本文件时,使用 __FILE__ 常量(或者使用 PHP5.3 新具有的 __DIR__ 常量):

    以下为引用的内容:

    // this is relative to the loaded script's path
    // it may cause problems when running scripts from different directories
    require_once('config/database.php');

    // this is always relative to this file's path
    // no matter where it was included from
    require_once(dirname(__FILE__) . '/config/database.php');

    使用 __LINE__ 使得调试更为轻松。你可以跟踪到具体行号。

    以下为引用的内容:

    // some code
    // ...
    my_debug("some debug message", __LINE__);
    /* prints
    Line 4: some debug message
    */

    // some more code
    // ...
    my_debug("another debug message", __LINE__);
    /* prints
    Line 11: another debug message
    */

    function my_debug($msg, $line) {
     echo "Line $line: $msg

    6、生成唯一标识符

    某些场景下,可能需要生成一个唯一的字符串。我看到很多人使用 md5() 函数,即使它并不完全意味着这个目的:

    以下为引用的内容:

    // generate unique string
    echo md5(time() . mt_rand(1,1000000));
    There is actually a PHP function named uniqid() that is meant to be used for this.

    // generate unique string
    echo uniqid();
    /* prints
    4bd67c947233e
    */

    // generate another unique string
    echo uniqid();
    /* prints
    4bd67c9472340
    */

    你可能会注意到,尽管字符串是唯一的,前几个字符却是类似的,这是因为生成的字符串与服务器时间相关。但实际上也存在友好的一方面,由于每个新生成的 ID 会按字母顺序排列,这样排序就变得很简单。为了减少重复的概率,你可以传递一个前缀,或第二个参数来增加熵:

    以下为引用的内容:

    // with prefix
    echo uniqid('foo_');
    /* prints
    foo_4bd67d6cd8b8f
    */

    // with more entropy
    echo uniqid('',true);
    /* prints
    4bd67d6cd8b926.12135106
    */

    // both
    echo uniqid('bar_',true);
    /* prints
    bar_4bd67da367b650.43684647
    */

    这个函数将产生比 md5() 更短的字符串,能节省一些空间。

    7、序列化

    你有没有遇到过需要在数据库或文本文件存储一个复杂变量的情况?你可能没能想出一个格式化字符串并转换成数组或对象的好方法,PHP 已经为你准备好此功能。有两种序列化变量的流行方法。下面是一个例子,使用 serialize() 和 unserialize() 函数:

    以下为引用的内容:

    // a complex array
    $myvar = array(
     'hello',
     42,
     array(1,'two'),
     'apple'
    );

    // convert to a string
    $string = serialize($myvar);

    echo $string;
    /* prints
    a:4:{i:0;s:5:"hello";i:1;i:42;i:2;a:2:{i:0;i:1;i:1;s:3:"two";}i:3;s:5:"apple";}
    */

    // you can reproduce the original variable
    $newvar = unserialize($string);

    print_r($newvar);
    /* prints
    Array
    (
        [0] => hello
        [1] => 42
        [2] => Array
            (
                [0] => 1
                [1] => two
            )

        [3] => apple
    )
    */

    这是原生的 PHP 序列化方法。然而,由于 JSON 近年来大受欢迎,PHP5.2 中已经加入了对 JSON 格式的支持。现在你可以使用 json_encode() 和 json_decode() 函数:

    以下为引用的内容:

    // a complex array
    $myvar = array(
     'hello',
     42,
     array(1,'two'),
     'apple'
    );

    // convert to a string
    $string = json_encode($myvar);

    echo $string;
    /* prints
    ["hello",42,[1,"two"],"apple"]
    */

    // you can reproduce the original variable
    $newvar = json_decode($string);

    print_r($newvar);
    /* prints
    Array
    (
        [0] => hello
        [1] => 42
        [2] => Array
            (
                [0] => 1
                [1] => two
            )

        [3] => apple
    )
    */

    这将更为行之有效,尤其与 JavaScript 等许多其他语言兼容。然而对于复杂的对象,某些信息可能会丢失。(整理http://www.178365.net

  • 返回列表
    相关阅读
    更多
    深度挖掘网站的商用价值,化繁为简的设计,为企业找到直接有效的解决方案
    +86 (029) 88765320
    +86 15829904657
    地址:西安市太华北路369号
    万达广场4#23F P.C:7100001
    boss@178365.net
    在线咨询: 985224206
    互联网协会成员单位
    西安力洋之星网络技术有限公司 | 版权所有
    Copyright 2008-2020 Liyang.Inc All Rights Reserved.
    Liyang.Inc