PHP/FI 版本 2.0

目录

  1. 简史
  2. 安装说明
  3. 那么,我能用 PHP/FI 做什么?
  4. CGI 重定向
  5. 安全问题
  6. 安全模式
  7. 从命令行运行 PHP/FI
  8. HTTP 身份验证
  9. Apache 请求变量
  10. Apache 模块说明
  11. Apache 模块配置指令
  12. FastCGI 支持
  13. 访问控制
  14. 访问日志记录
  15. 相对 URL 与绝对 URL - 或者,为什么我的图片会损坏?
  16. PHP/FI 如何处理 GET 和 POST 方法数据
  17. PHP 中的 GD(用于 GIF 创建的图形库)支持
  18. PHP/FI 和虚拟主机
  19. 文件上传支持
  20. Cookie 支持
  21. mSQL 支持
  22. Postgres95/PostgreSQL 支持
  23. mysql 支持
  24. Solid 支持
  25. Sybase 支持
  26. Oracle 支持
  27. Illustra 支持
  28. Adabas 支持
  29. 正则表达式
  30. 转义字符
  31. Unix 文件权限的八进制表示法
  32. PHP/FI 脚本语言
  33. 向 PHP/FI 添加您自己的函数
  34. 代码黑客说明

简史

PHP 起源于一个用 Perl 编写的简单 CGI 包装器。我是在合同之间的一个下午写的,当时我需要一个快速工具来了解谁在阅读我的在线简历。它从未打算超出我自己的私人使用范围。我放置简历的 Web 服务器极其过载,并且在派生进程方面存在持续问题。我用 C 重写了 Perl 包装器,以消除每次访问我的简历时派生 Perl 所带来的相当大的开销。

最终,同一 Web 服务器上的其他人发现了我的包装器,并询问他们是否可以使用它。然后,正如不可避免地会发生的那样,他们开始要求更多功能。我添加了更多功能,最终发布了一个半完整的版本,包括文档、邮件列表和常见问题解答。这个第一个软件包的名称是个人主页工具,后来改名为个人主页构建工具。

与此同时,我开始使用数据库,并编写了一个工具,可以轻松地将 SQL 查询嵌入到网页中。它本质上是另一个 CGI 包装器,解析 SQL 查询,并使基于这些查询创建表单和表格变得容易。这个工具被命名为 FI(表单解释器)。

PHP/FI 版本 2.0 是对这两个软件包的完整重写,将其合并到一个程序中。它现在已发展到嵌入到 HTML 文件中的简单编程语言的程度。最初的首字母缩略词 PHP 仍然存在。它实际上不再合适。如今,PHP/FI 更常用于整个网站,而不是用于小型个人主页设置。无论使用什么名称,它都可以通过允许您将简单的脚本直接放置在 HTML 文件中,从而消除对大量小型 Perl cgi 程序的需求。由于消除了多次派生 Perl 的开销,这加快了网页的整体性能。它还通过将网页的所有组件放置在一个 HTML 文件中,使管理大型网站变得更加容易。通过包括对各种数据库的支持,它也使开发支持数据库的网页变得非常容易。许多人发现嵌入式性质比尝试创建单独的 HTML 和 CGI 文件更容易处理。

PHP 版本 3.0 是又一次重写。如果您只是开始使用 PHP,我建议您从版本 3.0 开始,而不是继续使用 2.0。PHP3 很快就会取代 PHP/FI 2.0,所有开发工作现在都集中在 PHP3 上。除非 PHP/FI 2.0 中的剩余错误非常简单,否则不太可能修复它们。有关 PHP3 的更多信息,请访问 http://www.lerdorf.on.ca/php3

在整个文档中,所有对 PHP、FI 或 PHP/FI 的引用都指代同一件事。PHP 和 FI 之间的区别只是概念上的。两者都是从同一个源代码分发构建的。当我构建软件包时,没有任何访问日志记录或访问限制支持,我将我的二进制文件称为 FI。当我构建带有这些选项时,我称之为 PHP。


安装说明

在您开始之前

如果您完全没有 Unix 经验,您可能需要询问周围是否有对 Unix 略知一二的人来帮助您完成此安装。已经尽一切努力使其尽可能简单,但由于该软件相当复杂,并且依赖于许多不同的组件,因此假设它可以在所有系统上顺利运行是不现实的。您可能需要身边有人熟悉目标系统的具体情况。

安装之前需要了解的事项

- 您可以在服务器上运行 GET 和 POST 方法的 CGI 程序吗?
如果您安装的是 Apache 模块版本,则与之无关。 如果不能,则不能使用此软件包。在许多公共 ISP 上,CGI 程序要么被禁止,要么受到严格限制。如果在您的系统上是这种情况,请与您的系统管理员联系,并请他/她查看此软件包,看看他们是否可以为您安装它。

- 如果您的系统上安装了 mSQL,则需要知道此安装的基目录。

- 如果您的系统上安装了 Postgres95 或 PostgreSQL,则需要知道此安装的基目录。

- 如果您打算将日志和访问配置文件存储在 NFS 挂载的目录中,并且您的系统没有提供 NFS 文件锁定,那么您需要在 src/Makefile 中手动定义 NFS_HACK 变量,并且您可能需要使用稍微修改过的 gdbm 库。有关此方面的更多信息,请参阅 doc 目录中的 **nfs_hack.txt** 文件。

- 请注意,如果您对使用 PHP 跟踪对页面的访问不感兴趣,请不要将此选项编译到二进制文件中。您也应该省略访问限制代码。包括这些选项会造成相当大的开销。

- 如果您安装的是 Apache 模块版本,则需要知道 Apache 源代码目录的位置。

安装步骤

步骤 1。

运行安装程序:./install

您将被问到一些问题。如果您不理解所提问题,只需按回车键。默认选择在大多数系统上应该是安全的。但这不适用于询问您为配置和日志文件指定目录的问题。选择 httpd(通常为“nobody”)具有写入权限的任何目录。您可以在某个地方手动创建此目录,然后只需执行 **chown nobody directory**。

步骤 2。

进入 src 目录:cd src

查看 php.h 文件。这里可以设置一些编译时选项。

步骤 3。

输入:make

这将创建实际的可执行程序文件,默认情况下名为 php.cgi,或者如果您安装的是 Apache 模块,它将创建 libphp.a 文件。

步骤 4.(如果您没有安装 Apache 模块版本)

将 **php.cgi** 二进制文件复制到系统的 cgi-bin 目录。如果您没有访问权限,并且希望将其安装到您自己的个人目录中,您可以这样做,但您应该使用以下命令在可执行文件上设置 setuid 位:chmod u+s /path/php.cgi

如果您没有在二进制文件上设置 setuid 位,那么二进制文件创建的任何文件都将由 Web 服务器运行的用户 ID 拥有。如果这是可以接受的,那么您可以安全地关闭 setuid 位。

步骤 4.(如果您安装的是 Apache 模块版本)
更改到您的 Apache 源代码目录,mod_php.cmod_php.h 文件应该已经复制到那里。如果它们没有被复制,通常是由于权限问题,请手动将这两个文件复制到那里。编辑您的 Apache 配置文件,并添加在 **步骤 3** 结束时生成的 EXTRA_LIBS 行。然后添加

Module php_module mod_php.o

到文件的末尾。然后输入:./Configure,然后输入 make 重新构建您的 Apache httpd 二进制文件。安装此二进制文件。

接下来,您需要编辑 Apache conf/srm.conf 文件,并添加类似以下的代码:

AddType application/x-httpd-php .phtml

这定义了一个新的 MIME,application/x-httpd-php,它将触发 PHP 模块解析以 .phtml 扩展名结尾的任何文件。您可以为其选择任何您喜欢的扩展名。

您可能不想让每个人都能运行 PHP 解析的文件。您可以将上面的 AddType 行放在 *access.conf* 文件中的 ``...`` 指令内,以仅允许服务器上某些目录中的 PHP 解析的文档。

现在您已准备好重新启动 httpd 服务器。有关配置 PHP 模块的更多详细信息,请参阅 Apache 模块说明

测试软件

安装完成后,您可以在浏览器中输入类似于以下内容的 URL 来测试您的可执行文件是否有效:

http://your.site.domain/cgi-bin/php.cgi

这将显示一个包含版本号和各种其他有用信息的页面。

要测试 Apache 模块版本,请创建任何扩展名为 .phtml 的文件,并在文件中放入类似于以下内容的标签:``,然后查看它是否被解析。

使用软件

要在现有 HTML 文件上实际使用该软件,您只需将文件的路径附加到上面的 URL。例如:

http://your.site.domain/cgi-bin/php.cgi/path/file.html

您应该查看本文档的 CGI 重定向 部分。通过重定向运行 PHP/FI 意味着您可以自动拥有类似于 *http://your.site.domain/file.phtml* 的 URL 被 PHP/FI 解析。

这并不适用于 Apace 模块用户。


那么,我能用 PHP/FI 做什么?

如果您通过 PHP/FI 运行一个页面,您会注意到它添加了一个页脚,其中包含有关页面访问次数的信息(如果您已将访问日志记录编译到二进制文件中)。这只是 PHP/FI 可以为您做的事情的一小部分。它作为表单解释器 cgi 扮演着另一个非常重要的角色,因此名称中包含 FI 部分。例如,如果您在网页上创建了一个表单,您需要一些东西来处理该表单上的信息。即使您只想将信息传递到另一个网页,您也必须有一个 cgi 程序为您执行此操作。PHP/FI 使获取表单数据并使用它变得极其容易。

一个简单的例子

假设您有一个表单

<FORM ACTION="/cgi-bin/php.cgi/~userid/display.html" METHOD=POST>
<INPUT TYPE="text" name="name">
<INPUT TYPE="text" name="age">
<INPUT TYPE="submit">
</FORM>

然后您的 display.html 文件可以包含类似以下内容的内容:

<?echo "Hi $name, you are $age years old!<p>">

就这么简单!PHP/FI 会自动为表单中的每个表单输入字段创建一个变量。然后,您可以在 ACTION URL 文件中使用这些变量。

一旦您弄清楚如何使用变量,下一步就是开始在页面中使用一些逻辑流标签。例如,如果您想根据用户输入的内容显示不同的消息,您将使用 if/else 逻辑。在我们上面的示例中,我们可以通过将我们的 display.html 更改为根据用户输入的年龄显示不同的内容:

<?
    if($age>50);
        echo "Hi $name, you are ancient!<p>";
    elseif($age>30);
        echo "Hi $name, you are very old!<p>";
    else;
        echo "Hi $name.";
    endif;
>

PHP/FI 提供了一种功能非常强大的脚本语言,它可以完成比上面的简单示例演示的更多功能。有关更多信息,请参阅关于 PHP/FI 脚本语言 的部分。

您还可以使用 PHP/FI 来配置谁可以访问您的页面。这是使用内置的配置屏幕完成的。这样,您就可以例如指定只有来自特定域的人才能看到您的页面,或者您也可以创建一个规则来密码保护特定页面。有关更多详细信息,请参阅 访问控制 部分。

PHP/FI 也能够接收来自任何符合 RFC-1867 的 Web 浏览器的文件上传。此功能允许人们上传文本和二进制文件。使用 PHP/FI 的访问控制和逻辑功能,您可以完全控制谁可以上传以及上传文件后如何处理。有关更多详细信息,请参阅 文件上传 部分。

PHP/FI 支持名为 mSQL 的数据库包。这使您可以将信息放入数据库,并通过 .HTML 文件中的简单嵌入式 SQL 查询访问此信息。在网页中添加数据库后端从未如此简单。有关更多信息,请参阅关于 mSQL 支持 的部分。

PHP/FI 支持 Postgres95/PostgreSQL 数据库包。它支持在 .HTML 文件中嵌入式 SQL 查询。有关更多信息,请参阅关于 Postgres95/PostgreSQL 支持 的部分。

PHP/FI 还支持 mysql 数据库包。它支持在 .HTML 文件中嵌入式 SQL 查询。有关更多信息,请参阅关于 mysql 支持 的部分。


CGI 重定向

Apache 1.0.x 说明

运行 PHP/FI 的一个好方法是使用 Apache 服务器的 cgi 重定向模块。请注意,如果您使用的是 PHP/FI 的 Apache 模块版本,则无需担心重定向模块。有两个这样的重定向模块可用。一个是 Dave Andersen <[email protected]> 开发的,它可以在 ftp://ftp.aros.net/pub/util/apache/mod_cgi_redirect.c 获取,另一个与 Apache 捆绑在一起,名为 mod_actions.c。这两个模块非常相似。它们在使用方式上略有不同。两者都经过测试,并且都适用于 PHP/FI。

在撰写本文时(96 年 4 月 20 日)的一个重大问题是,当前的官方 Apache 版本 (1.0.5) 存在一个严重的限制,它阻止 cgi 重定向的请求与任何 post 方法数据相关联。我已经追踪并修复了我的 Apache 版本中的这个问题,并且在 PHP 主页 上的 文件档案 中有一个官方补丁。

Apache 1.0.x 的第二个重大问题是它在大多数架构上不能正确对齐双精度类型。您可能会发现自己使用 mod_php 时从 httpd 中获得奇怪的总线错误,请升级到 Apache 1.1 或编辑 *alloc.c* Apache 源代码文件。在这个文件中,您将找到以下代码段

  union align
  {
    /* Types which are likely to have the longest RELEVANT alignment
     * restrictions... we don't do much with doubles.
     */

    char *cp;
    void (*f)();
    long l;
    FILE *fp;
  };

您需要在此行中添加一个双精度类型并重新编译您的 Apache 服务器。正确的代码块是

  union align
  {
    /* Types which are likely to have the longest RELEVANT alignment
     * restrictions... we don't do much with doubles.
     */

    char *cp;
    void (*f)();
    long l;
    FILE *fp;
    double d;
  };

这些问题在 Apache 的后续版本中已全部解决。

查看 Apache 文档,了解如何添加模块。通常,您将模块名称添加到名为 *Configuration* 的文件。如果您想使用 mod_actions 模块,则要添加的行是

Module action_module mod_actions.o

如果您使用的是 mod_cgi_redirect.c 模块,请添加此行

Module cgi_redirect_module mod_cgi_redirect.o

然后编译您的 httpd 并安装它。要配置 cgi 重定向,您需要在您的 *mime.types* 文件中创建一个新的 mime 类型,或者您可以在您的 *srm.conf* 文件中使用 **AddType** 命令来添加 mime 类型。要添加的 mime 类型应类似于以下内容

application/x-httpd-php phtml

如果您使用的是 mod_actions.c 模块,则需要在您的 *srm.conf* 文件中添加以下行

Action application/x-httpd-php /cgi-bin/php.cgi

如果您使用的是 mod_cgi_redirect.c,则应在 *srm.conf* 中添加此行

CgiRedirect application/x-httpd-php /cgi-bin/php.cgi

不要尝试同时使用 mod_actions.c 和 mod_cgi_redirect.c。

安装并正确配置其中一个 cgi 重定向模块后,您将能够通过将文件的扩展名设为 **.phtml** 来指定您希望 php/fi 解析一个文件。此外,如果您在 *srm.conf* 文件中的 **DirectoryIndex** 配置行中添加了 **index.phtml**,那么如果您的索引文件名为 index.phtml,则目录中的顶级页面将自动被 php 解析。

Netscape HTTPD

您可以使用 Netscape Server CGI 重定向模块来自动将对具有给定扩展名的文件的请求重定向到由 PHP/FI 处理。此模块在 PHP/FI 主页 上的 文件档案 中可用。包中的自述文件明确解释了如何将其配置为与 PHP/FI 一起使用。

NCSA HTTPD

NCSA 目前不支持模块,因此要使用此服务器进行 cgi 重定向,您需要修改服务器源代码。在 PHP/FI 文件档案 中提供了使用 NCSA 1.5 执行此操作的补丁。


安全问题

PHP/FI 的 CGI 版本**不会**读取目录中可能存在的任何 *.htaccess* 文件。这意味着,如果您有使用标准 .htaccess 基于服务器的访问控制功能来保护的文件,人们可能可以通过 PHP/FI 加载页面来绕过此安全措施。请注意,对于 PHP/FI 的 Apache 模块版本,这不是问题。

CGI 版本的第二个问题是,如果它被放置在系统的 cgi-bin 目录中,它可以用于查看系统上的任何文件,只要运行它的用户 ID 可以访问它。

这个问题有几个不同的解决方案。最简单的可能是使用 *php.h* 中的 **PATTERN_RESTRICT** 功能。这使您可以定义允许由 PHP/FI 解析的扩展名(或扩展名模式)。如果文件没有这个扩展名,并且有人尝试使用 PHP/FI 加载它,则会显示一个 *访问拒绝* 消息。

另一种解决方案是使用 PHP/FI 访问控制机制来模拟 .htaccess 文件中的访问控制设置。将此信息保留在两个地方可能很繁琐,并且这两个系统不共享所有相同的功能。

这个问题也可以使用文件权限来解决。PHP/FI 可以设置为以您希望的任何用户身份运行 setuid。然后,要由 PHP/FI 读取的文件可以被赋予适当的权限,而不要由 PHP/FI 读取的文件应该由另一个用户 ID 拥有,并且它们的权限应相应地更改。

有关与为 PHP 提供共享访问权限的网站相关的其他安全选项,请参阅 安全模式 部分。


安全模式

PHP 的安全模式试图解决许多 ISP 面临的常见问题,即让所有用户运行 CGI 程序。使共享 CGI 访问更安全的常见机制是使用 cgi 包装器(如与 Apache 捆绑在一起的 su_exec 实用程序)。当 PHP 作为模块运行时,这将不适用于 PHP,因为它不是可以设置 setuid 的独立进程。

它是基于文件权限方案。简而言之,如果文件要么由尝试访问它的脚本的相同用户 ID 拥有,要么文件位于与尝试访问它的脚本相同的用户拥有的目录中,那么访问将被允许。这里的一个注意事项是,您必须确保您的操作系统不允许非 root 用户更改其文件的所属权。许多旧的 SysV 系统允许这样做。最常见的是 Irix。可以在 Irix 上的 OS 级更改此行为。

安全模式适用于每个可能存在安全风险的功能。以下是应用于每个相关功能的当前检查列表。在以下列表中,PHP UID 指的是当前由 PHP 解析的文件所有者的用户 ID,而 HTTP UID 指的是 httpd 进程运行时的用户 ID(通常是 nobody)。

Include, ReadFile, Fopen, File, Link, Unlink, Symlink, Rename, RmDir, ChMod, ChOwn, ChGrp
要包含的文件的所有者必须是 PHP UID,或者文件所在的目录必须由 PHP UID 拥有。
Exec, System, PassThru 和 Popen
要分叉并执行的可执行文件必须位于 PHP 编译时 php.h 中定义的 PHP_SAFE_MODE_EXEC_DIR #define 目录中。
Mysql_Connect
此函数接受一个可选的用户名,用于连接到 MySQL 数据库。在安全模式下,此用户名必须是当前正在解析的文件的所有者的用户名,或者 httpd 用户的名称(通常是 nobody)。
HTTP 身份验证
包含 HTTP 身份验证代码的脚本所有者的数字用户 ID 将被附加到身份验证域。这是为了防止有人编写一个密码抓取脚本,该脚本伪造同一服务器上的另一个经过身份验证的页面。

从命令行运行 PHP/FI

如果你构建了 PHP/FI 的 CGI 版本,你可以从命令行运行它,只需键入:php.cgi filename,其中 filename 是你想解析的文件。你也可以通过使脚本的第一行看起来像这样来创建独立的 PHP/FI 脚本

    #!/usr/local/bin/php.cgi -q
“-q” 抑制 HTTP 头的打印。如果你愿意,可以省略此选项。

HTTP 身份验证

PHP/FI 中的 HTTP 身份验证钩子只有在它作为 Apache 模块运行时才可用。在 Apache 模块 PHP/FI 脚本中,可以使用 Header() 命令向客户端浏览器发送“需要身份验证”消息,使其弹出用户名/密码输入窗口。用户填写用户名和密码后,将再次调用包含 PHP/FI 脚本的 URL,并将变量 $PHP_AUTH_USER、$PHP_AUTH_PW 和 $PHP_AUTH_TYPE 分别设置为用户名、密码和身份验证类型。目前只支持“基本”身份验证。

以下是一个脚本片段示例,它将强制客户端在一个页面上进行身份验证

    <?
        if(!$PHP_AUTH_USER) {
            Header("WWW-authenticate: basic realm=\"My Realm\"");
            Header("HTTP/1.0 401 Unauthorized");
                        echo "Text to send if user hits Cancel button\n"
            exit;
        } else {
            echo "Hello $PHP_AUTH_USER.<P>";
            echo "You entered $PHP_AUTH_PW as your password.<P>";
        }
    >

你可能不想简单地打印出 $PHP_AUTH_USER 和 $PHP_AUTH_PW,而是想要检查用户名和密码的有效性。也许通过向数据库发送查询,或者通过在 dbm 文件中查找用户。

注意那些有错误的 Internet Explorer 浏览器。它们对标题的顺序似乎非常挑剔。目前,在 HTTP/1.0 401 标题之前发送 WWW-authenticate 标题似乎可以解决问题。

为了防止有人编写一个脚本,该脚本会泄露通过传统外部机制进行身份验证的页面的密码,如果为该特定页面启用了外部身份验证,则不会设置 PHP_AUTH 变量。

但是请注意,以上内容不能阻止控制未经身份验证的 URL 的人从同一服务器上的经过身份验证的 URL 中窃取密码。php.h 中的 PHP_AUTH_VARS 定义可以被取消定义,以确保这些变量永远不会被设置,从而禁用任何使用 mod_php 尝试窃取密码的人。


Apache 请求变量

当以 Apache 模块的形式运行 PHP 时,可以通过在要使用的标题值开头添加 $req_ 来访问远程浏览器发送的请求标题变量。如果请求名称包含 - 字符(例如 User-Agent),那么你需要将 - 映射为 _(下划线)。即,将其引用为 $req_User_Agent。可以使用 phpinfo() 函数显示所有请求标题。

