澳门新葡萄京官网首页PHP特性

前言

一、用PHP进行HTTP认证

PHP
本人已然是生龙活虎种非常高效的语言,可是除了进行进程,PHP仍然有成都百货上千足以被优化之处。

PHP 的 HTTP 认证机制仅在 PHP 以 Apache
模块形式运营时才使得,因而该功效不适用于 CGI 版本。在 Apache 模块的 PHP
脚本中,能够用 header(卡塔尔国函数来向客商端浏览器发送“Authentication
Required”消息,使其弹出贰个客商名/密码输入窗口。当客户输入客户名和密码后,包涵有
U奥迪Q3L 的 PHP 脚本将会增加预约义变量PHP_AUTH_USER,PHP_AUTH_PW 和
AUTH_TYPE被再一次调用,那多个变量分别被设定为客户名,密码和验证项目。预约义变量保存在
$_SERVER 或者 $HTTP_SERVER_VAEscortS 数组中。帮忙“Basic”和“Digest”(自 PHP
5.1.0 起)认证方法

在本文中大家将介绍一下几点:

 

  1. 为啥PHP中优化的有无数要素是和代码未有提到的

  2. 在晋级PHP品质的历程中,为何大家还亟需领悟越来越多的关于其他方面包车型大巴文化

  3. 这个子系统形成瓶颈的来头以致解决的不二等秘书籍

  4. 我们还研商怎样调度以至优化PHP代码使其具有更佳的属性

二、Cookie

达到高品质

PHP 透明地支撑 HTTP cookie。cookie
是生机勃勃种在长间距浏览器端积存数据并以此来追踪和辨认顾客的建制。能够用
setcookie(卡塔尔(قطر‎ 或 setrawcookie(卡塔尔 函数来安装 cookie。cookie 是 HTTP
标头的黄金时代部分,因而 setcookie(卡塔尔(قطر‎函数必得在其它音信被输出到浏览器前调用,那和对 header()函数的节制相似。能够利用输出缓冲函数来推迟脚本的出口,直到按要求设置好了颇负的
cookie 可能别的 HTTP 标头。

当大家研究高品质时,大家并不独有指一个PHP脚本运维的有多么急迅,品质是指速度和可伸缩性的折中权衡。使用相当少财富的脚本因该会比另三个使用了缓存的本子要慢,可是在web服务器中,某意气风发随即可能运维同一个本子的多少个拷贝。

如果 variables_order中总结“C”,则别的从客商端发送的 cookie
都会被机关包含进 $_董事长KIE自动全局数组。借使指望对叁个 cookie
变量设置多少个值,则需在 cookie 的名目后加 [] 符号。

在底下的例子中,我们只要脚本a.php是壹位跑得那么些连忙赛跑选手,而b.php是一人全程马拉松长跑健将,他的快慢是基本不改变的。在负载较轻时,a.php
运转的要比b.php快,但是随着web服务器的载荷不断追加,b.php的性质只是减少了部分,而a.php却大势已去!

根据 register_globals的装置,能够从 cookie 组建平常的 PHP
变量。然而不推荐正视于此个性,因为出于安全原由此选项通常是关闭的。在前期的
PHP 版本中,当 track_vars配置选项展开时(此选项自 PHP 4.0.3
后连连打开的),系统还大概会设定 $HTTP_COOKIE_VARS。

这段时间大家以叁个切实可行中的例子来分解上边产生的气象。我们要写叁个PHP脚本,它从二个250k的公文中读取数据,何况生成叁个HTML文件。为了便利比较,大家写了三个落到实处均等效果脚本:hare.php
将文件一回性读入内部存款和储蓄器,而且叁遍性处理全数的数额;tortoise.php
二回只从文件中读取风流倜傥行,况兼毫不在内部存款和储蓄器中保留多于大器晚成行的新闻。结果是tortoise.php因为运用了越来越多的系统调用而真相大白的慢与hare.php。

 

脚本hare.php要求有0.04秒的CPU时间和的内部存款和储蓄器,tortoise.php必要有0.05秒的CPU是光阴和的内部存款和储蓄器。当时Web服务器有的物理内部存储器,和99%的空闲CPU。为了简化难点,大家不考虑内部存款和储蓄器碎片的意况。

三、会话

当有十叁个本子被同一时候运维时,hare.php将会据有掉全部的内部存款和储蓄器,而tortoise.php则足以剩下的闲暇内部存款和储蓄器。假诺第十叁个脚本要在服务器中运作,hare.php将不能不接纳虚构内部存款和储蓄器,那大概诱致其速度下落百分之五十,当时全部对hare.php的呼吁都将采纳0.88秒的CPU时间,与此同时,tortoise.php将依旧选拔0.06秒的CPU时间。

对电话机制(Session)在 PHP
中用来保存并发访问中的一些数码。那使能够扶植创造更为人性化的顺序,增添站点的重力。关于会话机制的越来越多音讯

下表中相当慢的PHP脚本使用了粗体以示不相同:

 

连接数

四、处理XForms

1个HTTP连接时的CPU时间

XForms 定义了风姿洒脱种古板 web
表单的变种,它能够用来更加多的平台和浏览器,以至非古板的媒体

12个HTTP连接时的CPU时间

五、文件上传管理

拾个HTTP连接时的CPU时间

* Post方法上传

hare.php

能够上传文本和二进制文件

0.04

连带安装见php.ini 的
file_uploads,upload_max_filesize,upload_tmp_dirpost_max_size以及
max_input_time 

0.40

 

0.88(使用了设想内部存款和储蓄器卡塔尔国

承保文件上传表单的性质是
enctype=”multipart/form-data”,否则文件上传不了

tortoise.php

 

0.06

* 全局变量$_FILES数组

0.06

其可含蓄全数上传的文书消息。

0.66

$_FILES[‘userfile’][‘name’]
顾客端机器文件的原名称。
$_FILES[‘userfile’][澳门新葡萄京官网首页 ,’type’]
文本的 MIME
类型,若是浏览器提供此音信的话。二个事例是“image/gif”。不过此 MIME
类型在 PHP 端并不检查,由此不用想当然感到有这些值。
$_FILES[‘userfile’][‘size’]
已上传文件的朗朗上口,单位为字节。
$_FILES[‘userfile’][‘tmp_name’]
文件被上传后在服务端积存的有的时候文件名。
$_FILES[‘userfile’][‘error’]
和该公文上传相关的错误代码。

地方的事例表明:提供好的品质并非可是指编写贰个高效的PHP脚本。达成高质量的PHP还供给对底层硬件、操作系统、以致常用的配套软件像web服务器和数据库系统都有卓绝的认知。

 

* 上传有的时候目录

文件被上传后,暗中同意地会被积累到服务端的暗中同意一时目录中,除非 php.ini 中的
upload_tmp_dir设置为其余的路子。服务端的私下认可有时目录可以经过更改 PHP
运行蒙受的境况变量 TMPDITiggo 来再一次安装,不过在 PHP 脚本内部通过运维putenv(卡塔尔函数来安装是不起功效的。该意况变量也能够用来认同别的的操作也是在上传的文书上进展的。

 

* 使用上传文件生效

函数 is_uploaded_file() 和 move_uploaded_file()

 

* 错误音信表明

PHP
将随文件音信数组一同再次回到多个应和的错误代码。该代码可以在文书上传时生成的公文数组中的
error 字段中被找到,也正是 $_FILES[‘userfile’][‘error’]。

UPLOAD_ERR_OK
其值为 0,未有不当发生,文件上传成功。
UPLOAD_ERR_INI_SIZE
其值为 1,上传的文书超越了 php.ini 中 upload_max_filesize
选项限定的值。
UPLOAD_ERR_FORM_SIZE
其值为 2,上传文件的轻重超过了 HTML 表单中 MAX_FILE_SIZE
选项钦定的值。
UPLOAD_ERR_PARTIAL
其值为 3,文件唯有风流倜傥部分被上传。
UPLOAD_ERR_NO_FILE
其值为 4,未有公文被上传。
UPLOAD_ERR_NO_TMP_DIR
其值为 6,找不到不经常文件夹。PHP 4.3.10 和 PHP 5.0.3 引入。
UPLOAD_ERR_CANT_WRITE
其值为 7,文件写入失利。PHP 5.1.0 引入

 

* 管见所及破绽

对 MAX_FILE_SIZE 设置的值,不能够超过 ini 设置中
upload_max_filesize选项设置的值。其暗中同意值为 2M 字节。

假如内部存款和储蓄器约束设置被激活,恐怕要求将 memory_limit 设置的更加大些,请确认
memory_limit 的设置丰盛的大。

如果
max_execution_time设置的值太小,脚本运转的小运大概会当先该装置。因而,也请确认保障max_execution_time 丰裕的大

max_execution_time仅仅只影响脚本本身运转的时光。任何此外费用在本子运维之外的年华,诸如用函数
system(State of Qatar对系统的调用、sleep(卡塔尔(قطر‎函数的运用、数据库查询、文件上传等,在计算脚本运营的最大日兔时都不包罗在内。

max_input_time以秒为单位设定了本子选取输入的最大时间,满含文件上传。对于非常大或五个文件,可能客商的网速非常慢时,恐怕会超过默许的
60 秒。 

如果 post_max_size设置的值太小,则超级大的文书会不可能被上传。因而,请确认保障post_max_size 的值丰硕的大

 

* 上传多少个公文

可以对 input 域使用差别的 name
来上传三个公文,并将它们的新闻自动以数组的方式组织。要变成那项功用,供给在
HTML 表单中对文本上传域使用和多选框与复选框近似的数组式提交语法

 

* 对Put方法的支撑

/* PUT data comes in on the stdin stream */
$putdata = fopen("php://stdin", "r");

/* Open a file for writing */
$fp = fopen("myputfile.ext", "w");

/* Read the data 1 KB at a time
   and write to the file */
while ($data = fread($putdata, 1024))
  fwrite($fp, $data);

/* Close the streams */
fclose($fp);
fclose($putdata);

让 Apache 大概 PHP 自动允许全数人覆盖 web
目录树下的此外公文显明是特别不明智的。因而,要管理相似的倡议,必须先告知
web 服务器必要用特定的 PHP 脚本来管理该伏乞。在 Apache 下,能够用
Script 选项来安装。它可以被停放到 Apache
配置文件中大致全部的地点。常常大家把它放置在 <Directory> 区域照旧<Virtualhost> 区域。

Script PUT /put.php

那将报告 Apache 将有所对 UCRUISERI 的 PUT 央求全体发送到 put.php 脚本,那个UENCOREI 必需和 PUT 命令中的内容相相配。当然,那是树立在 PHP 辅助 .php
扩大名,而且 PHP 已经在运行的只要之上。

那将会把文件拷贝到远程客商端诉求的职分。只怕希望在文件拷贝此前行行部分反省大概对客户认证之类的操作。这里唯后生可畏的难点是,当
PHP 采取到 PUT 方法的呼吁时,它将会把上传的文件储存到和任何用 POST
方法管理过的文书大器晚成律的目前目录。在乞请停止时,有的时候文件将被去除。由此,用来管理PUT 的 PHP
脚本必得将该公文拷贝到此外的地点。该一时文件的文件名被积攒在变量
$PHP_PUT_FILENAME 中,也得以经过 $REQUEST_UCR-VI
变量得到建议的对象文件名(在非 Apache web
服务器上只怕会有十分的大的退换)。该指标文件名是由长途客商端钦定的。也足以不固守改顾客端的音信,而把具有上传的文本存储到贰个极其的上传目录下

 

六、使用远程文件

设若在 php.ini 文件中激活了
allow_url_fopen选项,就能够在大多亟需用文件名作为参数的函数中应用
HTTP 和 FTP 的 U揽胜极光L 来替代文件名。同期,也得以在
include(卡塔尔国、include_once()、require() 及 require_once(State of Qatar 语句中动用
UTiggoL。

Example #1 获取远程文件的标题

$file = fopen ("http://www.example.com/", "r");
if (!$file) {
    echo "<p>Unable to open remote file.n";
    exit;
}
while (!feof ($file)) {
    $line = fgets ($file, 1024);
    /* This only works if the title and its tags are on one line */
    if (eregi ("<title>(.*)</title>", $line, $out)) {
        $title = $out[1];
        break;
    }
}
fclose($file);

 

Example #2 将数据保存到长途服务器

$file = fopen ("ftp://ftp.example.com/incoming/outputfile", "w");
if (!$file) {
    echo "<p>Unable to open remote file for writing.n";
    exit;
}
/* Write the data here. */
fwrite ($file, $_SERVER['HTTP_USER_AGENT'] . "n");
fclose ($file);

 

七、连接管理

在 PHP 内部,系统拥戴着连连情形,其状态有两种可能的情状:
■0 – NORMAL(正常)
■1 – ABORTED(非凡退出)
■2 – TIMEOUT(超时)

当 PHP 脚本符合规律地运作 NORMAL
状态时,连接为使得。当远程顾客端中断连接时,ABORTED
状态的标识将会被张开。远程客商端连接的暂停日常是由客商点击 STOP
开关以致的。当连接时间超越 PHP 的限制期限(请参阅 set_time_limit()函数)时,TIMEOUT 状态的暗号将被张开。

能够调整脚本是还是不是须求在顾客端中断连接时退出。有时候让脚本完整地运维会推动多数造福,纵然没有远程浏览器选择脚本的出口。暗中同意的事态是当远程顾客端连接中断时脚本将会退出。该管理进程可由
php.ini 的 ignore_user_abort 或由 httpd.conf设置中对应的“php_value
ignore_user_abort”以及 ignore_user_abort(卡塔尔(قطر‎ 函数来决定。若无报告
PHP 忽视顾客的间歇,脚本将会被中断,除非通过
register_shutdown_function(卡塔尔国设置了关闭触发函数。通过该关闭触发函数,当远程用户点击
STOP 按键后,脚本再一次尝试输出数据时,PHP
将会检查评定到连年已被暂停,并调用关闭触发函数。

本子也可以有希望被内置的剧本计时器中断。暗中同意的过期约束为 30
秒。那几个值可以透过安装 php.ini 的 max_execution_time或
httpd.conf设置中对应的“php_value max_execution_time”参数恐怕set_time_limit(State of Qatar函数来更改。当流速計超时的时候,脚本将会临近于上述连接中断的气象退出,先前被登记过的关门触发函数也将要那个时候被实践。在该关闭触发函数中,能够通过调用
connection_status(State of Qatar函数来检查超时是不是变成关闭触发函数被调用。要是超时以致了倒闭触发函数的调用,该函数将赶回
2。

亟待专一的少数是 ABORTED 和 TIMEOUT 状态能够并且有效。那在报告 PHP
忽略顾客的淡出操作时是只怕的。PHP
将照旧注意客商已经搁浅了延续但脚本如故在运作的情形。假使到了运营的时光约束,脚本将被分离,设置过的关门触发函数也将被实行。在这里时候会意识函数
connection_status() 返回 3。

 

八、数据库恒久连接

长久的数据库连接是指在剧本结束运营时不停息的连接。当收到八个永世连接的乞求时。PHP
将检查是否早就存在四个(前边早就开启的)雷同的永世连接。假设存在,将一向利用这一个接二连三;倘使官样文章,则树立贰个新的总是。所谓“雷同”的接连是指用相仿的客商名和密码到相同主机的三番五次。

对 web
服务器的干活和分布负载未有完全清楚的读者只怕会错误地知道恒久连接的功效。特别的,永远连接不会在同蓬蓬勃勃的连续几天上提供创立“客商会话”的力量,也不提供可行建构工作的技巧。实际上,从严厉意义上来讲,长久连接不会提供别的非恒久连接不可能提供的奇特效果。

为什么?

那和 web 服务器工作的格局有关。web 服务器可以用三种办法来利用 PHP 生成
web 页面。

先是种格局是将 PHP 用作二个“外壳”。以这种办法运转,PHP 会为向 web
服务器提出的每一个 PHP 页面央求生成并截止四个 PHP
解释器线程。由于该线程会随每种央浼的了断而得了,由此任何在这里个线程中运用的别的财富(举个例子指向
SQL
数据库服务器的总是)都会随线程的完结而关门。在这里种景色下,使用永恒连接不会拿走其余地转移——因为它们根本不是永世的。

其次,也是最常用的主意,是把 PHP 用作多进度 web
服务器的多个模块,这种方法前段时间只适用于
Apache。对于二个多进度的服务器,其一级特征是有三个父进度和后生可畏组子进度协和拨运输转,此中实际变化
web
页面包车型的士是子进程。每当客商端向父进度提议央浼时,该乞请会被传送给尚未曾被其它的客商端央浼占用的子进度。那约等于说当雷同的客户端第4回向服务端建议倡议时,它将有非常大概率被二个两样的子进度来处理。在拉开了二个恒久连接后,全部必要SQL 服务的后继页面都能够再一次行使那一个已经济建设立的 SQL Server 连接。

谈起底意气风发种方法是将 PHP 用作十二线程 web 服务器的多个插件。近日 PHP 4
已经支撑 ISAPI、WSAPI 和 NSAPI(在 Windows 遭受下),那一个使得 PHP
能够被看成诸如 Netscape FastTrack (iPlanet卡塔尔国、Microsoft’s Internet
Information Server (IIS卡塔尔(قطر‎ 和 O’Reilly’s WebSite Pro 等四线程 web
服务器的插件。恒久连接的一言一行和眼下所陈说的多进程模型在精气神上是平等的。注意
PHP 3 不帮衬 SAPI。

只要永世连接并不曾经肩负何附加的意义,那么使用它有怎么着实惠?

答案极其轻便——效用。当客商端对 SQL
服务器的一而再一连央浼特别频仍时,永恒连接将越加便捷。连接央求频仍的正经八百决议于比相当多成分。举例,数据库的品种,数据库服务和
web 服务是或不是在同等台服务器上,SQL
服务器如何加载负载等。但大家足足知道,当连接要求很频仍时,永世连接将鲜明的升高效能。它使得各样子进程在其生命周期中只做一回延续操作,而非每一趟在拍卖四个页面时都要向
SQL
服务器建议连接供给。那也算得,各个子进度将对服务器创建分级独立的恒久连接。比如,要是有
20 个分化的子进程运营某脚本组建了永世的 SQL
服务器恒久连接,那么实际上向该 SQL 服务器建设构造了 21个不一致的流传千古连接,种种进程据有三个。

留意,倘使长久连接的子进度数目抢先了设定的数据库连接数限定,系统将会生出局地毛病。固然数据库的还要连接数节制为
16,而在农忙会话的事态下,有 十四个线程试图连接,那么有叁个线程将不能连接。假使这时候,在剧本中出现了驱动连接不可能关闭的错误(譬喻Infiniti循环),则该数据库的
15个接二连三将神速地遭到震慑。请查阅使用的数据库的文书档案,以博得有关什么管理已丢弃的及闲置的连日的方法。

在动用永恒连接时还应该有局地特别的难点亟待专心。比方在永恒连接中使用数据表锁时,假诺脚本不管怎么着来头不可能自由该多少表锁,其随后接纳同三翻五次接的本子将会被永远的窒碍,使得供给重新起动
httpd
服务如故数据库服务。其余,在行使事务管理时,如若脚本在业务拥塞产生前告竣,则该窒碍也会耳熏目染到应用同三回九转接的下二个剧本。不管在什么情状下,都能够经过利用
register_shutdown_function(卡塔尔(قطر‎函数来注册三个粗略的清理函数来张开数据表锁,也许回滚事务。或许更加好的管理方式,是不在使用数据表锁也许事务管理的剧本中运用永恒连接,那足以从根本上扑灭那么些主题材料(当然仍可以在其余地点使用永世连接)。 

世代连接是为普通连接创建一定的布满而设计的。那象征必需能够保证在将恒久连接替换为非恒久连接时,脚本的作为不会转移。使用永世连接将(非常)有超级大可能率变动脚本的功能,但不转移其行事!

参见
fbsql_pconnect(),ibase_pconnect(),ifx_pconnect(),ingres_pconnect(),msql_pconnect(),mssql_pconnect(),mysql_pconnect(),ociplogon(),odbc_pconnect(),ora_plogon(),pfsockopen(),pg_pconnect()和
sybase_pconnect()。

 

九、安全形式

PHP
的白山情势是为了筹划减轻分享服务器(shared-server)安全主题素材而实行的。在结构上,试图在
PHP 层上化解这几个难题是不客观的,但改良 web
服务器层和操作系统层显得万分不现实。因而不菲人,特别是
ISP,这两天使用安全形式

* 保卫安全艺术和安全方式

保安措施和安全模式配置指令
名字 默认 可修改范围 更新日志
safe_mode "0" PHP_INI_SYSTEM  
safe_mode_gid "0" PHP_INI_SYSTEM 自 PHP 4.1.0 起可用
safe_mode_include_dir NULL PHP_INI_SYSTEM 自 PHP 4.1.0 起可用
safe_mode_exec_dir "" PHP_INI_SYSTEM  
safe_mode_allowed_env_vars "PHP_" PHP_INI_SYSTEM  
safe_mode_protected_env_vars "LD_LIBRARY_PATH" PHP_INI_SYSTEM  
open_basedir NULL PHP_INI_SYSTEM  
disable_functions "" 仅 php.ini 自 PHP 4.0.1 起可用
disable_classes "" 仅 php.ini 自 PHP 4.3.2 起可用

有关 PHP_INI_* 样式的越来越多实际情况与概念,见 Where a configuration
setting may be set。

 

那是布置指令的简便表明。

 

safe_modeboolean
是否启用 PHP 的平安形式。

safe_mode_gidboolean
私下认可意况下,安全格局在打开文件时会做 UID 比较检查。要是想将其放宽到 GID
相比较,则展开 safe_mode_gid。是不是在文书访谈时使用
UIDFALSE)或者 GIDTRUE)来做检查。

safe_mode_include_dirstring
当从今以后目录及其子目录(目录必得在
include_path中大概用生机勃勃体化路线来含有)满含文件时超过
UID/GID 检查。

从 PHP 4.2.0 起首,本指令能够担任和
include_path指令雷同的品格用冒号(Windows
中是分号)隔开分离的门路,而不只是二个目录。

钦赐的限定实际上是多个前缀,而非叁个目录名。那相当于说“safe_mode_include_dir

/dir/incl”将允许访谈“/dir/include”和“/dir/incls”,若是它们存在的话。若是指望将访谈调整在二个钦命的目录,那么请在结尾加上贰个斜线,举例:“safe_mode_include_dir
= /dir/incl/”。 假设本指令的值为空,在 PHP
4.2.3 中以至 PHP 4.3.3 起全体区别
UID/GID的文书将不能够被含有。在较早版本中,全部文件都能被含有。

safe_mode_exec_dirstring
后生可畏经 PHP 使用了平安方式,system()
和其它程序实施函数将不容运维不在那目录中的程序。必得采纳
/ 作为目录分隔符,富含 Windows 中。

safe_mode_allowed_env_varsstring
设置有个别情状变量大概是机密的广元缺口。本指令包涵有三个逗号分隔的前缀列表。在安全方式下,客商只可以更换那多少个名字具有在这里间提供的前缀的情形变量。暗中认可情状下,用户只好设置以
PHP_ 伊始的景况变量(举例 PHP_FOO = BAR)。

Note:

要是本指令为空,PHP 将使客商能够校正任哪个地方境变量!

 

safe_mode_protected_env_varsstring
本指令包蕴有一个逗号分隔的碰着变量的列表,最后客户不可能用 putenv()
来退换这一个景况变量。以致在 safe_mode_allowed_env_vars
中装置了同意改善时也无法校正那些变量。

 

参见
register_globals,display_errors
和 log_errors。

当 safe_mode 设置为 on,PHP
将因此文件函数或其目录检查当前剧本的具备者是还是不是和将被操作的文书的具备者相相配。举例:

-rw-rw-r--    1 rasmus   rasmus       33 Jul  1 19:20 script.php
-rw-r--r--    1 root     root       1116 May 26 18:01 /etc/passwd

运行 script.php

<?php readfile('/etc/passwd');?>

假虞升卿全形式被激活,则将会诱致以下错误:

Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2

 

与此同一时间,或然会存在这里么的条件,在该条件下,宽松的
GID反省已经够用,但严苛的 UID反省反而是不符合的。能够用
safe_mode_gid慎选来决定这种检讨。借使设置为
On则开展宽松的 GID 检查;设置为 Off(默认值)则进行 UID 检查。

除了 safe_mode 以外,就算设置了
open_basedir选料,则装有的文本操作将被限制在内定的目录下。举例:

<Directory /docroot>
  php_admin_value open_basedir /docroot
</Directory>

若果在装置了
open_basedir筛选后运转雷同的
script.php,则其结果会是:

Warning: open_basedir restriction in effect. File is in wrong directory in
/docroot/script.php on line 2

 

也能够单独地遮掩有些函数。请小心
disable_functions接收不能够在
php.ini 文件外界使用,相当于说相当小概在
httpd.conf文件的按不相同设想主机或分裂目录的办法来掩瞒函数。借使将如下内容到场到
php.ini 文件:

disable_functions readfile,system

则会拿到如下的出口:

Warning: readfile() has been disabled for security reasons in
/docroot/script.php on line 2

 

Warning

自然,那么些 PHP 节制不适用于可推行文件。

 

 

* 被双鸭山情势节制或屏蔽的函数

安全模式限制函数
函数名 限制
dbmopen() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
dbase_open() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
filepro() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
filepro_rowcount() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
filepro_retrieve() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
ifx_* sql_safe_mode 限制, (!= safe mode)
ingres_* sql_safe_mode 限制, (!= safe mode)
mysql_* sql_safe_mode 限制, (!= safe mode)
pg_loimport() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
posix_mkfifo() 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
putenv() 遵循 ini 设置的 safe_mode_protected_env_vars 和 safe_mode_allowed_env_vars 选项。请参考 putenv() 函数的有关文档。
move_uploaded_file() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
chdir() 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
dl() 当 PHP 运行在 安全模式 时,不能使用此函数。
backtick operator 当 PHP 运行在 安全模式 时,不能使用此函数。
shell_exec()(在功能上和 backticks 函数相同) 当 PHP 运行在 安全模式 时,不能使用此函数。
exec() 只能在 safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。
system() 只能在 safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。
passthru() 只能在 safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。
popen() 只能在 safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。
fopen() 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
mkdir() 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
rmdir() 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
rename() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
unlink() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
copy() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。 (on source and target)
chgrp() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
chown() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。
chmod() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 另外,不能设置 SUID、SGID 和 sticky bits
touch() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。
symlink() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。 (注意:仅测试 target)
link() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。 (注意:仅测试 target)
apache_request_headers() 在安全模式下,以“authorization”(区分大小写)开头的标头将不会被返回。
header() 在安全模式下,如果设置了 WWW-Authenticate,当前脚本的 uid 将被添加到该标头的 realm 部分。
PHP_AUTH 变量 在安全模式下,变量 PHP_AUTH_USER、PHP_AUTH_PW 和 PHP_AUTH_TYPE 在 $_SERVER 中不可用。但无论如何,您仍然可以使用 REMOTE_USER 来获取用户名称(USER)。(注意:仅 PHP 4.3.0 以后有效)
highlight_file(), show_source() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。 (注意,仅在 4.2.1 版本后有效)
parse_ini_file() 检查被操作的文件或目录是否与被执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与被执行的脚本有相同的 UID(所有者)。 (注意,仅在 4.2.1 版本后有效)
set_time_limit() 安全模式下不起作用。
max_execution_time 安全模式下不起作用。
mail() 在安全模式下,第五个参数被屏蔽。(注意,仅自 PHP 4.2.3 起受影响)
任何使用 php4/main/fopen_wrappers.c 的函数 ??

 

十、PHP命令行格局

PHP 提供了风流倜傥种新品类的 CLI SAPI(Server Application Programming
Interface,服务端应用编制程序端口)援救,名字为 CLI,意为 Command Line
Interface
,即命令行接口。望文生义,该 CLI SAPI 模块首要用作 PHP
的支出外壳选择。CLI SAPI和此外 CLI
SAPI模块相比较有成千上万的分裂的地方,大家将要本章中详细解说。值得生龙活虎提的是,CLI和
CGI 是不一样的 SAPI,即便它们之间有为数不菲联手的一坐一起。

CLI SAPI 最早是随 PHP 4.2.0
版本公布的,但依然只是叁个试验性的版本,并供给在运转 ./configure
时加上 –enable-cli参数。从 PHP 4.3.0 版本起先,CLI SAPI
成为了标准模块,–enable-cli参数会被私下认可得设置为 on,也得以用参数
–disable-cli来屏蔽。

从 PHP 4.3.0上马,CLI/CGI 二进制施行文书的公文名、地方和是不是留存会根据PHP 在系统上的安装而各异。在暗许情状下,当运营 make 时,CGI 和 CLI
都会被编写翻译并且分别放置在 PHP 源文件目录的 sapi/cgi/php 和 sapi/cli/php
下。能够小心到三个文本都被取名字为了 php。在 make
install
的长河中会发生怎么着决计于配置行。若是在陈设的时候采取了一个 SAPI
模块,如 apxs,也许应用了 –disable-cgi参数,则在 make install
的进度中,CLI 将被拷贝到 {PREFIX}/bin/php,除非 CGI
已经被停放在了特别地点。因而,比如,即使在构造行中有
–with–apxs,则在 make install 的进度中,CLI 将被拷贝到
{PREFIX}/bin/php。假使期望收回 CGI 实践文书的设置,请在 make
install
之后运营 make install-cli。也许,也得以在结构行中加上
–disable-cgi参数。

Note:

由于 –enable-cli
–enable-cgi况兼私下认可有效,因此,不必再配置行中加上
–enable-cli来使得 CLI 在 make install 进度中被拷贝到
{PREFIX}/bin/php。

 

在 PHP 4.2.0 到 PHP 4.2.3 之间的 Windows 发行李包裹中,CLI 的公文名字为php-cli.exe,相近文件夹下的 php.exe 为 CGI。从 PHP 4.3.0
版本开头,Windows 的发行李包裹中 CLI 的举行理文件书为
php.exe,被停放在叁个独自的名叫 cli 的公文夹下,即 cli/php.exe。在 PHP 5中,CLI 存在于主文件夹中,名字为 php.exe,而 CGI 版本名称为 php-cgi.exe。

从 PHP 5 起,二个名称叫 php-win.exe的新文件随包发表。它也就是 CLI
版本,可是 php-win 不出口任何内容,便不提供调节台(不会弹出“DOS
窗口”)。这种办法临近于 php-gtk。须求接受
–enable-cli-win32采用来配置它。

Note: 怎么着得到消息本身使用的是哪些 SAPI?

在指令行下,运营 php -v 便能查出该 php 是 CGI 照旧 CLI。请参见函数
class=”function”>php_sapi_name()
以致常量 PHP_SAPI

 

Note:

在 PHP 4.3.2 中投入了 Unix 的 man 页面。能够在命令行中键入 man
php
来查看。

 

以下为 CLI SAPI 和此外 CLI SAPI 模块比较的明朗差距:

  • CGI SAPI 分歧,其出口未有别的头音信。

    尽管 CGI SAPI 提供了注销 HTTP 头信息的章程,但在 CLI SAPI
    中并不设有相仿的不二诀窍以展开 HTTP 头新闻的输出。

    CLI 默许以平静情势起头,但为了保障包容性,-q
    –no-header参数为了向后卓殊依然保留,使得能够利用旧的 CGI 脚本。

    在运作时,不会把事业目录改为脚本的当前目录(能够动用 -C
    –no-chdir参数来合作 CGI 方式)。

    一差二错开上下班时间输出纯文本的错误消息(非 HTML 格式)。

  • CLI SAPI 强逼覆盖了
    php.ini中的有个别设置,因为这么些设置在外壳情形下是未有趣的。

    覆盖 php.ini 设置选项
    设置选项 CLI SAPI 默认值 备注
    html_errors FALSE 无意义的 HTML 标记符会使得出错信息很凌乱,所以在外壳下阅读报错信息是十分困难的。因此将该选项的默认值改为 FALSE
    implicit_flush TRUE 在命令行模式下,所有来自 print()echo() 的输出将被立即写到输出端,而不作任何地缓冲操作。如果希望延缓或控制标准输出,仍然可以使用 output buffering 设置项。
    max_execution_time 0(无限值) 鉴于在外壳环境下使用 PHP 的无穷的可能性,最大运行时间被设置为了无限值。为 web 开发的应用程序可能只需运行几秒钟时间,而外壳应用程序的运行时间可能会长的多。
    register_argc_argv TRUE

    由于该设置为 TRUE,将总是可以在 CLI SAPI中访问到 argc(传送给应用程序参数的个数)和 argv(包含有实际参数的数组)。

    对于 PHP 4.3.0,在使用 CLI SAPI 时,PHP 变量 $argc$argv已被注册并且设定了对应的值。而在这之前的版本,这两个变量在 CGI 或者 模块 版本中的建立依赖于将 PHP 的设置选项 register_globals设为 on。除了版本和 register_globals 设定以外,可以随时通过调用 $_SERVER或者 $HTTP_SERVER_VARS来访问它们。例如:$_SERVER[‘argv’]

     

    Note:

    那一个设置不能在装置文件
    php.ini或任何钦命的任何文件中被最早化为别的值。那一个私下认可值被限定在装有其余的装置文件被深入剖判后改造。但是,它们的值能够在程序运转的进度中被改换(纵然对此该运维进程来说,这一个设置项是未有趣的)。

     

  • 为了缓慢解决外壳情况下的办事,我们定义了之类常量:

    CLI 专用常量
    常量名称 描 述
    STDIN 一个已打开的指向 stdin的流。可以用如下方法来调用:

    <?php$stdin = fopen('php://stdin', 'r');?>

    如果想从 stdin读取一行内容,可以使用

    <?php$line = trim(fgets(STDIN)); // 从 STDIN 读取一行fscanf(STDIN, "%dn", $number); // 从 STDIN 读取数字?>
    STDOUT 一个已打开的指向 stdout的流。可以用如下方式来调用:

    <?php$stdout = fopen('php://stdout', 'w');?>
    STDERR 一个已打开的指向 stderr的流。可以用如下方式来调用:

    <?php$stderr = fopen('php://stderr', 'w');?>

     

    有了以上常量,就无需本人树立针对诸如
    stderr的流,只需轻松的使用这几个常量来替代流指向:

    php -r 'fwrite(STDERR, "stderrn");'
    

    毋庸本人来关闭那么些流,PHP 会自动完毕那些操作。

     

  • CLI SAPI不会将当前目录改为已运营的剧本所在的目录。

    以下轨范展现了本模块与 CGI SAPI 模块之间的比不上:

    <?php// 名为 test.php 的简单测试程序echo getcwd(), "n";?>

     

    在使用 CGI 版本时,其出口为

    $ pwd
    /tmp
    
    $ php-cgi -f another_directory/test.php
    /tmp/another_directory
    

     

    刚烈能够看见 PHP 将当前目录改成了正要运维过的本子所在的目录。

    使用 CLI SAPI 模式,得到:

    $ pwd
    /tmp
    
    $ php -q another_directory/test.php
    /tmp
    

    那使得在选取 PHP 编写外壳工具时收获了非常的大的有益。

     

    Note:

    能够在命令行运维时给该 CGI SAPI 加上 -C参数,使其帮衬 CLI
    SAPI
    的功能。

     

 

以下是 PHP 二进制文件(即
php.exe程序)提供的命令行形式的选项参数,随就可以以运转带 -h参数的 PHP
命令来询问那几个参数。

Usage: php [options] [-f] <file> [--] [args...]
       php [options] -r <code> [--] [args...]
       php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
       php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
       php [options] -- [args...]
       php [options] -a

  -a               Run interactively
  -c <path>|<file> Look for php.ini file in this directory
  -n               No php.ini file will be used
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -f <file>        Parse <file>.
  -h               This help
  -i               PHP information
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -r <code>        Run PHP <code> without using script tags <?..?>
  -B <begin_code>  Run PHP <begin_code> before processing input lines
  -R <code>        Run PHP <code> for every input line
  -F <file>        Parse and execute <file> for every input line
  -E <end_code>    Run PHP <end_code> after processing all input lines
  -H               Hide any passed arguments from external tools.
  -s               Display colour syntax highlighted source.
  -v               Version number
  -w               Display source with stripped comments and whitespace.
  -z <file>        Load Zend extension <file>.

  args...          Arguments passed to script. Use -- args when first argument
                   starts with - or script is read from stdin

 

CLI SAPI 模块有以下二种不一致的艺术来获取要运营的 PHP 代码:

  1. 让 PHP 运转内定文件。

     

    php my_script.php
    
    php -f my_script.php
    

     

    如上三种艺术(使用或不利用 -f参数)都能够运行给定的
    my_script.php 文件。可以选拔任何文件来运作,钦命的 PHP
    脚本并非一定要以 .php为扩张名,它们能够有私下的文书名和强大名。

  2. 在命令行直接运营 PHP 代码。

     

    php -r 'print_r(get_defined_constants());'
    

     

    在动用这种办法时,请当心外壳变量的代替及引号的使用。

    Note:

    请留意翻阅以上范例,在运作代码时从没起头和甘休的标识符!加上
    -r参数后,这么些标识符是不须要的,加上它们会招致语法错误。

     

  3. 透过专门的职业输入(stdin)提供应和必要要周转的 PHP 代码。

    以上用法提供了万分刚劲的功能,使得能够如下榜样所示,动态地转换 PHP
    代码并透过命令行运营这么些代码:

    $ some_application | some_filter | php | sort -u >final_output.txt
    

     

 

以上二种运维代码的情势不能够同偶然候选用。

和具备的外壳应用程序同样,PHP 的二进制文件(php.exe文件)及其运转的 PHP
脚本能够经受生龙活虎四种的参数。PHP
未有范围传送给脚本程序的参数的个数(外壳程序对命令行的字符数有限量,但平日都不会超越该限量)。传递给脚本的参数可在全局变量
$argv
中获得。该数组中下标为零的积极分子为脚本的称谓(当 PHP
代码来自专门的学业输入获直接用
-r参数以命令行方式运行时,该名称叫“”)。其余,全局变量
$argc 存有
$argv数组中成员变量的个数(而非传送给脚本程序的参数的个数)。

假定传送给脚本的参数不是以
标记最初,就无需过多的声名远扬哪些。向脚本传送以
领头的参数会导致错误,因为 PHP
会感觉应该由它本人来管理那么些参数。能够用参数列表分隔符
来解决这么些主题素材。在 PHP
拆解深入分析完参数后,该符号后有所的参数将会被形容传送给脚本程序。

 

# 以下命令将不会运行 PHP 代码,而只显示 PHP 命令行模式的使用说明:
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# 以下命令将会把“-h”参数传送给脚本程序,PHP 不会显示命令行模式的使用说明:
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

 

除开,还大概有另三个措施将 PHP
用于外壳脚本。能够在写叁个剧本,并在率先行以 #!/usr/bin/php
初始,在其后增加以 PHP 开始和最终标识符包罗的常规的 PHP
代码,然后为该文件设置科学的运营属性(比方:chmod +x
test
)。该方法能够使得该公文能够像外壳脚本或 PETiguanL 脚本同样被直接实行。

#!/usr/bin/php<?php var_dump($argv);?>

 

假若改文件名称叫 test 并被放置在当前目录下,能够做如下操作:

$ chmod +x test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}

 

正如所看见的,在向该脚本传送以 起初的参数时,脚本照旧能够健康运行。

PHP 4.3.3 以来有效的长选项:

命令行选项
选项名称 长名称 说明
-a –interactive

交互式运行 PHP。如果编译 PHP 时加入了 Readline 扩展(Windows 下不可用),那将会得到一个很好的外壳,包括一个自动完成的功能(例如可以在键入变量名的时候,按下 TAB 键,PHP 会自动完成该变量名)以及命令历史记录,可以用上下键来访问。历史记录存在 ~/.php_history 文件中。

Note:

通过 auto_prepend_fileauto_append_file包含的文件在此模式下会被解析,但有些限制,例如函数必须在被调用之前定义。

 

-c –php-ini

用该参数,可以指定一个放置 php.ini文件的目录,或者直接指定一个自定义的 INI文件(其文件名可以不是 php.ini),例如:

$ php -c /custom/directory/ my_script.php

$ php -c /custom/directory/custom-file.ini my_script.php

如果不指定此选项,PHP 将在默认位置搜索文件。

 

-n –no-php-ini

完全忽略 php.ini。此参数在 PHP 4.3.0 以后有效。

-d –define

用该参数可以自行设置任何可以在 php.ini文件中设置的配置选项的值,其语法为:

-d configuration_directive[=value]

 

例子(因版面原因而折行显示):

# 取值部分被省略,将会把配置选项设为 "1"
$ php -d max_execution_time
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# 取值部分为空白,将会把配置选项设为 ""
php -d max_execution_time=
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# 配置选项将被设置成为任何 '=' 字符之后的值
$  php -d max_execution_time=20
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$  php
        -d max_execution_time=doesntmakesense
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense"

 

-e –profile-info

激活扩展信息模式,被用于调试/测试。

-f –file

解析并运行 -f选项给定的文件名。该参数为可选参数,可以省略,仅指明需要运行的文件名即可。

-h and -? –help and –usage 使用该参数,可以得到完整的命令行参数的列表及这些参数作用的简单描述。
-i –info 该命令行参数会调用 phpinfo()函数并显示出结果。如果 PHP 没有正常工作,建议执行 php -i命令来查看在信息表格之前或者对应的地方是否有任何错误信息输出。请注意当使用 CGI 摸索时,输出的内容为 HTML格式,因此输出的信息篇幅较大。
-l –syntax-check

该参数提供了对指定 PHP 代码进行语法检查的方便的方法。如果成功,则向标准输出写入 No syntax errors detected in <filename>字符串,并且外壳返回值为 0。如果失败,则输出 Errors parsing <filename>以及内部解析器错误信息到标准输出,同时外壳返回值将别设置为 255

该参数将无法检查致命错误(如未定义函数),如果也希望检测致命错误,请使用 -f参数。

Note:

该参数不能和 -r一同使用。

 

-m –modules

使用该参数,PHP 将打印出内置以及已加载的 PHP 及 Zend 模块:

$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]

 

-r –run

使用该参数可以在命令行内运行单行 PHP 代码。无需加上 PHP 的起始和结束标识符(<?php?>),否则将会导致语法解析错误。

Note:

使用这种形式的 PHP 时,应注意避免和外壳环境进行的命令行参数替换相冲突。

显示语法解析错误的范例

$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse error, unexpected '='

这里的问题在于即使使用了双引号 ",sh/bash 仍然实行了参数替换。由于 $foo没有被定义,被替换后它所在的位置变成了空字符,因此在运行时,实际被 PHP 读取的代码为:

$ php -r " = get_defined_constants();"

正确的方法是使用单引号 。在用单引号引用的字符串中,变量不会被 sh/bash 还原成其原值。

$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
  ["E_ERROR"]=>
  int(1)
  ["E_WARNING"]=>
  int(2)
  ["E_PARSE"]=>
  int(4)
  ["E_NOTICE"]=>
  int(8)
  ["E_CORE_ERROR"]=>
  [...]

如果使用的外壳不是 sh/bash,可能会碰到更多问题。请将碰到的 Bug 向 » http://bugs.php.net/报告。注意,当试图将 shell 变量用到代码中或者使用反斜线时仍然很容易碰到问题。

 

 

Note:

-rCLI SAPI 中有效,在 CGI SAPI 中无效。

 

Note:

此选项只用于非常基本的用途。因此一些配置指令(例如 auto_prepend_fileauto_append_file)在此模式下被忽略。

 

-B –process-begin

在处理 stdin 之前先执行 PHP 代码。PHP 5 新加。

-R –process-code

对每个输入行都执行 PHP 代码。PHP 5 新加。

此模式下有两个特殊变量:$argn和 $argi。$argn包含 PHP 当前处理的行内容,而 $argi 则包含该行号。

-F –process-file

对每个输入行都执行 PHP 文件。PHP 5 新加。

-E –process-end

在处理完输入后执行的 PHP 代码。PHP 5 新加。

使用 -B-R-E选项来计算一个项目总行数的例子。

$ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Total Lines: $ln";'
Total Lines: 37328

 

-s –syntax-highlight and –syntax-highlight

显示有语法高亮色彩的源代码。

该参数使用内建机制来解析文件并为其生成一个 HTML高亮版本并将结果写到标准输出。请注意该过程所做的只是生成了一个 <code> […] </code>HTML 标记的块,并不包含任何的 HTML 头。

Note:

该选项不能和 -r参数同时使用。

 

-v –version

将 PHP,PHP SAPI 和 Zend 的版本信息写入标准输出。例如:

$ php -v
PHP 4.3.0 (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies

 

-w –strip

显示除去了注释和多余空白的源代码。

Note:

该选项不能和 -r参数同时使用。

 

-z –zend-extension

加载 Zend 扩展库。如果仅给定一个文件名,PHP 将试图从当前系统扩展库的默认路径(在 Linux 系统下,该路径通常由 /etc/ld.so.conf指定)加载该扩展库。如果用一个绝对路径指定文件名,则不会使用系统的扩展库默认路径。如果用相对路径指定的文件名,则 PHP 仅试图在当前目录的相对目录加载扩展库。

 

PHP 的命令行方式能使得 PHP 脚本能完全独立于 web 服务器单独运维。借使使用
Unix 系统,须求在 PHP
脚本的最前头加上意气风发行特殊的代码,使得它亦可被奉行,那样系统就能够明了用哪些程序去运作该脚本。在
Windows 平台下能够将 php.exe 和
.php文本的双击属性相关联,也得以编写三个批管理文件来用 PHP
施行脚本。为 Unix 系统扩展的第风姿洒脱行代码不会影响该脚本在 Windows
下的运作,因而也得以用该格局编写跨平台的剧本程序。以下是贰个简洁明了的 PHP
命令路程序的模范。

 

Example #1 试图以命令市场价格势运转的 PHP 脚本(script.php)

#!/usr/bin/php<?phpif ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {?>This is a command line PHP script with one option. Usage: <?php echo $argv[0]; ?> <option> <option> can be some word you would like to print out. With the --help, -help, -h, or -? options, you can get this help.<?php} else { echo $argv[1];}?>

 

在上述脚本中,用第大器晚成行特其余代码来指明该公文应当由 PHP
来推行。在那处运用 CLI 的版本,由此不会有 HTTP 头新闻输出。在用 PHP
编写命令行应用程序时,能够行使五个参数:$argc和
$argv。后边二个的值是比参数个数大
1
的整数(运营的剧本本人的称呼也被看做一个参数)。第叁个是含有有参数的数组,其首先个因素为脚本的名目,下标为数字
0($argv[0])。

上述程序中反省了参数的个数是当先 1 个如故小于 1 个。别的假设参数是
–help-help-h
-?时,打字与印刷出帮助消息,并还要动态输出脚本的称谓。即便还收受了别的参数,将其出示出来。

比方期待在 Unix 下运维以上脚本,须求使其品质为可施行文件,然后简短的运行
script.php echothisscript.php -h。在 Windows
下,可认为此编制三个批管理公事:

 

Example #2 运营 PHP 命令行脚本的批管理公事(script.bat)

@C:phpphp.exe script.php %1 %2 %3 %

 

要是将上述顺序命名叫 script.php,且 CLI 版的 php.exe 文件放置在
c:phpcliphp.exe,该批管理公事会赞助将增大的参数字传送给脚本程序:script.bat
echothis
script.bat -h

请参阅
Readline扩充模块的关于文书档案,以博得更加多的函数的音讯。这一个函数能够帮忙康健PHP 命令行应用程序。 

 

十意气风发、垃圾回笼机制

引用计数基本知识

种种php变量存在二个叫”zval”的变量容器中。三个zval变量容器,除了包含变量的品种和值,还包蕴多个字节的额外音讯。第一个是”is_ref”,是个bool值,用来标记这么些变量是或不是是归于援引集结(reference
set卡塔尔。通过那个字节,php引擎能力把普通变量和援引变量区分开来,由于php允许客户通过利用&来使用自定义援用,zval变量容器中还只怕有三个里头引用计数机制,来优化内部存款和储蓄器使用。第一个额外字节是”refcount”,用以代表针对这么些zval变量容器的变量(也称符号即symbolState of Qatar个数。全部的标志存在贰个标识表中,当中每一个符号都有效率域(scopeState of Qatar,那个主脚本(举例:通过浏览器央浼的的台本卡塔尔和每一个函数恐怕措施也都有功用域。

当一个变量被赋常量值时,就可以变卦叁个zval变量容器,如下例那样:

Example #1 Creating a new zval container

<?php$a = "new string";?>

 

在上例中,新的变量a,是在时下遵从域中生成的。并且生成了项目为 string
和值为new
string
的变量容器。在附加的三个字节消息中,”is_ref”被默许设置为
FALSE,因为从没任何自定义的援引生成。”refcount” 被设定为
1,因为此处独有二个变量使用这一个变量容器.
注意到当”refcount”的值是1时,”is_ref”的值总是FALSE.
假若你曾经设置了» Xdebug,你能因而调用函数 xdebug_debug_zval()显示”refcount”和”is_ref”的值。

 

Example #2 Displaying zval information

<?phpxdebug_debug_zval('a');?>

如上例程会输出:

a: (refcount=1, is_ref=0)='new string'

 

把贰个变量赋值给另生龙活虎变量将净增引用次数(refcount卡塔尔国.

 

Example #3 Increasing refcount of a zval

<?php$a = "new string";$b = $a;xdebug_debug_zval( 'a' );?>

如上例程会输出:

a: (refcount=2, is_ref=0)='new string'

 

此刻,援引次数是2,因为同五个变量容器被变量 a 和变量
b关联.当没供给时,php不会去复制已更动的变量容器。变量容器在”refcount“产生0时就被销毁.
当其余关系到有些变量容器的变量离开它的成效域(比方:函数施行完结卡塔尔国,只怕对变量调用了函数
unset()时,”refcount“就能减1,上面的事例就能够表明:

 

Example #4 Decreasing zval refcount

<?php$a = "new string";$c = $b = $a;xdebug_debug_zval( 'a' );unset( $b, $c );xdebug_debug_zval( 'a' );?>

上述例程会输出:

a: (refcount=3, is_ref=0)='new string'
a: (refcount=1, is_ref=0)='new string'

 

要是大家后日举办
unset($a);,包罗类型和值的这几个变量容器就能够从内部存款和储蓄器中删除。

复合类型(Compound TypesState of Qatar

当构思像 array和object如此那般的复合类型时,事情就有些有一点复杂.
与 标量(scalar卡塔尔(قطر‎类型的值不一致,array和 object类型的变量把它们的积极分子或品质存在自身的号子表中。那代表上边包车型大巴例子将扭转四个zval变量容器。

 

Example #5 Creating a array zval

<?php$a = array( 'meaning' => 'life', 'number' => 42 );xdebug_debug_zval( 'a' );?>

如上例程的出口附近于:

a: (refcount=1, is_ref=0)=array (
   'meaning' => (refcount=1, is_ref=0)='life',
   'number' => (refcount=1, is_ref=0)=42
)

Or graphically

澳门新葡萄京官网首页 1

 

这两个zval变量容器是: a,meaning和
number。增添和裁减”refcount”的平整和上面提到的雷同. 下边,
我们在数组中再增多贰个因素,而且把它的值设为数组中已存在成分的值:

 

Example #6 Adding already existing element to an array

<?php$a = array( 'meaning' => 'life', 'number' => 42 );$a['life'] = $a['meaning'];xdebug_debug_zval( 'a' );?>

如上例程的出口附近于:

a: (refcount=1, is_ref=0)=array (
   'meaning' => (refcount=2, is_ref=0)='life',
   'number' => (refcount=1, is_ref=0)=42,
   'life' => (refcount=2, is_ref=0)='life'
)

Or graphically

澳门新葡萄京官网首页 2

 

从以上的xdebug输出新闻,大家看看原有的数组成分和新扩充长的数组成分关联到同多个”refcount”2的zval变量容器.
尽管 Xdebug的出口展现三个值为‘life’的 zval 变量容器,其实是同叁个。
函数xdebug_debug_zval()不展现那几个音讯,可是你能通过显示内部存款和储蓄器指针音讯来见见。

除去数组中的多个因素,正是雷同于从功能域中删去一个变量.
删除后,数组中的这几个成分所在的器皿的“refcount”值减弱,相似,当“refcount”为0时,这些变量容器就从内部存款和储蓄器中被去除,下边又五个例证能够作证:

 

Example #7 Removing an element from an array

<?php$a = array( 'meaning' => 'life', 'number' => 42 );$a['life'] = $a['meaning'];unset( $a['meaning'], $a['number'] );xdebug_debug_zval( 'a' );?>

以上例程的输出临近于:

a: (refcount=1, is_ref=0)=array (
   'life' => (refcount=1, is_ref=0)='life'
)

 

近日,当我们抬高中二年级个数组本人作为那几个数组的因素时,事情就变得有意思,下个例证将说明那一个。例中大家投入了援引操作符,不然php将生成七个复制。

 

Example #8 Adding the array itself as an element of it self

<?php$a = array( 'one' );$a[] =& $a;xdebug_debug_zval( 'a' );?>

上述例程的输出临近于:

a: (refcount=2, is_ref=1)=array (
   0 => (refcount=1, is_ref=0)='one',
   1 => (refcount=2, is_ref=1)=...
)

Or graphically

澳门新葡萄京官网首页 3

 

能来看数组变量 (a卡塔尔国 同一时候也是其生龙活虎数组的第4个要素(1)指向的变量容器中“refcount”为
2。上边的出口结果中的”…”表达产生了递归操作,
明显在这里种情景下表示”…”指向原始数组。

跟刚刚相仿,对一个变量调用unset,将去除那几个标识,且它指向的变量容器中的引用次数也减1。所以,要是大家在施行完上边的代码后,对变量$a调用unset,
那么变量 $a 和数组成分 “1” 所指向的变量容器的援用次数减1, 从”2″形成”1″.
下例能够印证:

 

Example #9 Unsetting $a

(refcount=1, is_ref=1)=array (
   0 => (refcount=1, is_ref=0)='one',
   1 => (refcount=1, is_ref=1)=...
)

Or graphically

澳门新葡萄京官网首页 4

 

清理变量容器的主题材料(Cleanup Problems卡塔尔(قطر‎

尽管不再有有个别功能域中的任何标识指向那一个结构(就是变量容器卡塔尔(قطر‎,由于数组成分“1”仍旧指向数组自身,所以这几个容器不可能被息灭。因为从没其余的标志指向它,客户并未有主意清除这一个组织,结果就能促成内部存款和储蓄器泄漏。庆幸的是,php将要伸手甘休时撤消那一个数据构造,但是在php消弭在此以前,将消耗数不完空间的内部存款和储蓄器。假让你要落到实处解析算法,或许要做别的像三个子成分指向它的父成分这样的专业,这种景况就能够不常发出。当然,近似的情状也会发出在对象上,实际上对象更有希望出现这种状态,因为对象总是隐式的被引用。

设若地方的图景时有产生仅仅豆蔻梢头一遍倒无妨,不过只要现身几千次,以至几十万次的内部存款和储蓄器泄漏,那明摆着是个大难点。在长日子运作的剧本,譬如恳求基本上不会终止的照管进度(deamons卡塔尔国或然单元测验中的大的套件(sets卡塔尔中,在给
eZ
组件库的模版组件做单元测量试验时,后面一个(指单元测量检验中的大的套件卡塔尔就能够不能自已难点.它将索要耗用2GB的内部存款和储蓄器,而日常的测量检验服务器并没好似此大的内部存款和储蓄器空间。

 

 

 

回笼周期(Collecting Cycles卡塔尔

古板上,像在此早先的 php
用到的援用计数内部存款和储蓄器机制,无法管理循环的引用内部存储器泄漏。然则 5.3.0 PHP
使用小说» 引用计数系统中的同步周期回笼(Concurrent Cycle Collection in
Reference Counted
SystemsState of Qatar中的同步算法,来拍卖这么些内部存储器泄漏难题。

对算法的一丝一毫注明有个别超过那有的故事情节的限量,将只介绍当中根底部分。首先,大家先要构建部分中央准则,假如一个援引计数扩张,它将持续被运用,当然就不再在垃圾堆中。要是引用计数降至零,所在变量容器将被清除(free卡塔尔国。正是说,仅仅在引用计数降低到非零值时,才会生出垃圾周期(garbage
cycle卡塔尔。其次,在多少个杂质周期中,通过检查援引计数是或不是减1,而且检查哪些变量容器的援用次数是零,来发掘哪部分是垃圾堆。

 

澳门新葡萄京官网首页 5

澳门新葡萄京官网首页 6

 

为幸免不能不检查有着援引计数恐怕压缩的朽木粪土周期,这么些算法把全部希望根(possible
roots 都是zval变量容器卡塔尔国,放在根缓冲区(root
bufferState of Qatar中(用深黄来标识卡塔尔,那样能够并且保障每一个只怕的垃圾根(possible
garbage
rootState of Qatar在缓冲区中只现出一回。仅仅在根缓冲区满了时,才对缓冲区内部有着差异的变量容器实践垃圾回笼操作。看上海体育场面的步子
A。

在步骤 B
中,算法使用深度优先寻觅查找全数非常大可能的根,找到后将每种变量容器中的引用计数减“1″,为确定保障不会对同二个变量容器减四遍”1″,用栗色标识已减过“1”的。在步骤
C
中,算法再一遍对每一个根节点使用深度优先寻找,检查种种变量容器的援用计数。要是引用计数是
0
,变量容器用暗褐来标志(图中的深绿)。假设引用次数大于0,则回复在这里个点上选用深度优先寻找而将援引计数减”1“的操作(即援引计数加“1”),然后将它们重新用白灰标志。在结尾一步
D 中,算法遍历根缓冲区以从那边删除变量容器根(zval
roots卡塔尔(قطر‎,同期,检查是否有在上一步中被赫色标识的变量容器。种种被反动标识的变量容器都被免去。

未来,你已经对这几个算法有了主导领悟,大家回头来看那一个怎么与PHP集成。暗中认可的,PHP的杂质回笼机制是开拓的,然后有个
php.ini 设置允许你改改它:zend.enable_gc

当垃圾回收机制开荒时,每当根缓存区存满时,就能够推行上边描述的巡回查找算法。根缓存区有稳固的分寸,可存10,000个或者根,当然你能够经过纠正PHP源码文件Zend/zend_gc.c中的常量GC_ROOT_BUFFER_MAX_ENTRIES,然后重新编写翻译PHP,来改善那几个10,000值。当垃圾回笼机制关闭时,循环查找算法永不推行,然则,只怕根将平昔留存根缓冲区中,不管在陈设中杂质回笼机制是不是激活。

当废品回笼机制关闭时,借使根缓冲区存满了说不许根,越来越多的或然根鲜明不会被记录。那多少个没被记录的可能根,将不会被那个算法来解析管理。倘使他们是循环引用周期的大器晚成某些,将绝不可能被消除进而引致内部存款和储蓄器泄漏。

就算在废品回笼机制不可用时,恐怕根也被记录的原因是,相对于每一趟找到恐怕根后检查垃圾回笼机制是还是不是打开来说,记录恐怕根的操作越来越快。不过垃圾回笼和解析机制自己要耗不菲时日。

而外改过配置zend.enable_gc,也能通过各自调用gc_enable()
和 gc_disable()函数来开垦和倒闭垃圾回笼机制。调用这一个函数,与改正配置项来开发或关闭垃圾回笼机制的功力是均等的。尽管在恐怕根缓冲区尚未满时,也能强逼实施周期回笼。你能调用gc_collect_cycles()函数达到那一个目标。那么些函数将回来使用这一个算法回笼的周期数。

同意张开和关闭垃圾回笼机制並且同意自主的开始化的由来,是出于您的应用程序的某有些或然是高时间效益性的。在这里种气象下,你只怕不想选拔垃圾回收机制。当然,对你的应用程序的某部分关闭垃圾回笼机制,是在冒着或许内部存款和储蓄器泄漏的风险,因为有的或者根或然存不进一定量的根缓冲区。因而,就在你调用gc_disable()函数释放内部存款和储蓄器在此以前,先调用gc_collect_cycles()函数大概相比明智。因为那将清除已存放在根缓冲区中的全部相当的大恐怕根,然后在废品回收机制被关闭时,可留下空缓冲区以有更加多空间存款和储蓄或者根

 

 

 

属性方面考虑的成分

在上风度翩翩节我们已经轻松的涉及:回收恐怕根有细小的性格上海电影制片厂响,但那是把PHP
5.2与PHP 5.3相比较时才有的。即使在PHP
5.第22中学,记录恐怕根相对于完全不记录恐怕根要慢些,而PHP 5.3中对 PHP
run-time 的别样改动减少了这些特性损失。

此地最首要有五个领域对性能有影响。第二个是内部存款和储蓄器占用空间的节约,另三个是垃圾堆回笼机制执行内存清理时的进行时间扩大(run-time
delayState of Qatar。大家将研讨那多少个领域。

内部存款和储蓄器占用空间的节约

先是,达成污源回收机制的全体原因是为着,风华正茂旦先决条件餍足,通过清理循环引用的变量来节省里部存款和储蓄器占用。在PHP推行中,风姿浪漫旦根缓冲区满了依旧调用gc_collect_cycles()
函数时,就能进行垃圾回笼。在下图中,彰显了上面脚本分别在PHP 5.2 和 PHP
5.3条件下的内部存款和储蓄器占用情状,此中消亡了本子运行时PHP本人占用的中央内部存款和储蓄器。

 

Example #1 Memory usage example

<?phpclass Foo{ public $var = '3.1415962654';}$baseMemory = memory_get_usage();for ( $i = 0; $i <= 100000; $i++ ){ $a = new Foo; $a->self = $a; if ( $i % 500 === 0 ) { echo sprintf( '%8d: ', $i ), memory_get_usage() - $baseMemory, "n"; }}?>

澳门新葡萄京官网首页 7

 

在这里个很理论性的事例中,大家创设了叁个对象,那么些目的中的几个性质被设置为指回对象自己。在循环的下三个再一次(iteration卡塔尔国中,当脚本中的变量被重新复制时,就能够发出标准性的内部存款和储蓄器泄漏。在此个事例中,四个变量容器是泄漏的(对象容器和性质容器卡塔尔,可是只是能找到一个恐怕根:正是被unset的不胜变量。在10,000次重复后(也就发出总结10,000个大概根卡塔尔,当根缓冲区满时,就实施垃圾回笼机制,何况释放这么些事关的恐怕根的内存。那从PHP
5.3的锯齿型内部存款和储蓄器占用图中相当轻松就能够见到。每一回实践完10,000次重复后,推行垃圾回笼,并释放相关的重复使用的引用变量。在此个事例中由于外泄的数据布局非常轻便,所以垃圾回笼机制自己不必做太多做事。从这几个图形中,你能看见PHP 5.3的最大内部存款和储蓄器占用大致是9 Mb,而PHP 5.2的内部存款和储蓄器占用平昔增添。

推行时间扩充(Run-Time Slowdowns卡塔尔(قطر‎

垃圾堆回收影响属性的首个领域是它释放已泄漏的内部存储器费用的年华。为了见到那几个耗费时间时不怎么,我们多少改造了地点的本子,有更多次数的再一次况兼删除了循环中的内部存储器占用总结,第叁个本子代码如下:

 

Example #2 GC performance influences

<?phpclass Foo{ public $var = '3.1415962654';}for ( $i = 0; $i <= 1000000; $i++ ){ $a = new Foo; $a->self = $a;}echo memory_get_peak_usage(), "n";?>

 

大家将运行那么些本子五次,一遍通过配备zend.enable_gc开采垃圾回笼机制时,另一次是它停业时。

 

Example #3 Running the above script

time php -dzend.enable_gc=0 -dmemory_limit=-1 -n example2.php
# and
time php -dzend.enable_gc=1 -dmemory_limit=-1 -n example2.php

 

在自己的机械上,第叁个指令不仅实施时间大约为10.7秒,而第贰个指令花销11.4秒。时间上平添了7%。可是,实践这么些剧本时内存占用的峰值减少了98%,从931Mb
减低到10Mb。那一个条件不是非常不利,也许并不能够代表真实应用程序的数码,可是它实在彰显了垃圾回笼机制在内部存储器占用方面包车型客车裨益。好消息正是,对这么些剧本来说,在执行中冒出越多的巡回引用变量时,内部存款和储蓄器节省的越来越多的意况下,每趟时间增加的比重都以7%。

PHP内部 GC 总计音信

在PHP内部,能够来得越来越多的有关垃圾回笼机制怎样运作的新闻。可是要突显那么些消息,你要求先重新编写翻译PHP使benchmark和data-collecting
code可用。你必要在依据你的意愿运转./configure前,把情状变量CFLAGS设置成-DGC_BENCH=1。上面的吩咐串就是做这一个事:

 

Example #4 Recompiling PHP to enable GC benchmarking

export CFLAGS=-DGC_BENCH=1
./config.nice
make clean
make

 

当您用新编写翻译的PHP二进制文件来再一次实践下边包车型地铁事例代码,在PHP实践完结后,你将看到下边包车型地铁音讯:

 

Example #5 GC statistics

GC Statistics
-------------
Runs:               110
Collected:          2072204
Root buffer length: 0
Root buffer peak:   10000

      Possible            Remove from  Marked
        Root    Buffered     buffer     grey
      --------  --------  -----------  ------
ZVAL   7175487   1491291    1241690   3611871
ZOBJ  28506264   1527980     677581   1025731

 

驷不比舌的音信总括在率先个块。你能看出垃圾回笼机制运作了1十三回,何况在这里111回运转中,总共有超过六百万的内部存款和储蓄器分配被假释。只要垃圾回笼机制运作了至少一回,根缓冲区峰值(Root
buffer peak卡塔尔(قطر‎总是10000.

结论

平时,PHP中的垃圾回笼机制,仅仅在循环回笼算法确实运维时会一时光消耗上的充实。可是在平常的(更加小的卡塔尔脚本中应根本就平昔不质量影响。

而是,在平时脚本中有轮回回笼机制运作的情状下,内部存款和储蓄器的节约将同意更加的多这种本子同不经常间运转在你的服务器上。因为一同使用的内部存款和储蓄器没达到规定的标准上限。

这种利润在长日子运作脚本中越发分明,诸如长日子的测量试验套件或然daemon脚本此类。同期,对日常比Web脚本运营时刻长的»
PHP-GTK应用程序,新的排放物回笼机制,应该会大大改观长久以来感觉内部存款和储蓄器泄漏难点难以消除的视角。

 

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注