你必须知道的非常有用的9个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
*/

笔者注:php5.6之后的版本还有另外一种方法实现。
如下:

function add(...$args)
{
    $result = 0;
    foreach($args as $arg)
        $result += $arg;
    return $result;
}

同时可以在调用函数时,把数组展开为函数参数:

$arr = [2, 3];
add(1, ...$arr);
// 结果为 6

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_get_peak_usage()函数。

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时间,必须看用户时间和系统时间,默认提供秒和毫秒两部分数据。
用毫秒数的值除以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秒。
这是因为有可能有其他进程在运行,再者,在整个持续的3秒里面,脚本并没有100%的使用CPU。

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\n";
}

6、生成唯一ID
可能存在这样一种情况,你需要生成一段唯一的字符串。
我见过很多人用md5()函数来达到这个目的,即使是不适合用来达到这个目的:

// generate unique string
echo md5(time() . mt_rand(1,1000000));

事实上php有个名叫uniqid()的函数就可以达到这个目的。

// 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和其它许多语言。
但是,对于复杂对象,有可能会丢失一些信息。

8、压缩字符串
谈到压缩,通常我们会想到文件,比如ZIP归档。在PHP里面,不用任何归档文件压缩一个长字符串也是可能的。
下面的例子,我们将利用 gzcompress() 和 gzuncompress()函数:

$string =
"Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Nunc ut elit id mi ultricies
adipiscing. Nulla facilisi. Praesent pulvinar,
sapien vel feugiat vestibulum, nulla dui pretium orci,
non ultricies elit lacus quis ante. Lorem ipsum dolor
sit amet, consectetur adipiscing elit. Aliquam
pretium ullamcorper urna quis iaculis. Etiam ac massa
sed turpis tempor luctus. Curabitur sed nibh eu elit
mollis congue. Praesent ipsum diam, consectetur vitae
ornare a, aliquam a nunc. In id magna pellentesque
tellus posuere adipiscing. Sed non mi metus, at lacinia
augue. Sed magna nisi, ornare in mollis in, mollis
sed nunc. Etiam at justo in leo congue mollis.
Nullam in neque eget metus hendrerit scelerisque
eu non enim. Ut malesuada lacus eu nulla bibendum
id euismod urna sodales. ";

$compressed = gzcompress($string);

echo "Original size: ". strlen($string)."\n";
/* prints
Original size: 800
*/

echo "Compressed size: ". strlen($compressed)."\n";
/* prints
Compressed size: 418
*/

// getting it back
$original = gzuncompress($compressed);

我们使归档大小减小了几乎50%。类似的函数gzencode() 和 gzdecode() ,使用不同的算法可以得到类似的结果。

9、注册关闭函数
有一个叫register_shutdown_function(),允许你在脚本运行完毕的时候执行一些代码。
想象一下,你想在脚本运行结束的时候获取一些基准统计信息,比如运行了多长时间:

// capture the start time
$start_time = microtime(true);

// do some stuff
// ...

// display how long the script took
echo "execution took: ".
(microtime(true) - $start_time).
" seconds.";

起初这看起来微不足道,你只是把你的代码添加到文件底部,它会在运行结束时被执行。但是,假如你曾经调用了exit()函数,
这些代码将永远不会执行。另外,假如某个地方有致命错误,又或者脚步被用户终止了(在浏览器里面按下停止按钮),这些代码页不会
执行。
当你用register_shutdown_function()时,不管你的脚本因为什么而终止,它都会执行:当你用register_shutdown_function()时,不管你的脚本因为什么而终止,它都会执行:

$start_time = microtime(true);

register_shutdown_function('my_shutdown');

// do some stuff
// ...

function my_shutdown() {
global $start_time;

echo "execution took: ".
(microtime(true) - $start_time).
" seconds.";
}


转载链接 http://www.360us.net/archives/527


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
1. 智慧监狱概述 智慧监狱的建设背景基于监狱信息化的发展历程,从最初的数字化监狱到信息化监狱,最终发展到智慧监狱。智慧监狱强调管理的精细化、监管的一体化、改造的科学化以及办公的无纸化。政策上,自2017年以来,司法部连续发布了多项指导性文件,推动智慧监狱的建设。 2. 内在需求与挑战 智慧监狱的内在需求包括数据应用与共享的不足、安防系统的单一功能、IT架构的复杂性、信息安全建设的薄弱以及IT运维的人工依赖。这些挑战要求监狱系统进行改革,以实现数据的深度利用和业务的智能化。 3. 技术架构与设计 智慧监狱的技术架构包括统一门户、信息安全、综合运维、安防集成平台和大数据平台。设计上,智慧监狱采用云计算、物联网、大数据和人工智能等技术,实现资源的动态分配、业务的快速部署和安全的主动防护。 4. 数据治理与应用 监狱数据应用现状面临数据分散和共享不足的问题。智慧监狱通过构建数据共享交换体系、数据治理工具及服务,以及基于数据仓库的数据分析模型,提升了数据的利用效率和决策支持能力。 5. 安全与运维 智慧监狱的信息安全建设涵盖了大数据应用、安全管理区、业务区等多个层面,确保了数据的安全和系统的稳定运行。同时,综合运维平台的建立,实现了IT系统的统一管理和自动化运维,提高了运维效率和系统的可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值