返回列表 发帖

[Zend权威认证试题讲解]第八章 - 处理电子邮件

没有了E-Mail,这世界会变成什么样?网络交流把人们拉得更近,让公司能够更有效的开展业务,不幸的是,也带来了垃圾信息。
; |0 O. M5 @; K, X& W4 k) a7 N& ~还好,你不需要成为一个反垃圾邮件专家就能使用PHP处理电子邮件的功能。事实上,不管你是在运营一家在线商店,还是在编写一套论坛程序,你都会发现发送邮件是你工作中很重要的一部分——与用户保持联系这点非常重要。
4 u  |" a8 @' H) O用PHP编写邮件管理脚本很简单,但也不失挑战性。如果你只是想发送一封文本邮件,mail函数对你来说就够了。而如果你需要处理更复杂的电子信息——例如HTML邮件和附件时,那么你就需要深入学习一下E-Mail的工作原理了。6 c3 N$ M; @4 ?8 _! ~5 K
* d& n0 \  ~0 V

9 C- c8 k' Y* C! D6 S问题% n$ U) i8 e6 t# U: h& a

4 f! G' h  |/ Z! W- \: T+ N1.以下哪个不是合法的电子邮件地址?
4 L' w/ y% I" V, |0 D# ]+ H) H$ z5 }0 \1 {
A.john@89w.org6 F) n, F) Q4 c* c) R( q; Z
B."John Coggeshall" <someone@89w.org>
6 L) o' Q; ?6 l6 I# O. e, L6 ^) M: TC.joe @ 89w.org6 ~4 A+ V' M/ ~  \
D.jean-cóggeshall@89w.org" ~+ O" v' ~% p7 P6 _9 m
E.john
) a+ s* f& |5 _( X
8 k; `; f& o! a& B6 Y0 T7 H3 o2 b- a3 A$ V
2.在PHP中,使用sendmail程序从Windows或Novell系统中发送邮件的方式,与从类UNIX系统中发送的方式不同。以下哪些选项说明了这个不同?(双选)
7 y" b4 a& x# M' o' Z; e7 v# n; v, s1 F5 e
A.Windows/Novell不需要第三方软件的支持就能实现该功能0 i5 u( f' x" |" Y. f( e5 I' b
B.UNIX中,sendmail_from的配置来决定了邮件头中的From:信息。
6 M3 Z* Q5 O& k( QC.在Windows/Novell中,你无法发送有多个收件人的电子邮件,每个收件人都必须单独发送
) z7 G0 D4 R6 }  XD.有可能完全相同,这取决于sendmail_path的配置  j6 D: y# P1 Q9 a' Y( s- z- L
E.不同与Windows/Novell,在UNIX中,你必须用SMTP和smtp_port配置好MTA主机和端口
5 q& X# {6 x: R% z( Y+ j! t6 I3 w% E5 y! [. @

, `/ M) O3 ?1 J, p" q3.通过PHP发送有多个收件人或者MIME兼容的邮件,需要遵循什么步骤?
" u& k9 a/ |3 E, Q# a
* W) t# r- A- l" JA.将必要的头信息(header)通过$message参数(第三个参数)传递给mail函数
& T! A( N- e" C5 F* X- [+ H0 [$ wB.用PHP代码,通过SMTP直接与MTA连接。
4 W$ |1 C( G7 ^3 f/ d  e5 |: gC.将附加的头信息传递给mail函数的$additional_headers参数(第四个参数),每个header一行。
2 j; u1 F1 _2 B% ~5 q$ \D.向多个收件人发送E-Mail是允许的。PHP不支持发送MIME E-Mail。/ O9 a" _  X# ?  v  X+ ^
E.向mail函数传递$additional_headers参数,每个header一行,行以\r\n结尾, E3 [& I, C/ x/ P+ v
+ D* t' v4 y% @' Q) J2 g: O

4 @5 V7 M' S& X2 D4.使用MIME发送有附件的邮件时,邮件正文和附件必须靠一个特殊的分隔符分开。MIME E-Mail的头信息里如何定义这个分隔符?+ W2 X' B2 Q1 ~
2 i2 {0 @3 J; b7 \0 F
答案:____________
8 L& W3 k( q9 a3 v6 ?8 ^  K/ P2 U; G" e/ w, [/ S
/ ]0 d+ G) {7 w) r' ?/ C
5.使用MIME发送HTML邮件时,经常会用到一些经典的HTML标签,比如用<img>嵌入图片。以下那些方法能做到这点?(双选)! K4 E6 E9 B' F3 s) H8 w9 e

# w! }! O. g, j" RA.直接用<img>标签把图片文件嵌入邮件内容中,邮件客户端能自动显示6 b% O1 v( B6 }* ~
B.通过给<img>标签添加一个URL的src属性来调用外部服务器上的图片" o) h, G4 d) j) C
C.把图片作为MIME内容直接嵌入邮件中,再把<img>标签的src属性指定为内容ID7 G) E! l( h+ S0 t% ?9 h2 A
D.把图片作为附件,再把<img>标签的src属性指定为图片的文件名
; H6 c& W& E  K4 K  w+ IE.只有一个答案正确
8 P7 B0 B2 {, o7 e% y6 u6 A7 l8 ?) ]  v9 }- S  {# D/ `* O6 p
/ Z# \5 L7 z/ r$ |. v/ Q5 f
6.以下那种情况会用到mail函数的第五个(最后一个)参数$additional_parameters?. ~+ S7 A* H) \- S
% ?' z* z; v" W
A.从UNIX或Windows/Novell发送邮件时都会用到2 z) w0 E8 }/ h, U# S/ O
B.只有在Windows/Novell平台上用SMTP命令向MTA发送邮件时- t1 }# }9 V/ U0 D/ i# B. I) D
C.只有在和sendmail或一个指定了sendmail_path的打包程序协作发送时2 }4 I  k, j5 X8 x5 m. o
D.PHP里用不到这个参数1 P& E) T: @7 G: I
* O% m2 k- ?9 h  L1 V