例如。

    <
        echo "$req_connection<br>";
        echo "$req_host<br>";
    >
上面的简单脚本可能会输出
    Keep-Alive
    www.host.com

Apache 模块说明

以 Apache 模块的形式运行 PHP/FI 是使用该软件包最有效的方式。以模块形式运行意味着 PHP/FI 功能与 Apache 服务器的功能在一个程序中合并。以模块形式运行它有许多优点

性能

从性能方面来说,它比传统的 CGI 程序快得多。事实上,当以模块形式运行 PHP/FI 时,没有涉及 CGI。HTML 文件中的脚本代码由 Apache Web 服务器进程直接执行。

安全

以模块形式运行时,首先应用在 Apache 配置文件或私有 .htaccess 文件中定义的正常基于 httpd 的访问限制规则,然后才允许模块解析文件。或者,你也可以创建控制正常基于 httpd 的身份验证的 PHP/FI 脚本。参见 HTTP 身份验证

可配置性

由于解析器始终在 httpd 进程中处于活动状态,因此可以使用与配置 httpd 进程相同的配置文件在启动时对其进行配置。甚至可以通过将 PHP 配置指令 放置在 .htaccess 文件中来按目录配置模块。这仅适用于 Apache 2.x 及更高版本。

基于自定义服务器的功能

对于有兴趣从 Apache 内部访问其函数的 C 程序员来说,PHP/FI 框架为 Apache 本身和 PHP 提供了一个非常简单的接口。将函数添加到 PHP 并从解析的页面中调用该函数比从头开始编写整个 Apache 模块要容易得多。有关更多详细信息,请参阅本文档末尾的 将你自己的内部函数添加到 PHP/FI 部分。

Apache 模块配置指令

以下指令可以放置在 srm.conf 文件中,也可以放置在 access.conf 中的 <Directory>...</Directory> 标签内,或放置在 access.conf 中的 <Location /path>...</Location> 标签内,或放置在单独的 .htaccess 文件中。为了使指令在 .htaccess 文件中起作用,必须在 AllowOverride Apache 指令上设置 Options 覆盖,phpEngine 指令除外,它只能在 *.conf 文件中使用。

phpShowInfo on|off
启用或禁用 PHP 信息页脚。默认值为 on。
phpLogging on|off
启用或禁用日志记录。默认值为 on。
phpDebug on|off
启用或禁用自动 ?info 调试屏幕。默认值为 off。
phpUploadTmpDir directory
设置将表单上传的文件放置的目录。
phpDbmLogDir directory
设置将基于 dbm 的日志文件写入的目录。
phpSQLLogDB database
设置用于日志记录的 SQL 数据库的名称。默认值为“phpfi”。
phpSQLLogHost hostname
设置找到用于日志记录的 SQL 数据库的主机名。默认值为 localhost。
phpAccessDir directory
设置存储 PHP 内部访问控制文件的目录。
phpMaxDataSpace KiloBytes
子池在 PHP 模块内可以增长到的最大大小。将此值设置为较低的值将最大限度地减少 mod_php 对系统的影响,但也可能会限制人们编写复杂的脚本。默认值为 8K。
phpIncludePath colon-separated path
一个用冒号分隔的目录列表,PHP 在运行 include() 时将在其中查找文件。默认情况下,只在当前目录中查找。
phpAutoPrependFile file name
在实际解析 PHP/FI 文件之前,你可以在此处提供一个文件名,该文件在使用 PHP 的 Include() 函数解析“主文件”之前进行解析(这意味着 phpIncludePath 适用于文件名)。请记住,如果你从自动预先添加的文件中写入 HTML,那么你可能会发现自己难以在主文件中使用 Header() 函数。
phpAutoAppendFile file name
一个文件名,在实际解析 PHP/FI 文件后解析(使用 PHP 的 Include() 函数),类似于 phpAutoPrependFile。
phpAdaDefDB database
要使用的默认 Adabas 数据库。没有默认值
phpAdaUser username
默认 Adabas 数据库用户。没有默认值
phpAdaPW password
默认 Adabas 数据库密码。没有默认值
phpEngine on|off
启用或禁用 PHP 解析引擎。默认值为 on,并且此指令仅对希望允许来自 AllowOverride Options 列表中的指令在 .htaccess 文件中起作用,同时限制 mod_php 访问的站点有用。处理每个虚拟主机 PHP 安装的常见方法是在每个虚拟主机基础上使用 AddType 指令启用 PHP MIME 类型,然后在非 PHP 虚拟主机块中放置“phpEngine off”。如果非 PHP 客户尝试通过在 .htaccess 文件中放置 PHP MIME 类型来规避问题,那么 phpEngine off 设置会限制 PHP 解析器运行。
phpLastModified on|off
由于 php 页面是动态的,因此每次访问它们时都会被处理并发送到浏览器。但有时,当使用 php 进行基本包含时,只要源代码没有改变,解析后的页面就不会改变。在这种情况下,你可能希望避免页面重新生成/重新加载。如果启用了 phpLastModified,Apache 会将 Last-Modified 标签发送到浏览器,因此只有当页面发生更改时才会重新加载页面。(请注意,如果你使用页面日志记录,则不会记录多次访问!)

所有这些指令都是可选的。如果在任何地方都没有指定指令,则将使用编译时默认值。


FastCGI 支持

PHP/FI 可以与 FastCGI 支持一起编译。你需要在编译 PHP/FI 之前获取并编译适用于你平台的 FCGI 开发工具包。你还需要使 CGI 重定向 正常工作。然后按照 FastCGI 文档中的说明为你的平台配置 FastCGI。如果你在 Apache 服务器上使用 mod_fastcgi 模块,请按照以下步骤操作

现在,所有具有 .fhtml 扩展名的页面都将被传递给已经运行的 FastCGI php.fcgi 进程。php.fcgi 二进制文件仍然可以作为普通的 CGI 二进制文件工作,因此你可以从 php.cgi 到 php.fcgi 创建一个符号链接。

如果你没有使用 Apache,那么上面的步骤将类似,但并不完全相同。在 PHP/FI 文件存档 中,可以找到适用于 NCSA 和 Netscape 服务器的 CGI 重定向机制。


访问控制

请注意,内置的基于 PHP/FI 的访问控制可能会在未来的版本中被停用。你应该认真考虑使用你的 Web 服务器附带的安全机制。

如果你在编译软件包时选择包含访问控制,则可以将 ?config 附加到任何 URL 以编辑访问控制文件。即

http://your.machine.domain/cgi-bin/php.cgi/path/file.html?config

你的配置密码最初将设置为你的用户 ID。如果你的用户 ID 不能用作你的密码,则可能意味着 PHP 无法读取 /etc/passwd 文件以找到你的用户 ID。如果是这种情况,则初始密码将设置为“php”。建议更改此密码。请注意,多个用户可以通过单个 PHP/FI 二进制文件维护自己的个人配置文件。

访问控制最初可能很混乱。?config 屏幕被分成几个部分。顶部的部分用于更改用于确保只有知道此密码的人才能更改访问控制特性的密码。在系统范围的安装中,每个用户都有自己的配置屏幕和自己的密码。

?config 屏幕的第二部分包含多个表格。每个表格定义一个规则集。第一个规则集始终是默认规则集。如果页面没有为其专门定义规则集,则使用此默认规则集。在默认规则集之后,将跟随任意数量的特定规则集表格。

要为特定文件添加规则集,请在浏览器中输入文件的 URL,并在 URL 末尾添加 **?config**。在弹出的 **?config** 界面中,您将看到已为该页面添加了规则集(如果之前没有)。添加新的规则集时,它最初会设置为与默认规则集相同。下图显示了两个简单的规则集。第一个是默认规则集,它只是表示应该记录来自所有域的访问;第二个是针对文件 **/~rasmus/test.html**(仅此文件)的规则集,它规定来自 **.edu** 域的任何用户都将被拒绝访问。

[Image of ?config screen]

要编辑规则集,请修改规则集中的字段,直到达到所需的配置,然后点击 **提交更改** 按钮。如果需要更多规则,请点击 **添加规则** 按钮,然后编辑添加的规则。

要删除规则,请选中规则右侧的复选框,然后点击 **提交更改** 按钮。屏幕将重新绘制,规则应该会消失。

请注意,您需要在模式字段中输入正则表达式。有关详细信息,请参见本文档中的正则表达式部分。


访问日志记录

访问日志记录是另一项可选功能,可以通过在编译时回答安装脚本中的问题 **是** 来启用。您可以将访问日志数据存储在 dbm 文件中、mSQL 数据库中或 mysql 数据库中。后两者更强大,但也更难设置。

要使用 dbm 文件存储访问日志,您需要指定一个目录来写入日志文件。如果目录不存在,PHP 会尝试创建它。但为了确保目录具有正确的权限,您可能需要在第一次运行 PHP 之前自己创建该目录。目录的权限应该是这样的:运行 PHP cgi 程序的用户 ID 可以写入该目录。

要使用 mSQL 或 mysql 数据库存储访问日志数据,您需要首先确保在您的系统上安装并运行了 mSQL 或 mysql。然后,您需要创建一个数据库。默认名称是 "phpfi",但可以在 **src/php.h** 中更改。要为 mSQL 创建此数据库,请键入:

    msqladmin create phpfi

或为 mysql 键入:

    mysqladmin create phpfi

然后,对于 mSQL,请编辑您的 **msql.acl** 文件,并确保数据库的权限正确。以下内容应该足够了:

    database=phpfi
    read=*
    write=nobody,<your user id>
    access=local

对于 mysql,您需要确保 httpd 用户(通常是 "nobody")可以访问该数据库。与 mSQL 不同,mysql 将访问控制数据存储在数据库中。假设默认权限,您应该能够简单地执行以下命令:

    echo "INSERT INTO user VALUES ('localhost','nobody','','Y','Y','Y','Y','Y','Y','Y','Y','Y');" | mysql mysql

不要忘记使用以下命令加载此新配置:

    mysqladmin reload

对于您要存储日志数据的每个用户 ID,您需要创建两个表。脚本目录中的 **msqllog** shell 脚本将为您完成此操作。只需键入:

    msqllog <user id>

或为 mysql 键入:

    mysqllog <user id>

脚本将创建相应的表。您可能需要编辑脚本以使其反映您的系统上存储位置。

您可能想看一下这个脚本。它定义了日志表的字段大小。例如,如果您知道您的文件路径超过 64 个字符,则需要增加 **msqllog** 或 **mysqllog** 文件中 **logN** 和 **lastN** 表中的文件名大小。

访问日志记录存储有关页面每次“访问”的信息。然后,可以通过检查这些日志文件来总结这些信息。示例日志文件摘要脚本包含在软件包中。它是 **examples** 目录中的 **log.html** 文件。这是 dbm 日志文件分析器。mSQL 日志文件分析器称为 **mlog.html**。mysql 日志文件分析器称为 **mylog.html**。要运行它,请将其与其他 mlog.* 文件复制到您的 Web 服务器可以访问的目录中,然后键入:

    http://your.machine.domain/cgi-bin/php.cgi/path/mlog.html

或者,如果您使用的是 Apache 模块版本,则可以给脚本一个 ".phtml" 扩展名,并使用以下命令调用它:

    http://your.machine.domain/path/mlog.phtml

默认情况下,如果您使用启用了访问日志记录功能的 PHP 编译了 PHP,那么您的页面将显示一个包含一些访问信息的页脚。您可能不想看到这个页脚,但仍然要记录访问。如果您运行的是 Apache,则可以在您的 Apache httpd.conf 或 .htaccess 文件中添加 "phpShowInfo off" 行来关闭此页脚。如果您没有运行 Apache,则可以通过在 ?config 部分中为页面创建规则,或者通过在您的页面中添加类似于以下的标签来关闭这些日志页脚:

<?setshowinfo(0)>


相对 URL 与绝对 URL - 或者,为什么我的图片会损坏?

所有 CGI 包装器都会遇到一个常见问题,即 HTTPD 程序将当前目录更改为加载的任何内容的存储目录。对于 CGI 程序,当前目录设置为 CGI 程序所在的目录。这通常不是问题,除非涉及到相对 URL。

相对 URL 是依赖于当前目录与当前 HTML 文件所在的目录相同的 URL。例如,如果我有以下 URL:

    http://my.machine/~rasmus/file.html

实际的 HTML 文件可能是:

    ~rasmus/public_html/file.html

如果在 **file.html** 文件中我有以下标签:

    <IMG SRC="pic.gif">

正常加载时,预计此 gif 文件位于 **~rasmus/public_html/pic.gif** 中。但是,当通过 CGI 包装器使用类似于以下的 URL 加载时:

    http://my.machine/cgi-bin/php.cgi/~rasmus/file.html

则 HTTPD 将当前目录设置为 **/cgi-bin**(或 ScriptAlias 可能指向的位置),随后当页面加载时,预计 **pic.gif** 文件位于:**/cgi-bin/pic.gif**,这通常不是预期效果。

解决此问题的快速方法是使用绝对 URL。在上面的示例中,如果图像标签是:

    <IMG SRC="/~rasmus/pic.gif">

就不会有任何问题。使用绝对 URL 并不总是可取,因为它会降低页面的可移植性。您可能此时有一个明显的问题:“为什么 PHP 不会直接将当前目录更改到正确的位置?”。答案是 PHP 实际上确实将当前目录更改为它正在显示的 HTML 文件的位置。在 PHP 脚本标签中使用的任何文件路径都可以是相对路径。问题是 PHP 无法控制的标签,例如 <img > 和 <a href >,不会通过 PHP 传递。当解析这些标签时,PHP 就不再处于活动状态,并且当前工作目录已恢复为 HTTP 守护程序指定的目录。

解决方案 是一个折衷方案。PHP 提供了一个名为 **PATH_DIR** 的变量。它始终包含当前 HTML 文件的目录部分。如果此 PATH_DIR 变量用于 <img > 和 <a href > 标签中,则可以实现相对 URL 的效果,尽管对服务器来说它在解析时看起来像一个绝对 URL。从上面的示例来看,我们唯一需要做的更改是将 img 标签更改为:

    <IMG SRC="<?echo $PATH_DIR>/pic.gif">
通过使用上述方法,您可以移动包含此标签的文件,该标签始终会引用与源 HTML 文件在同一目录下的 **pic.gif** 文件。

另一种处理方法是使用 HTML 文件中的传统 <BASE HREF=...>。


PHP 如何处理 GET 和 POST 方法数据

PHP 将检测来自 HTML 表单的 GET 和 POST 方法数据。一个重要的点是,如果同时存在 GET 和 POST 方法数据,则始终优先处理 POST 方法数据。如果 PHP 变量由 POST 方法数据定义,或者由 Unix 环境中的 HTTP 守护程序定义,则 GET 方法数据无法覆盖它。这是为了防止有人在他们的 URL 中添加 **?REMOTE_HOST=some.bogus.host**,从而欺骗 PHP 日志记录机制记录此备用数据。但是,POST 方法数据可以覆盖这些变量。

GET 数据的任何部分(URL 中 '?' 后的数据),如果形式为 **word=something**,则将定义变量 **$word** 以包含值 **something**。即使数据不是这种形式,也可以使用 $argv 内置数组访问它。例如,在以下 URL 中:

    /cgi-bin/php.cgi/[email protected]&var=value
PHP 符号表的相关部分将是:
    $argc       = 4
    $argv[0]    = abc
    $argv[1]    = def
    $argv[2]    = [email protected]&var=value
    $EMAIL_ADDR = [email protected]
    $var        = value

注意,数据中的 EMAIL_ADDR 部分如何同时作为未解析的 $argv[2] 显示,以及如何创建 $EMAIL_ADDR 变量以包含 **[email protected]**。

$EMAIL_ADDR 变量在上面用作示例,因为它是一个有用的变量,如果您使用 PHP 的日志记录功能。通过添加:

    ?EMAIL_ADDR=

到页面上的任何链接中,只要知道用户的电子邮件地址,您就可以将其传播到下一页。PHP 日志记录系统会自动查找此变量,并将它的值记录为日志中的用户电子邮件地址。对于任何 PHP1 用户,上述内容与在 PHP1 中使用的 URL 中添加 **?<!--$email-->** 具有相同的功能。它看起来稍微复杂一些,但它也是完全通用的,允许您构建自己的复杂页面。

在上面的示例中,您还可以看到如何通过使用 "&" 字符分隔来直接在 GET 方法数据中定义多个变量。此 "&" 分隔的变量列表必须是 GET 方法数据的最后一个(或唯一)部分,才能使其有效。

SELECT MULTIPLE 和 PHP

HTML 结构中的 SELECT MULTIPLE 标签允许用户从列表中选择多个项目。然后,这些项目将传递给表单的操作处理程序。问题是它们都使用相同的窗口小部件名称传递。即:

    <SELECT NAME="var" MULTIPLE>

每个选定的选项都将作为以下内容到达操作处理程序:

var=option1
var=option2
var=option3

每个选项都将覆盖前一个 $var 变量的内容。解决方案是使用 PHP/FI 的非索引数组功能。应使用以下方法:

    <SELECT NAME="var[]" MULTIPLE>

这告诉 PHP/FI 将 **var** 视为一个数组,并将每个值的赋值都添加到数组中。第一个项目变为 $var[0],下一个变为 $var[1],依此类推。可以使用 count() 函数确定选择了多少个选项,可以使用 sort() 函数对选项数组进行排序(如果需要)。


IMAGE SUBMIT 和 PHP

提交表单时,可以使用图像代替标准的提交按钮,使用以下标签:

    <input type=image src=image.gif name=sub>

当用户点击图像上的某个地方时,伴随的表单将被传输到服务器,并包含两个额外的变量 **sub_x** 和 **sub_y**。它们包含用户在图像中的点击坐标。有经验的人可能注意到,浏览器发送的实际变量名称包含句点而不是下划线,但 PHP 会自动将句点转换为下划线。


PHP 中的 GD(用于 GIF 创建的图形库)支持

PHP 支持由 Thomas Boutell 编写的 GD 库版本 1.2。PHP 本身没有 GD 代码。如果您希望在 PHP/FI 中使用 GD 支持,则必须从 http://www.boutell.com/gd/http/gd1.3.tar.gz 获取 GD 库,安装它,然后重新安装 PHP。

并非所有 GD 功能都受 PHP 支持。有关支持函数的列表,请参见 函数的字母顺序列表。所有 GD 函数都以单词 **Image** 开头。

有关 GD 软件包的更多信息,请访问:http://www.boutell.com/gd/

GD 1.2 受版权保护 1994、1995 Quest Protein Database Center,Cold Springs Harbor Labs。


PHP/FI 和虚拟主机

PHP 在一些 http 守护程序支持的虚拟主机设置上运行良好。在这样的设置中可能出现的唯一问题与 httpd 设置 SCRIPT_NAME 环境变量的方式不一致有关。通常,它被设置为当前 CGI 程序相对于 httpd 服务器上的顶级 ROOT_DIR 的路径。但是,当使用虚拟域时,一些 httpd 不会正确设置 SCRIPT_NAME 变量,使其成为虚拟域的顶级目录的相对路径,而它应该如此。如果 **?config** 屏幕显示无效 URL 错误消息,则您知道您的设置中存在此问题。您需要编辑 **php.h** 文件并将 VIRTUAL_PATH #define 设置为您相对于顶级目录的 **php.cgi** 二进制文件的路径。

文件上传支持

PHP/FI 会自动检测来自支持基于表单的文件上传功能的浏览器的文件上传,该功能由 Xerox 的 E. NebelL. Masinter 提出,并在 RFC 1867 中描述。

可以通过创建一个类似于以下的特殊表单来构建文件上传屏幕

    <FORM ENCTYPE="multipart/form-data" ACTION="_URL_" METHOD=POST>
<INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="1000">
Send this file: <INPUT NAME="userfile" TYPE="file">
<INPUT TYPE="submit" VALUE="Send File">
</FORM>

_URL_ 应指向一个 php html 文件。MAX_FILE_SIZE 隐藏字段必须位于文件输入字段之前,其值为接受的最大文件大小。该值为字节数。在这个目标文件里,成功上传后会定义以下变量

$userfile

上传文件在服务器上存储的临时文件名。

$userfile_name

发送方系统中文件的原始名称。

$userfile_size

上传文件的字节大小。

$userfile_type

如果浏览器提供了此信息,则为文件的 MIME 类型。例如,“image/gif”。

上述变量的 $userfile 基名将与上传表单中的 NAME 字段匹配。

默认情况下,文件将存储在服务器的默认临时目录中。可以通过设置 PHP/FI 运行环境中的环境变量 TMPDIR 来更改此设置。但是,从 PHP/FI 脚本内部使用 PutEnv() 调用设置它将不起作用。或者,您可以通过编辑 php.h 并定义 UPLOAD_TMPDIR 变量来硬编码一个临时目录。

接收上传文件的 PHP/FI 脚本应实现确定对上传文件应执行的操作所需的任何逻辑。例如,可以使用 $file_size 变量来丢弃任何文件,无论它们太小还是太大。可以使用 $file_type 变量来丢弃任何不符合特定类型标准的文件。无论逻辑是什么,都应该从临时目录中删除文件或将其移动到其他位置。

请注意,CERN httpd 似乎会从客户端获取的 content-type MIME 头中删除第一个空格开始的所有内容。只要这种情况存在,CERN httpd 就不会支持文件上传功能。


Cookie 支持

PHP/FI 透明地支持 HTTP cookie,如 Netscape 的规范 所定义。cookie 是一种在远程浏览器中存储数据的机制,因此可以跟踪或识别返回用户。可以使用 SetCookie() 函数设置 cookie。cookie 是 HTTP 标头的一部分,因此必须在向浏览器发送任何输出之前调用 SetCookie() 函数。这与 Header() 函数的限制相同。

从客户端发送给您的任何 cookie 将自动变成一个 PHP/FI 变量,就像 GET 和 POST 方法数据一样。

如果您希望为单个 cookie 分配多个值,只需在 cookie 名称中添加 [] 即可。例如

    SetCookie("MyCookie[]","Rasmus Lerdorf", time()+3600);
请注意,除非路径或域不同,否则 cookie 将替换浏览器中相同名称的先前 cookie。因此,对于购物车应用程序,您可能希望保留一个计数器并将其传递。例如
    $Count++;
    SetCookie("Count",$Count, time()+3600);
    SetCookie("Cart[$Count]",$item, time()+3600);

mSQL 支持

mSQL 代表 mini-SQL,是由 David Hughes 编写的简小而简单的 SQL 数据库引擎。它可以从 ftp://ftp.bond.edu.au/pub/Minerva/msql 获取。

PHP/FI 支持丰富的 mSQL 支持函数

msql()
msql_Close()
msql_Connect()
msql_CreateDB()
msql_dbName()
msql_DropDB()
msql_FieldFlags()
msql_FieldLen()
msql_FieldName()
msql_FieldType()
msql_FreeResult()
msql_ListDBs()
msql_Listfields()
msql_ListTables()
msql_NumFields()
msql_NumRows()
msql_RegCase()
msql_Result()
msql_TableName()

