新浪sae上php部署 应用配置及日志系统

sae文档

应用配置

应用可以通过应用版本目录下的 config.yaml 来对 Apache 服务器做一些配置(类似于 Apache 的 htaccess 文件)。

通过配置,开发者可以很方便的实现以下功能:

  • 目录默认页面
  • 自定义错误页面
  • 压缩
  • 页面重定向
  • 页面过期
  • 设置响应头的 content-type
  • 设置页面访问权限

注解

PHP 运行环境的 config.yaml 文件不会部署到代码目录中,而只是存在于代码仓库中。

应用配置写在 config.yaml 文件的 handle 下,例如::

name: saetest
version: 1

handle:
- rewrite: if (!-d && !-f) goto "/index.php?%{QUERY_STRING}"

基本语法:

- OPTION: ARG1 ARG2 ...
- OPTION: if (CONDICTIONs) ACTION

其中 OPTION 为配置项,ARG1,ARG2 为参数,CONDITIONs 是一个或者多个 CONDITION,多个 CONDITION 之间使用 && 隔开。ACTION 是 if 条件满足后执行的动作。

CONDITION 可以是以下任意一种:

  • 使用 == 和 != 运算符比较变量和字符串;
  • 使用 ~ (大小写敏感)和 ~* (大小写不敏感)运算符匹配变量和正则表达式。正则表达式可以包含匹配组,匹配结果后续可以使用变量 %1..%9 引用(正则匹配使用 PCRE 库,你可以在其主页或者 Wikipedia 找到其语法相关文档);
  • 使用 > 、 >= 、 < 、 <= 比较变量和数字的大小;
  • 使用 -f 和 !-f 运算符检查文件是否存在;
  • 使用 -d 和 !-d 运算符检查目录是否存在;
  • 使用 -e 和 !-e 运算符检查文件、目录是否存在;

appconfig 支持的变量:

  • %{REQ:HEADER_NAME} HTTP 请求头中的字段,如 %{REQ:HTTP_HOST}
  • %{RESP:HEADER_NAME} HTTP 响应头中的字段,如 %{RESP:CONTENT_ENCODING}
  • %{QUERY_STRING} 查询串,一般是 url 中问号后面的内容
  • %{REQUEST_URI} 请求路径,即用户请求的 url 去掉主机部分和查询串后剩下的部分

目录默认页面

当访问 url 没有指定文件时,指定返回的文件。

语法:

- directoryindex: FILE [...]

directoryindex 在 config.yaml 文件中仅有一项

例子:

- directoryindex: aaa.php bbb.html

自定义错误页面

语法:

- errordoc: httpcode error_file

httpcode 是诸如 404、302 之类的 http 响应码,error_file 是服务器以 httpcode 响应请求时响应的文件。errordoc 在 config.yaml 中可以配置多项。

例子:

- errordoc: 404 /path/404.html
- errordoc: 403 /path/403.html

压缩

语法:

- compress: if (CONDICTIONs) compress

在 compress 中,CONDITIONs 只能有一个 CONDITION。

例子:

- compress: if (%{RESP:Content-Length} >= 10240) compress
- compress: if (%{REQ:Referer} == "gphone") compress
- compress: if (%{REQUEST_URI} ~ "/big/") compress

注解

通常情况,我们根据响应头 Content-length,判断是否需要压缩,例如:if (%{RESP:Content-Length} >= 10240) compress,这个静态页面,如 js,css,html 都是没有问题的。但是对 php 脚本,响应 header 中没有 Content-length 这个头,它使用 Transfer-Encoding: chunked, 这个头表示页面输出用 chunked 编码。此时要实现压缩,可以通过应用配置,同时在 PHP 脚本中输出相应头的方式实现。

例如在应用配置中写 if (%{RESP:Use-Compress} == “1”) compress,在需要压缩的 PHP 脚本中写 header(“Use-Compress: 1”)。

开发者可以通过检查是不是输出了响应头:Content-Encoding: gzip 来判断压缩是否生效。

URL 重写

语法:

- rewrite: if (CONDITIONs) goto target_url

在 rewrite 中,CONDITIONs 支持多个 CONDITION。除 HTTP 响应 header(没办法根据响应 header 做重定向)外都可以出现在 rewrite 的 CONDITION 中。

target_url 表示重定向的目标 url,在 target_url 可以用 %N 的形式引用 CONDITION 中以正则匹配到的组。

例子:

# 强制使用 https 访问
- rewrite: if (%{REQ:X-Forwarded-Proto} != "https") goto "https://%{HTTP_HOST}%{REQUEST_URI}"

# 当 url 匹配 urldir/(.*) ,并且 输入 header referer 等于 sina 时,跳转至页面 /usr/%1,%1 表示刚刚匹配的 urldir/(.*) 中的 (.*) 部分。
- rewrite: if (%{REQUEST_URI} ~ "urldir/(.*)" && %{REQ:REFERER} == "sina") goto "/url/%1"

