返回列表 发帖

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

没有了E-Mail,这世界会变成什么样?网络交流把人们拉得更近,让公司能够更有效的开展业务,不幸的是,也带来了垃圾信息。1 u2 ~+ H& S; G3 w4 O0 r2 Q
还好,你不需要成为一个反垃圾邮件专家就能使用PHP处理电子邮件的功能。事实上,不管你是在运营一家在线商店,还是在编写一套论坛程序,你都会发现发送邮件是你工作中很重要的一部分——与用户保持联系这点非常重要。
' v7 P8 n8 a4 V- D# z用PHP编写邮件管理脚本很简单,但也不失挑战性。如果你只是想发送一封文本邮件,mail函数对你来说就够了。而如果你需要处理更复杂的电子信息——例如HTML邮件和附件时,那么你就需要深入学习一下E-Mail的工作原理了。
( U8 \/ C0 n6 i) n1 p) m. D* |1 c/ K& F+ W# n1 j

! q  W8 X/ L6 A: s$ q" G$ ?. T/ T问题% Z3 e8 W4 O5 f* ]3 U+ o! u
5 @$ Y% _8 y9 Z9 R( O
1.以下哪个不是合法的电子邮件地址?
6 ^6 \1 V2 s/ h* F5 [) M* u6 v
2 J) H4 l. r  w# LA.john@89w.org0 P% J3 I" ]' n+ W( i( G1 b
B."John Coggeshall" <someone@89w.org>
2 w) `, M$ b+ K: l/ HC.joe @ 89w.org$ n+ r3 s1 z5 c
D.jean-cóggeshall@89w.org8 F5 k- y' O6 S0 e* {6 F2 b
E.john
9 ?& N" r- {+ Z( H; o' A) b$ x( H: A0 P9 i; Z
; g; [7 k  @3 q+ t
2.在PHP中,使用sendmail程序从Windows或Novell系统中发送邮件的方式,与从类UNIX系统中发送的方式不同。以下哪些选项说明了这个不同?(双选)
: S; F) n8 K  _- M$ c
. q+ D/ f$ ^- r  t: y# N4 q+ f- z) g  gA.Windows/Novell不需要第三方软件的支持就能实现该功能; p, n0 Q0 v! U4 n' d; B4 m
B.UNIX中,sendmail_from的配置来决定了邮件头中的From:信息。" N- Z' E9 N- E+ W- q+ ~, j
C.在Windows/Novell中,你无法发送有多个收件人的电子邮件,每个收件人都必须单独发送# t' L% B" X* l% }" \( K
D.有可能完全相同,这取决于sendmail_path的配置
4 z0 ?  X  n6 J; L1 E$ GE.不同与Windows/Novell,在UNIX中,你必须用SMTP和smtp_port配置好MTA主机和端口
( w8 V1 H- E# o! ?! H, K  X5 w0 V; h# n4 [. `' s

; y2 M$ H+ r( H- i8 q2 e3.通过PHP发送有多个收件人或者MIME兼容的邮件,需要遵循什么步骤?& E/ E" r. }, L& R. b

$ S" [0 Y! N' d) @5 B2 D" IA.将必要的头信息(header)通过$message参数(第三个参数)传递给mail函数
. @# w! U0 F6 A9 D  N! VB.用PHP代码,通过SMTP直接与MTA连接。' ], L; q: R' `& H2 E$ H
C.将附加的头信息传递给mail函数的$additional_headers参数(第四个参数),每个header一行。" S! ]! {" l1 f7 v; r
D.向多个收件人发送E-Mail是允许的。PHP不支持发送MIME E-Mail。
  Q% `% f9 ]+ A, I, |: HE.向mail函数传递$additional_headers参数,每个header一行,行以\r\n结尾& \( @( S  m* Y* d# ]1 r% w
5 s3 \! C% u4 z! a$ _5 F5 t/ ]

0 p* k* X: Q+ \3 T3 Y, }4.使用MIME发送有附件的邮件时,邮件正文和附件必须靠一个特殊的分隔符分开。MIME E-Mail的头信息里如何定义这个分隔符?1 ]0 ]/ T7 `1 O& c- v$ J: n
: f/ J; u- T, _! L, F
答案:____________8 Y" Z, E( r/ W, O
* s* G, G$ F! j

6 n# v4 R: s* h3 w3 e& B* v0 ]5.使用MIME发送HTML邮件时,经常会用到一些经典的HTML标签,比如用<img>嵌入图片。以下那些方法能做到这点?(双选)& t# y, Z. ^2 O+ ~
5 e* J1 H' _8 W2 g0 f& \/ ]0 r
A.直接用<img>标签把图片文件嵌入邮件内容中,邮件客户端能自动显示5 m/ w. b& N" `
B.通过给<img>标签添加一个URL的src属性来调用外部服务器上的图片
$ B+ y; _, k( R$ AC.把图片作为MIME内容直接嵌入邮件中,再把<img>标签的src属性指定为内容ID+ |) K* K# r4 T
D.把图片作为附件,再把<img>标签的src属性指定为图片的文件名
  L. \: m0 g( E: d; z, mE.只有一个答案正确
+ p2 l+ I! ]2 ^- [: m  m+ ?; m" G" i+ o0 t; q

# Z# D( }. x5 n7 _" H/ Z6.以下那种情况会用到mail函数的第五个(最后一个)参数$additional_parameters?
5 m9 J4 [: @) A3 `0 _4 ~
( h* i' O8 ?4 O, \  K! G3 P. D/ FA.从UNIX或Windows/Novell发送邮件时都会用到
7 n4 W7 m/ Z! u! E& P$ `) K  X6 v3 wB.只有在Windows/Novell平台上用SMTP命令向MTA发送邮件时. M7 F3 V% e+ J4 r3 w2 \% I
C.只有在和sendmail或一个指定了sendmail_path的打包程序协作发送时
6 m/ U" Y1 X" n" K( H7 G  V& OD.PHP里用不到这个参数' u7 R; \3 r; e

, D9 c/ P6 H" l2 J
, P$ t* K0 P8 x6 ?7.以下那种情况需要在头信息中添加邮件内容编码(Content-Transfer-Encoding)?
& g- Q: h; i" ?& n% c' }" k) w" L3 N' o) K; k
A.只有在发送非普通文本(ASCII)数据时, ]. J, M2 A- w# T* y9 Y" G) g  a4 a
B.需要指出E-Mail的格式时,例如HTML,普通文本(plain text),富文本(rich text)
+ T0 Y7 A6 g( a1 E, x: ?C.任何时候都可以用它来指出MIME的编码类型2 F# {& V# |" K2 J9 J, c
D.只能用来指定特殊的编码格式(例如base64)
% X6 ^. E; S  V, h, ?' J) fE.以上都不对' ?0 \/ D7 F. d# c, ~
* l- y' c: \2 T1 K* e2 Q; I
8.以下关于在头信息Content-Type中定义的MIME分隔符的描述,哪些正确?(三选)
2 v. i& `( g) q) G% g  B4 d! h( N2 r3 q
A.分隔符至少要8个字符6 n6 Z. {" x+ S( M
B.分隔符必须以两个连字号作为前缀(例如:--abcdefghi)和后缀来表示起止(例如:--abcdefghi--)
2 B, f2 @. i3 }C.分隔符在MIME邮件中必须是独一无二的
+ e% w$ @# g" J. w* x' LD.分隔符不能嵌套的其他分隔符中6 J( Y, u5 i' f" p  a2 r
E.用什么做分隔符都无所谓
7 w' I* a6 n  ?2 W; c4 d2 ?# i3 d+ _% _& g4 w1 R

) [: v( v7 u) T9.考虑如下E-Mail:
' j6 N" B7 z+ h: B6 M
9 ^8 `4 ]# v  `& N2 ~7 b- XFrom: John Coggeshall <john@php.net>
: E1 b# ~1 I% C; f8 S  aTo: Joe User <joe@example.comt>
  `" N+ a" Z$ w, }1 N# M) pSubject: Hello from John!/ W& q  A: h4 g* p4 R+ h4 E
Date: Wed, 20 Dec 2004 20:18:47 -04001 d- |/ [: p' V/ V9 H, A' u( @$ D
Message-ID: <1234@local.machine.example>' p7 s! O5 L% ?) ]. ?3 A
Hello, How are you?
# M. v) j- A- Q  I0 w% s/ x  w0 |) L
在头信息里添加什么才能让它成为一份MIME邮件?(不定项选择)
) y2 m  H0 \+ w7 a6 U/ V9 C% b# g6 I2 ]7 ]
A.MIME-Version& Y, C3 U% X# ~8 ?
B.Content-Disposition  {" y2 H) _) x( D/ z% ~: C
C.Content-Type) }2 Q0 H4 D9 x" _: t2 H
D.Content-Transfer-Encoding
+ w: o  N# p9 OE.Content-ID
: {# c  k* l' [) E4 j0 L
/ p) e7 V) d9 a" E5 B# ]
/ v% F9 v8 S5 W  `8 z& a  X9 ?1 A; Q10.发送一封包含HTML、富文本和普通文本三个版本的邮件,要想客户端能选择一个合适的版本打开,MIME的content-type应该是什么?" k" \# Z) e8 [' F! K! Q. `

