返回列表 发帖

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

没有了E-Mail,这世界会变成什么样?网络交流把人们拉得更近,让公司能够更有效的开展业务,不幸的是,也带来了垃圾信息。$ W8 z$ n4 @0 b8 p* n
还好,你不需要成为一个反垃圾邮件专家就能使用PHP处理电子邮件的功能。事实上,不管你是在运营一家在线商店,还是在编写一套论坛程序,你都会发现发送邮件是你工作中很重要的一部分——与用户保持联系这点非常重要。+ k$ h* ?  f7 @# S, r1 Z7 b0 B
用PHP编写邮件管理脚本很简单,但也不失挑战性。如果你只是想发送一封文本邮件,mail函数对你来说就够了。而如果你需要处理更复杂的电子信息——例如HTML邮件和附件时,那么你就需要深入学习一下E-Mail的工作原理了。
6 N& R1 c& _- A3 }: y- j" N( O% [3 z1 l$ s# s# m
9 I4 a1 O$ L' _. }- k2 W& j/ e3 l3 K
问题) v4 j. @# N' U9 R/ \* {; S

4 m+ ~4 Q4 B% F1.以下哪个不是合法的电子邮件地址?* H4 U6 W! }/ L" D
* l( W. ~/ m+ O( t4 f* H
A.john@89w.org
* V: B! m& R0 T" K( `! fB."John Coggeshall" <someone@89w.org>
6 D4 D9 q- c0 A0 K/ ^$ \C.joe @ 89w.org2 t+ W1 `. r+ c3 k+ v
D.jean-cóggeshall@89w.org4 ^; y0 v3 P( v1 Q
E.john
& C" ~+ `. L. V, U8 }$ o1 @
0 }" G( C2 f& N; C: S- X( D, T6 a
+ d- i7 B6 \1 A* V2.在PHP中,使用sendmail程序从Windows或Novell系统中发送邮件的方式,与从类UNIX系统中发送的方式不同。以下哪些选项说明了这个不同?(双选)# N+ y/ C# V8 |& c/ ]0 J
" K9 O: f4 V  k6 t& N: g
A.Windows/Novell不需要第三方软件的支持就能实现该功能
1 h1 E# z  G, }B.UNIX中,sendmail_from的配置来决定了邮件头中的From:信息。
1 T8 R- |0 r$ u" kC.在Windows/Novell中,你无法发送有多个收件人的电子邮件,每个收件人都必须单独发送
: {& w% V; U2 c' v9 DD.有可能完全相同,这取决于sendmail_path的配置
; d, L, a0 ~4 E' H, @5 @1 v" o  ^E.不同与Windows/Novell,在UNIX中,你必须用SMTP和smtp_port配置好MTA主机和端口. B4 i. c$ l# M! `
. P& _0 l& u8 [# M

( t. T) M! f( J9 e7 C4 _3.通过PHP发送有多个收件人或者MIME兼容的邮件,需要遵循什么步骤?9 w, `$ q: W+ s6 e9 |

/ H- C3 G7 s4 {A.将必要的头信息(header)通过$message参数(第三个参数)传递给mail函数) U2 B' `! X* t% t2 E5 q
B.用PHP代码,通过SMTP直接与MTA连接。" |* e4 C5 f8 W: K: F5 O
C.将附加的头信息传递给mail函数的$additional_headers参数(第四个参数),每个header一行。' \3 }& S4 U1 r' C' r5 U; y2 H: ?
D.向多个收件人发送E-Mail是允许的。PHP不支持发送MIME E-Mail。
5 Q8 S* \. {! t' S, H6 {E.向mail函数传递$additional_headers参数,每个header一行,行以\r\n结尾/ \' ?; I% Q: {( M1 ~
6 f( C9 R. v- z: U: c0 g

$ g: [9 F! N$ w2 x' X2 A- i! _+ W/ H4.使用MIME发送有附件的邮件时,邮件正文和附件必须靠一个特殊的分隔符分开。MIME E-Mail的头信息里如何定义这个分隔符?' C; \0 M$ k! i

* q6 [% z5 g( ~, }0 s- {" K* x答案:____________
* N9 B# M/ c( P; M" t. U3 q- t8 B1 ]

' N  Q; K9 o. b  {7 ]5.使用MIME发送HTML邮件时,经常会用到一些经典的HTML标签,比如用<img>嵌入图片。以下那些方法能做到这点?(双选)$ i/ I& _6 j) K! f5 v. u" j. n1 Q

% ?6 {# P( u! H) L/ W3 v6 FA.直接用<img>标签把图片文件嵌入邮件内容中,邮件客户端能自动显示
! N$ q: g, p6 a0 bB.通过给<img>标签添加一个URL的src属性来调用外部服务器上的图片5 w+ ?! ^$ K% D' B  p% g. i
C.把图片作为MIME内容直接嵌入邮件中,再把<img>标签的src属性指定为内容ID1 p2 e3 j" I' i2 r% s1 B4 ]
D.把图片作为附件,再把<img>标签的src属性指定为图片的文件名  m8 S1 `" a# P0 w7 c
E.只有一个答案正确+ L- S8 t' {" ^, I$ q/ X

' o6 p8 d- D" O
! l; r+ _. Z4 Z$ u" W9 d- R6.以下那种情况会用到mail函数的第五个(最后一个)参数$additional_parameters?" Z, L: o; Y6 ?1 e3 o. `

. j8 k# ^& t- @+ KA.从UNIX或Windows/Novell发送邮件时都会用到
9 R" ]3 b2 E; R. Y7 y+ z" k* L( iB.只有在Windows/Novell平台上用SMTP命令向MTA发送邮件时+ S3 u: `( t* K$ Y1 H2 a
C.只有在和sendmail或一个指定了sendmail_path的打包程序协作发送时# K$ d7 a9 `! {& O5 I
D.PHP里用不到这个参数7 j8 _' K5 a7 [) A9 {

; n- L! C- J  {
( J8 G4 M/ W0 k! i  c7.以下那种情况需要在头信息中添加邮件内容编码(Content-Transfer-Encoding)?, L* H7 Z( }! i  n+ O

0 h) {. c! a. F" i7 {6 l1 I5 gA.只有在发送非普通文本(ASCII)数据时: A( a; F2 U" r1 n- A
B.需要指出E-Mail的格式时,例如HTML,普通文本(plain text),富文本(rich text)
( f/ g( B; y7 a. KC.任何时候都可以用它来指出MIME的编码类型
" `+ K' q. r, M8 @: O! X: OD.只能用来指定特殊的编码格式(例如base64)( H  @3 ^& r% P6 V  D  B
E.以上都不对# f# x6 x$ N/ n5 f
7 Z& p- r* L8 T! n9 ?
8.以下关于在头信息Content-Type中定义的MIME分隔符的描述,哪些正确?(三选)
7 ~, D1 o5 g/ F7 [$ M+ P* |  U( A8 X3 i: S* A" W% |  \2 \
A.分隔符至少要8个字符9 ]; p& {( M5 d
B.分隔符必须以两个连字号作为前缀(例如:--abcdefghi)和后缀来表示起止(例如:--abcdefghi--)
$ n! Q5 f0 ]6 P% Q3 C& w9 {C.分隔符在MIME邮件中必须是独一无二的& o( \: R: g) G: {
D.分隔符不能嵌套的其他分隔符中1 ?2 H# F! F7 H' L" `
E.用什么做分隔符都无所谓6 ?; k. u4 V1 Q4 S, _* `: ?
$ h7 E5 i/ z$ R) U2 q1 ^* `* ?/ ?

& \/ @4 }6 E, o. C! W% a, N8 }9.考虑如下E-Mail:
1 T) P' w# h7 ?& C5 ^6 E% k
5 F6 A/ R* x- {) a  PFrom: John Coggeshall <john@php.net>0 J1 u0 N$ o6 Q! V
To: Joe User <joe@example.comt>
, w: `" H7 E: ?& y; u3 }Subject: Hello from John!4 ]8 h  y: ~( ^+ g  \+ j
Date: Wed, 20 Dec 2004 20:18:47 -04004 R; b1 r/ w$ G1 Z/ I
Message-ID: <1234@local.machine.example>2 v* Z' k9 h9 s# G  Q* C
Hello, How are you?; Y' h0 h+ K( j7 h* P

& q9 N, d0 |/ p7 q& {$ t8 {在头信息里添加什么才能让它成为一份MIME邮件?(不定项选择)
+ ~/ ]/ D  l0 b9 r* A% O, G+ h1 R7 g9 a' Q" V4 L8 U$ P
A.MIME-Version
) _! R; C7 M4 w9 H# v. X7 NB.Content-Disposition  @2 D9 g) X& c6 M3 E- E* {
C.Content-Type
7 J% K6 y# S: ^( y: n0 p' tD.Content-Transfer-Encoding$ Y; v, Q. Z/ x- v
E.Content-ID8 j; I/ J2 x  h" f5 Y8 m
$ a; q- J. |6 v3 n0 I
1 N, e1 N# ?! P$ t* o
10.发送一封包含HTML、富文本和普通文本三个版本的邮件,要想客户端能选择一个合适的版本打开,MIME的content-type应该是什么?
: i7 |- i2 g% u" a
( N3 r4 j* F1 h% Q, I. zA.multipart/mixed  C! V4 v  x$ M" j; n1 ]& N1 T% L/ ^
B.multipart/alternative
1 W  b% Q+ b0 r7 q$ a6 kC.multipart/default& q0 F1 A( v- J7 J0 h: T: q& A! S
D.multipart/related
& f% I5 ?! j6 H! @E.不可能用content-type实现
- D* y# l; K# m: a: K( h: O( S/ P9 G
0 C/ d5 z1 Y/ X, J- h
11.假设你的机器上没有安装sendmail,要想mail函数能在Windows下使用,需要做什么?- z) Z" o+ X. w( B/ j7 }% Z

7 @$ ~8 o) _: U9 rA.安装sendmail服务器
5 R! Y7 {7 R6 c( \* d% VB.安装Microsoft Exchange% B# A$ n5 O( n/ m( {
C.在你的电脑上安装任何一种邮件服务器) A1 `+ Z) s' @1 |& t8 o+ j
D.改变php.ini的设置; F; k+ W: [$ q8 b- X7 F
E.写一个连接公共电子邮件服务器的脚本
5 c5 g. E+ M9 L3 _! H+ S7 ^4 z& g2 C4 n9 D* L' H

1 W0 w* x3 K8 {0 R9 x' |! d4 E12.有一个向用户提交的地址发送指定内容的文本邮件的表单,以下哪种方法有助于防止通过该表单进行跨站攻击?(双选)
, C$ t2 N  U4 C# D9 R1 N
( Y% a' h) t$ Q4 ]5 [2 C2 s3 D# |& |A.使用GET方式传值
; J$ s/ J3 o4 r' B, m! K$ @$ I1 i* kB.用htmlentities()处理电子邮件地址
" F+ v: K* z) q2 b: Z$ W/ f1 lC.使用POST方式传值
- O8 P+ ^: s: aD.用htmlentities()处理邮件正文0 y* y7 V9 [( K
E.确保填写邮件地址的文本域不能有换行符
+ j4 r5 a1 Y  w
/ G3 x6 z8 {9 f) g0 `9 E
. x* U- }8 D& R& a' ~13.如何将一个数组作为附件发送,并要能在接收后重新组合?
4 F. q: w7 P' l' K: a
* N( J: {5 ]4 cA.用serialize()把它转换成字符串,再用htmlentities()处理一下
+ S4 _# K5 a2 Y( iB.把它存在文件中,并用base64_encode()进行编码5 f/ G  J" w1 u! B
C.用serialize()把它转换成数组
. ~- m7 W! y* KD.用serialize()把它转换成数组,再用base64_encode()进行编码3 z* U( W; c" n5 R
E.把它存在文件中,再用convert_uuencode()进行编码
: {3 L# j( L( w9 v+ g& C6 j  N1 Y% _& F# D* n3 G- `* ?
7 ~6 J' }) V: G$ j5 t4 @) V! u
14.要确定需要嵌入在MIME/multipart 邮件中的文件该使用什么MIME类型,以下那种方法最好?
0 b5 ?, t* C% y6 `' G9 ~1 C" }) d$ u( S
A.堆一个检测脚本出来
& q1 F& X. @- V1 `B.创建一个MIME类型和文件后缀名的列表,根据后缀名选定需要的MIME类型! U0 ]8 Q- i: N  Q" u
C.写一个识别文件MIME类型与内容是否相符的函数) X. X- @* L6 ~6 \, P$ M& X
D.使用mime_content_type函数
- |" F( |  g) f9 p% HE.把文件上传到外部服务器上
# a5 g9 |3 ^# a9 S6 c5 Z8 l9 Q' }2 r- D8 Y+ g/ Z# S
. ^; f. g) C4 |2 |1 Z, S; Q
15.在UNIX环境下使用本地安装的sendmail,如何才能随意设置邮件的发件人名字与发件人地址?(三选)
* t5 l, N$ J( G  p$ p8 x
% d+ ]3 E. n2 WA.添加一个From头信息7 J- O- _6 r' N
B.使用-f参数
/ U7 i' t! K" V) l& v3 y/ MC.添加一个Reply-to的头信息% B' A) ~5 m& E0 }7 C
D.确保运行Apache的用户有修改sendmail设置的权利; |- ~0 _' w0 j9 d7 O- C
E.确保Apache在root用户下运行$ d7 ]/ L$ f# ~8 d) h- i, R# G
答案速查
8 u% l: \" Z5 W1:D2 L% k7 B3 `2 c( y: Z
2:AD
+ L: a9 E" G9 {& U3:E+ o1 V" }5 u; P. M- i
4:Content-Type:MIME7 a) S2 t- R% K
5:BC
7 {, g% u( V4 p- J6:A
# i, P2 J' H/ ]' x9 d4 K7:C) ~' s+ A) O- t7 s. ~
8:BCE
+ R. I6 b' E, v4 \. F9:ACD+ g3 C) ~1 T  t9 R8 n' S
10:B& }" X6 t: I- l( W+ u% h# J
11:D
* `; U  @& `+ j! H* n/ S12:CE
+ `4 x, c  @9 f. [+ }13:D- j. @( k3 ]- m0 W  g0 O: A6 E4 n( {
14:D
" X, S* a9 o( _; P' i7 z0 g15:ABD9 ?! B: X4 F7 F9 ^7 y: p- c
/ @- N+ I- n1 E- @
" M8 I* s4 k! D1 M2 T9 [1 P

) y0 O/ ~# x# Y+ s答案详解
3 C' a2 Q2 v6 O* t  X! e( U1 F
5 o. I: k: B  ]* N" {1.列出的E-Mail地址中只有D不合法。A和B都是最经典、常用的电子邮件地址。C看起来不合法,但邮件传输代理(MTA)会自动过滤多余的空格。E可以在本地发送时使用。那么就只剩下D了,它里面有一个非法字符。- T% e/ g! r1 |8 Q1 ]( ?
" ^: M3 w7 u6 ], V: e
2.正确答案是A和D。UNIX版本的PHP需要用sendmail程序(或者功能等同的替代品)通过MTA发送邮件,Windows/Novell版本的则通过SMTP直接用MTA发送。然而,如果允许的话,Windows/Novell上的PHP也可以进行配置,来通过“sendmail封装器”模拟sendmail发信。也就是说PHP在这三个版本上能够以相同的方式实现此功能。注意,在Windows/Novell上使用mail()时,需要配置sendmail_from。而UNIX则把这件事交给sendmail程序自己来处理。
0 y" p# }! _9 w1 x# Z4 g
% o, W8 G' Q; y. A' E0 l3.PHP可以用mail函数发送任何格式合法的电子邮件,于是编写用SMTP发信的PHP脚本成为了下策。要在E-Mail中添加额外的头信息,则必须向函数传递$additional_headers参数,每个头信息以一个回车符和一个换行符结尾(\r\n)。发送复杂的邮件,比如带附件的或者HTML格式的邮件,则不仅需要添加额外的头信息,还要添加MIME类型。所以答案是E。* {: g. u6 e6 S! M! C8 k! }
' v3 h0 r) z: G( @! i4 ]
4.发送由多个部分组成的MIME邮件时,你必须指定一个分隔符(任何US-ASCII字符串),它必须不同于邮件主题中任何一个部分。分隔符必须与MIME信息中嵌入的任何一部分都不同。分隔符在Content-Type: MIME中定义。  R( i; b! a2 N1 e$ O; u
7 m3 M" E/ m+ G# E- |7 `
5.有两个选项指出了在HTML邮件中包含图片等资源的正确方法。最快的方法就是直接引用一张远程图片。然而,图片以及其他资源能够以MIME内容块的形式嵌入MIME邮件自身。这些内容块会被赋予ID,可以通过把src属性设置为cid:资源标识加内容ID的方式来调用。因此答案B和C正确。
: u" {. a, g- Q' E' N0 U7 p7 v' h5 S1 y1 ?$ X% D3 C- N3 n
6.mail函数的最后一个参数用来向sendmail程序传递参数,不过这只能在安装了sendmail的UNIX系统上进行。如果Windows/Novell系统上配置了sendmail_path,那么这个参数同样也是可用的。
8 f+ ]! x7 \9 u3 _0 N$ a
- p5 o3 ~. m  ^5 b* i7.答案是C。MIME头信息里的内容编码(Content-Transfer-Encoding)用来指出MIME邮件中各个片段的编码。头信息中包含一组指出了编码算法的二进制数据。默认情况下,7bit,quoted-printable,base64,8bit和binary是可用的编码类型。不过任何人也可以通过使用x-<unique name for encoding>来声明自己的编码格式。
/ t* P/ Q8 |" g& ?3 V
, `$ B, Z$ _1 |5 j# H/ `' Q. A# G, P2 n8.正确答案是B,C和E。分隔符是MIME邮件中至关重要的一部分。虽然分隔符的长度没有官方限制,但由于分隔符由文本字符构成,因此它绝对不能出现在邮件主体中,否则就会造成混乱。考虑一种灾难性的情况:假设我们用John做分隔符,那么邮件中提到的人名John就会分隔邮件,导致邮件内容的混乱。4 Y, |; K8 ~, \  y7 G
/ l" N& }, S/ H7 T- S& N" s
9.要从给定的文本信息中创建一份合法的MIME邮件,正确的答案是A,C和D。MIME邮件在开头处必须有MIME-Version头信息,而邮件的每个片段(包括“root”片段)都必须有Content-Type和content-transfer-encoding这两个部分。答案中提到的另外两个头信息是可选的:Content-Disposition用来指出片段要如何显示(比如显示为附件),Content-ID是片段中的各个内容的唯一识别符。- g8 q8 p; k6 L1 K. S0 P7 |+ Q
8 n3 U! K# G, e) S4 a
10.正确答案是B。这种特殊的MIME类型用来定义一个含多个内容相同的子版本片段的母片段。比如说,一个multipart/alternative片段包含一个text/plain和一个text/html版本的片段。然后由电子邮件客户端选择一个最合适的版本来显示给用户。通常情况下,最好放入一个文本格式的版本,这样不支持MIME的邮件客户端也能正常读取。3 w6 h# r$ \6 c5 b

+ J7 z" Y# D% B11.在类UNIX系统中,PHP依靠sendmail程序来处理邮件。而在Windows中,除非已有sendmail包装器,否则将使用服务器的SMTP配置来进行。答案是D。
4 b9 m; r/ W$ f) M$ X$ r; [3 p( h7 p: w$ o( V
12.在普通文本邮件中使用htmlentities()不能防止跨站攻击,反而可能会让邮件内容变得不可读。强制使用POST传递变量只能让攻击变的困难,但并非绝对安全。确保E-Mail文本域(将变成To:的部分)中没有换行符,能够防止恶意用户把自己的邮件地址添加进收件人地址中。因此答案是C和E。
! I5 Z" y$ s7 j3 J% I3 F# r2 a6 }8 u7 d& p1 h
13.把数组序列化成一个字符串是传输这个数组的正确方式——第一步先让数组变得可以通过E-Mail网络传输。接下来你需要对它进行编码,以使得它能够安全传输。在PHP4中,最简单的方法是用base64_encode把它编码成每字符7bit的形式。答案是D。; u4 E' y, P( j; T* ~9 ?8 O1 i
' n2 t. o) X( [) U) |9 t0 \
14.要判断一个文件的MIME类型,最简单的方法是使用mime_content_type函数。答案是D。注意,虽然别的扩展库里有能更好的解决这个问题的函数(译者注:比如PECL的FileInfo),但在这里使用mime_content_type仍然是可以的。/ r3 q6 g1 [7 n/ s2 G1 K7 z, [

# A: E4 V2 O9 J" T3 U( D15.在头信息中添加From不能完全保证sendmail不会在邮件中重写你的发件人地址。事实上,你需要通过发送器向sendmail传递-f参数。除此之外,你还必须确保运行Apache的用户有修改头信息中的From内容的权限。因此答案是A,B和D。

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