# 当 url 匹配 urldir/(.*),并且请求的是一个目录时,跳转至 /url/%1
- rewrite: if (-d && %{REQUEST_URI} ~ "urldir/(.*)") goto "/url/%1"

# 当 url 匹配 path,并且请求的不是一个文件时,跳转至 /url/query.php
- rewrite: if (!-f && %{REQUEST_URI} ~ "path") goto "/url/query.php"

# 当查询串等于 so,并且 url 以 zhaochou 结尾时,跳转至 /url/%1,%1 表示 query_string 匹配到的部分。
- rewrite: if (%{QUERY_STRING} ~ "^(so)$" && %{REQUEST_URI} ~ "zhaochou$") goto "/url/%1"

# 当查询串不包含 sohu,并且 url 以 zhaochou 结尾时,跳转至 /url/query.php?%{QUERY_STRING},%{QUERY_STRING}表示查询串。
- rewrite: if (%{QUERY_STRING} !~ "sohu" && %{REQUEST_URI} ~ "zhaochou$") goto "/url/query.php?%{QUERY_STRING}"

# 如果 url 既不是文件,也不是目录,跳转至 index.php?%{QUERY_STRING}
- rewrite: if (!-d && !-f) goto "/index.php?%{QUERY_STRING}"

警告

  1. 如果有形如 %{REQUEST_URI} ~ “^(.*)$”类的请求,一定要加上是否是目录或者文件,防止无穷的 rewrite。
  2. 在 goto 语句中,虽然某些时候可以不以 / 开头,但是强烈建议以 / 开头。

指定过期时间和头信息

语法:

- expire: if (CONDITION) time seconds
- mime: if (CONDITION) type content-type

seconds 是秒数,content-type 是表示文档类型的字符串。

例子:

- expire: if (%{REQ:REFERER} ~ "sina") time 10
# 如果 url 请求文件的扩展名是 pdf2,设置 Content-Type 为 application/pdf
- mime: if (%{REQUEST_URI} ~ "\.pdf2$") type "application/pdf"
- mime: if (%{REQUEST_URI} ~ "\.pdf2$") type "application/pdf"
# 只要请求 header referer 包含字符串 sina,就设置 Content-Type 为 text/plain
- mime: if (%{REQ:REFERER} ~ "sina") type "text/plain"

if 语句支持单个 CONDITION。可以出现在 CONDITION 中的变量参考 Apache Docs ,只支持字符串和正则匹配。

基于主机的访问控制

语法:

- hostaccess: if (CONDITION) deny IP
- hostaccess: if (CONDITION) allow IP

if 语句只支持单个 CONDITION。

IP 需要加引号,IP 可以是一个或多个 ip 地址、all(所有 IP 地址)、 CIDR (如 108.192.8.0/24),具体可以参考 Apache 配置,allow 是白名单,deny 是黑名单。

例子::

# 禁止 127.0.0.1 访问 private 目录
- hostaccess: if (%{REQUEST_URI} ~ "/private/") deny "127.0.0.1"

# 只允许 127.0.0.1 访问.conf 结尾的文件
- hostaccess: if (%{REQUEST_URI} ~ "\.conf$") allow "127.0.0.1"

# 禁止 127.0.0.1 的所有访问(这个要慎用)
- hostaccess: deny "127.0.0.1"

# 对 cron 任务保护,防止被外部抓取,我们将 cron 任务放在 cron 目录下 (sae 中 cron 服务执行时,走的是内部网络)
- hostaccess: if (%{REQUEST_URI} ~ "/cron/") allow "10.0.0.0/8" 允许 10 打头的所有 IP

# 对于屏蔽一组 IP 地址,可以写成子网掩码形式,或者将多个 IP 之间加以空格。子网掩码形式如下:
- hostaccess: if (%{REQUEST_URI} ~ "/cron/") deny "108.192.8.0/24" 屏蔽 108.192.8 打头的所有 IP

# 允许 108.134.13.24 和 108.122.122.13 这两个 IP
- hostaccess: allow "108.134.13.24 108.122.122.13"

HTTP 基础认证

语法:

- passwdaccess: passwd "USERNAME:PASSWORD..."
- passwdaccess: if (CONDITION) passwd "USERNAME:PASSWORD..."

例子:

# 所有访问都要密码,允许用户 writer 用密码 123zxc 访问
- passwdaccess: passwd "write:123zxc"

# 访问 secret 目录需要密码,允许用户 test 用密码 123qwe 访问,用户 coder 用密码 123asd 访问
- passwdaccess: if (%{REQUEST_URI} ~ "/secret/") passwd "test:123qwe coder:123asd"

# 访问.text 结尾的文件需要密码,允许用户 writer 用密码 123zxc
- passwdaccess: if (%{REQUEST_URI} ~ "\.text$") passwd "writer:123zxc"