+ n- x2 a, h( A. W7.以下那种情况需要在头信息中添加邮件内容编码(Content-Transfer-Encoding)?3 g$ P' [# |0 f7 Z# V' Y
2 O* A& A7 Z3 D( ]! k! @, i
A.只有在发送非普通文本(ASCII)数据时
/ V1 H0 o9 v; j" y( S$ {% G2 OB.需要指出E-Mail的格式时,例如HTML,普通文本(plain text),富文本(rich text)
  Z4 h, e: d5 {& qC.任何时候都可以用它来指出MIME的编码类型
3 Z$ {. j/ `% R" d; }D.只能用来指定特殊的编码格式(例如base64)! B2 p, |  Y+ o% n0 _$ n
E.以上都不对9 G5 s- B+ [3 @) w' Y, `
+ ?) U, V4 ]( N* ^1 Y
8.以下关于在头信息Content-Type中定义的MIME分隔符的描述,哪些正确?(三选)( s; X5 v5 @8 p% @5 H
9 ?7 s# H" x; U" G* u
A.分隔符至少要8个字符
/ b' P- ]) N9 \' m% {2 MB.分隔符必须以两个连字号作为前缀(例如:--abcdefghi)和后缀来表示起止(例如:--abcdefghi--)
; [! S/ O# I6 Y$ e$ {5 Q/ ~C.分隔符在MIME邮件中必须是独一无二的
& X" q' R+ Y3 f; d1 SD.分隔符不能嵌套的其他分隔符中: n% Q$ G" h' G" t
E.用什么做分隔符都无所谓
) b) R1 k8 J, [* Z8 {  B8 [- |" d1 {8 E/ O
0 A3 U4 h4 z9 }) V7 a. w# F1 X
9.考虑如下E-Mail:0 V+ o. a3 _# U) k  O
) U1 P1 Y$ E- T$ p! t
From: John Coggeshall <john@php.net>
: ]/ z$ Y2 H4 \0 {# Q$ l5 c0 UTo: Joe User <joe@example.comt>
: W  K( J% {# \- m" k% x9 BSubject: Hello from John!: p+ }& M) p! u1 o0 y
Date: Wed, 20 Dec 2004 20:18:47 -0400. j5 x: }% u, k5 Q
Message-ID: <1234@local.machine.example>
8 G- }, L# u+ Y) C+ v2 ~4 C+ ^) W/ IHello, How are you?& Y+ T4 T1 v7 |: _

8 c$ o) {+ M4 a7 T( V  g在头信息里添加什么才能让它成为一份MIME邮件?(不定项选择)
* J  ~* k8 y0 d/ i0 s0 ?  L% |
6 S3 x9 L7 {4 v6 O+ s( wA.MIME-Version' i+ y# U6 F# I) Y, \3 y
B.Content-Disposition
" L/ W$ q; j3 |$ e2 C5 W: M! DC.Content-Type
% a  s2 L; d+ b! A! TD.Content-Transfer-Encoding% Q6 C1 ]% F- J. [
E.Content-ID
. a. o2 @% i! E; T( v, a0 {7 t, w& ^( @- ?5 j8 Z

' @) X& k' J- u+ Q9 M10.发送一封包含HTML、富文本和普通文本三个版本的邮件,要想客户端能选择一个合适的版本打开,MIME的content-type应该是什么?
% ]0 \- s& a7 i: n7 @% O
* a, J. c/ X5 j+ U. B/ r% YA.multipart/mixed
+ [2 k4 a& n, j& r0 q: aB.multipart/alternative
9 G, k0 g$ q4 ?( \( q; bC.multipart/default6 Y  y* ?) R" W. @
D.multipart/related( V# Y, ^7 J  C
E.不可能用content-type实现0 T2 d8 e6 g8 W2 S
4 j+ V7 r+ d% V
) R) M1 N5 Y$ I
11.假设你的机器上没有安装sendmail,要想mail函数能在Windows下使用,需要做什么?
3 s1 X# w7 s, ~- B2 a, u5 E) i  }2 g" H# A$ Y
A.安装sendmail服务器5 T5 [/ g1 \  Q5 U
B.安装Microsoft Exchange/ \0 m9 {; s; D2 E6 z
C.在你的电脑上安装任何一种邮件服务器  q( {3 g8 T- Y6 B! }' E9 v. w
D.改变php.ini的设置9 Q7 S( s/ t4 M1 ]& Y4 c
E.写一个连接公共电子邮件服务器的脚本; x1 z. h' ^7 d- d+ o6 W6 A
6 [4 o$ n% }: j8 b. |" X

9 {* q& s7 g& L" e) N12.有一个向用户提交的地址发送指定内容的文本邮件的表单,以下哪种方法有助于防止通过该表单进行跨站攻击?(双选), M2 Z. _0 k1 n

- J" v. x) ?2 y. i+ c: t$ i6 C& TA.使用GET方式传值! t8 Z0 y8 I; L) J, _6 V) P& \! K
B.用htmlentities()处理电子邮件地址4 |1 o* S; l4 c: ?/ u
C.使用POST方式传值1 b- R) f. s# w
D.用htmlentities()处理邮件正文* Z. a) f" S' J. ^* }! ]% x, P
E.确保填写邮件地址的文本域不能有换行符+ ]; z9 K# r  c; n; u* K1 v

1 o9 _$ l/ r2 [% o+ {3 p+ u. W9 Z: W0 E  h
13.如何将一个数组作为附件发送,并要能在接收后重新组合?: c, h4 S7 b6 e: M
% D( |( |9 T  p9 _
A.用serialize()把它转换成字符串,再用htmlentities()处理一下
- {0 R( P# f- kB.把它存在文件中,并用base64_encode()进行编码0 y; P8 B' R6 b- ?8 {& _* \: O$ R
C.用serialize()把它转换成数组
% m; ^8 N# _% _, MD.用serialize()把它转换成数组,再用base64_encode()进行编码
# k$ h: n9 T0 u* S8 }+ r2 \E.把它存在文件中,再用convert_uuencode()进行编码' e; i6 x) ^2 B8 S' W

% S5 R; v! W1 T5 i9 v3 y* ]1 B7 V% H. Q$ c4 g
14.要确定需要嵌入在MIME/multipart 邮件中的文件该使用什么MIME类型,以下那种方法最好?
. K0 p2 s; ^1 O5 W& a! g' B/ B1 d
  @6 `9 \. }3 P# H) XA.堆一个检测脚本出来
$ j! ?( E/ T* B8 oB.创建一个MIME类型和文件后缀名的列表,根据后缀名选定需要的MIME类型( y" Y1 h5 F7 ?" O8 X; a4 i
C.写一个识别文件MIME类型与内容是否相符的函数' X- A2 _! N3 ]3 q2 G+ T
D.使用mime_content_type函数
; z1 ]  _2 P3 X9 i0 jE.把文件上传到外部服务器上. C, T( f, z8 X8 o; D

% o/ O4 D* T; z6 ~0 y) i! K4 {  n% u1 A6 T6 l9 P, P8 b
15.在UNIX环境下使用本地安装的sendmail,如何才能随意设置邮件的发件人名字与发件人地址?(三选)
& D. V4 `0 |3 R7 n1 c+ P3 K9 w  {& H. E9 P) [( r6 U! w- c, H
A.添加一个From头信息
2 a2 p3 W" Y/ _; b0 M3 d& b2 fB.使用-f参数/ V0 j! `4 x1 ~' W
C.添加一个Reply-to的头信息
/ K7 g! ?$ {& f. @% {6 ~% VD.确保运行Apache的用户有修改sendmail设置的权利
- N% J5 t5 _. a6 @# \; w" rE.确保Apache在root用户下运行! l5 X0 U- f( n9 E- x4 V. y- D
答案速查% e( ?: t+ z  U" t; \" m  B2 b
1:D) O! ^& L2 f8 x" J5 n7 G
2:AD" c8 G( m/ G" ?# c: g
3:E
3 q+ d" ]8 B* G' j) W4:Content-Type:MIME
! R, J, n% m2 W. s8 Z: F8 a( D5:BC% V0 j3 B, R0 N% M3 T% h& v8 c
6:A
. I# N! C- ^) L5 e7:C& }  }: i- F1 F5 ]6 R
8:BCE
: j7 b: R! G- v/ b! Z+ `9:ACD% j' N  ^: y- T# `
10:B
! S9 h9 y' G" @11:D- W2 f: B- S, f1 c( q" d( Q2 g4 T
12:CE' D+ e+ f1 g; W5 H  j0 q
13:D7 o# O! d& D4 D" [9 Z" W! O6 d
14:D, M5 U2 e1 C$ |6 K4 ~7 e. N
15:ABD
4 G* x) G4 f& c
) ~9 H, E9 }% I
" z% J; x0 ~! F: f" }
% `7 j3 C3 b  P# p) B答案详解
/ W2 t# I9 {2 z( b0 Q( P8 R
( X' ?- _1 f* u" V- I- a) R1.列出的E-Mail地址中只有D不合法。A和B都是最经典、常用的电子邮件地址。C看起来不合法,但邮件传输代理(MTA)会自动过滤多余的空格。E可以在本地发送时使用。那么就只剩下D了,它里面有一个非法字符。6 R+ P  o6 X+ g
( A2 P4 W: w8 l9 S( z) w
2.正确答案是A和D。UNIX版本的PHP需要用sendmail程序(或者功能等同的替代品)通过MTA发送邮件,Windows/Novell版本的则通过SMTP直接用MTA发送。然而,如果允许的话,Windows/Novell上的PHP也可以进行配置,来通过“sendmail封装器”模拟sendmail发信。也就是说PHP在这三个版本上能够以相同的方式实现此功能。注意,在Windows/Novell上使用mail()时,需要配置sendmail_from。而UNIX则把这件事交给sendmail程序自己来处理。
+ o+ F3 z/ _0 H6 z  t/ ?+ Y
, v& n% D9 ?: d8 z2 O% q9 s3.PHP可以用mail函数发送任何格式合法的电子邮件,于是编写用SMTP发信的PHP脚本成为了下策。要在E-Mail中添加额外的头信息,则必须向函数传递$additional_headers参数,每个头信息以一个回车符和一个换行符结尾(\r\n)。发送复杂的邮件,比如带附件的或者HTML格式的邮件,则不仅需要添加额外的头信息,还要添加MIME类型。所以答案是E。
( K. f# g0 X1 ?4 v$ [& Z& ?. @9 P* [* G: P. s
4.发送由多个部分组成的MIME邮件时,你必须指定一个分隔符(任何US-ASCII字符串),它必须不同于邮件主题中任何一个部分。分隔符必须与MIME信息中嵌入的任何一部分都不同。分隔符在Content-Type: MIME中定义。0 {4 f( U/ i6 H8 V; U, Z: t

' S5 [7 S: J7 j( ^5.有两个选项指出了在HTML邮件中包含图片等资源的正确方法。最快的方法就是直接引用一张远程图片。然而,图片以及其他资源能够以MIME内容块的形式嵌入MIME邮件自身。这些内容块会被赋予ID,可以通过把src属性设置为cid:资源标识加内容ID的方式来调用。因此答案B和C正确。
4 D' B( O* F0 W# G, n4 R
7 E& U7 ]/ h/ ?/ Z4 K% J6.mail函数的最后一个参数用来向sendmail程序传递参数,不过这只能在安装了sendmail的UNIX系统上进行。如果Windows/Novell系统上配置了sendmail_path,那么这个参数同样也是可用的。
2 s1 Z/ B, p: b/ i  r7 p8 o& q! T2 X% s
7.答案是C。MIME头信息里的内容编码(Content-Transfer-Encoding)用来指出MIME邮件中各个片段的编码。头信息中包含一组指出了编码算法的二进制数据。默认情况下,7bit,quoted-printable,base64,8bit和binary是可用的编码类型。不过任何人也可以通过使用x-<unique name for encoding>来声明自己的编码格式。
$ n" `) i+ @7 r9 c  y1 I0 h9 K+ p  S8 Z3 _. g' z
8.正确答案是B,C和E。分隔符是MIME邮件中至关重要的一部分。虽然分隔符的长度没有官方限制,但由于分隔符由文本字符构成,因此它绝对不能出现在邮件主体中,否则就会造成混乱。考虑一种灾难性的情况:假设我们用John做分隔符,那么邮件中提到的人名John就会分隔邮件,导致邮件内容的混乱。$ E3 d1 W- s4 A3 r! `. v, i  p
5 ^, L$ F8 @4 d+ r# I% ~1 M( |
9.要从给定的文本信息中创建一份合法的MIME邮件,正确的答案是A,C和D。MIME邮件在开头处必须有MIME-Version头信息,而邮件的每个片段(包括“root”片段)都必须有Content-Type和content-transfer-encoding这两个部分。答案中提到的另外两个头信息是可选的:Content-Disposition用来指出片段要如何显示(比如显示为附件),Content-ID是片段中的各个内容的唯一识别符。
8 q3 A3 u% K, g8 h9 ]: @" ]7 b  M
10.正确答案是B。这种特殊的MIME类型用来定义一个含多个内容相同的子版本片段的母片段。比如说,一个multipart/alternative片段包含一个text/plain和一个text/html版本的片段。然后由电子邮件客户端选择一个最合适的版本来显示给用户。通常情况下,最好放入一个文本格式的版本,这样不支持MIME的邮件客户端也能正常读取。- ^; k( \8 w7 Y( t- L

  p) k1 i, z& k11.在类UNIX系统中,PHP依靠sendmail程序来处理邮件。而在Windows中,除非已有sendmail包装器,否则将使用服务器的SMTP配置来进行。答案是D。
3 x: P$ v9 S1 E, ]: _4 ~5 l3 X9 h1 }" C, O+ G' \& B
12.在普通文本邮件中使用htmlentities()不能防止跨站攻击,反而可能会让邮件内容变得不可读。强制使用POST传递变量只能让攻击变的困难,但并非绝对安全。确保E-Mail文本域(将变成To:的部分)中没有换行符,能够防止恶意用户把自己的邮件地址添加进收件人地址中。因此答案是C和E。
/ ^# v* n2 p6 b$ a! f1 y% S! V
9 z% i' v* l) T+ D7 D. S5 e13.把数组序列化成一个字符串是传输这个数组的正确方式——第一步先让数组变得可以通过E-Mail网络传输。接下来你需要对它进行编码,以使得它能够安全传输。在PHP4中,最简单的方法是用base64_encode把它编码成每字符7bit的形式。答案是D。
2 t5 B( {# I, r9 }4 z  Z
% v2 @% v8 R& \2 Q& r& [14.要判断一个文件的MIME类型,最简单的方法是使用mime_content_type函数。答案是D。注意,虽然别的扩展库里有能更好的解决这个问题的函数(译者注:比如PECL的FileInfo),但在这里使用mime_content_type仍然是可以的。1 [: `9 v8 H: A$ I8 x8 G
2 H! {/ c* p, H* a/ T8 N$ p/ U
15.在头信息中添加From不能完全保证sendmail不会在邮件中重写你的发件人地址。事实上,你需要通过发送器向sendmail传递-f参数。除此之外,你还必须确保运行Apache的用户有修改头信息中的From内容的权限。因此答案是A,B和D。

返回列表
【捌玖网络】已经运行: