|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14325
- 金币
- 2448
- 威望
- 1647
- 贡献
- 1396
|
[Zend权威认证试题讲解]第八章 - 处理电子邮件
没有了E-Mail,这世界会变成什么样?网络交流把人们拉得更近,让公司能够更有效的开展业务,不幸的是,也带来了垃圾信息。
& u1 ?* D1 o& s: ~ u: u. ?还好,你不需要成为一个反垃圾邮件专家就能使用PHP处理电子邮件的功能。事实上,不管你是在运营一家在线商店,还是在编写一套论坛程序,你都会发现发送邮件是你工作中很重要的一部分——与用户保持联系这点非常重要。
: w5 a3 \$ v6 @# N- R) t0 b& w" \用PHP编写邮件管理脚本很简单,但也不失挑战性。如果你只是想发送一封文本邮件,mail函数对你来说就够了。而如果你需要处理更复杂的电子信息——例如HTML邮件和附件时,那么你就需要深入学习一下E-Mail的工作原理了。/ j9 c3 B! L' S$ W* I' z
5 W7 b$ n3 j0 k9 R$ S P
' I: B2 R- N. ^ S/ U问题
; s1 t2 H- h, z4 P1 O' r1 k* t: j1 T: Z+ G4 _+ G3 w# M9 s0 M- j( H
1.以下哪个不是合法的电子邮件地址?
. ]9 p8 k% [2 i# i. x2 x: ^* _ I( x2 m' k" r! u3 C5 s' B
A.john@89w.org
$ ]5 F' [2 \4 I7 Q0 y% {B."John Coggeshall" <someone@89w.org>3 f* n8 O" {; Y5 q& J
C.joe @ 89w.org+ w6 ?# V5 U$ P: t- f& |
D.jean-cóggeshall@89w.org+ u/ a) K/ }& ^9 S
E.john" T& _0 l2 P0 ?6 ^1 B6 u& v
; Y' d( b2 l1 Q K7 G v
- l& S' Z3 W( F2.在PHP中,使用sendmail程序从Windows或Novell系统中发送邮件的方式,与从类UNIX系统中发送的方式不同。以下哪些选项说明了这个不同?(双选)
& R6 n' j% Q# H7 C& T% {- d X: ]+ B% p) H0 Z0 ?
A.Windows/Novell不需要第三方软件的支持就能实现该功能/ ?0 g+ M+ ]; R! n
B.UNIX中,sendmail_from的配置来决定了邮件头中的From:信息。
+ ]5 _ S) h: ^; A7 d9 ]( C) L: x5 zC.在Windows/Novell中,你无法发送有多个收件人的电子邮件,每个收件人都必须单独发送; f* h- S3 n5 v: y& F* x6 j
D.有可能完全相同,这取决于sendmail_path的配置' n+ E) M: J+ l" n8 D% e
E.不同与Windows/Novell,在UNIX中,你必须用SMTP和smtp_port配置好MTA主机和端口% o- {+ D" q' m( i( C! |
, i6 i. L* W6 ]0 D! `0 P
8 E" D! g: r0 L- D+ Y4 ^) x3.通过PHP发送有多个收件人或者MIME兼容的邮件,需要遵循什么步骤?
3 A o9 @5 L; t7 L$ J) V
5 c1 [4 v; ^! |* _# [8 Z6 x* ^A.将必要的头信息(header)通过$message参数(第三个参数)传递给mail函数
) \( {' a) F, @. ]. I) pB.用PHP代码,通过SMTP直接与MTA连接。
5 g2 h% ], o$ z7 y# _ L3 P7 ]C.将附加的头信息传递给mail函数的$additional_headers参数(第四个参数),每个header一行。
: ~6 L( }- O! N8 N" }3 _- [D.向多个收件人发送E-Mail是允许的。PHP不支持发送MIME E-Mail。# w) d. G# {# K1 Q( w& l- T" {
E.向mail函数传递$additional_headers参数,每个header一行,行以\r\n结尾: y" v2 c" t" E% \& }& G6 o* u. A
8 b w3 U' o' {# @8 ~ g6 [6 m0 w
' @6 Q8 y6 f# H9 Z( j/ a! V3 E9 H _3 I4.使用MIME发送有附件的邮件时,邮件正文和附件必须靠一个特殊的分隔符分开。MIME E-Mail的头信息里如何定义这个分隔符?0 d' C/ G N2 `
5 c3 w) q; S, ]3 x+ O答案:____________2 H G T* B+ f; _3 l; J) @# {
' u7 j8 S. T' O/ V
; R/ B2 {# z* _; u3 k7 `$ t5.使用MIME发送HTML邮件时,经常会用到一些经典的HTML标签,比如用<img>嵌入图片。以下那些方法能做到这点?(双选); v7 S+ u: H n8 v6 ?6 ~8 J
5 |4 W) @# `2 \. m2 }
A.直接用<img>标签把图片文件嵌入邮件内容中,邮件客户端能自动显示2 k1 c: q% `% n4 x6 k
B.通过给<img>标签添加一个URL的src属性来调用外部服务器上的图片
! V0 D! q" X, d+ Q" mC.把图片作为MIME内容直接嵌入邮件中,再把<img>标签的src属性指定为内容ID
: @: `+ r* c; \5 c# N$ D: s% R) p4 jD.把图片作为附件,再把<img>标签的src属性指定为图片的文件名" o' l$ U1 O) A0 A8 R
E.只有一个答案正确6 \) c$ }$ h* E) [+ X1 I$ p
+ d* O1 c: C9 i3 h$ y5 |% K( A6 M5 t2 L
6.以下那种情况会用到mail函数的第五个(最后一个)参数$additional_parameters?& d* Q+ w8 P# X3 }0 u0 W
: ]( b1 |! q7 D
A.从UNIX或Windows/Novell发送邮件时都会用到
; h' q) C- _3 s( I4 e" N) KB.只有在Windows/Novell平台上用SMTP命令向MTA发送邮件时
0 E& y+ R3 {% a9 G6 p. DC.只有在和sendmail或一个指定了sendmail_path的打包程序协作发送时
8 W4 ~; F" J, B5 f( K' ?1 uD.PHP里用不到这个参数2 S0 F, a# |# \4 G' F
& F5 y9 O$ l, ]$ | O V3 v% ^2 w: Z6 h2 C
; O/ } U! L' E/ K3 C7.以下那种情况需要在头信息中添加邮件内容编码(Content-Transfer-Encoding)?
6 y, ^" A% y9 N4 j" Z: s( a3 h6 z4 w9 H; C2 }
A.只有在发送非普通文本(ASCII)数据时/ h! G+ {% j. E
B.需要指出E-Mail的格式时,例如HTML,普通文本(plain text),富文本(rich text)# |# q. X- f% m$ e) J# f
C.任何时候都可以用它来指出MIME的编码类型5 |. k( H6 V8 Y) H& T) `/ Z
D.只能用来指定特殊的编码格式(例如base64)$ x* L" o. M s" @9 L
E.以上都不对5 D. H6 H* D4 O- X% D Y) I, X
! w' G4 y: E/ N& {6 u
8.以下关于在头信息Content-Type中定义的MIME分隔符的描述,哪些正确?(三选)
: t7 q: ~/ e: n: B8 [
, }- y' D+ s. FA.分隔符至少要8个字符8 F! U9 E: `! D Q# H: }. l* h) W
B.分隔符必须以两个连字号作为前缀(例如:--abcdefghi)和后缀来表示起止(例如:--abcdefghi--)6 Z) Z$ v" B% o* b! H5 t
C.分隔符在MIME邮件中必须是独一无二的8 ~- j- e& n1 Z4 c0 C6 v; y
D.分隔符不能嵌套的其他分隔符中- e- L5 E/ E) W9 }, L/ Z* ?
E.用什么做分隔符都无所谓3 B* K$ s1 Z% W/ J7 i
* h9 A2 M8 B; \" C a/ R( ~2 [4 h2 f
8 _- ]5 s/ F) x# J, ^& T0 A9.考虑如下E-Mail:
4 s: B6 P" `( S
3 p. O2 L& S: k9 [" m+ X8 UFrom: John Coggeshall <john@php.net>
. B0 A. h' u+ x$ n8 G% rTo: Joe User <joe@example.comt>
' O+ }2 r) B3 q* K: w+ @$ ~Subject: Hello from John!
0 D) D3 P% c. J. t& E* O# l$ LDate: Wed, 20 Dec 2004 20:18:47 -0400: P: j1 ?% K2 _' |( J8 B# P
Message-ID: <1234@local.machine.example>4 |% z6 @4 ^$ v$ ^
Hello, How are you?
1 ^ Q5 h6 J$ _; q# }1 j7 }/ n7 b( d- C
在头信息里添加什么才能让它成为一份MIME邮件?(不定项选择)3 H6 |: K/ M, S6 S8 s
( l* G$ e; z% R/ i# u
A.MIME-Version5 U {+ F, L( E9 M3 q
B.Content-Disposition
3 G }$ \# x+ t3 yC.Content-Type
, l5 g4 [* C# w" V4 KD.Content-Transfer-Encoding
# {. D& `/ z8 YE.Content-ID
# W6 }" ^! y' f! a9 q+ T; x* V5 J. a
" S- P8 x9 {4 |5 }2 M o, X1 Y10.发送一封包含HTML、富文本和普通文本三个版本的邮件,要想客户端能选择一个合适的版本打开,MIME的content-type应该是什么?
+ P' y5 K* s, ^+ D: S& u+ x z' y6 D, a/ m
A.multipart/mixed4 N J; ~ l& f6 H+ Z* N/ D: _3 A
B.multipart/alternative
0 c- i+ S3 @/ `+ CC.multipart/default
0 I1 b' F. F& P* ^# }/ hD.multipart/related' ?' ~1 }2 M$ @' S' D. | H0 _# V
E.不可能用content-type实现, }. {8 L; M; K1 Q4 |1 x
) N: ], E, T0 g" o& k5 F
$ A% Q9 l$ q9 c( l7 g2 \. h# G
11.假设你的机器上没有安装sendmail,要想mail函数能在Windows下使用,需要做什么?0 P4 N3 t3 A% S& Y; p8 N
9 m% A2 B# p+ ^ EA.安装sendmail服务器
: S5 l, m' N9 N% EB.安装Microsoft Exchange
) x5 Q3 T" Z) IC.在你的电脑上安装任何一种邮件服务器6 Y; K& d. a r0 c% ?
D.改变php.ini的设置
5 p/ v0 \7 t+ v y( p, s; c( lE.写一个连接公共电子邮件服务器的脚本
1 X3 k" J) {; ^" t* F8 f
t! T4 ?/ s5 p
m5 f5 d* x5 C4 ]12.有一个向用户提交的地址发送指定内容的文本邮件的表单,以下哪种方法有助于防止通过该表单进行跨站攻击?(双选)& L3 }) H' L$ I5 f
# i5 r2 [* M$ b, GA.使用GET方式传值
& U4 X# Y0 I7 a5 UB.用htmlentities()处理电子邮件地址
( `0 ?- u" Q1 U9 @+ `; C. Y# IC.使用POST方式传值. j6 e# l0 ~% k# R1 K9 N
D.用htmlentities()处理邮件正文' f! v8 s3 b; E* }9 s- J
E.确保填写邮件地址的文本域不能有换行符' V% `5 P0 E5 Z" H4 ~
/ o w- h7 l; v$ L
! t5 X! u' F9 g5 \5 N; J13.如何将一个数组作为附件发送,并要能在接收后重新组合?0 y/ y8 s& t9 B0 o7 P& Q" I
" A+ |, ]) u7 ~! R1 t* O# g. R8 nA.用serialize()把它转换成字符串,再用htmlentities()处理一下" A P' U, X `! Y' \ q4 z
B.把它存在文件中,并用base64_encode()进行编码
& V& j1 `' {& t3 e5 \. }6 KC.用serialize()把它转换成数组
3 }1 ^: }8 _7 D" \" ND.用serialize()把它转换成数组,再用base64_encode()进行编码# m2 G7 L2 _, g; k4 `: b9 d
E.把它存在文件中,再用convert_uuencode()进行编码5 j8 [9 {, B+ y' j9 c0 W
M' K4 t( S. J: o9 M A: k# A8 s; T( b+ G* O" F7 E. i
14.要确定需要嵌入在MIME/multipart 邮件中的文件该使用什么MIME类型,以下那种方法最好?! K: S) B( T! s" a6 {1 d
7 A/ y! c' q7 B, A/ O
A.堆一个检测脚本出来
2 q4 _: Y! j. }+ c1 X4 sB.创建一个MIME类型和文件后缀名的列表,根据后缀名选定需要的MIME类型 u a/ \1 K& N7 F+ [$ G
C.写一个识别文件MIME类型与内容是否相符的函数$ j3 ?/ k7 c ^6 b2 I! y% n4 X
D.使用mime_content_type函数% r+ e6 | M; K2 _: }+ \: U
E.把文件上传到外部服务器上
" q$ [4 L4 V. r9 o" c
; ]1 n& }" ~" v$ l& A0 s" t
% v2 V, Y- d7 z" ~15.在UNIX环境下使用本地安装的sendmail,如何才能随意设置邮件的发件人名字与发件人地址?(三选)1 q5 c' a9 c8 L8 a& e U
. O/ Q' ^9 m. B, b: v3 d
A.添加一个From头信息. a; B) X2 z* {. W. q0 [
B.使用-f参数
, a: ~3 j- J. W* xC.添加一个Reply-to的头信息# W- j9 T0 X, ?
D.确保运行Apache的用户有修改sendmail设置的权利
6 G% x- i" _; ?; ?2 `8 ZE.确保Apache在root用户下运行/ K3 o9 r8 c; B
答案速查
% f# r! f: v: @: X& i& |; K1:D
7 i! k' M- z- V `) `& h5 `2:AD
; M( \+ F/ `" O. ~* Z6 |0 T* ~3:E
" P/ n6 ^1 Q) g! {6 m7 C4:Content-Type:MIME
1 B# E3 G5 g+ S8 m- }" [( r7 H5:BC
C0 f) s$ J6 n: k" l9 O" w& ~6:A
" r& c% u& o3 }& q4 |1 b' Z7:C: u8 i- D; z y5 Z( a
8:BCE
; ?* w6 ]# A$ E9:ACD
6 [/ @. `4 u# M; c: v2 ^5 q10:B
7 R* N4 X4 s2 i g. i- Y F11:D+ E5 l g, @3 T! A6 A
12:CE
4 s" C0 b3 t4 j% ]) `3 v& U! g- a h13:D
% k) d( G, G. E; Z8 v8 x& g% Y14:D; e7 j" r* P8 [, A8 R$ P$ t6 ~
15:ABD
% @% N0 K" }2 \ }, h- A1 Y! p, V% r7 c
0 }# n3 t6 M# u% H* a, ?
' g1 }& I& n5 ]9 i$ e1 D答案详解
; ]9 B# L: v- N6 C) G8 m
2 x" I& [ r! Z, O7 f+ Q1.列出的E-Mail地址中只有D不合法。A和B都是最经典、常用的电子邮件地址。C看起来不合法,但邮件传输代理(MTA)会自动过滤多余的空格。E可以在本地发送时使用。那么就只剩下D了,它里面有一个非法字符。/ A& s$ f+ O3 |8 e2 n: l( V
$ r; l1 r6 ^5 ]: U% x% O2.正确答案是A和D。UNIX版本的PHP需要用sendmail程序(或者功能等同的替代品)通过MTA发送邮件,Windows/Novell版本的则通过SMTP直接用MTA发送。然而,如果允许的话,Windows/Novell上的PHP也可以进行配置,来通过“sendmail封装器”模拟sendmail发信。也就是说PHP在这三个版本上能够以相同的方式实现此功能。注意,在Windows/Novell上使用mail()时,需要配置sendmail_from。而UNIX则把这件事交给sendmail程序自己来处理。
* K2 Z9 I4 S$ k; m8 S# V
+ M- E' U6 |: {0 d3.PHP可以用mail函数发送任何格式合法的电子邮件,于是编写用SMTP发信的PHP脚本成为了下策。要在E-Mail中添加额外的头信息,则必须向函数传递$additional_headers参数,每个头信息以一个回车符和一个换行符结尾(\r\n)。发送复杂的邮件,比如带附件的或者HTML格式的邮件,则不仅需要添加额外的头信息,还要添加MIME类型。所以答案是E。
* Z) i5 M& m6 x$ F$ N: m b
( A0 Y& d- o* ~4.发送由多个部分组成的MIME邮件时,你必须指定一个分隔符(任何US-ASCII字符串),它必须不同于邮件主题中任何一个部分。分隔符必须与MIME信息中嵌入的任何一部分都不同。分隔符在Content-Type: MIME中定义。3 z% @# ^; R) e9 ~
" v: M3 h* y( s+ B0 [* e# l5.有两个选项指出了在HTML邮件中包含图片等资源的正确方法。最快的方法就是直接引用一张远程图片。然而,图片以及其他资源能够以MIME内容块的形式嵌入MIME邮件自身。这些内容块会被赋予ID,可以通过把src属性设置为cid:资源标识加内容ID的方式来调用。因此答案B和C正确。
: g0 N, K( w$ E! e
5 p4 e6 ]9 C0 s6.mail函数的最后一个参数用来向sendmail程序传递参数,不过这只能在安装了sendmail的UNIX系统上进行。如果Windows/Novell系统上配置了sendmail_path,那么这个参数同样也是可用的。
4 P; q! T2 a( G
) P" g2 z% {& N0 O& H3 n* W7.答案是C。MIME头信息里的内容编码(Content-Transfer-Encoding)用来指出MIME邮件中各个片段的编码。头信息中包含一组指出了编码算法的二进制数据。默认情况下,7bit,quoted-printable,base64,8bit和binary是可用的编码类型。不过任何人也可以通过使用x-<unique name for encoding>来声明自己的编码格式。
$ J$ g7 [$ g9 l4 R2 S. B" K1 S2 u# D! n1 g' P. m! W. S2 O+ u
8.正确答案是B,C和E。分隔符是MIME邮件中至关重要的一部分。虽然分隔符的长度没有官方限制,但由于分隔符由文本字符构成,因此它绝对不能出现在邮件主体中,否则就会造成混乱。考虑一种灾难性的情况:假设我们用John做分隔符,那么邮件中提到的人名John就会分隔邮件,导致邮件内容的混乱。5 [% J+ f, J! i- H: }7 W) i/ i
/ l/ p6 q/ X. C
9.要从给定的文本信息中创建一份合法的MIME邮件,正确的答案是A,C和D。MIME邮件在开头处必须有MIME-Version头信息,而邮件的每个片段(包括“root”片段)都必须有Content-Type和content-transfer-encoding这两个部分。答案中提到的另外两个头信息是可选的:Content-Disposition用来指出片段要如何显示(比如显示为附件),Content-ID是片段中的各个内容的唯一识别符。4 l% Q- @6 h. w' A' `0 L8 G
& y1 }" d2 U7 _ q5 |6 p; k
10.正确答案是B。这种特殊的MIME类型用来定义一个含多个内容相同的子版本片段的母片段。比如说,一个multipart/alternative片段包含一个text/plain和一个text/html版本的片段。然后由电子邮件客户端选择一个最合适的版本来显示给用户。通常情况下,最好放入一个文本格式的版本,这样不支持MIME的邮件客户端也能正常读取。4 z* V; l/ I! z1 z) V$ b; C4 E' G
+ H$ U$ W1 }& ~11.在类UNIX系统中,PHP依靠sendmail程序来处理邮件。而在Windows中,除非已有sendmail包装器,否则将使用服务器的SMTP配置来进行。答案是D。
X9 s9 Q8 {; b! M5 e- K
1 X% E: C2 ~' c& I4 p12.在普通文本邮件中使用htmlentities()不能防止跨站攻击,反而可能会让邮件内容变得不可读。强制使用POST传递变量只能让攻击变的困难,但并非绝对安全。确保E-Mail文本域(将变成To:的部分)中没有换行符,能够防止恶意用户把自己的邮件地址添加进收件人地址中。因此答案是C和E。% A, q5 |; w, Y0 K
2 B& [3 S2 A$ K. \- H13.把数组序列化成一个字符串是传输这个数组的正确方式——第一步先让数组变得可以通过E-Mail网络传输。接下来你需要对它进行编码,以使得它能够安全传输。在PHP4中,最简单的方法是用base64_encode把它编码成每字符7bit的形式。答案是D。4 {0 }" B" f. @1 q$ _0 o# ?" d, J/ X
( q G% I8 [- o( ~14.要判断一个文件的MIME类型,最简单的方法是使用mime_content_type函数。答案是D。注意,虽然别的扩展库里有能更好的解决这个问题的函数(译者注:比如PECL的FileInfo),但在这里使用mime_content_type仍然是可以的。
: D: y1 ~8 y8 A; H
3 U) T( ^ i% p& J15.在头信息中添加From不能完全保证sendmail不会在邮件中重写你的发件人地址。事实上,你需要通过发送器向sendmail传递-f参数。除此之外,你还必须确保运行Apache的用户有修改头信息中的From内容的权限。因此答案是A,B和D。 |
|