# 用户的网站后台程序都放在 admin 目录下,需要对 admin 目录做密码保护
- passwdaccess: if (%{REQUEST_URI} ~ "/admin/") passwd "admin:admin123"

if 语句中只支持单个 CONDITION ,%{REQ:HEADER_NAME}, %{REQUEST_URI}可以出现在 CONDITION 中,只支持字符串和正则匹配。

Session

新浪云 PHP 环境默认提供了共享的 Session 存储,用户可以不用任何设置直接使用 PHP 提供的 Session 系列函数进行 Session 相关操作。

若用户需要使用特殊的 Session 存储,如将 Session 存入 MySQL,Memcached,KVDB 等服务中,可以参考: PHP: session_set_save_handler - Manual 实现自定义 Session Handler。 新浪云 提供了 Memcached 存储 Session 的方案,可通过如下代码将 Session 数据存入 Memcached 中。

例子:使用新浪云 Memcached 服务作为 Session 存储



//PHP 5.3 版本
$handler = new sinacloud\sae\MemcacheSessionHandler();
session_set_save_handler(
    array($handler, 'open'),
    array($handler, 'close'),
    array($handler, 'read'),
    array($handler, 'write'),
    array($handler, 'destroy'),
    array($handler, 'gc')
);

session_start();
...

//PHP 5.6 版本
$handler = new sinacloud\sae\MemcacheSessionHandler();
session_set_save_handler($handler, true);

session_start();
...

外网访问

您可以通过以下方式来访问外网:

  • php curl 库 访问外网的 HTTP 资源。所有 curl 访问的日志可以在日志中心查看。
  • fsockopen 通过 TCP Socket 访问外网资源。

范例一,使用 curl 库抓取 http://www.sinaapp.com 。


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.sinanapp.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

范例二,使用 fsockopen 连接 IP 1.2.3.4 的 80 端口。


$fp = fsockopen("tcp://1.2.3.4:80", 13, $errno, $errstr);
if (!$fp) {
    echo "ERROR: $errno - $errstr\n";
} else {
    fwrite($fp, "\n");
    echo fread($fp, 26);
    fclose($fp);
}

?>

范例三,使用 Socket 与外部网站进行 SSL 连接。



$fp = fsockopen("ssl://passport.baidu.com", 443, $errno, $errstr);
if (!$fp) {
    echo "ERROR: $errno - $errstr \n";
} else {
    $str="GET /?login HTTP/1.1\r\n";
    $str.="User-Agent: curl/7.19.6 (i686-pc-linux-gnu) libcurl/7.19.6 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5\r\n";
    $str.="Host: passport.baidu.com\r\n";
    $str.="Accept: */*\r\n\r\n";

    fwrite($fp, $str);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}

?>

注解

外网访问出口 IP 列表:

  • 220.181.136.56
  • 220.181.136.57
  • 220.181.129.102
  • 220.181.129.119
  • 220.181.129.89
  • 220.181.129.126
  • 220.181.129.121
  • 220.181.129.92
  • 220.181.129.99
  • 220.181.84.185
  • 123.125.23.213
  • 123.125.23.214

如果你需要给访问的外部接口添加 IP 访问授权,建议添加以下四个 CIDR 规则:

  • 220.181.129.0/24
  • 220.181.136.0/24
  • 220.181.84.0/24
  • 123.125.23.0/24

由于出口IP会变动,建议您使用 域名解析方式 获取出口IP地址:

  • dig iplist.sinacloud.com TXT

日志系统

新浪云提供了实时的日志查询功能,方便开发者在线调试分析。

PHP 运行环境中输出的日志类型有: Apache 的访问日志,PHP 的错误日志,可以在日志中心面板中查看。

你可以使用 PHP 的 error_log 、 trigger_error 来写日志,更多使用方法请参见 PHP 官方文档: 错误处理和日志记录 。

注解

目前 PHP 运行环境单个请求最多输出 1000 条日志,超过限制的日志输出会被丢弃。

.htaccess 配置文件

新浪云 PHP 运行环境支持 Apache 原生的 htaccess 配置文件格式,你可以直接使用应用根目录下的 .htaccess 文件来配置服务器。目前支持的指令包括:

  • SetEnv
  • SetEnvIf
  • SetEnvIfNoCase
  • Header
  • RequestHeader
  • RewriteEngine
  • RewriteRule
  • RewriteCond
  • AddType
  • AddEncoding
  • DirectoryIndex
  • ErrorDocument
  • FilterProvider
  • FilterChain
  • AddDefaultCharset
  • Options
  • Allow
  • Deny
  • Order
  • Satisfy
  • ExpiresActive
  • ExpiresByType
  • ExpiresDefault

警告

.htaccess 配置文件不能和 config.yaml 配置文件里应用配置(handle 段)一起使用,如果两个一起使用,会导致配置错乱。

你可能感兴趣的:(PHP7)