8 Y. A# i+ T9 R' jA.multipart/mixed
, ?8 v2 j2 {" k5 nB.multipart/alternative
( _) w& O( W4 U  }2 I2 o2 eC.multipart/default- {  V& y* e  p& f
D.multipart/related
' O( N! W: d  e$ ^  mE.不可能用content-type实现; {) g! G8 B& w4 ~- c: i4 X1 J1 x; ^
+ s2 P6 y# u4 w$ J- `% k

# @$ L& m5 `4 i# m& S9 K! r# P11.假设你的机器上没有安装sendmail,要想mail函数能在Windows下使用,需要做什么?" x4 N8 J" e/ ]; J5 K3 x+ `

# C2 \5 [/ y* O7 i7 b! ]A.安装sendmail服务器4 E: I/ u/ @; @
B.安装Microsoft Exchange
1 K1 ]. L  A$ S% o% RC.在你的电脑上安装任何一种邮件服务器3 y1 D4 V8 ~/ Q; D
D.改变php.ini的设置
0 R! e- @/ h8 I  {' o1 F) ?& C) ^4 jE.写一个连接公共电子邮件服务器的脚本' j; A9 t) k/ H" A& ]

  p$ \: [, {0 p1 z  J. \' Y1 x* f  S8 Q" R7 ~
12.有一个向用户提交的地址发送指定内容的文本邮件的表单,以下哪种方法有助于防止通过该表单进行跨站攻击?(双选)4 w1 ^# N$ K0 R; U% N+ \- `
, U$ q, \! T, v  x; r7 g
A.使用GET方式传值# ?+ W" P# M# j: q
B.用htmlentities()处理电子邮件地址) |$ R, Z- T' g7 ?
C.使用POST方式传值5 F# h) \3 p; d  U
D.用htmlentities()处理邮件正文
; i! z8 m. Z% a/ r- Y9 V3 f/ O; OE.确保填写邮件地址的文本域不能有换行符: s6 T) O  Z# `; K: ~$ e
) G5 v3 j4 Z- E( q- u, w* h
: D$ C0 x/ a3 {# Y' v
13.如何将一个数组作为附件发送,并要能在接收后重新组合?
2 Z% Q, j1 K' K' ~' C  a4 {9 t, y3 h( V$ x) i
A.用serialize()把它转换成字符串,再用htmlentities()处理一下- v: G6 p, ^* g0 m9 Y1 I' W3 a
B.把它存在文件中,并用base64_encode()进行编码
! m6 F- _. ^, s/ \) r$ M$ bC.用serialize()把它转换成数组9 n; _  I, I2 r9 M% F% k$ ?
D.用serialize()把它转换成数组,再用base64_encode()进行编码  u. X" P1 `. u; R" G+ X
E.把它存在文件中,再用convert_uuencode()进行编码
5 r. {8 X! Z( [5 C  g' D+ `" ~9 ^' v" Q; G
7 K: {/ u4 d* r& f+ F
14.要确定需要嵌入在MIME/multipart 邮件中的文件该使用什么MIME类型,以下那种方法最好?$ P9 {+ o" d8 B) m0 F9 l

' q& |4 w/ D* V) YA.堆一个检测脚本出来
5 b/ y% n* t* D3 SB.创建一个MIME类型和文件后缀名的列表,根据后缀名选定需要的MIME类型
- v2 E$ M+ `! O' z9 lC.写一个识别文件MIME类型与内容是否相符的函数
1 L: y) A( ]- S- Z' b# R# kD.使用mime_content_type函数
) j& T( l$ \4 b$ r4 G' a( i9 pE.把文件上传到外部服务器上: E# h7 O# h4 p9 f/ D+ l

5 }3 T) ^1 X& x3 [) C
( P: ?8 S! _+ E7 d7 o0 F, N15.在UNIX环境下使用本地安装的sendmail,如何才能随意设置邮件的发件人名字与发件人地址?(三选). E3 R7 G2 |+ q4 v

1 I; a- y. o- `" r- f, A$ F/ _A.添加一个From头信息
8 w' n  j( K! @6 NB.使用-f参数: E$ n$ n. x: |6 _
C.添加一个Reply-to的头信息, n3 t0 A. Z8 M: ?! e' V
D.确保运行Apache的用户有修改sendmail设置的权利: i4 u" E( Y( ~9 B
E.确保Apache在root用户下运行! w: _! G& r- Z# E9 M$ F( A
答案速查
8 N% |2 ~9 m( T1:D  g  \; U5 ]. ?$ P/ q
2:AD- d1 N% x: G* k3 {  G* p
3:E$ m& e3 j' j/ k$ }, S3 V
4:Content-Type:MIME5 _& g  z6 u  b" q* @# \4 V
5:BC& x( c5 R, `' |! V0 }7 {) [" a
6:A/ `' }& T' v: o6 u7 F1 T
7:C1 R/ B: b, K1 k
8:BCE( {. [: j& Y: a/ c" w6 O" l
9:ACD  T( h- P$ ]$ l7 l1 N: [% A
10:B
& r! S8 v- f# M! o; }11:D
* g& i- _5 d% t8 U" T5 |  _12:CE
, l/ e) |% k- e) w( l13:D/ |, C" g9 T: R# u  i
14:D
( h; @$ u+ a# O  p+ y2 o7 ^15:ABD8 k% \: L8 r1 {9 {

, e- j2 t5 |- F* F" E$ N' l
  o+ C6 S6 l# C. I$ C) J% U% x5 O5 P, o" _" S* D4 J2 r" c$ i# X0 i6 M
答案详解) P7 u% b& |  k- w6 G5 B
' C4 O" l6 o3 N" N
1.列出的E-Mail地址中只有D不合法。A和B都是最经典、常用的电子邮件地址。C看起来不合法,但邮件传输代理(MTA)会自动过滤多余的空格。E可以在本地发送时使用。那么就只剩下D了,它里面有一个非法字符。  }& B$ c  P! F" u' S  b+ _+ t& g

5 e. G) @2 L; h( E; v6 j2.正确答案是A和D。UNIX版本的PHP需要用sendmail程序(或者功能等同的替代品)通过MTA发送邮件,Windows/Novell版本的则通过SMTP直接用MTA发送。然而,如果允许的话,Windows/Novell上的PHP也可以进行配置,来通过“sendmail封装器”模拟sendmail发信。也就是说PHP在这三个版本上能够以相同的方式实现此功能。注意,在Windows/Novell上使用mail()时,需要配置sendmail_from。而UNIX则把这件事交给sendmail程序自己来处理。
5 C: l1 c& w, t1 K3 _! p- v8 \& U/ V* E& r5 ]5 `7 J
3.PHP可以用mail函数发送任何格式合法的电子邮件,于是编写用SMTP发信的PHP脚本成为了下策。要在E-Mail中添加额外的头信息,则必须向函数传递$additional_headers参数,每个头信息以一个回车符和一个换行符结尾(\r\n)。发送复杂的邮件,比如带附件的或者HTML格式的邮件,则不仅需要添加额外的头信息,还要添加MIME类型。所以答案是E。6 O# q% k% d7 @7 B* }6 x) T# x

4 U4 C% I8 X" o( I$ S# l. r1 f4.发送由多个部分组成的MIME邮件时,你必须指定一个分隔符(任何US-ASCII字符串),它必须不同于邮件主题中任何一个部分。分隔符必须与MIME信息中嵌入的任何一部分都不同。分隔符在Content-Type: MIME中定义。2 j' K( d2 F* |3 R
5 N3 Q, M+ x& g, c! e- x
5.有两个选项指出了在HTML邮件中包含图片等资源的正确方法。最快的方法就是直接引用一张远程图片。然而,图片以及其他资源能够以MIME内容块的形式嵌入MIME邮件自身。这些内容块会被赋予ID,可以通过把src属性设置为cid:资源标识加内容ID的方式来调用。因此答案B和C正确。
' s" ?0 c" m; w+ }! K7 P
, x& @  O8 a$ {* ~6.mail函数的最后一个参数用来向sendmail程序传递参数,不过这只能在安装了sendmail的UNIX系统上进行。如果Windows/Novell系统上配置了sendmail_path,那么这个参数同样也是可用的。
, u7 }+ [1 O4 L! J9 ^4 D
5 e0 ?" G2 a8 D  d0 \3 U& @7.答案是C。MIME头信息里的内容编码(Content-Transfer-Encoding)用来指出MIME邮件中各个片段的编码。头信息中包含一组指出了编码算法的二进制数据。默认情况下,7bit,quoted-printable,base64,8bit和binary是可用的编码类型。不过任何人也可以通过使用x-<unique name for encoding>来声明自己的编码格式。4 h& y$ k( T' R/ ~3 [

! E" c3 A/ e, R$ S  q+ i8.正确答案是B,C和E。分隔符是MIME邮件中至关重要的一部分。虽然分隔符的长度没有官方限制,但由于分隔符由文本字符构成,因此它绝对不能出现在邮件主体中,否则就会造成混乱。考虑一种灾难性的情况:假设我们用John做分隔符,那么邮件中提到的人名John就会分隔邮件,导致邮件内容的混乱。. g5 b  a6 b$ `' m5 G1 M1 B* Q* W
9 e) W# W) U1 e/ p, q: I& H
9.要从给定的文本信息中创建一份合法的MIME邮件,正确的答案是A,C和D。MIME邮件在开头处必须有MIME-Version头信息,而邮件的每个片段(包括“root”片段)都必须有Content-Type和content-transfer-encoding这两个部分。答案中提到的另外两个头信息是可选的:Content-Disposition用来指出片段要如何显示(比如显示为附件),Content-ID是片段中的各个内容的唯一识别符。
: m0 }2 ]" z( T- g: X* C) }+ T7 f( y5 u" |2 W& K# e0 E0 A
10.正确答案是B。这种特殊的MIME类型用来定义一个含多个内容相同的子版本片段的母片段。比如说,一个multipart/alternative片段包含一个text/plain和一个text/html版本的片段。然后由电子邮件客户端选择一个最合适的版本来显示给用户。通常情况下,最好放入一个文本格式的版本,这样不支持MIME的邮件客户端也能正常读取。
" H. k+ k" m, s$ w( j' L
6 {) B* M/ x& B+ q11.在类UNIX系统中,PHP依靠sendmail程序来处理邮件。而在Windows中,除非已有sendmail包装器,否则将使用服务器的SMTP配置来进行。答案是D。
! {7 w: a) w6 B6 M7 ^3 K; f
0 S  {0 I* w6 P% F% s4 x1 w/ R' y12.在普通文本邮件中使用htmlentities()不能防止跨站攻击,反而可能会让邮件内容变得不可读。强制使用POST传递变量只能让攻击变的困难,但并非绝对安全。确保E-Mail文本域(将变成To:的部分)中没有换行符,能够防止恶意用户把自己的邮件地址添加进收件人地址中。因此答案是C和E。
4 K9 ^# X- h8 ^& P# B4 I7 F% a2 }4 G
13.把数组序列化成一个字符串是传输这个数组的正确方式——第一步先让数组变得可以通过E-Mail网络传输。接下来你需要对它进行编码,以使得它能够安全传输。在PHP4中,最简单的方法是用base64_encode把它编码成每字符7bit的形式。答案是D。) r" u& b8 h) r; m* J" x4 B

  [2 w. P0 a; ?( q- D  W14.要判断一个文件的MIME类型,最简单的方法是使用mime_content_type函数。答案是D。注意,虽然别的扩展库里有能更好的解决这个问题的函数(译者注:比如PECL的FileInfo),但在这里使用mime_content_type仍然是可以的。
6 m& p# Y7 T* N6 T& l6 E# g6 Z& E  z4 y3 t( I% F! S/ ?- ]
15.在头信息中添加From不能完全保证sendmail不会在邮件中重写你的发件人地址。事实上,你需要通过发送器向sendmail传递-f参数。除此之外,你还必须确保运行Apache的用户有修改头信息中的From内容的权限。因此答案是A,B和D。

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