除了这些函数之外,PHP/FI 还可以编译为自动转义 GET 或 POST 数据中找到的任何正向单引号 ( ' ) 字符。如果 php.h 文件中定义了 MAGIC_QUOTES 变量,则这些引号将被自动转义,从而更容易将表单数据直接传递给 msql 查询。


Postgres95/PostgreSQL 支持

Postgres95/PostgreSQL 是一个强大的公共领域数据库,它实现了 SQL 语言的很大一部分。它支持 mSQL 中不可用的许多数据类型和命令。有关 Postgres 及其软件本身的更多信息,请访问以下 URL:http://www.postgreSQL.org/

以下 PHP 函数可用于 Postgres95

pg_Connect()
pg_Close()
pg_Host()
pg_Port()
pg_Options()
pg_tty()
pg_DBname()
pg_Exec()
pg_Result()
pg_FreeResult()
pg_GetLastOid()
pg_NumRows()
pg_NumFields()
pg_FieldNum()
pg_FieldName()
pg_FieldType()
pg_FieldSize()
pg_FieldPrtLen()
pg_errorMessage()

注意:不支持二进制游标。

除了这些函数之外,PHP/FI 还可以编译为自动转义 GET 或 POST 数据中找到的任何正向单引号 ( ' ) 和双引号 ( " ) 字符。如果 php.h 文件中定义了 MAGIC_QUOTES 变量,则这些引号将被自动转义,从而更容易将表单数据直接传递给 Postgres 查询。

以下是一个示例脚本,它连接到 localhost 上名为“mydb”的 Postgres 数据库,并检索表中的人员的姓名和年龄

<?
   $conn = pg_Connect("localhost", "5432", "", "", "mydb");
   if (!$conn) {
      echo "An error occured.\n";
      exit;
   }

   $result = pg_Exec($conn, "select * from table1");
   if (!$result) {
      echo "An error occured.\n";
      exit;
   }

   $num = pg_NumRows($result);
   $i = 0;

   while ($i < $num) {
      echo "name: ";
      echo pg_Result($result, $i, "name");
      echo "  age: ";
      echo pg_Result($result, $i, "age");
      echo "<BR>";
      $i++;
   }

   pg_FreeResult($result);
   pg_Close($conn);
>

mysql 支持

mysql 是 mSQL 包的克隆。您可以从 http://www.tcx.se/ 获取副本。

PHP/FI 支持丰富的 mysql 支持函数

mysql()
mysql_Close()
mysql_Connect()
mysql_CreateDB()
mysql_dbName()
mysql_DropDB()
mysql_FieldFlags()
mysql_FieldLen()
mysql_FieldName()
mysql_FieldType()
mysql_FreeResult()
mysql_ListDBs()
mysql_Listfields()
mysql_ListTables()
mysql_NumFields()
mysql_NumRows()
mysql_Result()
mysql_TableName()

除了这些函数之外,PHP/FI 还可以编译为自动转义 GET 或 POST 数据中找到的任何正向单引号 ( ' ) 字符。如果 php.h 文件中定义了 MAGIC_QUOTES 变量,则这些引号将被自动转义,从而更容易将表单数据直接传递给 mysql 查询。


Solid 支持

Solid 服务器是一个高吞吐量 SQL 服务器。它支持 ANSI SQL2、ODBC、SAG CLI 和 X/Open SQL 标准。有关 Solid 服务器的更多信息,请访问 www.solidtech.com。Solid 与 PHP 的接口由 DigiFace Internet Services 开发。

以下 PHP 函数可用于 Solid Server

Solid_Connect()
Solid_Close()
Solid_Exec()
Solid_Result()
Solid_FreeResult()
Solid_NumRows()
Solid_NumFields()
Solid_FieldNum()
Solid_FieldName()

除了这些函数之外,PHP/FI 还可以编译为自动转义 GET 或 POST 数据中找到的任何正向单引号 ( ' ) 字符。如果 php.h 文件中定义了 MAGIC_QUOTES 变量,则这些引号将被自动转义,从而更容易将表单数据直接传递给 Solid 查询。

以下是 Postgres 部分中显示的相同脚本,已针对 Solid 服务器进行了调整。

<?
   $conn = Solid_Connect("", "username", "password");
   if (!$conn) {
      echo "An error occured.\n";
      exit;
   }

   $result = Solid_Exec($conn, "select * from table1");
   if (!$result) {
      echo "An error occured.\n";
      exit;
   }

   while (Solid_FetchRow($result)) {
      echo "name: ";
      echo Solid_Result($result, "name");
      echo "  age: ";
      echo Solid_Result($result, "age");
      echo "<BR>";
   }

   Solid_FreeResult($result);
   Solid_Close($conn);
>

Sybase 支持

支持函数使用 Sybase DB 库 API 调用。因此,您必须在系统中安装 sybase API 库和头文件,才能使用 sybase 支持编译 PHP/FI。

以下 PHP/FI 函数可用于 Sybase。

SybSQL_CheckConnect()
SybSQL_Connect()
SybSQL_DBuse()
SybSQL_Exit()
SybSQL_Fieldname()
SybSQL_GetField()
SybSQL_IsRow()
SybSQL_NextRow()
SybSQL_NumFields()
SybSQL_NumRows()
SybSQL_Query()
SybSQL_Result()
SybSQL_Result_All()
SybSQL_Seek()

有关完整示例,请参阅 sybSQL_Result() 函数后面的示例。


Oracle 支持

PHP/FI 与 Oracle 的接口使用 Oracle 调用接口 (OCI)。您需要在系统上安装 OCI 库才能使用 Oracle 支持编译 PHP/FI。

以下 PHP/FI 函数可用于 Oracle

Ora_Bind()
Ora_Close()
Ora_Commit()
Ora_CommitOff()
Ora_CommitOn()
Ora_Exec()
Ora_Fetch()
Ora_GetColumn()
Ora_Logoff()
Ora_Logon()
Ora_Open()
Ora_Parse()
Ora_Rollback()

示例 PHP/FI Oracle 应用程序

<?
PutEnv("ORACLE_HOME=path_to_your_oracle_home"
PutEnv("ORACLE_SID=database"

/* Establish a connection between PHP and Oracle. */
$conn = Ora_Logon("username" "password"

if ($conn < 0) {
    echo("Could not connect to Oracle.\n"
    exit;
}

/* Open a cursor in Oracle. */
$cursor = Ora_Open($conn);

if ($cursor < 0) {
    echo("Could not open a cursor.\n"
    Ora_Logoff($conn);
    exit;
}

/* Turn off autocommit. */
Ora_CommitOff($conn);

/* This is the SQL query. */
$query = "SELECT * FROM some_table"

if (Ora_Parse($cursor, $query) < 0) {
    echo("Parse failed!\n"
    Ora_Logoff($conn);
    exit;
}

/* Execute the SQL statement associated with $cursor and
   prepare storage for select-list items. */
$ncols = Ora_Exec($cursor);

echo "lt;P>\n"
echo "lt;TABLE BORDER=1 CELLSPACING=0>\n"

/*  Retrieve all rows from the database one after another. */
while (Ora_Fetch($cursor) == 1) {
    $i = 0;
    echo "lt;TR>\n"
    while ($i < $ncols) {
     /* Get data for a single column of currently fetched row. */
     $col = Ora_GetColumn($cursor, $i);
        echo("lt;TD>$col</TD>\n"
     $i++;
    }
    echo("lt;/TR>\n"
}

echo "</TABLE>\n";

/* Close the Oracle connection. */
Ora_Close($cursor);

/* Disconnect the logon data area. */
Ora_Logoff($conn);
>

Informix Illustra 支持

Illustra 是 Informix 出售的商业数据库。它具有几个尚未完全支持的功能。Illustra 最大的优势在于它是一个面向对象的数据库,能够以面向对象的方式进行扩展。例如,可以在数据库中拥有 Image 作为基本类型。可以从 Illustra 主页 获取更多信息。

以下 PHP 函数可用于 Illustra

mi_Connect()
mi_Close()
mi_DBname()
mi_Exec()
mi_Result()
mi_NumRows()
mi_NumFields()
mi_FieldNum()
mi_FieldName()

注意:类型操作尚不支持。

以下是一个示例脚本,它连接到 localhost 上名为“mydb”的 illustra 数据库,并检索表中的人员的姓名和年龄

<?
   $conn = mi_Connect("mydb", "username", "password");
   if ($conn<0) {
      echo "An error occured on connection.\n";
      exit;
   }

   $result = mi_Exec($conn, "select * from table1");
   if ($result < 0) {
      echo "An error occured.\n";
      exit;
   }

   $num = mi_NumRows($result);
   $i = 0;

   while ($i < $num) {
      echo "name: ";
      echo mi_Result($result, $i, "name");
      echo "  age: ";
      echo mi_Result($result, $i, "age");
      echo "<BR>";
      $i++;
   }

   mi_Close($conn);
>

Adabas 支持

Adabas D 是一种高级 RDBMS,可在许多平台上使用。一个特殊的版本,称为个人版,可免费用于 Linux 和 Win32。它被限制为 5 个同时用户和 100 MB 的数据。有关 Adabas D 的更多信息,请参阅 http://www.softwareag.com

以下 PHP 函数可用于访问 Adabas 数据库

Ada_Connect()
Ada_Close()
Ada_Exec()
Ada_Result()
Ada_ResultAll()
Ada_FreeResult()
Ada_NumRows()
Ada_NumFields()
Ada_NumRows()
Ada_NumFields()
Ada_FieldNum()
Ada_FieldName()
Ada_FieldType()
以下是 Postgres 和 Solid 部分中显示的相同脚本,已针对 Adabas D 进行了调整。
<?
   $conn = Ada_Connect("node:db", "username", "password");
   if (!$conn) {
      echo "An error occured.\n";
      exit;
   }

   $result = Ada_Exec($conn, "select * from table1");
   if (!$result) {
      echo "An error occured.\n";
      exit;
   }

   while (Ada_FetchRow($result)) {
      echo "name: ";
      echo Ada_Result($result, "name");
      echo "  age: ";
      echo Ada_Result($result, "age");
      echo "<BR>";
   }

   Ada_FreeResult($result);
   Ada_Close($conn);
>

正则表达式

正则表达式用于 PHP/FI 中的复杂字符串操作。正则表达式支持的脚本接口通过以下函数实现:EReg()ERegi()EReg_Replace()ERegi_Replace()Reg_Match()Reg_Replace()Reg_Search()。所有三个函数的第一个参数都是一个正则表达式字符串。EReg 函数使用 POSIX 1003.2 定义的 POSIX 扩展正则表达式,而 Reg 函数则实现基本正则表达式。有关正则表达式的完整描述,请参阅您的 regex(7) 手册页。如果您没有此页面,则由 Henry Spencer 编写的 regex(7) 手册页可以在 PHP/FI 发行版中的 src/regex 目录中找到。请您的系统管理员为您安装此手册页。

一些正则表达式示例及其功能

ereg("abc",$string);
如果 $string 中的任何位置都找到“abc”,则返回 true。
ereg("^abc",$string);
如果在 $string 的开头找到“abc”,则返回 true。
ereg("abc$",$string);
如果在 $string 的结尾找到“abc”,则返回 true。
eregi("(ozilla.[23]|MSIE.3)",$HTTP_USER_AGENT);
如果客户端浏览器是 Netscape 2、3 或 MSIE 3,则返回 true。
ereg("([[:alnum:]]+) ([[:alnum:]]+) ([[:alnum:]]+)",$string,$regs);
将三个空格分隔的单词放入 $regs[1]、$regs[2] 和 $regs[3] 中。
ereg_replace("^","<BR>",$string)
在 $string 的开头添加一个 <BR> 标签。
ereg_replace("$","<BR>",$string)
在 $string 的结尾添加一个 <BR> 标签。
ereg_replace(10,"",$string);
删除 $string 中的任何换行符。
ereg_replace(13,"<BR>",$string);
将 $string 中的所有回车符替换为一个 <BR> 标签。

转义字符

在大多数使用引号字符串参数的地方都支持以下转义序列

   \a --> bell
        \b --> backspace
        \n --> linefeed
        \r --> carriage return
        \t --> tab
        \nnn --> octal char
        \xXX --> hex char

Unix 文件权限的八进制表示法

PHP/FI 脚本语言中的几个函数需要八进制参数来表示 Unix 风格的权限参数。在这个八进制表示法中,使用 3 位来表示值 0-7。这三个位中的每一位都代表一个特定的权限。八进制传统上在某些情况下用前导 0 表示,例如 0755。您不需要在 PHP 中使用这个前导 0,因为期望八进制参数的函数会简单地假设该参数是八进制的。但是,使用前导 0 是一个好习惯,可以提醒您不再处理 10 进制值。

位 描述

    xxx
    ^^^
    ||+----1 bit (execute permission)
    |+-----2 bit (write permission)
    +------4 bit (read permission)
这三个位为所有者、组和世界重复三次。因此,0755 表示
    owner: r,w,x
    group: r, ,x
    world: r, ,x
请注意,目录上的执行位表示“访问”,而不是“执行”。在第四个八进制半字节中还有扩展位,如 0?755
    4: suid bit   (set userid)
    2: sgid bit   (set group id)
    1: sticky bit (on a directory, only the owner can delete a file)

PHP/FI 脚本语言

PHP 脚本语言在语法上与 C 语言有很多相似之处。它支持变量、数组、函数调用、不同的变量类型以及编写复杂 cgi 程序所需的大多数内容。

以下部分描述了每个 PHP/FI 函数,并且可以通过简单地在该文档的 url 后追加 #function_name 来快速找到,因为每个函数描述都已用其名称标记。

语法

每个 PHP 指令以 <? 开头,以 > 结束。或者,指令可以分组在一个 <? > 对中,并用 ; 字符分隔。

支持变量,并在变量名前面加一个 $ 来表示。例如,要将一个变量设置为 5 并显示该变量,以下代码有效

   <?$a = 5>
        <?echo $a>

这与以下代码相同

   <? $a = 5; echo $a >

或者甚至

   <?
        $a = 5;
        echo $a;
        >

额外的空白字符(如空格、制表符和换行符)将被忽略。应该利用此特性来格式化 PHP 脚本块,使其更容易阅读。变量名称区分大小写,但函数调用不区分大小写。在本文档后面的函数概述中,大小写仅用于使函数名称更易读。在实际的脚本语言中,您可以使用任何您想要的大小写。

支持注释。注释的写法与 C 语言中的注释写法相同。/* 开始注释,*/ 结束注释。注释可以放置在 <? ... > 块中的任何位置。


变量

支持三种类型的变量。长整型双精度浮点型字符型。它们会自动检测。例如

   <?$a = 5>

会导致 $a 成为一个 INTEGER 类型的变量。

   <?$a = 5.0>

会导致 $a 成为一个 DOUBLE 类型的变量。

   <?$a = "5">

会导致 $a 成为一个 STRING 类型的变量。

变量的类型通常并不重要。每个变量,无论其类型如何,都会在内部转换为所有三种类型,并且各种函数会尝试使用正确的类型。只有少数函数会受变量类型的影响。

所有三种变量类型也可以通过在其名称后追加 [value] 来作为数组处理。与 C 不同的是,这些实际上是类似于 Perl 中使用的关联数组。以下是有效的代码

   <?
          $a[0] = 5;
          $a["hello"] = 6;
          echo $a[0];
          echo $a["hello"];
        >

请注意,如果一个变量既用作数组又用作普通变量,则普通变量等同于数组中的索引“0”项。即

    $a = 1;

与以下代码相同

    $a[0] = 1;

PHP/FI 还支持非索引数组。非索引数组将在向其中添加项时生成自己的索引。例如

    $a[] = "Hello";
    $a[] = "There";

插入非索引数组中的第一个项始终分配索引 0,第二个分配索引 1,依此类推。因此,可以使用以下代码打印出上述项

    echo $a[0];
    echo $a[1];

可以通过简单的赋值来复制数组。如果 $b 是一个数组,则可以使用以下代码将所有值复制到一个名为 $a 的新数组中

    $a = $b;

请注意,如果 PHP 不强制您在使用变量之前定义它们。如果在上面的语句中,$b 未定义,那么 $a 将被设置为一个空字符串("")。

[] 符号还用于指示要追加数组。如果 $a 和 $b 都是数组,则可以使用以下代码将 $b 追加到 $a

    $a[] = $b;

在上述代码中,关联数组和普通编号数组之间会存在差异。编号数组将被重新编号,以便来自 $b 的所有元素都位于来自 $a 的原始元素之后。而对于关联数组,$b 中的元素将与 $a 中的元素合并。任何已经在 $a 中存在的元素(具有相同索引名称的项)都将被 $b 元素覆盖。

您可以使用 count() 函数来确定任何数组中的项数。

语言固有的另一个特点是,变量的类型决定了某些基本操作的执行方式。例如

    $a = $b + $c;

可以执行几种不同的操作。如果 $b 是一个数字,则将 $c 的数值加到 $b 上,并将总和存储在 $a 中。在这种情况下,$c 的类型无关紧要。该操作由第一个变量的类型引导。如果 $b 是一个字符串,则将 $c 的字符串值追加到 $b 上,并将结果字符串放入 $a 中。这也导致一些注意事项。您应该阅读有关 重载运算符 的部分,以更好地了解如何处理它们。


关联数组

上一节介绍了关联数组。关联数组是一个数组,其索引不必是数值顺序的值。数组索引可以是任何数字或字符串。PHP/FI 提供了一组函数来操作这些关联数组。这些函数包括 Next()Prev()Reset()End()Key()


变量变量

有时能够拥有可变变量名会很方便。也就是说,可以动态设置和使用的变量名。普通变量的设置方法如下

    $a = "hello";

可变变量采用变量的值,并将其作为变量的名称进行处理。在上面的示例中,hello 可以通过使用两个美元符号来用作变量的名称。即

    $$a = "world";

此时,已在 PHP/FI 符号树中定义并存储了两个变量

    Variable Name        Variable Content
         a                   hello
         hello               world

因此,以下语句

    echo "$a $$a";

产生的输出与以下语句完全相同

    echo "$a $hello";

即它们都产生:hello world


语言结构

就语言结构而言,PHP 语言非常简单。以下命令用于指导控制流通过文件

条件的语法类似于 C 语言的语法。== 用于测试相等性。!= 表示不相等。还支持:><>=<=。条件 AND 是 &&,条件 OR 是 ||

示例

    <?
      if($a==5 &&  $b!=0 );
        $c = 100 + $a / $b;
      endif;
    >

上述代码也可以用标准 C 语法编写
在这种情况下,关闭花括号后面不需要分号。

    <?
      if($a==5 && $b!=0) {
          $c = 100 + $a / $b;
      }
    >

两种语法之间没有区别。我个人喜欢使用 endif、endswitch 和 endwhile,这样我就可以明确知道自己结束的是哪个结构。但是,这些结束结构始终可以用关闭花括号替换。

需要注意的是,语言的流程并不依赖于代码中脚本块的组织方式。您可以在一个块中开始 if 表达式,并在另一个块中结束该表达式。例如

   <?if($a==5 &&  $b!=0)>
                  <b>Normal html text</b>
        <?endif>

在这个示例中,很容易看出为什么有时使用 endif 关键字比使用关闭花括号更可取。上面的代码比以下代码更易读

   <?if($a==5 &&  $b!=0) {>
                  <b>Normal html text</b>
        <? } >

这两个版本都是有效的,它们将执行完全相同的事情。


用户定义函数

您可以使用以下语法在 PHP 脚本中定义函数

    <?
      Function Test (
        echo "This is a test\n";
      );
    >

现在可以从脚本中的任何位置调用此函数,只要调用是在函数定义之后。一个示例调用可能是

    <?
      Test();
    >

像这样的用户定义函数的行为与 PHP 的内部函数完全相同,因为您可以向它们传递参数并让它们返回值。以下是一个函数定义的语法,该函数接受 3 个参数并返回这些参数的总和

    <?
      Function Sum $a,$b,$c (
        return($a+$b+$c);
      );

      echo Sum($a,$b,$c);
    >

return 语句用于从函数中返回值。只能使用此机制返回单个值,但是,如果需要在主代码和函数之间传递更多值,可以使用全局变量。这将我们带到有关变量范围的部分。


变量作用域

变量的范围是定义它的上下文。在大多数情况下,所有 PHP/FI 变量都只有一个范围。但是,在用户定义函数中,引入了局部函数范围。默认情况下,在函数内部使用的任何变量都仅限于局部函数范围。例如

    $a=1; /* global scope */
    Function Test (
      echo $a; /* reference to local scope variable */
    );
    Test();

此脚本将不会产生任何输出,因为 echo 语句引用了 $a 变量的局部版本,并且它在此范围内没有被分配值。您可能会注意到,这与 C 语言略有不同,因为 C 语言中的全局变量会自动对函数可用,除非被局部定义明确覆盖。这可能会导致一些问题,因为人们可能会无意中更改全局变量。在 PHP/FI 中,如果要在函数中使用全局变量,则必须在函数内声明它们为全局变量。一个示例

    $a=1;
    $b=2;
    Function Sum $first,$second (
      global $a,$b;

      $b = $a + $b;
    );
    Sum();
    echo $b;

上面的脚本将输出“3”。通过在函数内声明 $a 和 $b 为全局变量,对这两个变量的所有引用都将引用全局版本。函数可以操作的全局变量数量没有限制。但是,在调用函数之前,该变量必须存在于全局范围内。您不能从函数内部创建新的全局变量。

变量范围的另一个重要特征是 static 变量。静态变量仅存在于局部函数范围内,但当程序执行离开该范围时,它不会丢失其值。考虑以下示例

    Function Test (
      $a=0;
      echo $a;
      $a++;
    );

此函数毫无用处,因为每次调用它时,它都会将 $a 设置为 0 并打印“0”。$a++ 用于递增变量,没有任何作用,因为一旦函数退出,$a 变量就会消失。为了创建一个有用的计数函数,该函数不会丢失当前计数,将 $a 变量声明为静态变量

    Function Test (
      static $a=0;
      echo $a;
      $a++;
    );

现在,每次调用 Test() 函数时,它都会打印 $a 的值并递增它。

静态变量在递归调用函数时也很重要。递归函数是指调用自身的函数。编写递归函数时要小心,因为有可能使其无限递归。您必须确保您有一个适当的方法来终止递归。以下简单的函数递归地计数到 10

    Function Test (
      static $count=0;

      $count++;
      echo $count;
      if($count <  10) {
        Test();
      }
    );

数学表达式

PHP 支持在期望表达式的任何位置执行完整的数学运算。考虑运算顺序。以下是有效的运算符

   <? $a = 2 + 1 > Addition
        <? $a = 2 - 1 > Subtraction
        <? $a = 2 * 1 > Multiplication
        <? $a = 2 / 1 > Division
        <? $a = 2 % 1 > Modulus
        <? $a = 2 ^ 1 > Bit-wise Exclusive OR

支持括号和运算顺序,因此以下代码有效

   <?$a = (2+1)*3+6/3>

支持类似 C 的增量运算符 +=-=。即

    <? $a += $b>

这等同于

    <? $a = $a + $b>

支持类似 C 的按位运算符 &=|=^=。即

    <? $a &= 4>
这等同于
    <? $a = $a &  4>

While 循环

您可以使用 while(); endwhile; 结构在 PHP 脚本中循环。

   <?
          $a=0;
          while($a<100) {
                  $a++;
                  echo $list[$a];
          }
        >

上面的示例展示了使用 while 循环来显示数组内容的用法。警告 尽管 PHP 语言支持 ++-<!>- 等增量运算符来递增和递减变量,但它们的行为并不完全像在 C 语言中那样。变量会立即递增。与 C 语言不同,没有在操作之前或之后递增变量的概念。

如上面的 语言结构 部分所述,可以使用 while(); endwhile; 获得相同的结果。


Switch 结构

PHP 支持与 C 等效的 switch 结构非常相似。

   <?
          $a=0;
          switch($a) {
                case 1;
                  echo "a is 1";
                  break;
                case "hello";
                  echo "a is hello";
                  break;
                default;
                  echo "a is unknown";
                  break;
          }
        >

以上是一个switch结构的例子。它类似于一系列if/elseif/else结构,但更容易阅读。PHP switch结构与C语言中的唯一区别在于使用分号来终止每一行。没有冒号。

如上面语言结构部分所述,同样可以通过switch(); endswitch;来实现。

所有这些结构当然可以像C语言一样嵌套使用,彼此包含。PHP发行版中examples目录中的各种文件应该可以为学习该语言提供一个良好的起点。


安全变量 - 防范 GET 方法攻击

之前部分讨论了GET和POST方法数据以及变量。如果你仔细想想,你可能会想到一个安全问题。例如,如果我在一个网页上从数据库获取了一些数据,并将这些数据保存在名为“data”的变量中,并通过POST方法表单传递。在随后的页面中,我可以访问这个变量并对其进行操作。但是,如果有人直接访问了这个第二个页面,并在URL中添加了“?data=something”,从而执行了GET方法变量设置,那么他们就有效地绕过了原始的POST方法表单。

PHP提供了一个SecureVar()函数,用于将变量名标记为安全变量。这些安全变量只能在PHP脚本中直接设置,或者来自POST方法表单。它们不能使用GET方法变量定义机制设置。从上面我们的场景来看,如果我们在第二个页面的开头添加一行代码:

    <?SecureVar("data")>

那么GET方法的技巧将不起作用。“data”变量将为空,除非它直接来自第一个页面上的POST方法表单。

SecureVar()实际上接受正则表达式作为参数,因此你可以标记应该以这种安全方式处理的变量名的模式。例如:

    <?SecureVar(".*data.*")>

将标记任何变量名为“data”的变量为安全变量。

请注意,POST方法表单本身并不安全。人们可以通过简单地对系统上的HTTP端口进行telnet来模拟对任何表单的发布。如果你确实关心安全问题,你需要采取适当的安全措施来阻止人们这样做。


重载运算符和处理变量类型

重载运算符是一个运算符,例如“+”,它可以根据要求对其进行操作的表达式的类型执行不同的操作。

问题是PHP理解3种变量类型:整数、双精度和字符串。当首次为变量赋值时,PHP会自动确定变量类型。

例如:

    $a = 1;     Type would be integer
    $b = 1.5;   Type would be double
    $c = "1";   Type would be string

现在,当你做类似的事情时会发生什么:

    $d = $a + $c;

解析器会查看算术表达式的第一部分,并使用它来确定结果的类型,从而也确定要执行的算术的性质。在上面的例子中,由于$a是一个整数,$d将是一个整数,并且会进行整数加法,得到的结果为

    $d = 2      Type is integer

因此

    $d = $c + $a

结果为

    $d = "11"   Type is string

以上对我来说很有道理,一旦你理解了它,它可能就可行了。但是,当使用更复杂的表达式时,它会变得非常混乱。

解决方案是一个简单的类型转换机制。实际上,所有变量都会自动转换为所有3种类型,并且一个内部标志只是标记了变量的实际类型。因此,当我写道:

    $a = 1;

在符号表中,我内部存储了3个版本。

    Integer:  1    <-- flag
    Double :  1.0
    String :  "1"

SetType()函数可以移动这个标志,指示变量的类型。

    SetType($a,"double");

这将强制$a从那时起被视为一个双精度数。

GetType()函数返回类型。在这种情况下,GetType($a)将返回“double”。

还存在函数可以返回3种不同的类型,而不会移动类型标志。

    IntVal($a)     returns  1
    DoubleVal($a)  returns  1.0
    StrVal($a)     returns  "1"

这不会改变PHP变量的重载运算符特性,但它确实为你提供了一些工具来更好地处理它们。PHP并不是一个完整的Perl克隆。它必须小而快。Perl通过强制类似“+”运算符仅对数字起作用来解决重载运算符的陷阱。如果你想添加字符串,你必须使用“.”运算符。一旦你开始为每种类型使用不同的运算符,你就会开始使语言变得更加复杂。例如,你不能对字符串使用“==”,现在你需要使用“eq”。我不明白这样做有什么意义,尤其是对于像PHP这样的东西,大多数脚本都非常简单,而且在大多数情况下是由非程序员编写的,他们想要一种具有基本逻辑语法的语言,这种语言没有太高的学习曲线。


抑制函数调用的错误

在某些情况下,可能需要忽略特定PHP函数可能报告的致命错误。例如,你可能希望忽略dbmopen()调用的错误,并简单地检查调用的返回值,而不会在网页上显示错误消息。这可以通过在函数调用之前添加“@”字符来实现。例如:

    $err_code = @dbmopen($filename,"w");

可以通过查看PHP内部变量$phperrmsg来检查本来应该打印的实际错误消息。

一种更通用的抑制错误消息打印的方法是使用SetErrorReporting()函数。使用此函数,可以通过在代码块之前添加类似以下的调用来禁用整个代码块的错误打印:

    SetErrorReporting(0);

这将关闭所有错误。然后可以使用以下命令重新启用它们:

    SetErrorReporting(1);

内部函数

PHP有许多内置函数。函数的调用方式与在C语言中的调用方式相同。有些函数接受一个或多个参数,有些函数返回可以赋值给变量或用作另一个函数的参数的值。例如:

   <?$t=time()>

这将time()函数的返回值赋值给t变量。

函数的字母顺序列表

Abs(arg)

Abs返回arg的绝对值。

Ada_Close(connection_id)

Ada_Close将关闭与给定连接标识符关联的Adabas服务器的连接。

此函数仅在PHP中启用Adabas支持时才可用。

$connection = Ada_Connect(数据源名称, 用户名, 密码)

Ada_Connect打开与Adabas服务器的连接。每个参数都应该是一个带引号的字符串。第一个参数(数据源名称)是一个字符串,格式为“servername:databasename”。如果你想访问本地数据库,可以省略servername(但不包括冒号)。此函数返回一个connection_id。此标识符由其他Adabas函数使用。你可以同时打开多个连接。此函数将在错误时返回0

此函数仅在PHP中启用Adabas支持时才可用。

$result = Ada_Exec(connection_id, 查询字符串)

Ada_Exec将SQL语句发送到由connection_id指定的Adabas服务器。connection_id必须是Ada_Connect返回的有效标识符,或者特殊值0。如果connection_id为0,ada_exec会尝试建立或使用带有配置指令phpAdaDefDB, phpAdaUserphpAdaPW给出的参数的连接。
此函数的返回值是一个标识符,用于通过其他Adabas函数访问结果。此函数在错误时将返回0。当命令执行成功但预期不会返回数据时(例如,插入或更新命令),它将返回1。请注意,不返回数据的select仍然会返回大于1的有效结果。

此函数仅在PHP中启用Adabas支持时才可用。

Ada_FetchRow(result_id [,row_number])

Ada_FetchRow获取Ada_Exec返回的数据的一行。调用Ada_FetchRow后,可以使用Ada_Result访问该行的字段。如果未提供rownumber,Ada_FetchRow将尝试获取结果集中的下一行。每次调用Ada_FetchRow时,可以使用Ada_Result访问新的一行。如果Ada_FetchRow成功(存在一行),则返回1,如果没有更多行,Ada_FetchRow将返回0。Ada_FetchRow的返回值可以作为while循环的条件。可以混合调用带和不带rownumber的Ada_FetchRow()。为了多次遍历结果,你可以使用rownumber 1调用Ada_FetchRow(),然后继续使用不带rownumber的Ada_FetchRow()来查看结果。

此函数仅在PHP中启用Adabas支持时才可用。

Ada_FieldName(result_id, field_number)

Ada_FieldName将返回给定Adabas结果标识符中,占据给定列号的字段的名称。字段编号从0开始。

此函数仅在PHP中启用Adabas支持时才可用。

Ada_FieldNum(result_id, field_name)

Ada_FieldNum将返回给定Adabas结果标识符中,对应于命名字段的列槽的编号。字段编号从0开始。此函数在错误时将返回-1

此函数仅在PHP中启用Adabas支持时才可用。

Ada_FieldType(result_id, field_name|field_number)

Ada_FieldType将返回给定Adabas结果标识符中,由名称或编号引用的字段的SQL类型。注意:字段编号从0开始。

此函数仅在PHP中启用Adabas支持时才可用。

Ada_FreeResult(result_id)

只有在你担心脚本运行时使用太多内存时才需要调用Ada_FreeResult。所有结果内存将在脚本结束后自动释放。但是,如果你确定在脚本中不再需要结果数据,则可以将结果标识符作为参数调用Ada_FreeResult,相关的结果内存将被释放。

此函数仅在PHP中启用Adabas支持时才可用。

Ada_NumFields(result_id)

Ada_NumFields将返回Adabas结果中的字段(列)数。参数是由Ada_Exec返回的有效结果标识符。此函数在错误时将返回-1

此函数仅在PHP中启用Adabas支持时才可用。

Ada_NumRows(result_id)

Ada_NumRows将返回Adabas结果中的行数。参数是由Ada_Exec返回的有效结果标识符。此函数在错误时将返回-1。对于INSERT、UPDATE、DELETE语句,Ada_NumRows()返回受影响的行数。对于SELECT语句,这是可用的行数。

此函数仅在PHP中启用Adabas支持时才可用。

Ada_Result(result_id, field name | index)

Ada_Result将返回由Ada_Exec产生的结果标识符中的值。字段名称指定要返回的行的哪个单元格。你也可以使用字段索引作为无引号的数字,而不是命名字段。字段索引从0开始。如果请求的字段是BYTE(二进制)类型,或者长度超过4096字节,则内容将直接发送到客户端。提示:[VAR]CHAR BYTE字段可以通过使用HEX() db函数返回到php变量中;例如 SELECT HEX(SYSKEY) SYSKEY FROM MYTABLE。

此函数仅在PHP中启用Adabas支持时才可用。

Ada_ResultAll(result_id [,format])

Ada_ResultAll将打印由Ada_Exec产生的结果标识符中的所有行。结果以HTML表格格式打印。使用可选的formatstring可以进行额外的整体表格格式设置(例如,bgcolor=将设置背景颜色,>caption> </caption将设置标题)。注意:“format”的内容将插入HTML表格标签中,如下所示 <table format >...

此函数仅在PHP中启用Adabas支持时才可用。

AddSlashes(arg)

用反斜杠转义任何 $ \ 或 '(如果设置了MAGIC_QUOTES)。另见 StripSlashes().

ASort(array)

Sort用于按升序对PHP关联数组进行排序。使用ARSort()进行降序排序。与Sort()函数不同,ASort()保持索引-值配对。它理解三种变量类型,如果数组包含字符串,则按字母顺序排序,如果数组包含数字,则按数值排序。对于包含混合类型的数组,数组中的第一种类型将指定排序方法。请注意,如果你要对非关联数组进行排序,应该使用Sort()函数。

BinDec(binary_string)

BinDec返回由binary_string参数表示的二进制数的十进制等价物。可以转换的最大数字是31位长,或十进制的4294967295。另见DecBin()函数。

Ceil(value)

Ceil()将浮点值向上舍入到下一个整数。返回值的类型是double(浮点型),以便它可以正确地用于复杂的方程中。要获得整数类型,请使用:$new = IntVal(Ceil($value));
另见Floor().

ChDir(dir)

ChDir 将当前工作目录更改为参数中指定的目录。

ChGrp(file,group)

ChGrp 更改指定文件的组 ID。

ChMod(file,perms)

ChMod 更改指定文件的权限。perms 参数必须以 八进制 表示法指定。例如:ChMod($filename,0755)

ChOwn(file,owner)

ChOwn 将指定文件更改为由指定所有者拥有。请注意,这只有在 PHP/FI 二进制文件以 root 身份运行时才有效(这通常不是一个好主意)。

Chop(string)

Chop 删除所有尾随空格,包括换行符、制表符和空格,并返回新字符串。

Chr(arg)

Chr 返回由整数参数表示的 ASCII 字符。

ClearStack()

ClearStack() 函数是对 PHP 解析器缺陷的一种解决方法。这个缺陷是 PHP 只有一个表达式栈。在用户定义函数内部,这个表达式栈永远不会被清除,因为它的内容可能在调用用户定义函数的上下文中复杂的表达式中需要。这意味着如果你在一个用户定义函数内有一个有很多迭代的 while 循环,你可能会消耗大量的堆栈空间。你甚至可能遇到最大数据空间限制。你可以在你的 while 循环中添加对 ClearStack() 的调用来防止这种内存消耗,但是权衡是你不能在任何类型的上下文中使用你的函数。即你需要将函数的输出赋值给一个临时变量,然后在任何你需要的上下文中使用这个临时变量。

ClearStatCache()

stat() 系统调用通常在大多数操作系统上是一个昂贵的操作。为了确保对各种 File* 函数(如 FilePerms()FileInode() 等)的重复调用,最后一次 stat() 调用的结果总是会被缓存。如果其中一个 File* 函数再次使用相同的参数被调用,缓存的 stat() 结果将被使用。为了强制执行新的 stat() 系统调用,可以调用 ClearStatCache() 函数来清除缓存的 stat() 结果。

closeDir()

closeDir 关闭使用 openDir 函数打开的目录。

CloseLog()

CloseLog() 关闭 Syslog() 用于写入系统记录器的描述符。有关更多详细信息,请参阅 closelog(3) UNIX 手册页。另请参阅 Syslog()OpenLog()InitSyslog()

Cos(arg)

Cos 返回 arg 的余弦,以弧度表示。另请参阅 Sin()Tan()

Count(array)

Count 返回数组变量中的项目数。如果变量不是数组,则返回值将为 1(因为普通变量类似于只有一个项目的数组)。如果变量未定义,则返回值将为 0。

Crypt(string,[salt])

Crypt 将使用标准 Unix DES 加密方法加密字符串。参数是要加密的字符串和一个可选的两位盐字符串,用于基于此进行加密。有关更多信息,请参阅 Unix 系统上 crypt 函数的手册页。如果你的 Unix 系统上没有 crypt 函数,你可以使用 Michael Glad 的公共领域 UFC-Crypt 包,该包是在丹麦开发的,因此只要你从非美国网站 FTP,它就不会受到美国出口法律的限制。

Date(format,time)

Date 函数用于以各种方式显示时间和日期。该函数接受一个格式字符串和一个时间作为参数。如果省略时间参数,则将使用当前时间和日期。时间参数指定为自 1970 年 1 月 1 日 Unix 纪元以来的秒数。格式字符串用于指示应显示哪些日期/时间组件以及它们的格式。以下字符在格式字符串中被识别。任何未识别的字符都会被详细打印

  • Y - 年份 例如:1995
  • y - 年份 例如:95
  • M - 月份 例如:Oct
  • m - 月份 例如:10
  • F - 月份 例如:October
  • D - 星期 例如:Fri
  • l - 星期 例如:Friday
  • d - 日期 例如:27
  • z - 年中的日期 例如:299
  • H - 24 小时制小时 例如:13
  • h - 12 小时制小时 例如:1
  • i - 分钟 例如:5
  • s - 秒 例如:40
  • U - 自纪元以来的秒数 例如:814807830
  • A - AM/PM
  • a - am/pm

另请参阅 MkTime() 函数。

dbList()

dbList 输出有关编译到 PHP 中的 db 支持的信息。

dbmClose(filename)

dbmClose 只是关闭指定的 dbm 文件。它还会解锁任何锁文件,因此关闭任何已打开的 dbm 文件很重要。

dbmDelete(filename,key)

dbmDelete 将删除由给定 key 参数指定的键/内容对。

dbmExists(filename,key)

dbmExists 如果键存在则返回 1,否则返回 0。

dbmFetch(filename,key)

dbmFetch 将返回与给定键关联的内容字符串。

dbmFirstKey(filename)

dbmFirstKey 返回 dbm 文件中的第一个键。请注意,不保证任何特定顺序,因为顺序取决于 dbm 实现中计算的哈希表值。如果需要,可以使用 Sort 函数对来自 dbm 文件的数据数组进行排序。

dbmInsert(filename,key,content)

dbmInsert 将一个新的键/内容数据对插入 dbm 文件。如果键已存在,则插入将失败。

dbmNextKey(filename,key)

dbmNextKey 返回指定键之后的下一个键。通过调用 dbmfirstkey() 后跟对 dbmnextkey() 的连续调用,可以访问 dbm 文件中的每个键/内容对。

dbmOpen(filename,mode)

dbmOpen() 打开一个 dbm 文件。第一个参数是要打开的 dbm 文件的完整路径文件名,第二个参数是文件打开模式,可以是 "r""n""w",分别表示读取、新建(隐式写入)和写入。如果使用 ndbm 支持,ndbm 实际上会创建 filename.dirfilename.pag 文件。gdbm 只使用一个文件,内部扁平 ASCII 文件支持也是如此,而 Berkeley 的 libdb 创建一个 filename.db 文件。请注意,PHP 除了 dbm 库本身可能执行的任何文件锁定之外,还执行自己的文件锁定。PHP 不会删除它创建的 .lck 文件。它使用这些文件只是作为固定 inode 来执行文件锁定。有关 dbm 文件的更多信息,请参阅你的 Unix 手册页,或从 ftp://prep.ai.mit.edu/pub/gnu 获取 GNU 的 gdbm。

dbmReplace(filename,key,content)

dbmReplace 与 dbminsert() 函数类似,唯一的区别是如果键已存在,则旧内容字符串将被替换为新的内容字符串。

DecBin(number)

DecBin 返回包含给定 number 参数的二进制表示的字符串。可以转换的最大数字是 31 位长或十进制的 4294967295。另请参阅 BinDec() 函数。

DecHex(number)

DecHex 将十进制数转换为十六进制字符串。另请参阅 HexDec() 函数。

DecOct(number)

DecOct 将十进制数转换为八进制数。另请参阅 OctDec()

doubleval(variable)

doubleval 返回变量的双精度(浮点)值。另请参阅 strval()intval() 函数。

Echo [format_string] expression [, expression [,...]]

Echo 不是一个函数。即你不需要在参数周围加上括号。它用于显示 PHP 函数或 PHP 变量的结果。有关支持的特殊字符列表,请参阅 转义字符部分。format_string 是可选的,如果不存在,则不会进行任何输出格式化。format_string 类似于 C printf 函数的 format_string。有关更多详细信息,请参阅 printf 的手册页。可以使用单个 echo 命令打印最多 5 个表达式。如果你尝试打印更多,你会收到解析器错误。请注意,表达式的类型并不重要。表达式会根据 format_string 的指定自动转换为相应的类型(如果存在)。如果你想格式化某些内容并将格式化的字符串分配给变量而不是显示它,请使用 sprintf() 函数。

支持以下转换:

%d %i
打印一个带符号的十进制数。
%o
打印一个八进制数。
%u
打印一个无符号的十进制数。
%x %X
打印一个十六进制数。
%f
打印一个浮点数。
%e %E
以科学记数法打印一个浮点数。
%g %G
根据需要以科学记数法或普通记数法打印一个浮点数。
%c
打印单个字符。
%s
打印一个字符字符串。
%%
打印一个文字百分号。

接受以下标志:

'-'
在字段宽度内左对齐输出。
'+'
确保所有整数都带符号(带有正负号)。
' '
类似于'+',但使用空格代替加号。
'#'
在十六进制和八进制数前面打印前缀,将其指定为十六进制和八进制数。
'''
将数字分成组(通常是三个数字一组,用逗号分隔)。
'0'
用零填充字段宽度。

所有这些标志都取决于你的 C 库的 printf 函数是否支持它们(例如 '' 是 GNU 扩展)。

大多数转换都接受字段宽度和精度,如 demo_echo.html 文件(位于 /examples 目录中)所示。没有必要指定任何类型修饰符,实际上,如果类型修饰符没有意义,PHP 会报错(这几乎总是这种情况)。PHP 会抱怨(并拒绝接受)任何它不认识的东西。给出的任何额外的参数(格式字符串不需要)都会被忽略。

End(variable)

End 将给定变量的内部数组指针移动到数组的最后一个项目,并返回此项目的价值。这对于以相反的顺序遍历关联数组很有用。另请参阅 Reset()Prev()。以下示例将以相反的顺序遍历关联数组

    <?
      Reset($array);
      $first_key = key($array);
      End($array);
      $k = key($array);
      while($k != $first_key);
        echo $array[$k];
        prev($array);
        $k = key($array);
      endwhile;
      echo $array[$k];
    >
ereg(expr,arg[,regs])

如果在参数字符串中匹配正则表达式,则 ereg 返回非零值。例如,条件 <?if (ereg("^This.*", "This is an example string")> 将为真,因为 "^This.*" 表达式表示匹配字符串开头的单词 This,然后匹配其后的任何字符。如果 regs 参数存在,则匹配寄存器将填充到 regs 参数命名的数组中的位置 0-10。寄存器 0 将始终包含完整的匹配字符串。有关正则表达式的更多信息,请参阅本文档的 正则表达式部分

eregi(expr,arg[,regs])

eregi 与 ereg() 函数相同,只是正则表达式应用于忽略大小写的模式。

ereg_replace(expr,replace,arg)

ereg_Replace 会扫描整个参数字符串,并将字符串中与给定表达式匹配的任何部分替换为替换字符串。例如,在字符串 "This is an example string" 中,我们可以非常轻松地使用命令将每个空格替换为破折号:ereg_replace(" ","-","This is an example string")。有关正则表达式的更多信息,请参阅本文档的正则表达式部分

eregi_replace(expr,replace,arg)

eregi_replace 与ereg_replace() 函数完全相同,只是正则表达式应用于忽略大小写的场合。

EscapeShellCmd(string)

EscapeShellCmd 会转义字符串中任何可能被用来欺骗 shell 命令执行任意命令的字符。此函数应用于确保在将来自用户输入的任何数据传递给Exec()System() 函数之前转义这些数据。一个标准用法是

    <?system(EscapeShellCmd($cmd))>
Eval(string)

Eval 会将字符串参数的内容视为一个迷你 PHP/FI 脚本。它将把它作为一个单独的 PHP/FI 脚本执行。在 eval 中设置或访问的任何变量都将来自当前上下文中 eval 语句的全局引用框架。在字符串参数上执行变量替换,因此如果要在字符串表达式中使用变量,则应转义它们。一些例子

    $a = "echo phpversion();";
    eval($a);

    eval("echo phpversion();");

    eval("\$a=1; echo \$a;");
Exec(command_string [, array [,return_var]])

Exec 会执行给定的 unix 命令,但不会输出任何内容。它只返回命令结果的最后一行。如果您需要执行一个命令并让所有来自命令的数据直接返回,而没有任何干扰,请使用PassThru() 函数。如果存在数组参数,则指定的数组将填充 unix 命令输出的每一行,从数组的末尾开始。在调用之前确保UnSet 数组,如果您的数组已经包含元素并且您想从数组元素 0 开始填充它。如果存在 return_var 参数以及数组参数,则执行的 unix 命令的返回状态将写入此变量。请注意,如果您要允许来自用户输入的数据传递给此 Exec 函数,那么您应该使用EscapeShellCmd() 函数来确保用户无法欺骗系统执行任意命令。另请参见system() 函数。

Exit

Exit 命令用于在解析到此标记时立即终止解析。

Exp(arg)

Exp 返回 e 的 arg 次方。另请参见pow()

fclose($fd)

fclose() 关闭由fopen() 打开的文件。参数是由 fopen() 调用返回的文件指针索引。

feof($fd)

Feof 在文件指针索引参数引用的文件到达文件末尾时返回 true。

fgets($fd,bytes)

fgets() 从由fopen() 打开的文件中读取一行。参数是由 fopen() 返回的文件指针索引以及要读取的最大字节数。当读取到最大字节数或在行尾时,读取结束。这类似于 C fgets() 调用。另请参见fputs()

fgetss($fd,bytes)

与 fgets() 函数相同,只是这个函数在读取文件时尝试剥离任何 HTML 标记或 PHP/FI 脚本标记。

$array = File(filename)

File 读取整个文件并返回一个数组,每个数组元素都包含文件的每一行,从数组索引0开始。

fileAtime(filename)

fileAtime 返回最后一次数据访问的时间。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 fileAtime 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

fileCtime(filename)

fileCtime 返回最后一次状态更改的时间。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 fileCtime 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

fileGroup(filename)

fileGroup 返回文件所有者的组 ID。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 fileGroup 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

fileInode(filename)

fileInode 返回文件的 inode。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 fileInode 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

fileMtime(filename)

fileMtime 返回最后一次数据修改的时间。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 fileMtime 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

fileOwner(filename)

fileOwner 返回文件所有者的 uid。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 fileOwner 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

filePerms(filename)

filePerms 返回文件的权限位。这是 Unix C stat 结构的st_mode 字段。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 filePerms 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

fileSize(filename)

fileSize 返回文件的大小(以字节为单位)。如果文件不存在,或者由于其他原因无法访问,则此函数返回 -1。如果要重复调用 fileSize 和其他 file* 函数,并且要访问的文件可能会更改或消失,则应该在调用 file* 函数之前调用ClearStatCache()

fileType(filename)

fileType 返回文件的类型。返回值之一是:"dir"、"file"、"fifo"、"char"、"block" 或 "link"。它们分别表示目录、普通文件、fifo 特殊、字符特殊、块特殊和符号链接。

Floor(value)

Floor() 将浮点数向下舍入到前一个整数。返回值的类型为 double(浮点数),以便它可以正确地用于复杂的方程。要获取整数类型,请使用:$new = IntVal(Floor($value));
另请参见Ceil()

Flush()

Flush() 函数用于刷新输出缓冲区。对于 Apache 模块,它会刷新 Apache 的输出缓冲区,而对于 CGI 版本,它只会刷新 stdout。在作为 Apache 下的 CGI 运行时,服务器会缓冲 CGI 脚本的输出,因此此 Flush() 函数在此处不会有太大帮助。如果您在 Apache Web 服务器下运行 PHP 的 CGI 版本,请查看将您的脚本作为 nph- 脚本运行。或者,还可以运行 Apache 模块版本的 PHP。

$fp = fopen(filename,mode)

fopen() 打开一个文件并返回一个文件指针索引。如果无法打开文件,则函数返回 -1。它类似于 C fopen() 调用。filename 参数是要打开文件的相对或绝对路径,mode 参数是以下之一:"r"、"r+"、"w"、"w+"、"a"、"a+"。有关更多信息,请参见 Unix 手册页上的 fopen() 调用。另请参见popen() 函数描述。另请参见fclose() 函数描述。

示例

    $fp = fopen("/home/rasmus/file.txt","r");
fputs(fp,string)

fputs() 将一行写入由fopen() 打开的文件。参数是由 fopen() 返回的文件指针索引以及要写入的字符串。请注意,字符串参数可能包含特殊转义字符\n\r\t,分别用于输出换行符、回车符和制表符。另请参见fgets()

FPassThru(fp)

FPassThru() 会直接输出fp 上所有剩余的数据。它与ReadFile() 不同,因为它还可以处理使用fsockopen() 打开的文件。它与PassThru() 不同,因为它不处理命令,而是处理打开的文件。FPassThru() 返回读取和写入的字节数。

fseek(fp,pos)

fseek() 定位由 $fd 参数标识的文件指针,该参数是fopen() 调用的返回值。文件指针定位在文件开头加上pos 参数指定的偏移量。另请参见ftell()rewind()

fp = fsockopen(hostname,port)

fsockopen() 打开一个套接字连接并返回一个文件指针索引。此文件指针索引可被fgetsfputsfclose 使用。参数是主机名和端口号。返回值是:-3 如果套接字无法创建,-4 如果主机名上的 DNS 查找失败,-5 如果连接被拒绝或超时,-6 如果实际的 fdopen() 调用失败或 -7 如果 setvbuf() 调用失败。如果端口号为 0,则主机名参数将被视为 Unix 域套接字的文件名(如果您的操作系统支持 Unix 域套接字)。

pos = ftell(fp)

ftell() 返回由 fp 参数标识的文件指针的位置,该参数是fopen() 调用的返回值。位置随后可用作 fseek() 的参数。另请参见fseek()rewind()

getAccDir()

getAccDir 返回 PHP 访问配置文件所在的目录。访问配置文件名来自用户的数字用户 ID,这些配置文件代表了这些用户的访问配置。

GetEnv(string)

GetEnv 返回由string 指定的环境值的 value。通常不使用此函数,因为环境变量可直接用于 PHP/FI。如果引用了内部符号表中找不到的变量,则会自动搜索环境空间。当需要确保环境变量未被正常的 PHP/FI 变量覆盖时,应使用 GetEnv。依赖于 http 服务器定义的变量(如 REMOTE_ADDR 和 REMOTE_HOST)的安全机制应使用 GetEnv 加载这些变量,而不是直接引用它们,例如 $REMOTE_ADDR,以避免有人伪造表单并将数据发布到您的服务器,从而绕过您可能拥有的任何安全机制。

getHostByName(domain_name)

getHostByName 将给定的域名转换为 nnn.nnn.nnn.nnn 格式的 IP 地址。

getHostByAddr(ip_address)

getHostByAddr 将给定的 nnn.nnn.nnn.nnn 格式的 IP 地址转换为完全限定的域名。

GetImageSize(filename)

GetImageSize() 函数接受完整路径文件名或相对于调用脚本位置的相对路径。它返回一个包含宽度、高度和类型的 3 元素数组。宽度和高度以像素为单位,类型 1 表示 GIF,类型 2 表示 JPG 文件,类型 3 表示 PNG 文件。不支持其他文件类型。返回数组中的第四个元素是一个字符串,包含“width=x height=y”,适合直接在 IMG 标签中使用。请注意,使用此函数不需要 GD 图像库。以下是一个示例

    <?
        $result = GetImageSize("img/flag.jpg");
    >
    <IMG SRC="img/flag.jpg" ?echo $result[3]> >
getLastAccess()

getLastAccess 返回上次访问当前页面时的日期和时间,以 Unix 时间格式表示。此值可以传递给 Date() 函数以进行格式化。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

getLastbrowser()

getLastBrowser 返回上次访问当前页面的用户使用的浏览器的标识字符串。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

getLastEmail()

getLastEmail 返回上次访问当前页面的用户的电子邮件地址。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

getLastHost()

getLastHost 返回上次访问当前页面的用户的主机名。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

getLastMod()

getLastMod 返回上次修改当前页面的日期和时间,以 Unix 时间格式表示。此值可以传递给 Date() 函数以进行格式化。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

getLastref()

getLastRef 返回上次访问当前页面的用户的引用文档的 URL。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

getLogDir()

getLogDir 返回可以找到 PHP 日志文件的顶级目录。实际的日志文件位于此目录下的目录中。每个子目录都是日志文件所属用户的数字用户 ID。然后,在每个目录中都会找到一系列 dbm 日志文件,每个文件都以它们所代表的文件的数字 inode 作为文件名的主要组成部分。

getMyInode()

getMyInode 返回当前 HTML 文件的数字 inode。

getMyPid()

getMyPid() 返回 PHP 解析过程的当前进程 ID。

getMyUid()

getMyUid 返回当前 HTML 文件所有者的数字用户 ID。

getRandMax()

getRandMax 返回 Rand 函数将返回的最大随机数。如果返回的值似乎不准确,请查看 PHP 发行版中的 php.h 源文件以获取更多信息。

getStartLogging()

getStartLogging 返回当前页面开始记录的时间和日期,以 Unix 时间格式表示。当使用基于 mSQL 的日志记录时,这更准确,因为每个日志文件中都保留了一个时间戳。对于 dbm 日志记录,返回的时间是创建用户日志目录的时间。

getToday()

getToday 返回当前页面自当地时间午夜 12 点以来的总点击次数。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

getTotal()

getTotal 返回当前页面自页面开始访问日志记录以来的总点击次数。
仅当 PHP 编译时启用了访问日志记录时,此功能才可用。

GetType(variable)

GetType 返回变量的类型。返回值是一个字符串,它可能是“integer”、“double”或“string”之一。另请参阅 SetType() 函数

gmDate(format,time)

gmDate 与 Date 函数相同,只是它使用格林尼治标准时间而不是当前本地时间。

Header(header_string)

Header 命令用于 HTML 文件的顶部,用于发送原始 HTTP 标头字符串。有关原始 http 标头的更多信息,请参阅 HTTP 规范。请记住,Header() 命令必须在发送任何实际输出之前使用,无论是通过普通的 HTML 标签还是通过 PHP echo 命令。
可以在 HTTP 身份验证 部分找到使用示例。

HexDec(hex_string)

HexDec 将十六进制字符串转换为十进制数。另请参阅 DecHex() 函数。

HtmlSpecialChars(string)

HtmlSpecialChars 将字符串参数中 ASCII 码在 160 到 255(含)之间的任何字符转换为其相应的 HTML 实体名称。该函数返回转换后的字符串。<>&" 也将被转换。

ImageArc(im, cx, cy, w, h, s, e, col)

ImageArc 在 im 表示的图像中绘制一个以 cx,cy 为中心的椭圆形(左上角为 0,0)。w 和 h 分别指定椭圆形的宽度和高度,而起始点和结束点以度数指定,由 s 和 e 参数表示。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageChar(im, size, x, y, c, col)

ImageChar 在由 im 标识的图像中绘制字符 c,坐标为 x,y(左上角为 0,0),颜色为 col。size 参数可以是 1、2、3、4 或 5,表示要使用的字体的尺寸。1 是最小,5 是最大。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageCharUp(im, size, x, y, c, col)

ImageCharUp 在由 im 标识的图像中垂直绘制字符 c,坐标为 x,y(左上角为 0,0),颜色为 col。size 参数可以是 1、2、3、4 或 5,表示要使用的字体的尺寸。1 是最小,5 是最大。
此功能仅在 PHP 中启用了 GD 支持时才可用。

col = ImageColorAllocate(im, red, green, blue)

ImageColorAllocate 返回一个颜色标识符,表示由给定的 RGB 成分组成的颜色。im 参数是 ImageCreate 函数的返回值。ImageColorAllocate 必须被调用以创建要在 im 表示的图像中使用的每种颜色。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageColorTransparent(im, col)

ImageColorTransparent 将 im 图像中的透明颜色设置为 col。im 是 ImageCreate 返回的图像标识符,col 是 ImageColorAllocate 返回的颜色标识符。此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageCopyResized(dst_im, src_im, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH )

ImageCopyResized 将一个图像的矩形部分复制到另一个图像。dst_im 是目标图像,src_im 是源图像标识符。如果源坐标和目标坐标以及宽度和高度不同,则将对图像片段执行适当的拉伸或收缩。坐标是指左上角。此函数可用于复制同一图像内的区域(如果 dst_imsrc_im 相同),但如果区域重叠,则结果将不可预测。
此功能仅在 PHP 中启用了 GD 支持时才可用。

im = ImageCreate(x_size, y_size)

ImageCreate 返回一个图像标识符,表示一个大小为 x_size x y_size 的空白图像。
此功能仅在 PHP 中启用了 GD 支持时才可用。

im = ImageCreateFromGif(filename)

ImageCreateFromGif 返回一个图像标识符,表示从给定 filename 中获得的图像。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageDestroy(im)

ImageDestroy 释放与图像 im 相关联的任何内存。im 是 ImageCreate 函数返回的图像标识符。此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageFill(im, x, y, col)

ImageFill 执行一个洪水填充,从坐标 x,y(左上角为 0,0)开始,用颜色 col 填充图像 im。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageFilledPolygon(im, points, num_points, col)

ImageFilledPolygon 在图像 im 中创建一个填充的多边形。points 是一个 PHP 数组,包含多边形的顶点。例如,points[0] = x0, points[1] = y0, points[2] = x1, points[3] = y1,等等。num_points 是顶点的总数。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageFilledRectangle(im, x1, y1, x2, y2, col)

ImageFilledRectangle 在图像 im 中创建一个填充的矩形,颜色为 col,从左上角坐标 x1,y1 开始,到右下角坐标 x2,y2 结束。0,0 是图像的左上角。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageFillToBorder(im, x, y, border, col)

ImageFillToBorder 执行一个洪水填充,其边界颜色由 border 定义。填充的起点为 x,y(左上角为 0,0),区域用颜色 col 填充。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageGif(im [,filename])

ImageGif 从图像 im 创建 filename 中的 GIF 文件。im 参数是 ImageCreate 函数的返回值。filename 参数是可选的,如果省略,则原始图像流将直接返回。通过使用 Header() 函数发送 image/gif 内容类型,您可以创建一个 PHP/FI 脚本,该脚本使用此函数直接返回 GIF 图像。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageInterlace(im, interlace)

ImageInterlace 打开或关闭交错位。如果 interlace 为 1,则 im 图像将被交错,如果 interlace 为 0,则交错位将被关闭。此函数仅在 PHP 中启用了 GD 支持时才可用。

ImageLine(im, x1, y1, x2, y2, col)

ImageLine 在图像 im 中绘制一条从 x1,y1 到 x2,y2(左上角为 0,0)的直线,颜色为 col
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImagePolygon(im, points, num_points, col)

ImagePolygon 在图像 im 中创建一个多边形。points 是一个 PHP 数组,包含多边形的顶点。例如,points[0] = x0, points[1] = y0, points[2] = x1, points[3] = y1,等等。num_points 是顶点的总数。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageRectangle(im, x1, y1, x2, y2, col)

ImageRectangle 在图像 im 中创建一个颜色为 col 的矩形,从左上角坐标 x1,y1 开始,到右下角坐标 x2,y2 结束。0,0 是图像的左上角。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageSetPixel(im, x, y, col)

ImageSetPixel 在图像 im 中绘制一个坐标为 x,y(左上角为 0,0)的像素,颜色为 col
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageString(im, size, x, y, s, col)

ImageString 在由 im 标识的图像中绘制字符串 s,坐标为 x,y(左上角为 0,0),颜色为 col。size 参数可以是 1、2、3、4 或 5,表示要使用的字体的尺寸。1 是最小,5 是最大。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageStringUp(im, size, x, y, s, col)

ImageStringUp 在由 im 标识的图像中垂直绘制字符串 s,坐标为 x,y(左上角为 0,0),颜色为 col。size 参数可以是 1、2、3、4 或 5,表示要使用的字体的尺寸。1 是最小,5 是最大。
此功能仅在 PHP 中启用了 GD 支持时才可用。

ImageSX(im)

ImageSX 返回由 im 标识的图像的宽度。

ImageSY(im)

ImageSY 返回由 im 标识的图像的高度。

Include(filename)

Include 命令可用于将其他文件插入当前 html 文件中。这对于可能需要包含在数百个 HTML 文件中的页眉和页脚非常有用。通过使用 include 命令,您只需在需要更改时修改页眉或页脚文件,而无需在其他地方进行修改。由于对包含的文件执行了完整的 PHP 解析,因此您也可以使用 include 命令包含您可能编写的通用 PHP 脚本。有点像拥有一个您可以从 HTML 文件中调用的原始共享脚本库。您可以将这些通用库文件放在一个目录中,并设置 PHP 的 include 路径,而无需使用路径名引用这些文件。对于 Apache 模块用户,可以使用 phpIncludePath 指令进行配置,对于 CGI 用户,可以使用 PHP_INCLUDE_PATH 环境变量进行配置。此路径与 $PATH 一样,以冒号分隔,就像您在 UNIX shell 中一样。例如

    <?include("/path/filename.txt")>
InitSyslog()

InitSyslog() 定义了在使用 OpenLog() 和 Syslog() 时所需的某些 PHP 变量。出于效率原因,这些变量默认情况下不会被定义。变量的命名方式与 <syslog.h> C 包含文件中的命名方式相同(例如 $LOG_LOCAL0)。有关更多详细信息,请参阅您的 syslog(3) UNIX 手册页。另请参阅 InitSyslog()Syslog()CloseLog()

intval(variable)

intval 返回变量的长整型值。另请参阅 strval()doubleval() 函数。

IsSet(variable)

IsSet 函数在给定变量已定义时返回 1,否则返回 0。

Key(variable)

Key 返回当前数组项目的键。当前项目由给定变量的数组指针的位置确定。此数组指针可以使用 Reset()End()Next()Prev() 函数进行操作。此函数主要用于确定关联数组中项目的键值,但它也适用于普通数组。

Link(target,link)

Link() 创建一个硬链接。有关创建符号链接(软链接)的信息,请参阅 Symlink() 函数。另请参阅 ReadLinkLinkInfo 函数。

LinkInfo(path)

LinkInfo 返回由 lstat 系统调用返回的 UNIX C stat 结构的 st_dev 字段。此函数用于验证链接(由 path 指向)是否真的存在(使用与 stat.h 中定义的 S_ISLNK 宏相同的方法)。如果发生错误,则返回 -1。

Log(arg)

Log 返回 arg 的自然对数。

Log10(arg)

Log10 返回 arg 的以 10 为底的对数。

LogAs(filename)

LogAs() 函数将当前页面上的点击视为实际上在参数 filename 上接收的点击。

Mail(to,subject,message[,headers])

Mail 自动将 message 参数中指定的邮件发送给 to 参数中指定的接收者。可以通过 to 参数中的空格指定多个收件人。

例如。

   mail("[email protected]",
        "My Subject",
        "Line 1\nLine 2\nLine 3");
如果传递了第四个字符串参数,则此字符串将插入到标头的末尾,例如
   mail("[email protected]", "the subject", $message,
        "X-Mailer: PHP/FI " + phpversion());
Max(array)

Max 返回 PHP 数组的最大值。即它将搜索整个数组以查找最大元素。如果它是字符串数组,则返回的字符串是在数组排序后在字母顺序上位于最后的字符串。

Md5(message)

Md5 返回字符串值的 MD5 哈希值。

mi_Close(connection_id)

mi_Close 将关闭与给定连接标识符关联的 Illustra 数据库的连接。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

$connection = mi_Connect(database, username, password)

mi_Connect 打开与 Illustra 数据库的连接。每个参数都应该是带引号的字符串。此函数返回一个 connection_id。此标识符需要其他 Illustra 函数。您可以同时打开多个连接。要连接到的主机由运行 PHP 可执行文件的机器上的 MI_PARAMS 文件控制。目前不支持远程调用。此函数在发生错误时将返回 **-1**。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

mi_DBname(connection_id)

mi_DBname 将返回给定 Illustra 连接标识符连接到的数据库的名称。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

$result = mi_Exec(connection_id, query_string)

mi_Exec 将 SQL 语句发送到由 connection_id 指定的 Illustra 数据库。connection_id 必须是由 mi_Connect 返回的有效标识符。此函数的返回值是用于从其他 Illustra 函数访问结果的标识符。此函数在发生错误时将返回 **-1**。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

mi_FieldName(connection_id, result_id, field_number)

mi_FieldName 将返回在给定 Illustra 结果和连接标识符下占用给定列号的字段的名称。字段编号从 0 开始。

此函数在发生错误时将返回 **-1**。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

mi_FieldNum(connection_id, result_id, field_name)

mi_FieldNum 将返回与给定 Illustra 结果标识符中命名字段相对应的列槽的编号。字段编号从 0 开始。此函数在发生错误时将返回 **-1**。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

mi_NumFields(connection_id, result_id)

mi_NumFields 将返回 Illustra 结果中的字段数(列数)。参数是由 mi_Exec 返回的有效结果标识符。此函数在发生错误时将返回 **-1**。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

mi_NumRows(connection_id, result_id)

mi_NumRows 将返回 Illustra 结果中的行数。参数是由 mi_Exec 返回的有效结果标识符。此函数在发生错误时将返回 **-1**。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

mi_Result(connection_id, result_id, row_number, field name/index)

mi_Result 将从 mi_Exec 生成的结果标识符返回值。row_number 和字段名称指定要返回的结果表中的哪个单元格。行编号从 0 开始。您可以使用字段索引作为无引号的数字,而不是命名字段。字段索引从 0 开始。

从数据库返回的所有值都以字符串形式显示,因为目前没有类型检测可用。

此功能仅在 PHP 中启用了 Illustra 支持的情况下才可用。

Microtime()

Microtime() 返回字符串“msec sec”,其中 sec 是自 1970 年 1 月 1 日 00:00 GMT 以来的秒数,msec 是微秒部分(作为秒的几分之一)。例如“0.87633900 825010464”。
此功能仅在支持 gettimeofday() 系统调用的操作系统上可用。

Min(array)

Min 返回 PHP 数组的最小值。即它将搜索整个数组以查找最小元素。如果它是字符串数组,则返回的字符串是在数组排序后在字母顺序上位于最前面的字符串。

MkDir(dir,mode)

MkDir 创建一个目录。mode 参数必须以 八进制 表示法给出。例如 MkDir("DirName",0755);

MkTime(hour,min,sec,mon,day,year)

MkTime 返回一个 Unix 时间戳(长整型)格式的时间,该时间对应于参数指定的日期和时间。参数可以省略,在这种情况下,给定组件将根据当前的本地时间和日期设置为当前值。这些省略的参数只能从右到左省略。即 MkTime(hour,min,sec) 有效,但 MkTime(mon,day,year) 无效。请注意,此函数作为进行日期运算和日期验证的工具非常方便。您可以为它提供无效的参数,例如大于 12 的月份或大于 31 的日期,它仍然可以计算出正确的日期。如果任何参数超出正常范围,它也会生成错误消息。在调用函数之前使用 SetErrorReporting(0) 函数关闭此错误报告,然后您可以检查 $phperrmsg 中可能发生的任何错误。

例如。

        SetErrorReporting(0);
        $a = MkTime(0,0,0,13,1,1997);
        SetErrorReporting(1);
        echo $phperrmsg;
$result = msql($database,$query)

msql 发送 mSQL 查询。参数是数据库名称和查询字符串。即 **<?msql("MyDatabase" , "select * from table")>**。此函数的返回值是一个结果标识符,用于从其他 msql_ 函数访问结果。结果标识符是一个正整数。当没有创建结果标识符时,函数返回 **0**。对于不返回任何内容的任何查询,例如 createupdatedropinsertdelete,情况就是这样。如果发生错误,该函数将返回 **-1**。描述错误的字符串将被放置在 $phperrmsg 中,并且除非函数被调用为 **@msql()**,否则此错误字符串也会被打印出来。对于 mSQL 2.0,$result 变量将包含受执行的 SQL 命令影响的行数。如果您希望您的应用程序可移植到 mSQL 1.0,请不要依赖此方法。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_close()

msql_Close 关闭与 msql 守护进程的套接字连接(如果存在打开的连接)。请注意,由于一次只能打开一个并发 mSQL 会话,因此此函数不带参数。

msql_connect($hostname)

msql_Connect 指定 mSQL 数据库引擎所在的 hostname 或 IP。这等效于 mSQL C API 中的 msqlConnect() 函数。此函数与 C API 等效项之间的唯一区别是,如果未调用此函数,则在首次调用 msql() 函数时默认会建立与本地主机的连接。并且,不需要 msql_close 函数,因为一次只能有一个连接处于活动状态。如果在文件中第二次调用 msql_connect(),则与第一个主机的连接将自动关闭。要显式连接到本地主机的 msql 守护进程,请使用:**<?msql_connect("localhost")>**
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_CreateDB($database)

msql_CreateDB 创建给定的数据库。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_dbName($result,$i)

msql_dbName 返回存储在从 msql_ListDbs() 函数返回的结果指针的 $i 位置的数据库名称。可以使用 msql_NumRows() 函数确定有多少个数据库名称可用。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_DropDB($database)

msql_DropDB 删除给定的 mSQL 数据库。请谨慎使用,因为数据库中的所有数据都将丢失。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_FieldFlags($result,$i)

msql_FieldFlags 返回指定字段的字段标志。目前,这可以是“非空”、“主键”、“两者兼有”或“” (空字符串)。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_FieldLen($result,$i)

msql_FieldLen 返回指定字段的长度。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_FieldName($result,$i)

msql_FieldName 返回指定字段的名称。函数的参数是结果标识符和字段索引。即 msql_FieldName($result,2); 将返回与结果标识符关联的结果中的第二个字段的名称。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_FieldType($result,$i)

msql_FieldType 类似于 msql_FieldName() 函数。参数相同,但返回字段类型。这将是“int”、“char”或“real”之一。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_FreeResult($result)

msql_FreeResult 仅在您担心在脚本运行时使用过多内存时才需要调用。所有结果内存将在脚本完成后自动释放。但是,如果您确定在脚本中不再需要结果数据,则可以使用结果标识符作为参数调用 msql_freeresult,并且相关的结果内存将被释放。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

$result = msql_ListDBs()

msql_ListDBs 将返回一个结果指针,其中包含当前 mSQL 守护进程可用的数据库。使用 msql_dbName() 函数遍历此结果指针。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

$result = msql_Listfields($database,$tablename)

msql_listfields 检索有关给定 tablename 的信息。参数是数据库名称和表名。返回一个结果指针,可与 msql_fieldflags、msql_fieldlen、msql_fieldname、msql_fieldtype 一起使用。结果标识符是一个正整数。如果发生错误,该函数返回 -1。描述错误的字符串将被放置在 $phperrmsg 中,并且除非函数被调用为 @msql(),否则此错误字符串也会被打印出来。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

$result = msql_ListTables($database)

msql_ListTables 接受数据库名称和结果指针,类似于 msql() 函数。可以使用 msql_TableName() 函数从结果指针中提取实际表名。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_NumFields($result)

msql_NumFields 返回结果中的字段数。参数是由 msql() 函数返回的结果标识符。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_NumRows($result)

msql_NumRows 只是返回结果中的行数。参数是由 msql() 函数返回的结果标识符。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_RegCase(string)

msql_RegCase 接受一个字符串参数,并将其转换为发送到 mSQL 以获取不区分大小写的匹配所需的正则表达式。这将把类似于“abc”的字符串转换为“[Aa][Bb][Cc]”。
此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_Result($result,$i,field)

msql_Result 显示返回记录中的一个字段。参数是由 msql() 函数返回的结果标识符,一个整数,表示要查看的记录的索引,以及一个字段名称。field 参数支持“table.field”语法以处理来自连接的结果。此函数可能最好用一个完整的示例来说明

    <?
      $name = "bob";
      $result = msql($database,"select * from table where firstname='$name'");
      $num = msql_numrows($result);
      echo "$num records found!<p>";
      $i=0;
      while($i<$num);
        echo msql_result($result,$i,"fullname");
        echo "<br>";
        echo msql_result($result,$i,"address");
        echo "<br>";
        $i++;
      endwhile;
    >

以上脚本连接到本地机器上的 mSQL 引擎,将name 变量设置为bob,并发送一个查询,该查询要求从firstname 字段设置为bob 的表中获取所有字段。然后它显示找到的记录数,然后循环遍历每个找到的记录,并显示每个记录的fullnameaddress 字段。如您所见,在打印的字段周围添加 HTML 标记以以表格或任何所需的方式格式化结果将是微不足道的。请注意,没有 msql_connect() 调用。只有在需要连接到远程数据库时才需要调用 msql_connect。

此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。

msql_TableName($result,$i)

msql_TableName 接受 msql_ListTables() 函数返回的结果指针以及一个整数索引,并返回一个表的名称。可以使用 msql_NumRows() 函数来确定结果指针中的表数。一个示例是

    <?
      $result = msql_listtables("dbname");
      $i=0;
      while($i <  msql_numrows($result));
        $tb_names[$i]=msql_tablename($result, $i);
        echo $tb_names[$i];
        echo "<BR>";
        $i++;
      endwhile;
    >

此功能仅在 PHP 中启用了 mSQL 支持的情况下才可用。
$result = mysql($database,$query)

mysql 发送一个 mysql 查询。参数是数据库名称和查询字符串。即 <?mysql("MyDatabase" , "select * from table")>。此函数的返回值是结果标识符,用于从其他 mysql_ 函数访问结果。结果标识符是一个正整数。当没有创建结果标识符时,该函数返回 0。对于不返回任何内容的任何查询,情况都是如此,例如createupdatedropinsertdelete。如果发生错误,该函数将返回 -1。描述错误的字符串将放在 $phperrmsg 中,除非该函数被调用为 @mysql(),否则该错误字符串也将被打印出来。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_affected_rows()

mysql_affected_rows() 返回最后一个 INSERT、UPDATE 或 DELETE 查询影响的行数。

mysql_close()

mysql_Close 关闭与 mysql 守护进程的套接字连接(如果存在打开的连接)。

mysql_connect($hostname [,username [,password]])

mysql_Connect 指定 mysql 数据库引擎所在的主机名或 IP。这等同于 mysql C API 中的 mysqlConnect() 函数。此函数与 C API 等效函数之间的一个区别是,如果未调用该函数,则在第一次调用 mysql() 函数时默认连接到本地主机。并且,不需要 mysql_close 函数,因为一次只能有一个连接处于活动状态。如果在一个文件中第二次调用 mysql_connect(),则与第一个主机的连接将自动关闭。

可以提供可选的用户名和密码。请注意,当 PHP 编译为在 安全模式 下运行时,用户名必须与正在处理的文件的所有者相同,或者与 httpd 进程的所有者相同(通常是 nobody)。任何其他用户名都将失败。

要明确连接到本地主机上的 mysql 守护进程,请使用:<?mysql_connect("localhost")>
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_CreateDB($database)

mysql_CreateDB 创建给定的数据库。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_dbName($result,$i)

mysql_dbName 返回存储在 mysql_ListDbs() 函数返回的结果指针的$i 位置的数据库名称。可以使用 mysql_NumRows() 函数来确定有多少个数据库名称可用。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_DropDB($database)

mysql_DropDB 删除给定的 mysql 数据库。谨慎使用,因为数据库中的所有数据都将丢失。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_FieldFlags($result,$i)

mysql_FieldFlags 返回指定字段的字段标志。目前,这可以是“非空”、“主键”、“两者的组合”或“” (空字符串)。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_FieldLen($result,$i)

mysql_FieldLen 返回指定字段的长度。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_FieldName($result,$i)

mysql_FieldName 返回指定字段的名称。该函数的参数是结果标识符和字段索引。例如,mysql_FieldName($result,2); 将返回与结果标识符关联的结果中第二个字段的名称。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_FieldType($result,$i)

mysql_FieldType 类似于 mysql_FieldName() 函数。参数相同,但返回字段类型。这将是“int”、“char” 或“real” 之一。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_FreeResult($result)

只有在担心脚本运行时使用过多内存时才需要调用 mysql_FreeResult。当脚本完成时,所有结果内存将自动释放。但是,如果您确定在脚本中不再需要结果数据,则可以将结果标识符作为参数调用 mysql_freeresult,并且关联的结果内存将被释放。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_insert_id()

mysql_insert_id() 返回为 AUTO_INCREMENT 字段生成的 ID。此函数不接受任何参数。它将返回由执行的最后一个 INSERT 查询返回的自动生成的 ID。

$result = mysql_ListDBs()

mysql_ListDBs 将返回一个包含当前 mysql 守护进程可用的数据库的结果指针。使用 mysql_dbName() 函数来遍历此结果指针。
此函数仅在 PHP 中启用 mysql 支持时才可用。

$result = mysql_Listfields($database,$tablename)

mysql_listfields 检索有关给定表名的信息。参数是数据库名称和表名。返回一个结果指针,可以使用它与 mysql_fieldflags、mysql_fieldlen、mysql_fieldname、mysql_fieldtype。结果标识符是一个正整数。如果发生错误,该函数返回 -1。描述错误的字符串将放在 $phperrmsg 中,除非该函数被调用为 @mysql(),否则该错误字符串也将被打印出来。
此函数仅在 PHP 中启用 mysql 支持时才可用。

$result = mysql_ListTables($database)

mysql_ListTables 接受数据库名称和结果指针,非常类似于 mysql() 函数。应使用 mysql_TableName() 函数从结果指针中提取实际的表名。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_NumFields($result)

mysql_NumFields 返回结果中的字段数。参数是 mysql() 函数返回的结果标识符。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_NumRows($result)

mysql_NumRows 只是返回结果中的行数。参数是 mysql() 函数返回的结果标识符。
此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_Result($result,$i,field)

mysql_Result 显示返回记录中的字段。参数是 mysql() 函数返回的结果标识符、一个整数,它是要查看的记录的索引,以及一个字段名称。字段参数支持“table.field” 语法来处理来自联接的结果。mSQL 1.0 和 mysql 之间的一个区别是,mysql 支持可以对结果数据进行操作的函数。这些函数可以在此函数中应用。此函数最好通过一个完整的示例来说明

    <?
      $name = "bob";
      $result = mysql($database,"select * from table where firstname='$name'");
      $num = mysql_numrows($result);
      echo "$num records found!<p>";
      $i=0;
      while($i<$num);
        echo mysql_result($result,$i,"lcase(fullname)");
        echo "<br>";
        echo mysql_result($result,$i,"address");
        echo "<br>";
        $i++;
      endwhile;
    >

以上脚本连接到本地机器上的 mysql 引擎,将name 变量设置为bob,并发送一个查询,该查询要求从firstname 字段设置为bob 的表中获取所有字段。然后它显示找到的记录数,然后循环遍历每个找到的记录,并显示每个记录的fullnameaddress 字段。result 函数中的 lcase() 调用将返回的字符串更改为小写。有关可以应用于结果数据的完整函数集,请参阅您的 mysql 文档。如您所见,在打印的字段周围添加 HTML 标记以以表格或任何所需的方式格式化结果将是微不足道的。请注意,没有 mysql_connect() 调用。只有在需要连接到远程数据库时才需要调用 mysql_connect。

此函数仅在 PHP 中启用 mysql 支持时才可用。

mysql_TableName($result,$i)

mysql_TableName 接受 mysql_ListTables() 函数返回的结果指针以及一个整数索引,并返回一个表的名称。可以使用 mysql_NumRows() 函数来确定结果指针中的表数。一个示例是

    <?
      $result = mysql_listtables("dbname");
      $i=0;
      while($i <  mysql_numrows($result));
        $tb_names[$i]=mysql_tablename($result, $i);
        echo $tb_names[$i];
        echo "<BR>";
        $i++;
      endwhile;
    >

此函数仅在 PHP 中启用 mysql 支持时才可用。

Next 将内部数组指针移动到数组中的下一项。当使用非索引方法($array[])访问数组时,这会自动发生。该函数返回新项目的 value。此函数可用于将指针向前移动,而不必显式访问数组。一种用法是遍历关联数组,只打印出数组的键,而不打印实际内容。

    <?
      Reset($array);
      $i=0;
      while($i < count($array));
        echo key($array);
        next($array);
        $i++;
      endwhile;
    >
OctDec(octal_number)

OctDec 将八进制数转换为十进制数。另请参阅 DecOct()

openDir(directory)

openDir 打开指定的目录并将一个内部指针放置到目录的开头。使用 readDir 函数读取目录条目,并且应使用 closeDir 函数关闭打开的目录。

OpenLog(ident,options,facility)

OpenLog() 初始化系统以进行进一步的 Syslog() 调用。有关详细信息,请参阅 openlog(3) UNIX 手册页。另请参阅 InitSyslog()Syslog()CloseLog()

Ora_Bind(cursor_ind, php_variable_name, sql_variable_name, size)
Ora_Bind() 执行 PHP 变量与 Oracle 变量的绑定。

函数参数为
cursor_id - 用于 _解析_ 的 SQL 查询或 PL/SQL 块的 Oracle 游标 ID;
php_variable_name - PHP 脚本中的变量名称,不带前导“$”
sql_variable_name - SQL 中的变量名称,带前导冒号
size - 绑定时要考虑的最大字节数

注意事项
1) PHP 变量应该用至少size 字节长度的字符串初始化,即使它是仅返回的变量。
2) Ora_Bind() 应该在 Ora_Parse 之后和 Ora_Exec 之前使用。在重新解析 SQL 语句的情况下,所有使用的变量都必须重新绑定。

Ora_Bind() 在成功时返回 0,在失败时返回 -1。

有一个 Ora_Bind() 使用示例

        /* This is the PHP variable to be bound */
        $rc  = "12345";

        /* This is the SQL query. */
        $query = "SELECT * FROM my_table where my_index = :indiana";

        ........

        if (Ora_Parse($cursor, $query) < 0) {
            echo("Parse failed!\n"
            Ora_Logoff($conn);
            exit;
        }

        if (Ora_Bind($cursor, "rc", ":indiana", strlen($rc)) < 0) {
            echo("Binding failed!\n"
            Ora_Logoff($conn);
            exit;
        }

        /* Execute the SQL statement associated with $cursor and
        prepare storage for select-list items. */
        $ncols = Ora_Exec($cursor);

        ......

Ora_Close(conn_ind)
Ora_Close() 关闭由 conn_ind 标识的 Oracle 连接。成功时返回 0,失败时返回 -1。
Ora_Commit(conn_ind)
conn_ind 上提交当前事务。当前事务从 Ora_Logon() 调用或从最后一个 Ora_Commit() 或 Ora_Rollback() 开始,持续到发出 Ora_Commit()、Ora_Rollback()Ora_Logoff() 调用为止。Ora_Commit() 在失败时返回 -1(以及错误消息)。
Ora_CommitOff(conn_ind)
Ora_CommitOff() 在 Oracle 连接 conn_ind 上关闭自动提交(每个 SQL 数据操作语句的自动提交)。
Ora_CommitOn(conn_ind)
Ora_CommitOff() 在 Oracle 连接 conn_ind 上打开自动提交(每个 SQL 数据操作语句的自动提交)。
Ora_Exec(cursor_ind)
Ora_Exec() 执行与 cursor_ind 关联的 SQL 语句并为 select 列表项准备存储空间。返回值是选择列数,或者在错误时为 -1。
Ora_Fetch(cursor_ind)
Ora_Fetch() 从数据库中检索一行。如果检索到一列,则返回 1;如果没有更多列要检索,则返回 0;或者在错误时返回 -1。
Ora_GetColumn(cursor_ind, column)
Ora_GetColumn() 检索返回行中单个列的数据。必须先调用 Ora_Fetch(),然后才能调用 Ora_GetColumn()。
Ora_Logoff(conn_ind)
Ora_Logoff() 断开属于 conn_ind 的登录数据区的连接并释放使用的 Oracle 资源。
Ora_Logon(userid, password)
Ora_Logon() 在 PHP 和 Oracle 数据库之间建立连接,使用给定的用户 ID 和密码。成功时返回 0,失败时返回 -1。
Ora_Open(conn_ind)
Ora_Open() 在 Oracle 中打开一个游标,该游标维护有关 SQL 语句处理的状态信息。返回游标索引,或者在错误时返回 -1。
Ora_Parse(cursor_ind, sql_statement [, defer])
Ora_Parse() 解析 SQL 语句或 PL/SQL 块,并将其与游标关联。可选的第三个参数可以设置为 1 以延迟解析。成功时返回 0,或者在错误时返回 -1。
Ora_Rollback(cursor_ind)
Ora_Rollback() 回滚当前事务。有关当前事务的定义,请参阅 Ora_Commit()
Ord(arg)

Ord 返回 arg 的第一个字符的 ASCII 值。

Parse_Str(arg)

Parse_str 接受与普通 URL 编码字符串相同的字符串,并提取变量及其值。
例如。

    <? parse_str("a[]=hello+world&a[]=second+variable");
        echo $a[],"<br>";
        echo $a[],"<br>";
    >

produces

hello world
second variable
PassThru(command_string [,return_var])

PassThru() 函数类似于 Exec() 函数,它执行一个 Unix 命令。如果 return_var 参数存在,则 Unix 命令的返回状态将被放置在此处。当 Unix 命令的输出是二进制数据需要直接传回浏览器时,此命令应代替 Exec 或 System 使用。一个常见用途是执行类似于 pbmplus 实用程序的东西,它可以输出直接的图像流。通过将内容类型设置为 image/gif 然后调用 pbmplus 程序输出 gif,你可以创建输出图像的 PHP/FI 脚本。

pclose(fp)

Pclose 关闭使用 popen() 函数打开的管道。

pg_Close(connection_id)

pg_Close 将关闭与给定连接标识符关联的 Postgres 数据库的连接。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

$connection = pg_Connect(host, port, options, tty, dbname)

pg_Connect 打开与 Postgres 数据库的连接。每个参数都应该是带引号的字符串,包括端口号。options 和 tty 参数是可选的,可以为空字符串。此函数返回 connection_id。此标识符是其他 Postgres 函数所需的。你可以同时打开多个连接。此函数在错误时将返回 0

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_DBname(connection_id)

pg_DBname 将返回给定 Postgres 连接标识符连接到的数据库的名称。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_ErrorMessage(connection_id)

如果在存在有效连接的最后一个数据库操作上发生了错误,此函数将返回一个包含后端服务器生成的错误消息的字符串。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

$result = pg_Exec(connection_id, query_string)

pg_Exec 将发送 SQL 语句到由 connection_id 指定的 Postgres 数据库。connection_id 必须是由 pg_Connect 返回的有效标识符。此函数的返回值是用于访问其他 Postgres 函数结果的标识符。此函数在错误时将返回 0。当命令正确执行但预计不会返回数据(例如插入或更新命令)时,它将返回 1。请注意,不返回数据的 select 仍然会返回大于 1 的有效结果。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_FieldName(result_id, field_number)

pg_FieldName 将返回在给定 Postgres 结果标识符中占用给定列号的字段的名称。字段编号从 0 开始。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_FieldPrtLen(result_id, row_number, field_name)

pg_FieldPrtLen 将返回 Postgres 结果中特定值的实际打印长度(字符数)。行编号从 0 开始。此函数在错误时将返回 -1

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_FieldNum(result_id, field_name)

pg_FieldNum 将返回在给定 Postgres 结果标识符中对应于命名字段的列槽号。字段编号从 0 开始。此函数在错误时将返回 -1

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_FieldSize(result_id, field_name)

pg_FieldSize 将返回给定 Postgres 结果中命名字段的内部存储大小(以字节为单位)。字段大小为 0 表示可变长度字段。此函数在错误时将返回 -1

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_FieldType(result_id, field_number)

pg_FieldType 将返回一个字符串,其中包含给定 Postgres 结果标识符中给定字段的类型名称。字段编号从 0 开始。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_FreeResult(result_id)

只有在担心脚本运行时使用太多内存的情况下才需要调用 pg_FreeResult。当脚本完成时,所有结果内存将自动释放。但是,如果你确定在脚本中不再需要结果数据,可以调用 pg_freeresult 并将结果标识符作为参数,关联的结果内存将被释放。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_GetLastOid()

pg_GetLastOid 可用于检索分配给插入元组的 Oid,如果通过 pg_Exec 发送的最后一个命令是 SQL Insert。如果存在有效的 Oid,此函数将返回一个正整数。如果发生了错误或通过 pg_Exec 发送的最后一个命令不是 Insert,它将返回 -1

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_Host(connection_id)

pg_Host 将返回给定 Postgres 连接标识符连接到的主机名。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_NumFields(result_id)

pg_NumFields 将返回 Postgres 结果中的字段(列)数。参数是 pg_Exec 返回的有效结果标识符。此函数在错误时将返回 -1

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_NumRows(result_id)

pg_NumRows 将返回 Postgres 结果中的行数。参数是 pg_Exec 返回的有效结果标识符。此函数在错误时将返回 -1

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_Options(connection_id)

pg_Options 将返回一个字符串,其中包含在给定 Postgres 连接标识符上指定的选项。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_Port(connection_id)

pg_Port 将返回给定 Postgres 连接标识符连接到的端口号。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_Result(result_id, row_number, field name/index)

pg_Result 将返回由 pg_Exec 生成的结果标识符中的值。row_number 和字段名称指定要返回的结果表中的哪个单元格。行编号从 0 开始。你可以使用字段索引作为未加引号的数字,而不是命名字段。字段索引从 0 开始。

Postgres 有许多内置类型,这里只直接支持基本类型。所有形式的整数、布尔值和 oid 类型都作为整数返回。所有形式的浮点数和实数类型都作为双精度值返回。所有其他类型(包括数组)都作为字符串返回,格式与你在 'monitor' 或 'psql' 程序中看到的默认 Postgres 格式相同。

计划在以后的日期支持从 Postgres 结果返回数值和字符串数据的 PHP 数组。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

pg_tty(connection_id)

pg_tty 将返回服务器端调试输出发送到的给定 Postgres 连接标识符上的 tty 名称。

此功能仅在 PHP 中启用 Postgres 支持后才可用。

phpInfo()

phpInfo 打印与将“?info”添加到 PHP/FI 解析的 URL 或单独运行 php.cgi 二进制文件时获得的页面相同。它对于调试 Apache 模块版本中的脚本特别有用,因为它显示了许多有用的内部数据。

phpVersion()

phpVersion 返回当前运行的 PHP/FI 的版本号。

fp = popen(command,mode)

Popen 打开一个到命令的管道并返回一个文件指针索引。此文件指针索引可由 fgetsfputsfclose 使用。参数是要运行的命令和模式。模式可以是“r”表示读取或“w”表示写入。有关详细信息,请参阅 UNIX C 库 popen 手册页。使用 popen() 打开的任何文件都应使用 pclose() 函数关闭。

pos(var)

Pos() 函数返回数组元素在该数组中的数字位置。这对于普通数组来说不是很有用,但对于关联数组来说它可能很方便。

pow(x,y)

计算 x 的 y 次方。另请参见 Exp()

Prev 将给定变量的内部数组指针移动到数组中的前一项。如果已经在列表开头,则指针将指向第一项。该函数返回新项目的价值。此函数对于以相反顺序遍历关联数组很有用。请参阅 End() 定义中的示例。另请参见 Next()

PutEnv(string)

PutEnv 将给定字符串放入环境中。不是特别有用,因为当 PHP 完成页面时,本地环境变量会被清除,但在某些情况下,如果从 PHP 脚本中调用的其他东西检查环境变量,它会很有用。例如,如果你想运行多个 mSQL 守护进程,则需要使用 PutEnv 在不同的套接字之间来回切换。

QuoteMeta(arg)

QuoteMeta 返回一个字符串,该字符串由 arg 组成,其中任何正则表达式特殊字符都用反斜杠转义。

Rand()

Rand 返回 0 到 RANDMAX 之间的随机数。请记住在调用 rand() 之前,使用对 srand() 的调用来播种随机数生成器。你只需要播种随机数生成器一次。可以使用 getRandMax 函数确定 RANDMAX。通常,通过简单地对结果使用模运算符来选择一个特定范围。

readDir()

readDir 从当前打开的目录结构中读取下一项。读取一项后,指针将前进到目录中的下一项,对该函数的下次调用将返回目录中的下一项。使用 openDir 函数打开目录,然后调用此函数。

ReadFile(filename)

$size = ReadFile(Filename) - 读取文件 filename 并直接输出它。它返回实际读取的字节数。它不同于 File() 命令,因为它不会将文件存储在内存中,并且可以安全用于二进制文件。此函数通常用于可能在其他情况下执行 PassThru("cat filename") 的地方。使用 ReadFile 效率更高。

ReadLink(path)
ReadLink 与 readlink C 函数相同,并返回符号链接 path 的内容,如果发生错误,则返回 -1。另请参见 LinkInfo
reg_Match(expr,arg[,regs])

此函数已被 ereg() 函数取代。但是,它仍然可用于向后兼容。
如果在参数字符串中匹配正则表达式,reg_Match 将返回非零值。例如,条件 <?if (reg_match("^This.*", "This is an example string")> 将为真,因为 "^This.*" 表达式表示在字符串开头匹配单词 This,然后匹配任何后续字符。如果 regs 参数存在,则匹配寄存器将填充到由 regs 参数命名的数组中的位置 0-10。寄存器 0 将始终包含完全匹配的字符串。有关正则表达式的更多信息,请参阅本文档的 正则表达式部分

reg_replace(expr,replace,arg)

此函数已被 ereg_replace() 函数取代。但是,它仍然可用于向后兼容。
reg_Replace 扫描整个参数字符串并将字符串中由给定表达式匹配的任何部分替换为替换字符串。例如,在字符串 "This is an example string" 中,我们可以使用命令 reg_replace(" ","-","This is an example string") 非常轻松地将每个空格替换为连字符。有关正则表达式的更多信息,请参阅本文档的 正则表达式部分

reg_Search(expr,arg[,regs])

此函数已被 ereg() 函数取代。但是,它仍然可用于向后兼容。
reg_Search 将扫描整个参数字符串,以查找与给定正则表达式匹配的任何内容。如果找到匹配项,它将返回从匹配项开始位置开始的字符串部分。如果未找到匹配项,则返回零长度字符串。如果 regs 参数存在,则匹配寄存器将填充到由 regs 参数命名的数组中的位置 0-10。寄存器 0 将始终被分配完全匹配的字符串。有关正则表达式的更多信息,请参阅本文档的 正则表达式部分

Rename(old,new)

将文件名 old 重命名为 new。类似于 Unix C rename() 函数。

Reset(variable)

重置将给定数组变量的内部数组指针移动到数组的第一个项目,并返回该项目的 value。这对于遍历关联数组和非索引数组很有用。另请参见 End()Next()。以下示例遍历关联数组

    <?
      Reset($array);
      $i=0;
      while($i < count($array));
        echo $array[]; /* pointer automatically moves ahead one */
        $i++;
      endwhile;
    >
return(value)

Return 退出当前函数调用并将指定 value 返回给调用者。有关更多信息,请参见 用户定义函数 部分。

rewind($fd)

rewind() 重置由 $fd 参数标识的文件指针,该参数是 fopen() 调用的返回值。文件指针定位在文件的开头。另请参见 ftell()fseek()

rewindDir()

rewindDir 将当前目录指针移回目录的开头。在调用此函数之前,请使用 openDir 函数打开目录。

RmDir(dir)

RmDir() 删除给定的目录。有关删除常规文件,请参见 Unlink() 函数。

SetCookie(name,value,expire,path,domain,secure)

SetCookie() 定义一个 cookie,该 cookie 将与其他标头信息一起发送。除 name 参数之外的所有参数都是可选的。如果只存在 name 参数,则该名称的 cookie 将从远程客户端删除。您也可以用空字符串 ("") 替换任何参数,以跳过该参数。expire 和 secure 参数是整数,不能用空字符串跳过。请改用零 (0)。expire 参数是一个常规 Unix 时间整数,由 time()mktime() 函数返回。以下是一些示例

    SetCookie("TestCookie","Test Value");
    SetCookie("TestCookie",$value,time()+3600);  /* expire in 1 hour */
    SetCookie("TestCookie",$value,time()+3600,"/~rasmus/",".utoronto.ca",1);

请注意,当您发送 cookie 时,cookie 的 value 部分会自动进行 URL 编码,并且在收到 cookie 时,它会自动解码并分配给与 cookie 名称相同的变量。即,要在脚本中查看测试 cookie 的内容,只需执行以下操作

    echo $TestCookie;
SetErrorReporting(arg)

SetErrorReporting 将当前错误报告状态设置为 arg 的 value。如果非零,则会打印错误,如果为 0,则不会。该函数返回先前的错误报告状态。这是一种比在单个函数前面加上“@”字符更通用的禁用错误报告的方法。有关更多信息,请参见 抑制函数调用中的错误 部分。

SetLogging(arg)

SetLogging() 启用或禁用页面的访问统计信息记录。如果 arg 非零,则启用记录,如果为零,则禁用记录。

SetShowInfo(arg)

SetShowInfo() 启用或禁用通过 PHP 加载的所有页面底部的信息页脚。如果 arg 非零,则启用页脚,如果为零,则禁用页脚。

SetType(variable,type)

SetType 设置变量的类型。type 参数是“integer”、“double”或“string”之一。另请参见 GetType() 函数。

shl(n,b)

将 value n 左移 b 位。

shr(n,b)

将 value n 右移 b 位。

Sin(arg)

Sin 返回 arg 的正弦值(以弧度表示)。另请参见 Cos()Tan()

Sleep(secs)

Sleep 将延迟 secs 秒。类似于 Unix C sleep() 函数。另请参见 USleep() 函数。

Solid_Close(connection_id)

Solid_Close 将关闭与给定连接标识符关联的 Solid 服务器的连接。

此函数仅在 PHP 中启用 Solid 支持后才可用。

$connection = Solid_Connect(数据源名称, 用户名, 密码)

Solid_Connect 打开与 Solid 服务器的连接。每个参数都应是一个带引号的字符串。第一个参数(数据源名称)可以是空字符串,导致连接到 localhost 上的默认服务器。此函数返回 connection_id。其他 Solid 函数需要此标识符。您可以同时打开多个连接。此函数在出错时将返回 0

此函数仅在 PHP 中启用 Solid 支持后才可用。

$result = Solid_Exec(connection_id, 查询字符串)

Solid_Exec 将 SQL 语句发送到 connection_id 指定的 Solid 服务器。connection_id 必须是由 Solid_Connect 返回的有效标识符。此函数的返回值是一个标识符,用于通过其他 Solid 函数访问结果。此函数在出错时将返回 0。当命令正确执行但预期没有返回数据(例如 insert 或 update 命令)时,它将返回 1。请注意,不返回数据的 select 仍然会返回一个大于 1 的有效结果。

此函数仅在 PHP 中启用 Solid 支持后才可用。

Solid_FetchRow(result_id)

Solid_FetchRow 获取由 Solid_Exec 返回的数据行。调用 Solid_FetchRow 后,可以使用 Solid_Result 访问该行的字段。每次调用 Solid_FetchRow 时,都可以通过 Solid_Result 访问新行。如果 Solid_FetchRow 成功(存在新行),则返回 1,如果不再有行,Solid_FetchRow 将返回 0。Solid_FetchRow 的返回值可以用作 while 循环的条件。

此函数仅在 PHP 中启用 Solid 支持后才可用。

Solid_FieldName(result_id, 字段编号)

Solid_FieldName 将返回在给定 Solid 结果标识符中占据给定列号的字段的名称。字段编号从 0 开始。

此函数仅在 PHP 中启用 Solid 支持后才可用。

Solid_FieldNum(result_id, 字段名称)

Solid_FieldNum 将返回在给定 Solid 结果标识符中对应于命名字段的列槽的编号。字段编号从 0 开始。此函数在出错时将返回 -1

此函数仅在 PHP 中启用 Solid 支持后才可用。

Solid_FreeResult(result_id)

仅当您担心在脚本运行时使用过多的内存时,才需要调用 Solid_FreeResult。所有结果内存将在脚本结束后自动释放。但是,如果您确定在脚本中不再需要结果数据,则可以使用结果标识符作为参数调用 Solid_FreeResult,并且关联的结果内存将被释放。

此函数仅在 PHP 中启用 Solid 支持后才可用。

Solid_NumFields(result_id)

Solid_NumFields 将返回 Solid 结果中的字段(列)数量。参数是由 Solid_Exec 返回的有效结果标识符。此函数在出错时将返回 -1

此函数仅在 PHP 中启用 Solid 支持后才可用。

Solid_NumRows(result_id)

Solid_NumRows 将返回 Solid 结果中的行数。参数是由 Solid_Exec 返回的有效结果标识符。此函数在出错时将返回 -1重大警告:SOLID SQL 服务器使用 ODBC 作为其主要(也是唯一)接口。SolidNumRows() 在底层使用 SQLRowCount 来获取行数。SQLRowCount 遵循了微软一贯的传统,即不必要的限制、奇怪的异常和其他奇怪的东西。这意味着该函数只会返回 INSERT、UPDATE 或 DELETE 子句影响的行数。没有 SELECT!作为解决方法,您可以尝试 SQL 的 count() 语句或计算行数的 while 循环。如果您需要 Solid_NumRows() 来确定 SELECT 子句后要读取多少记录,请尝试检查来自 Solid_FetchRow() 的返回值。因此,代替

     $num = Solid_NumRows();
    $i=0;
    while ($i < $num) {
        /* print results... */
        $i++;
    }

您可以尝试

    while(Solid_FetchRow($result)) {
        /* print results... */
    }

此函数仅在 PHP 中启用 Solid 支持后才可用。

Solid_Result(result_id, 字段名称/索引)

Solid_Result 将从 Solid_Exec 生成的结果标识符返回 value。字段名称指定要返回的行中的哪个单元格。您可以使用字段索引作为未加引号的数字,而不是命名字段。字段索引从 0 开始。

此函数仅在 PHP 中启用 Solid 支持后才可用。

Sort(array)

Sort 用于按升序对 PHP 数组进行排序。要按降序排序,请使用 RSort() 函数。它理解三种变量类型,如果数组包含字符串,则按字母顺序排序,如果数组包含数字,则按数字顺序排序。对于包含混合类型的数组,数组中的第一个类型将指定排序方法。请注意,如果要排序关联数组,则应使用 ASort() 函数。

Soundex(string)

此函数接受一个字符串参数并返回该字符串的 soundex 键。Soundex 键具有这样的属性,即发音相似的单词会生成相同的 soundex 键,因此可以用于简化数据库中的搜索,在这些数据库中您知道发音但不知道拼写。此 soundex 函数返回一个 4 个字符长的字符串,以一个字母开头。
此特定 soundex 函数是由 Donald Knuth 在“计算机程序设计艺术,第 3 卷:排序与查找”,Addison-Wesley (1973),第 391-392 页中描述的。
示例

   Euler and Ellery map to E460
   Gauss and Ghosh map to G200
   Hilbert and Heilbronn map to H416
   Knuth and Kant map to K530
   Lloyd and Ladd map to L300
   Lukasiewicz and Lissajous map to L222

Sprintf(format,arg [,arg,arg,arg,arg])

Sprintf 返回由 format 参数和 arg 定义的格式化输出创建的字符串。它类似于 echo 命令的格式化版本,不同之处在于它只返回字符串,而 echo 显示字符串。它也类似于同名的 C 函数。区别在于此版本不接受超过 5 个 arg 参数。如果您需要将超过 5 个参数格式化为单个字符串,只需为每个参数组多次调用 sprintf()。请注意,参数的类型不会影响输出。参数类型会自动转换为与格式字符串中指定的类型匹配的类型。

Sqrt(arg)

Sqrt 返回 arg 的平方根。

Srand(integer)

Srand 为随机数生成器播种。此函数接受任何整数作为参数。选择种子 value 的一种方法是使用 date 函数来获取当前的秒数(从分钟开始)。请注意,此函数 不返回值!此函数只是为随后对 rand() 函数的调用播种随机数生成器。例如

   <?srand(date("s"))>
strchr(string,arg)

strchr 和 strstr 实际上是相同的函数。它们可以互换使用,并且为了完整起见,两者都包括在内。它们将返回从找到给定子字符串的位置开始的字符串参数的一部分。例如,在上面的字符串“This is an example string”中,调用:<?echo strchr($string,"an ")> 将返回字符串:"an example string"

strtr(input,set1,set2)
strtr() 将 "string" 中位于 "set1" 中的每个字符转换为 "set2" 中的对应字符。不在 set1 中的字符将保持不变。当字符在 "set1" 中出现多次,而 "set2" 中的对应字符并不都相同时,只使用最后一个字符。当 "set1" 或 "set2" 中的一个比另一个长时,较长的 "set?" 将被截断为较短的 "set?" 的长度。
StripSlashes(arg)

StripSlashes 取消转义字符串参数。另请参见 AddSlashes()

strlen(string)

strlen 返回字符串的长度。

strrchr(string,arg)

strrchr 将从参数字符串的末尾开始搜索单个字符,并向后工作。如果找到该字符,它将返回从搜索字符开始的字符串,如果没有找到,它将返回空字符串。

strstr(string,arg)

strstr 和 strchr 实际上是相同的函数。它们可以互换使用,并且为了完整起见,两者都包括在内。它们将返回从找到给定子字符串的位置开始的字符串参数的一部分。例如,在上面的字符串“This is an example string”中,调用:<?echo strstr($string,"an ")> 将返回字符串:"an example string"

strtok(string,arg)

strtok 用于对字符串进行标记。也就是说,如果您有一个像 "This is an example string" 这样的字符串,您可以使用空格字符作为标记将此字符串标记为其各个单词。您将使用以下脚本代码

   <?
          $string = "This is an example string";
          $tok = strtok($string," ");
          while($tok);
                  echo "Word=$tok<br>";
                  $tok = strtok(" ");
          endwhile;
        >

请注意,只有第一次调用 strtok 才会使用字符串参数。每次后续调用 strtok 只需要使用令牌,因为它会跟踪它在当前字符串中的位置。要重新开始或对新字符串进行标记,只需再次使用字符串参数调用 strtok 以初始化它。请注意,您可以在 arg 参数中放置多个令牌。当找到参数中的任何一个字符时,字符串将被标记。

strtolower(string)

strtolower 将字符串参数转换为全小写字符。

strtoupper(string)

strtoupper 将字符串参数转换为全大写字符。

strval(variable)

strval 返回变量的字符串值。另请参见 intval()doubleval() 函数。

substr(string, start, length)

substr 返回给定字符串的一部分。起始位置由 start 参数给出。字符串中的第一个位置是位置 0。length 参数指定从起始位置返回的字符数。

sybSQL_CheckConnect()

如果已建立与数据库的连接,则此函数返回 1,否则返回 0。

sybSQL_DBuse(database)

此函数对指定数据库发出 Sybase Transact-SQL use 命令。该函数的唯一参数是要使用的数据库的名称。例如:sybsql_dbuse("pubs2");

该函数在成功时返回 1,在失败时返回 0。

sybSQL_Connect()

此函数打开与 Sybase 服务器的网络连接。此函数依赖于几个环境变量,这些变量必须在调用此函数之前由调用者设置。

环境变量是

DSQUERY - Sybase 服务器的别名,如 Sybase 接口文件中定义。
DBUSER - 以此用户身份连接到 Sybase 服务器。
DBPW - 用户的密码。

这些变量可以通过多种方式设置。如果 php/fi 作为 CGI 程序运行,则可以使用 shell 包装器来设置这些变量,或者您可以使用内置的 PHP/FI 函数 putenv() 在 HTML 页面中直接设置这些变量。您也可以从表单输入中获取值,而不是直接在 putenv() 中使用这些值。这些变量可以在文件中定义,并使用 PHP/FI include 语句包含在 html 文件中。

该函数在成功时返回 1,在失败时返回 0。

sybSQL_Exit()

此函数强制关闭 Sybase 连接。如果没有调用,连接将在 PHP 页面完全解析后自动关闭,因此调用此函数是可选的。

sybSQL_Fieldname(index)

此函数返回常规结果列的字段名。该函数的参数是字段索引。例如:sybsql_fieldname(0);。注意:字段索引从 0 开始。

如果结果列没有名称,则该函数返回一个空字符串 ("").

sybSQL_GetField(field)

此函数获取当前结果行中特定列的值。该函数的唯一参数是指定字段的字符串。例如:$value=sybsql_getfield("@10"); 注意:必须在调用此函数之前调用 sybsql_nextrow()。如果需要递增行指针,则必须调用 sybsql_nextrow(),因为此函数只读取行缓冲区中的当前行。

如果指定的列有值,则该函数返回值作为字符串,否则该函数返回一个空字符串 ("").

sybSQL_IsRow()

此函数指示当前 SQL 命令是否返回任何行。

如果 SQL 命令返回任何行,则该函数返回 1,如果命令没有返回任何行,则返回 0。

sybSQL_NextRow()

此函数将行指针递增到下一个结果行。

只要有行要读取,该函数就会返回 1。如果没有要读取的行或发生错误,该函数就会返回 0。

sybSQL_NumFields()

此函数返回当前结果行中的字段数。

该函数返回当前结果行中的行数。如果没有字段,该函数返回 0。

sybSQL_NumRows()

此函数返回当前结果缓冲区中的行数。注意:当调用此函数时,它会立即定位到第一行,然后它会调用 dbnextrow() 直到没有更多行,并递增内部计数器以计算结果缓冲区中的行数。然后它指向最前面的行。因此,在调用此函数后,行计数器始终指向最前面的行。这很糟糕,但我目前不知道其他方法。

如果结果缓冲区中没有行,该函数将返回 0。

sybSQL_Query()

此函数向服务器提交 Sybase SQL 查询请求。该函数的唯一参数是查询字符串。例如:$rc=sybsql_query("select * from authors");

如果查询成功传递,则该函数返回 1,如果请求失败,则返回 0。

sybSQL_Result(string)

此函数打印当前结果行中的特定字段。该函数的唯一参数是一个字符串,其中包含有关要打印的字段的信息。字段用 @ 后跟一个数字来指定。例如,@0 表示第一行,@10 表示第 11 行。注意,字段号从 0 开始。该函数最好通过一个完整的示例来说明

<?
    /*
    ** assuming all the necessary variables for
    ** connection is already set. please note, NO error checking is
    ** done. You should always check return code of a function.
    */

    /* connect */
    $rc=sybsql_connect();

    /* use the pub2 database */
    $rc=sybsql_dbuse("pubs2");

    /* send the SQL request */
    $rc=sybsql_query("select * from authors");
    $i=0;

    /* find the no of rows returned */
    $nrows=sybsql_numrows();

    /* start table */
    echo "<table border>\n";
    /*
    ** print only first and 2nd field
    */
    while($i<$nrows) {
        sybsql_result("<tr><td>@0</td>@1</td></tr>\n");
        $i++;
    }
    /* end table */
    echo "</table>\n";
>

上面的示例使用 HTML 表格来格式化输出。当然,可以使用任何其他有效的 HTML 标签。

sybSQL_Result_All()

此函数打印当前结果缓冲区中的所有行。结果以硬编码的 HTML 表格格式打印。注意,此函数不应该在循环中调用。如果输出中包含任何列标题,该函数将打印列的名称。

sybSQL_Seek(row)

此函数将请求的行号设置为行缓冲区中的当前行。该函数的唯一参数是行号。例如:$rc=sybsql_seek(10); 注意,行号从 0 开始。

如果查找成功,则该函数返回 1,如果查找失败,则返回 0。当当前结果缓冲区中的所有行都被访问后,行指针指向最后一行。如果需要向后移动并访问更多行,则可以使用此函数来实现。

Symlink(target,link)

Symlink() 创建符号链接。请参见 Link() 函数以创建硬链接。

Syslog(level,message)

Syslog() 使用 UNIX 的 syslog(3) 功能将消息记录到系统中。有关更多详细信息,请参见您的 UNIX 手册页。另请参见 InitSyslog()OpenLog()CloseLog()

System(command_string [,return_var])

System 就像 C system() 命令一样,它会执行给定的 unix 命令并输出结果。如果提供了一个变量作为第二个参数,那么执行的 unix 命令的返回状态代码将被写入该变量。注意,如果您要允许来自用户输入的数据传递到此 System 函数,那么您应该使用 EscapeShellCmd() 函数来确保用户无法欺骗系统执行任意命令。如果 PHP 作为 Apache 模块运行,System() 调用还会在每行输出后自动刷新 Apache 输出缓冲区。如果您需要执行命令并将命令的所有数据直接传回,而没有任何干扰,请使用 PassThru() 函数。另请参见 Exec 函数。

Tan(arg)

Sin 返回 arg 的正切值(以弧度为单位)。另请参见 Sin()Cos()

TempNam(path, prefix)

TempNam 返回一个位于 path 指定的目录中的唯一文件名,该文件名以 prefix 给出的文件名前缀开头。它与 Unix C tempnam() 函数相同。

Time()

Time 只返回自 Unix 纪元(1970 年 1 月 1 日 00:00:00)以来的当前本地时间(以秒为单位)。它相当于调用 Date("U")。如果您需要比每秒更高的粒度,请使用 Microtime 函数。

Umask([mask])

Umask(mask) 将 PHP 的 umask 设置为 mask & 0777 并返回旧的 umask。如果 PHP/FI 是 Apache 模块,则 PHP/FI 完成后将恢复 Apache 的旧 umask。mask 必须以 八进制 符号指定,就像 ChMod() 一样。不带参数的 Umask() 只返回当前的 umask。

UniqId()

UniqId 返回一个基于当前时间(以微秒为单位)的前缀唯一标识符。例如,如果您在可能在同一微秒内生成标识符的多个主机上同时生成标识符,则前缀很有用。前缀最多可以有 114 个字符长。

Unlink(filename)

Unlink 删除给定的文件名。类似于 Unix C unlink() 函数。请参见 RmDir() 函数以删除目录。

UnSet($var)

UnSet 取消定义给定的变量。对于数组,整个数组将被清除。也可以取消设置单个数组元素。

UrlDecode(arg)

UrlDecode 解码使用 UrlEncode 函数编码的字符串。在典型的使用中,不需要解码 URL 编码的字符串,因为这些字符串在页面之间传递时会自动解码。但是,为了完整性,包含了此函数。

UrlEncode(arg)

UrlEncode 将 arg 中的任何非 "a-zA-Z0-9_-." 字符编码为 %xx,其中 xx 是它们的十六进制 ASCII 值。将返回编码后的字符串。

USleep(microsecs)

Sleep 将延迟给定的微秒数。类似于 Unix C usleep() 函数。另请参见 Sleep() 函数。

Virtual(filename)

Virtual 是一个 Apache 特定函数,它等效于 mod_include 中的 <!--#include virtual...-->。它执行 Apache 子请求。它对于包含 CGI 脚本或 .shtml 文件,或者您希望通过 Apache 解析的任何其他内容很有用(对于 .phtml 文件,您可能希望使用 <?Include>)。


在 PHP/FI 中添加您自己的内部函数

PHP/FI 提供的函数集可能并不包含您可能需要的特定函数。通过仔细遵循下面描述的步骤,您可以将自己的函数添加到 PHP/FI 中。

在开始修改 PHP/FI 的内部机制之前,您需要获取最新版本的 Bison 的副本。Bison 是 GNU 的 YACC(Yet Another Compiler Compiler)实现。您的操作系统附带的 YACC 可能是也可能不是足够好,但为了确保万无一失,请获取 Bison。您可以在 ftp://prep.ai.mit.edu/pub/gnu 找到它。

您还应该查看 Makefile 并启用调试。只需取消 Makefile 中的 DEBUG 行的注释即可。调试信息的输出文件由 php.h 中的 DEBUG_FILE 指定。默认情况下,它被设置为 /tmp/php.err。您可以根据需要更改它。

您可能还想记住的一件事是,php 以与系统上的 httpd 相同的用户 ID 运行,除非您当然是以设置的 setuid 位运行它,并且此 httpd 用户通常没有对各个目录的写入权限。这意味着如果您执行导致 php 核心转储的操作,您将不会获得核心文件。解决此问题的简单方法是使您保存测试 .html 文件的目录对所有人可写。PHP 会将当前目录更改为它正在读取的 .html 文件的目录,因此如果可以,它会将其核心转储在那里。

在以下步骤中,我们将使用 Time() 函数来说明如何添加函数。

步骤 1 - 定义函数的语法

如果您的函数接受 0 到 6 个参数,则有预定义的语法可用。您可以跳过此步骤。

你的函数的语法定义在 *parse.raw* 文件中。首先要添加一个 token。token 是一个大写关键字,通常与你的函数名称相同。所有 token 都定义在 *parse.raw* 文件的顶部附近。顺序无关紧要。然后你需要构建你自己的 YACC 语法规则。查看现有的规则并找到一个类似于你正在添加的函数的函数。请记住,大多数正常函数都是标准函数,它们从表达式堆栈中读取它们的实参。你的函数很可能属于这一组,在这种情况下,你不需要修改 *parse.raw* 文件。

步骤 2 - 将你的函数添加到词法分析器哈希表

为此,编辑 *lex.c* 并找到文件顶部的哈希表。找到以下行,static cmd_table_t cmd_table[22][30] = {,它定义了哈希表的开头。[22][30] 定义了用于保存哈希表的二维数组的大小。22 是最大函数名称长度加 1,30 指的是任何一个哈希列表中的最大函数数量。如果你超过了这两个限制,只需在这里增加它们即可。

这个哈希表可能被认为是全世界最简单的哈希表。哈希值为要散列的函数名称字符串的长度。因此,对于我们的 *Time()* 示例,我们需要添加一个哈希值为 4 的条目。因此,我们向 4 的哈希列表添加以下行:

      { "time",INTFUNC0,UnixTime },

此条目将字符串映射到 INTFUNC0 token。你可以在 *parse.raw* 中查找 INTFUNC0 token 的语法,你会发现它是一个针对具有 0 个实参的内部函数调用的通用语法。上面引号中的字符串是你将在 .html 文件中用于调用函数的实际字符串。请记住,PHP/FI 函数名称**不**区分大小写。最后的 **UnixTime** 元素是要调用的实际函数。

步骤 3 - 编写你自己的函数

你实际上可以用任何你喜欢的语言编写你的函数,只要它可以通过正常的 C 函数调用约定调用,并且你有一种方法可以创建与系统上的链接器兼容的目标文件或库文件。通常情况下,我们将假设你用 C 编写你的函数。PHP/FI 附带的所有函数都是用 C 编写的。Time() 函数,或者在 PHP 中被称为 UnixTime(),可以在 *date.c* 中找到,如下所示:

void UnixTime(void) {
    char temp[32];

    sprintf(temp,"%ld",(long)time(NULL));
    Push(temp,LNUMBER);
}

注意,该函数是 void。这表示它不返回任何内容。这对你来说可能很令人困惑,因为显然该函数需要以某种方式返回时间。时间是返回的,但不是作为函数的返回值。它被推送到一个称为表达式堆栈的东西上。表达式堆栈只是一个字符串及其相关类型的堆栈。PHP/FI 仅理解三种基本变量类型:STRING、LNUMBER 和 DNUMBER。STRING 是一个字符字符串,LNUMBER 是一个长整数,DNUMBER 是一个 double,或浮点数,值。在本例中,要返回的值是以 Unix 格式表示的时间(自 1970 年 1 月 1 日以来的秒数),因此是一个整数。表达式堆栈只接受字符串,所以我们将长整数用 sprintf 转换为字符串,并将其推送到堆栈上,表示它实际上是一个长整数,使用以下行:Push(temp,LNUMBER);

步骤 4 - 将你的函数原型添加到 php.h

在 *php.h* 文件的下半部分,你会发现 php 中所有函数原型的完整列表。它们按它们所在的目录分组。只需将你的原型添加到此文件中的适当位置即可。对于我们的 Time() 示例,添加以下行:

void UnixTime(void);
步骤 5 - 编译

每次你对 *parse.raw* 文件进行更改时,都要记住重新制作解析器。输入:make parser 来完成此操作。你必须至少拥有 1.25 版本的 Bison 才能制作 PHP 解析器。完成后,通过输入:make 来进行正常编译。

步骤 6 - 向我发送你的添加内容!

如果你想将你的函数添加到下一版 PHP/FI,请将它们发送给我。最好的方法可能是创建一个上下文敏感的 diff。为此,你需要一个干净的未修改发行版的副本。只需对已修改的文件进行一个 diff -c,将它们与原始文件进行比较即可。请不要向我发送 *parse.c* 中更改的 diff,因为该文件是自动生成的。而是向我发送来自 *parse.raw* 的 diff。

Time() 示例说明了添加函数所涉及的步骤。你想要添加的函数很可能比此示例复杂得多。你可能希望能够向你的函数传递实参,并让它以某种方式操作这些实参。你甚至可能希望它以不同的方式调用。这些概念将通过 PHP/FI crypt() 函数来阐明。另请参阅名为 代码黑客笔记 的部分,以获取有关为 PHP/FI 编写代码的更多技术细节。

*parse.raw* 中的 Crypt() 语法

%token CRYPT
        .
        .
        .
    | CRYPT '(' expr ',' expr ')'
        {
            if(GetCurrentState(NULL) || inCase || inElseIf) Crypt(1);
        }
    | CRYPT '(' expr ')'
        {
            if(GetCurrentState(NULL) || inCase || inElseIf) Crypt(0);
        }

这里展示了如何定义一个语法,该语法允许你使用 1 或 2 个实参调用函数。你可以编写不同的函数来处理这两种情况,或者像这里一样简单地发送一个模式参数来指示函数调用的模式。注意,在这种情况下,你不能使用预定义的 INTFUNCn 语法,因为你的函数可以接受可变数量的实参。

另一个方面是展示了如何实际表示函数实参。在大多数情况下,你将希望使用 **expr** 标识符。此标识符表示实参是一个表达式。表达式可以是文字值、函数调用或许多表达式的组合。有关详细信息,请参阅 parse.raw 中表达式的完整 yacc 语法定义。

*lex.c* 中的哈希表条目

      { "crypt",CRYPT,NULL },

注意,在这种情况下,最后一项是 NULL,因为函数调用直接在 *parse.raw* 中处理。如果你使用 INTFUNCn 语法,则将你的函数名称放在此 NULL 的位置。*crypt.c* 中的实际 Crypt() 函数:

/*
 * If mode is non-zero, a salt is expected.
 * If mode is zero, a pseudo-random salt will be selected.
 */
void Crypt(int mode) {
#if HAVE_CRYPT
        Stack *s;
        char salt[8];
        char *enc;

        salt[0] = '\0';
        if(mode) {
                s = Pop();
                if(!s) {
                        Error("Stack error in crypt");
                        return;
                }
                if(s->strval) strncpy(salt,s->strval,2);
        }
        s = Pop();
        if(!s) {
                Error("Stack error in crypt");
                return;
        }
        if(!salt[0]) {
                salt[0] = 'A' + (time(NULL) % 26);
                salt[1] = 'a' + (time(NULL) % 26);
                salt[2] = '\0';
        }
        enc = (char *)crypt(s->strval,salt);
#if DEBUG
        Debug("Crypt returned [%s]\n",enc);
#endif
        Push(enc,STRING);

#else
        Error("No crypt support compiled into this version");
#endif
}

此函数最重要的方面是 **s = Pop()** 调用。函数的实参必须从表达式堆栈中逐个弹出。当你编写一个接受多个实参的函数时,请记住堆栈是一个后进先出数据结构。这意味着你将按相反的顺序从堆栈中弹出你的实参。最后一个实参先弹出。在上面的示例中,我们检查是否处于 2 个实参模式。如果是,我们从堆栈中弹出实参并保存它。然后我们从堆栈中弹出下一个实参。Pop() 返回一个指向 Stack 结构 (s) 的指针。Stack 结构如下所示(来自 *php.h*):

/* Expression Stack */
typedef struct Stack {
    short type;
    unsigned char *strval;
    long intval;
    double douval;
    VarTree *var;
    struct Stack *next;
} Stack;

*type* 通常是 STRING、LNUMBER 或 DNUMBER 之一。*strval*、*intval* 和 *douval* 分量分别是该值的字符串、整数和 double 表示。如果表达式实际上是一个已定义的变量,则 *var* 分量包含一个指向定义此变量的变量结构的指针。

在我们的 Crypt() 函数中,我们只关心实参的字符串值,因此我们使用 *s->strval*。许多 PHP/FI 函数可以通过检查 *s->type* 并相应地使用 *s->strval*、*s->intval* 和/或 *s->douval* 来根据变量类型执行不同的操作。

在调用 **真正的** crypt() 函数并获得加密字符串后,我们的 Crypt() 函数调用 *Push(enc,STRING);* 将返回值推送到表达式堆栈。应该注意的是,表达式堆栈在每个 PHP/FI 行之后都会被清除,因此如果你将永远不会被任何内容弹出的表达式推送到此堆栈中,那将无关紧要。

Crypt() 示例中的 *Debug()* 调用显示了如何在你的函数中添加调试输出。Debug() 是一个 varargs(可变参数列表)函数,就像 printf 一样。


代码黑客笔记

PHP/FI 中的内存管理是一件棘手的事情。由于我们可以作为服务器模块运行,因此必须非常小心内存资源。我们不仅需要重新进入,还需要处理这样一个事实,即我们可以在任何时候收到超时信号,此时我们将退出模块。我们没有收到任何警告,也没有时间释放我们可能分配的任何内存。并且必须释放此内存,否则与我们链接的 httpd 进程的数据空间可能会无限增长。这也适用于以 CGI 模式运行的 PHP,因为它可以设置为作为 FastCGI 持久进程运行。

解决方案是使用内存子池。当会话终止时,这些池会由 Apache 自动清除,或者在 FastCGI 持久进程的情况下,这些池会在每次 FastCGI 包装器循环执行时在 *main.c* 中被清除。目前使用了三个这样的池。它们编号为 0、1 和 2。子池编号是 *emalloc* 和 *estrdup* 函数的第一个参数。

池 0 - 会话生命周期
从该池分配的任何内存都将跨越整个会话。最好尽可能减少使用此池。例如,如果有人创建了一个迭代 1000 次的 while 循环,并且在这个 while 循环中,他们调用了从池 0 分配内存的东西,那么这块内存将被分配 1000 次。这是一种快速耗尽所有分配的数据空间的方法。
池 1 - 临时存储(最短生命周期)
如果函数内部需要一个临时工作缓冲区,则它的内存必须来自此池。此池在每次调用 yylex() 时都会被清除。即,内存几乎在你离开函数时就会丢失。
池 2 - 表达式空间(中等生命周期)
此池在表达式持续时间内存在。此处的表达式是指一个完整的 PHP/FI 命令行。它不会在函数内部被清除,因为调用该函数的更高级别表达式在函数返回之前不会完成。yylex() 函数中的 ClearIt 标志指示何时可以安全地清除此池。

使用子池完全消除了在代码中的任何地方显式释放内存的必要性,唯一例外是使用常规 malloc 调用分配的内存,这些调用由可以链接到 PHP 的各种库进行分配。gdbm 库就是一个例子。

To Top