|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14321
- 金币
- 2446
- 威望
- 1647
- 贡献
- 1394
|
[Zend权威认证试题讲解]第八章 - 处理电子邮件
没有了E-Mail,这世界会变成什么样?网络交流把人们拉得更近,让公司能够更有效的开展业务,不幸的是,也带来了垃圾信息。
5 [& \' Q+ @ P! c; ^还好,你不需要成为一个反垃圾邮件专家就能使用PHP处理电子邮件的功能。事实上,不管你是在运营一家在线商店,还是在编写一套论坛程序,你都会发现发送邮件是你工作中很重要的一部分——与用户保持联系这点非常重要。# s9 x! F# m9 w. u2 `
用PHP编写邮件管理脚本很简单,但也不失挑战性。如果你只是想发送一封文本邮件,mail函数对你来说就够了。而如果你需要处理更复杂的电子信息——例如HTML邮件和附件时,那么你就需要深入学习一下E-Mail的工作原理了。. Y \! ?7 E' k, t' V/ `
" O! W( k, `# \- c/ H; l
2 }7 Y5 `6 U+ C! n问题# U$ x% G. x; c. [* a7 _3 y( S
7 i& B. i$ I b$ n1 T* M
1.以下哪个不是合法的电子邮件地址?
( J" ^9 z+ Y) ?9 x% y, J7 e' b
+ A- `! Y: w8 C1 x. NA.john@89w.org
1 M0 s0 N \* oB."John Coggeshall" <someone@89w.org>
3 q T2 ]+ G5 jC.joe @ 89w.org: ^2 W6 n# P% K! i% L
D.jean-cóggeshall@89w.org
5 Y/ R6 T; L, o+ p2 ~E.john
% @# @& A2 t, ] s9 q
" _8 z+ P' Y- K; t
9 O0 r$ f& d; S' R( ^2 m2.在PHP中,使用sendmail程序从Windows或Novell系统中发送邮件的方式,与从类UNIX系统中发送的方式不同。以下哪些选项说明了这个不同?(双选)
; h+ _5 N1 x0 T3 u* H# m" B. W+ X8 Z" ^1 v, X
A.Windows/Novell不需要第三方软件的支持就能实现该功能
' U! N' m' |0 {( \( H2 |7 A3 i- yB.UNIX中,sendmail_from的配置来决定了邮件头中的From:信息。5 L9 }8 s- a6 i, n) Z4 ~
C.在Windows/Novell中,你无法发送有多个收件人的电子邮件,每个收件人都必须单独发送
1 }! ^( g! s( KD.有可能完全相同,这取决于sendmail_path的配置$ k' [' R. a: q: m' ^3 I5 Y# Q
E.不同与Windows/Novell,在UNIX中,你必须用SMTP和smtp_port配置好MTA主机和端口; N3 K7 c2 v% C2 e5 s7 \5 ~
" R* N& e: s) x+ I1 ?2 d
9 s' N* [9 n+ H$ ]3.通过PHP发送有多个收件人或者MIME兼容的邮件,需要遵循什么步骤?
/ }5 v4 m1 p% a. o, r
5 Q4 A- @0 T8 I9 V: e/ V: rA.将必要的头信息(header)通过$message参数(第三个参数)传递给mail函数
- b, Y/ R* d0 U+ {B.用PHP代码,通过SMTP直接与MTA连接。* R5 Z/ B; X6 A, Y- _/ ^
C.将附加的头信息传递给mail函数的$additional_headers参数(第四个参数),每个header一行。
. L n E* @2 |; m- f0 @/ iD.向多个收件人发送E-Mail是允许的。PHP不支持发送MIME E-Mail。: K3 l1 z, {, V; J7 W) {7 `
E.向mail函数传递$additional_headers参数,每个header一行,行以\r\n结尾
! }, ]8 G1 F# O, q& ^+ d% A
' E" u6 y" D# N9 `" k
$ C) k) T* K8 h; K2 G4.使用MIME发送有附件的邮件时,邮件正文和附件必须靠一个特殊的分隔符分开。MIME E-Mail的头信息里如何定义这个分隔符?
" o K7 B- s3 r( p- k# }/ e( d# j* H
答案:____________
, Q: K" b, i. T- z
0 l& {1 p5 n! A2 ?* a: ^
% `5 @, u3 T9 l) U u7 M5.使用MIME发送HTML邮件时,经常会用到一些经典的HTML标签,比如用<img>嵌入图片。以下那些方法能做到这点?(双选)
# M. }, [; Z, a: V- A! H" y
4 T) p& R5 b zA.直接用<img>标签把图片文件嵌入邮件内容中,邮件客户端能自动显示% v& E2 X4 U5 u* P0 j
B.通过给<img>标签添加一个URL的src属性来调用外部服务器上的图片
" Y, Y2 s; A0 w6 U& IC.把图片作为MIME内容直接嵌入邮件中,再把<img>标签的src属性指定为内容ID
, S$ h+ f6 U2 T7 KD.把图片作为附件,再把<img>标签的src属性指定为图片的文件名: V: j q( R6 n# P% j! W
E.只有一个答案正确
" G% |! S. \ s0 r
! |2 A- ~3 Q/ w6 ?; A8 r8 s- b _3 ~$ Z( Y+ | H& G# P, i
6.以下那种情况会用到mail函数的第五个(最后一个)参数$additional_parameters?& V( a0 R7 W, f- m
0 W& k+ w3 {) h. I2 e
A.从UNIX或Windows/Novell发送邮件时都会用到
) U( X2 O O4 d0 {! P UB.只有在Windows/Novell平台上用SMTP命令向MTA发送邮件时
m# ?8 S5 F& h4 X' m! gC.只有在和sendmail或一个指定了sendmail_path的打包程序协作发送时
. _- F6 Y) ]8 {( G+ n6 ID.PHP里用不到这个参数
2 T4 V; j+ i4 g" X9 b/ h- ?8 l3 f9 j: w( D+ ]3 M, Z; q6 H
( D1 Q& R$ |+ S* k1 W7.以下那种情况需要在头信息中添加邮件内容编码(Content-Transfer-Encoding)?% T4 {; `; p" E9 T8 u
, q, P# V3 {: A; r4 oA.只有在发送非普通文本(ASCII)数据时
$ v3 a1 ~4 _; ~' S( H" H& }B.需要指出E-Mail的格式时,例如HTML,普通文本(plain text),富文本(rich text)
+ A2 x/ A. v" g' r4 J+ \: }+ N) WC.任何时候都可以用它来指出MIME的编码类型6 p" S# c# a( v- @( O/ B9 `
D.只能用来指定特殊的编码格式(例如base64)% Y* n* Y7 `- Y- k1 p1 G5 r
E.以上都不对
0 I, J3 A& W) N6 ]0 C6 M; p! d
8 ]* v$ |. ~% g/ }9 g% Y8.以下关于在头信息Content-Type中定义的MIME分隔符的描述,哪些正确?(三选)
# C6 L9 |; f6 y- a$ i( y! y
# B' a" V; _5 OA.分隔符至少要8个字符! s+ O4 ?! W- x( O& L8 d% M% a2 R
B.分隔符必须以两个连字号作为前缀(例如:--abcdefghi)和后缀来表示起止(例如:--abcdefghi--)
+ E& i: L$ Z9 v5 OC.分隔符在MIME邮件中必须是独一无二的1 F+ f( C2 j% o. ^
D.分隔符不能嵌套的其他分隔符中
2 t$ h) y( @& U! E5 D+ yE.用什么做分隔符都无所谓
# |4 B% S4 }7 ^. _0 D% M) |, S' {8 p3 s& K4 i0 }2 z- A
) \: Q+ r0 I7 O) ?
9.考虑如下E-Mail:
2 p% z5 }5 l* y5 N4 G4 v' Z1 Z0 u" T( z1 X' W& ~) m
From: John Coggeshall <john@php.net>/ N3 N5 e: V, W' J% m8 D
To: Joe User <joe@example.comt>
4 t6 ~, Z9 `! j1 b4 E& ?8 r: kSubject: Hello from John!
2 m' F6 |% T: H( i2 x5 aDate: Wed, 20 Dec 2004 20:18:47 -0400
% H* G( P% _, p# k7 ~7 Z9 w RMessage-ID: <1234@local.machine.example>
% @2 V$ P) }* g' I. ?& xHello, How are you?
- B: ]* t. p% o7 I/ A+ g- J4 v
在头信息里添加什么才能让它成为一份MIME邮件?(不定项选择)1 ~7 o+ }, |1 s* E h& k# y7 o% t
/ z9 o0 X9 i. g! g& F3 ~1 s) y! b
A.MIME-Version
( {9 J) _+ y/ E* g6 DB.Content-Disposition; C8 {% B$ r V5 |
C.Content-Type6 r5 {3 Z" {: o/ F+ D
D.Content-Transfer-Encoding" p* U: }) c, t* X0 }
E.Content-ID
0 ?. l4 Q4 {4 Y- z' A0 |
, `( t8 I o0 o5 t0 b
3 i+ Y/ k5 f' q! [6 S3 x10.发送一封包含HTML、富文本和普通文本三个版本的邮件,要想客户端能选择一个合适的版本打开,MIME的content-type应该是什么?/ y7 O7 _8 |. h9 x$ u/ u$ w$ f) C
/ A" A$ b+ v' h3 B+ g
A.multipart/mixed
6 ]- O( m f' H6 ]& a! {) X$ s' h5 }! xB.multipart/alternative' p( G; ~5 Z' J; N0 G
C.multipart/default, Y6 K3 ], S1 i
D.multipart/related
$ U$ K1 W# g+ X: j o3 ?2 T: S# zE.不可能用content-type实现
7 Q% J5 ~1 w1 [! d& V$ O' L1 I
- B0 G- e* d0 A1 y" s6 X/ D8 s* G9 ^3 `2 a# K6 V
11.假设你的机器上没有安装sendmail,要想mail函数能在Windows下使用,需要做什么?& C# t: L2 t2 ?
. T: n7 E. S' r( g+ t: Q! z" rA.安装sendmail服务器2 E, w2 [9 Z9 W3 x' |
B.安装Microsoft Exchange
- U9 L, _# V7 g9 UC.在你的电脑上安装任何一种邮件服务器
5 G4 y. F+ Q( q# xD.改变php.ini的设置3 Y9 Y4 _3 L' L$ ?+ i/ N
E.写一个连接公共电子邮件服务器的脚本( i- W) R. Q+ w: n
. ~4 p0 @6 g6 ^: a1 M9 Y1 J: C( M
# y, C8 X$ Y3 r! W/ Y' M: t
12.有一个向用户提交的地址发送指定内容的文本邮件的表单,以下哪种方法有助于防止通过该表单进行跨站攻击?(双选)
3 Z( {3 j3 b6 o T" M2 w; t; L
+ B5 r& Z" F6 \# b! W& FA.使用GET方式传值$ ^& d& ^; Z& }" X4 @" t a
B.用htmlentities()处理电子邮件地址
; s1 d% E6 ^5 z5 xC.使用POST方式传值# Y: V0 Y9 V/ p, `9 l6 p" }4 U
D.用htmlentities()处理邮件正文
' `- a/ f. I9 ]* w0 V! X C; fE.确保填写邮件地址的文本域不能有换行符
( g, O' d* I. ^9 Q* Z, D+ K9 @; ]" u
) z0 Y( F3 l n/ ]
. b) ~# P- k9 c, q9 U2 W( W+ ^13.如何将一个数组作为附件发送,并要能在接收后重新组合?) n1 E, u. x4 t0 a1 `, ^% j
0 \' {% F1 Y v7 h
A.用serialize()把它转换成字符串,再用htmlentities()处理一下: ]3 k. t ^2 p. G; K2 I
B.把它存在文件中,并用base64_encode()进行编码
5 A& d! H/ L+ _ EC.用serialize()把它转换成数组7 d2 R9 |/ e" o+ z7 V
D.用serialize()把它转换成数组,再用base64_encode()进行编码
: c. C2 ^( r9 S0 i/ F' BE.把它存在文件中,再用convert_uuencode()进行编码6 ]$ z* l% p4 u" W8 J6 k
- M) B1 ?0 A* G3 l. d( w
$ S- y7 o- \( h5 a14.要确定需要嵌入在MIME/multipart 邮件中的文件该使用什么MIME类型,以下那种方法最好?/ d2 X4 ~5 T$ O5 A0 I
( n, b0 f6 f: H0 m# ^8 L
A.堆一个检测脚本出来" V( d% r0 W) [* C+ @6 k
B.创建一个MIME类型和文件后缀名的列表,根据后缀名选定需要的MIME类型
: q2 b7 u$ k. \2 Q: HC.写一个识别文件MIME类型与内容是否相符的函数9 X+ C+ F, @% d7 H' R E" f
D.使用mime_content_type函数
" K' z4 R8 v/ L6 L. s+ ^" |E.把文件上传到外部服务器上& X' w, h a4 X# l0 a8 o5 m3 D
$ e- a. F T7 i
! j/ s, }4 x0 r! k+ u+ U. `. E15.在UNIX环境下使用本地安装的sendmail,如何才能随意设置邮件的发件人名字与发件人地址?(三选)6 x$ Z8 h8 q/ T
/ J5 w1 G( F+ D7 E. Y8 a
A.添加一个From头信息3 i9 |$ |0 m% r0 f
B.使用-f参数
. l0 X6 A j+ ^; Q [C.添加一个Reply-to的头信息
' B7 [9 ]& H/ C7 S7 ~# t9 Q7 FD.确保运行Apache的用户有修改sendmail设置的权利) E% D `% \! h9 [3 |; `7 |
E.确保Apache在root用户下运行/ {+ j' {! p$ r; f( O1 V& F# G: G- [
答案速查
/ f) v1 q r% F+ s2 \1:D
a: k( T7 H: k- y: x2:AD2 ^$ L3 C+ T& r% K
3:E
; `: X" o; m* w# D/ O$ h+ R/ w4:Content-Type:MIME2 W4 q) u+ g: l9 h$ ~, \* a! R2 @' l+ R
5:BC% q0 V' Q) _) e1 y3 E( L% T( s
6:A
1 ]5 H) y/ i3 C4 k/ y7:C
4 }- a0 K6 D' ^8:BCE8 K3 j$ Y- |, o) R9 ~7 q. ^# h
9:ACD2 v( s8 i5 b) {
10:B
/ {( ]/ N, L. b# }& G3 t2 X8 H11:D
" W1 w" s) j' f% |8 Y3 y2 `1 s12:CE
+ |& }9 w" c1 K13:D
3 Y- t0 _7 a1 F14:D
$ `% X- |* G/ z, G( w- y( X15:ABD
& j8 B+ D: W9 S& S5 q$ r* {, p
* b) D. K" `! I" S" ~) e0 y0 v- a# \; P
! i! i' b1 c' J0 Q V
答案详解
7 L' D+ U- S# j* d( M) I0 N4 O
' J: Z3 a% o5 D! j. F% u* b; h6 }1.列出的E-Mail地址中只有D不合法。A和B都是最经典、常用的电子邮件地址。C看起来不合法,但邮件传输代理(MTA)会自动过滤多余的空格。E可以在本地发送时使用。那么就只剩下D了,它里面有一个非法字符。
' F* q" X& b& n& Q; Z# j& M4 B6 F3 v* N9 R: U$ s
2.正确答案是A和D。UNIX版本的PHP需要用sendmail程序(或者功能等同的替代品)通过MTA发送邮件,Windows/Novell版本的则通过SMTP直接用MTA发送。然而,如果允许的话,Windows/Novell上的PHP也可以进行配置,来通过“sendmail封装器”模拟sendmail发信。也就是说PHP在这三个版本上能够以相同的方式实现此功能。注意,在Windows/Novell上使用mail()时,需要配置sendmail_from。而UNIX则把这件事交给sendmail程序自己来处理。
" ~1 M3 N' }+ y! ^+ F/ x
" ?, Q( k) j- k7 F2 I+ j3.PHP可以用mail函数发送任何格式合法的电子邮件,于是编写用SMTP发信的PHP脚本成为了下策。要在E-Mail中添加额外的头信息,则必须向函数传递$additional_headers参数,每个头信息以一个回车符和一个换行符结尾(\r\n)。发送复杂的邮件,比如带附件的或者HTML格式的邮件,则不仅需要添加额外的头信息,还要添加MIME类型。所以答案是E。
) T0 Y4 a5 `& E6 u/ [/ x' C+ H
4.发送由多个部分组成的MIME邮件时,你必须指定一个分隔符(任何US-ASCII字符串),它必须不同于邮件主题中任何一个部分。分隔符必须与MIME信息中嵌入的任何一部分都不同。分隔符在Content-Type: MIME中定义。/ n7 \/ s& r n2 I; K4 ?4 u& B6 O
+ ^' p4 S, N- T; ?' M5.有两个选项指出了在HTML邮件中包含图片等资源的正确方法。最快的方法就是直接引用一张远程图片。然而,图片以及其他资源能够以MIME内容块的形式嵌入MIME邮件自身。这些内容块会被赋予ID,可以通过把src属性设置为cid:资源标识加内容ID的方式来调用。因此答案B和C正确。- f4 q' H' k. h4 T; H
3 w8 G) R" \* O" \" S3 W1 C
6.mail函数的最后一个参数用来向sendmail程序传递参数,不过这只能在安装了sendmail的UNIX系统上进行。如果Windows/Novell系统上配置了sendmail_path,那么这个参数同样也是可用的。. K: b; F5 V! Y- Z
5 w9 i+ a9 I1 C u3 b$ p7.答案是C。MIME头信息里的内容编码(Content-Transfer-Encoding)用来指出MIME邮件中各个片段的编码。头信息中包含一组指出了编码算法的二进制数据。默认情况下,7bit,quoted-printable,base64,8bit和binary是可用的编码类型。不过任何人也可以通过使用x-<unique name for encoding>来声明自己的编码格式。/ g4 r8 R- f6 L9 N1 Y* w
" [7 I5 q7 x9 W, |
8.正确答案是B,C和E。分隔符是MIME邮件中至关重要的一部分。虽然分隔符的长度没有官方限制,但由于分隔符由文本字符构成,因此它绝对不能出现在邮件主体中,否则就会造成混乱。考虑一种灾难性的情况:假设我们用John做分隔符,那么邮件中提到的人名John就会分隔邮件,导致邮件内容的混乱。- y7 a }; \1 a
% N2 z. J; ~- j
9.要从给定的文本信息中创建一份合法的MIME邮件,正确的答案是A,C和D。MIME邮件在开头处必须有MIME-Version头信息,而邮件的每个片段(包括“root”片段)都必须有Content-Type和content-transfer-encoding这两个部分。答案中提到的另外两个头信息是可选的:Content-Disposition用来指出片段要如何显示(比如显示为附件),Content-ID是片段中的各个内容的唯一识别符。8 |$ U( I0 ^8 c4 U, y; r
+ I5 g2 `9 k0 |" Z& ~10.正确答案是B。这种特殊的MIME类型用来定义一个含多个内容相同的子版本片段的母片段。比如说,一个multipart/alternative片段包含一个text/plain和一个text/html版本的片段。然后由电子邮件客户端选择一个最合适的版本来显示给用户。通常情况下,最好放入一个文本格式的版本,这样不支持MIME的邮件客户端也能正常读取。
$ T+ n1 m! m6 k
- Q! C) o7 L( d- j, ?1 H1 [11.在类UNIX系统中,PHP依靠sendmail程序来处理邮件。而在Windows中,除非已有sendmail包装器,否则将使用服务器的SMTP配置来进行。答案是D。
+ F3 X3 z2 K& u5 N! w1 l$ B# C% u' T
12.在普通文本邮件中使用htmlentities()不能防止跨站攻击,反而可能会让邮件内容变得不可读。强制使用POST传递变量只能让攻击变的困难,但并非绝对安全。确保E-Mail文本域(将变成To:的部分)中没有换行符,能够防止恶意用户把自己的邮件地址添加进收件人地址中。因此答案是C和E。# U' M& _' b4 [7 o: c! o( w
# T8 `! K! u7 M3 d2 a! ~1 T2 _13.把数组序列化成一个字符串是传输这个数组的正确方式——第一步先让数组变得可以通过E-Mail网络传输。接下来你需要对它进行编码,以使得它能够安全传输。在PHP4中,最简单的方法是用base64_encode把它编码成每字符7bit的形式。答案是D。9 x% y- k0 d- I
; H ^! M# e; W, w: A) W4 D
14.要判断一个文件的MIME类型,最简单的方法是使用mime_content_type函数。答案是D。注意,虽然别的扩展库里有能更好的解决这个问题的函数(译者注:比如PECL的FileInfo),但在这里使用mime_content_type仍然是可以的。
$ |! V2 G8 S( b, t; S
. g m; f: j- g1 q15.在头信息中添加From不能完全保证sendmail不会在邮件中重写你的发件人地址。事实上,你需要通过发送器向sendmail传递-f参数。除此之外,你还必须确保运行Apache的用户有修改头信息中的From内容的权限。因此答案是A,B和D。 |
|