返回列表 发帖

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

没有了E-Mail,这世界会变成什么样?网络交流把人们拉得更近,让公司能够更有效的开展业务,不幸的是,也带来了垃圾信息。
2 z& y% r2 e' o& ^还好,你不需要成为一个反垃圾邮件专家就能使用PHP处理电子邮件的功能。事实上,不管你是在运营一家在线商店,还是在编写一套论坛程序,你都会发现发送邮件是你工作中很重要的一部分——与用户保持联系这点非常重要。8 z+ i8 B- d2 Z+ H
用PHP编写邮件管理脚本很简单,但也不失挑战性。如果你只是想发送一封文本邮件,mail函数对你来说就够了。而如果你需要处理更复杂的电子信息——例如HTML邮件和附件时,那么你就需要深入学习一下E-Mail的工作原理了。
& ~/ Y& J- U4 X& ~0 p/ M0 R; B
3 |$ X3 K8 M" K& I5 x
4 ]1 D8 _, G7 m" C) Y) ~问题
6 W5 q5 u& s/ ?; q( h4 ]2 `, I" h5 P. z: Y$ m  b. T
1.以下哪个不是合法的电子邮件地址?; Q" c& m- w6 f# P" p
# |" l) B7 B9 u6 w& e7 v% x
A.john@89w.org
: U6 _; a) p! [* I" c% qB."John Coggeshall" <someone@89w.org>
# r' K0 l) Q5 fC.joe @ 89w.org
( n7 c# J2 Y" V6 \3 KD.jean-cóggeshall@89w.org) C+ i4 i8 ?5 }- H
E.john" e, ?! w: |( \" d/ [
, s4 C4 u; i/ ]9 Q4 [  ^
! c" Q: U: _9 W  Z
2.在PHP中,使用sendmail程序从Windows或Novell系统中发送邮件的方式,与从类UNIX系统中发送的方式不同。以下哪些选项说明了这个不同?(双选)) L7 _' d$ C$ t  j5 v- Z* B

- l# d( h/ r9 |3 JA.Windows/Novell不需要第三方软件的支持就能实现该功能
' [, H" \( b2 M5 f1 L6 P5 mB.UNIX中,sendmail_from的配置来决定了邮件头中的From:信息。
+ h3 ^% V2 _( h+ ~C.在Windows/Novell中,你无法发送有多个收件人的电子邮件,每个收件人都必须单独发送
1 u7 O& Y" x: {) UD.有可能完全相同,这取决于sendmail_path的配置
6 E2 ^) O/ H2 E' g* rE.不同与Windows/Novell,在UNIX中,你必须用SMTP和smtp_port配置好MTA主机和端口1 ~4 f9 n( Y* I5 p2 F: B3 L) t% O, h
, e# Y8 D6 h) p6 X: N& l( V7 I' v& g' D

" h$ W6 B( K" t* F$ V) r7 _3.通过PHP发送有多个收件人或者MIME兼容的邮件,需要遵循什么步骤?
* o4 {5 N, M4 a6 P+ a& C* k" J3 w0 O% L5 G% Y
A.将必要的头信息(header)通过$message参数(第三个参数)传递给mail函数
3 e: l; @& q( t4 {B.用PHP代码,通过SMTP直接与MTA连接。% c4 e% v( T7 E5 X
C.将附加的头信息传递给mail函数的$additional_headers参数(第四个参数),每个header一行。7 I  }9 h4 V# y! [! I/ v
D.向多个收件人发送E-Mail是允许的。PHP不支持发送MIME E-Mail。* J2 y' b1 @$ Y; L% i# O& b9 c5 E
E.向mail函数传递$additional_headers参数,每个header一行,行以\r\n结尾" U- l9 R3 n8 N& I
/ F" e' h, T6 m7 D

$ {/ `8 ]( k, N7 N& N4.使用MIME发送有附件的邮件时,邮件正文和附件必须靠一个特殊的分隔符分开。MIME E-Mail的头信息里如何定义这个分隔符?& G( Y! I3 `' k% Z

& d! Y& Q  L2 j: |' j9 G1 V) I6 h答案:____________
% K; ^' {0 ~8 r) W$ x
" Y5 r$ A! g( |* J
" N& j$ P2 W) C- R$ }2 }5.使用MIME发送HTML邮件时,经常会用到一些经典的HTML标签,比如用<img>嵌入图片。以下那些方法能做到这点?(双选)
( i2 H" H3 ?1 U+ `$ V: W, i, p' m
7 R- {* z: d3 w' F3 j; cA.直接用<img>标签把图片文件嵌入邮件内容中,邮件客户端能自动显示
1 l4 d7 r$ I; rB.通过给<img>标签添加一个URL的src属性来调用外部服务器上的图片
2 {: J; q4 A8 W9 AC.把图片作为MIME内容直接嵌入邮件中,再把<img>标签的src属性指定为内容ID7 X6 P6 h5 D9 C* [) p, ?2 ^& m% k
D.把图片作为附件,再把<img>标签的src属性指定为图片的文件名, ~' T- ~4 i# E- E; I7 f' e
E.只有一个答案正确
4 [6 I# l" P5 D' J! J* U& u. m
' u$ I7 \" H: f3 n; p
/ H; {" ~+ B) h2 B* I6.以下那种情况会用到mail函数的第五个(最后一个)参数$additional_parameters?+ G9 d- j+ C: {7 `0 t

9 ]% J  X4 L- P  G7 A. n9 |% pA.从UNIX或Windows/Novell发送邮件时都会用到& ^) I6 ~+ E# x$ H/ z7 g
B.只有在Windows/Novell平台上用SMTP命令向MTA发送邮件时
& N- e7 `+ ^* W! y1 bC.只有在和sendmail或一个指定了sendmail_path的打包程序协作发送时
5 Z# h; J, ]- a" r: t/ F% G4 aD.PHP里用不到这个参数
0 y( N6 g" Q! R! ?8 t5 O6 }
, N7 T5 P" G+ v2 f/ Z1 O
, v7 @3 r1 c8 i; E- V, C  j1 [% ^7.以下那种情况需要在头信息中添加邮件内容编码(Content-Transfer-Encoding)?
2 C" d! C, d; j2 \4 K3 y( l% J" P) z2 d" f/ C! a
A.只有在发送非普通文本(ASCII)数据时
! H$ N6 N; |5 aB.需要指出E-Mail的格式时,例如HTML,普通文本(plain text),富文本(rich text)& h3 m7 I6 W" t
C.任何时候都可以用它来指出MIME的编码类型
. D2 `. Q* p! |$ O' w- y$ n: L" m) W5 ID.只能用来指定特殊的编码格式(例如base64)  R) O. n+ |0 j' |+ F
E.以上都不对
; V9 K6 R& A0 }% Y4 M: d5 Q; ~, Y  F9 Y- }
8.以下关于在头信息Content-Type中定义的MIME分隔符的描述,哪些正确?(三选)6 ]9 Q) u. I6 \0 S$ W  s
4 a) o$ K( z6 {5 e9 m; L
A.分隔符至少要8个字符
* v$ t9 _8 B3 \' f. W# I7 A8 DB.分隔符必须以两个连字号作为前缀(例如:--abcdefghi)和后缀来表示起止(例如:--abcdefghi--)
  {3 Q1 B* V7 `. q. e0 oC.分隔符在MIME邮件中必须是独一无二的+ x; `3 \+ X5 E
D.分隔符不能嵌套的其他分隔符中' @2 Z- z/ a& V' X6 w
E.用什么做分隔符都无所谓6 W3 z* n' ?% B4 _$ r1 d; s
' x2 R2 s! e( l* Y

9 _) U- {& t) g1 g$ i; U' C7 V9.考虑如下E-Mail:" z. N/ }, K7 N; M+ F* y

1 B) {9 d# O" HFrom: John Coggeshall <john@php.net>. R6 p+ i) R8 X1 r$ |: A
To: Joe User <joe@example.comt>
9 C+ ~8 c/ ~- V- eSubject: Hello from John!
0 S$ j/ J# @. {' m7 r+ A* ^Date: Wed, 20 Dec 2004 20:18:47 -0400
# Y& D/ R- i) e& z# m8 hMessage-ID: <1234@local.machine.example>
) u- X! ~+ J' o8 _% FHello, How are you?. y2 Z4 J3 g& p( n. b9 t

7 ~* q' P+ Q0 y/ K! w在头信息里添加什么才能让它成为一份MIME邮件?(不定项选择); a. H  u# v9 N  E( {2 k
4 E+ _0 R3 `% C4 e! B  r. a; w( e
A.MIME-Version
1 [9 B5 y$ [& i5 y6 uB.Content-Disposition' K$ [1 Q" i, D4 \' F; V
C.Content-Type
, E6 j4 N* ~# O3 R8 {- fD.Content-Transfer-Encoding. Y8 H. d) p7 O5 |0 O6 @
E.Content-ID
# w1 e7 N5 {. j5 M
% n. i/ g- B& `/ W8 |$ r8 O; p
0 e9 G# i3 Y/ E) `5 S10.发送一封包含HTML、富文本和普通文本三个版本的邮件,要想客户端能选择一个合适的版本打开,MIME的content-type应该是什么?
1 L* `3 f) K; P/ X$ \
5 }. R5 t6 r: R) e/ L: n5 lA.multipart/mixed% y! B% v9 {) `: c- v
B.multipart/alternative
5 W2 i. A" K+ E2 |. TC.multipart/default; x/ ~: }1 d" ?1 R
D.multipart/related5 z: l9 d$ }$ R3 V8 f
E.不可能用content-type实现
+ \& u0 F; A) ?* r; ?$ F* n! w5 n/ M, x# z, o# D6 S+ G. a

% i9 M4 _1 ^0 u! q11.假设你的机器上没有安装sendmail,要想mail函数能在Windows下使用,需要做什么?
1 R0 y& E8 Y3 w% O* G1 k( ^* v: m* y9 H& F' h
A.安装sendmail服务器( @( ]& u% Q0 Y1 G+ {4 d1 Q
B.安装Microsoft Exchange
4 }3 M- Y' g2 d; hC.在你的电脑上安装任何一种邮件服务器
: m9 i; Q; G! a% X4 Q5 bD.改变php.ini的设置/ `8 L0 y6 X* d6 X; |! H
E.写一个连接公共电子邮件服务器的脚本  a+ F+ A! X: W# V9 Z

  z' M2 G; D0 U" _4 _
  l5 c# i5 J/ a3 d7 h- l: P; R12.有一个向用户提交的地址发送指定内容的文本邮件的表单,以下哪种方法有助于防止通过该表单进行跨站攻击?(双选)
9 G0 U8 I% F3 A" G8 y; Z2 K/ P5 Z- a' b5 R% H
A.使用GET方式传值
+ M& Y( M- r& RB.用htmlentities()处理电子邮件地址
! Z9 k" j1 z" WC.使用POST方式传值& k+ |8 D$ E) }0 S3 D4 @
D.用htmlentities()处理邮件正文
  P0 V& M) v5 F3 b: U4 FE.确保填写邮件地址的文本域不能有换行符
2 V6 f; M: t( X( Z( M/ f4 m; Q( H: y. a/ [; D5 V: j3 c8 E

9 _7 h# p7 [# k+ Y! t13.如何将一个数组作为附件发送,并要能在接收后重新组合?
* Y& k$ c  m4 l0 X
1 O) }; y3 S- I: z  v( RA.用serialize()把它转换成字符串,再用htmlentities()处理一下) e1 }# M7 O8 c6 y
B.把它存在文件中,并用base64_encode()进行编码
9 Y% L9 P, i) D) P' `C.用serialize()把它转换成数组
6 X4 C1 x9 Q3 Y# M+ W5 lD.用serialize()把它转换成数组,再用base64_encode()进行编码1 o% Q, n3 T0 \! J
E.把它存在文件中,再用convert_uuencode()进行编码
' W  T. z! `6 J
! y+ |/ |1 v! M: U$ w
- X* s$ d5 ?% n8 C/ Z14.要确定需要嵌入在MIME/multipart 邮件中的文件该使用什么MIME类型,以下那种方法最好?# Y- s9 G% t7 [/ d
* u8 u" V' A' K/ \# ]
A.堆一个检测脚本出来) r* k1 G7 s  U
B.创建一个MIME类型和文件后缀名的列表,根据后缀名选定需要的MIME类型
7 B# F/ E/ ]1 nC.写一个识别文件MIME类型与内容是否相符的函数
2 h2 J3 s* d" c2 k2 L% y! bD.使用mime_content_type函数
" K. G$ O" x+ E  z0 ?& oE.把文件上传到外部服务器上' o/ _1 y+ D6 z  S

+ t+ e6 u% J7 n8 z* L6 X  m
; C3 U/ ]0 \/ d# B5 ^+ b' i5 L15.在UNIX环境下使用本地安装的sendmail,如何才能随意设置邮件的发件人名字与发件人地址?(三选): s; G1 Q5 }/ u+ l6 j, Q

5 q* O8 w  ], l- JA.添加一个From头信息
3 x- a: g9 h, t* K$ ]$ A: W& l0 DB.使用-f参数* X& M; \1 [! X# p) O% [! E
C.添加一个Reply-to的头信息
; F) `5 Y5 z7 r- GD.确保运行Apache的用户有修改sendmail设置的权利# F* u6 m. h" j. {
E.确保Apache在root用户下运行0 k6 w- T) @5 M! p, O
答案速查- ^& O8 ^8 O1 {3 p* H
1:D
" R2 \" _2 q8 W2:AD; Z8 n/ \3 k' h' J! ~. }5 N
3:E
* \% y! n& r/ c  _2 ^9 B( E4:Content-Type:MIME  L+ y1 W! T! o+ Q/ ^/ l& O% a
5:BC
; m3 b( }5 n, k1 l6:A8 f4 I8 P) P% h6 i0 ~
7:C2 F# q8 @& ^* w4 O* G
8:BCE
8 l1 m& L6 I$ w, L/ K9:ACD
0 d/ G: p9 T% ]' [5 ]10:B
$ F1 B4 o& h( x# |& ]* i5 q/ z; E' J11:D2 L; a$ `9 `: u- d
12:CE
$ z  b  D3 {4 e0 f: A13:D
" Q  I, P) N* O! `" j  b( ~3 I14:D
  z* \% ?, |! q) B8 e; O15:ABD& v4 C  j+ P1 a
8 [# I0 X/ x4 X* p

( `- u: S6 Y8 h$ L. U( J# d7 K! y& h2 q$ h8 H/ J
答案详解
! ^2 [4 k' |* ]" V0 f  A9 ~3 y, Y
# Y/ A3 a8 Q( q+ o, ]/ E6 H7 ?) h1 F: U1.列出的E-Mail地址中只有D不合法。A和B都是最经典、常用的电子邮件地址。C看起来不合法,但邮件传输代理(MTA)会自动过滤多余的空格。E可以在本地发送时使用。那么就只剩下D了,它里面有一个非法字符。
; S  y2 ]: }9 h
8 _' i- r. I3 i0 |# D# J! j5 q5 l2.正确答案是A和D。UNIX版本的PHP需要用sendmail程序(或者功能等同的替代品)通过MTA发送邮件,Windows/Novell版本的则通过SMTP直接用MTA发送。然而,如果允许的话,Windows/Novell上的PHP也可以进行配置,来通过“sendmail封装器”模拟sendmail发信。也就是说PHP在这三个版本上能够以相同的方式实现此功能。注意,在Windows/Novell上使用mail()时,需要配置sendmail_from。而UNIX则把这件事交给sendmail程序自己来处理。* U9 t, @8 n, r4 {
+ y# ~2 \) V5 S/ B5 i6 ]$ ~
3.PHP可以用mail函数发送任何格式合法的电子邮件,于是编写用SMTP发信的PHP脚本成为了下策。要在E-Mail中添加额外的头信息,则必须向函数传递$additional_headers参数,每个头信息以一个回车符和一个换行符结尾(\r\n)。发送复杂的邮件,比如带附件的或者HTML格式的邮件,则不仅需要添加额外的头信息,还要添加MIME类型。所以答案是E。; F, [1 n# `5 P! v+ `$ i' F

1 m3 U* p2 N- j$ G6 }# z( X+ {. I6 m4.发送由多个部分组成的MIME邮件时,你必须指定一个分隔符(任何US-ASCII字符串),它必须不同于邮件主题中任何一个部分。分隔符必须与MIME信息中嵌入的任何一部分都不同。分隔符在Content-Type: MIME中定义。
8 c! v1 N' R/ K7 Z5 p7 B' V; O$ A9 P, R- r5 O9 k  b
5.有两个选项指出了在HTML邮件中包含图片等资源的正确方法。最快的方法就是直接引用一张远程图片。然而,图片以及其他资源能够以MIME内容块的形式嵌入MIME邮件自身。这些内容块会被赋予ID,可以通过把src属性设置为cid:资源标识加内容ID的方式来调用。因此答案B和C正确。4 s* g6 t( w1 Z% v  k2 u

( {) M7 x8 \+ b/ r5 z: P2 B6.mail函数的最后一个参数用来向sendmail程序传递参数,不过这只能在安装了sendmail的UNIX系统上进行。如果Windows/Novell系统上配置了sendmail_path,那么这个参数同样也是可用的。
7 G3 I3 ]3 B9 e7 ~, J& b( |4 `7 x/ o! B( e5 O
7.答案是C。MIME头信息里的内容编码(Content-Transfer-Encoding)用来指出MIME邮件中各个片段的编码。头信息中包含一组指出了编码算法的二进制数据。默认情况下,7bit,quoted-printable,base64,8bit和binary是可用的编码类型。不过任何人也可以通过使用x-<unique name for encoding>来声明自己的编码格式。, X0 r, Z$ a! k7 h# _! v6 P

& G" e) S8 ]* b/ G8.正确答案是B,C和E。分隔符是MIME邮件中至关重要的一部分。虽然分隔符的长度没有官方限制,但由于分隔符由文本字符构成,因此它绝对不能出现在邮件主体中,否则就会造成混乱。考虑一种灾难性的情况:假设我们用John做分隔符,那么邮件中提到的人名John就会分隔邮件,导致邮件内容的混乱。
, e7 h3 |1 t* ]! R6 `& @0 f( o/ ?4 j9 ^# }2 t
9.要从给定的文本信息中创建一份合法的MIME邮件,正确的答案是A,C和D。MIME邮件在开头处必须有MIME-Version头信息,而邮件的每个片段(包括“root”片段)都必须有Content-Type和content-transfer-encoding这两个部分。答案中提到的另外两个头信息是可选的:Content-Disposition用来指出片段要如何显示(比如显示为附件),Content-ID是片段中的各个内容的唯一识别符。+ n+ Z4 o; v; R7 i

" n1 b; F/ n8 \% B, V& U# ?10.正确答案是B。这种特殊的MIME类型用来定义一个含多个内容相同的子版本片段的母片段。比如说,一个multipart/alternative片段包含一个text/plain和一个text/html版本的片段。然后由电子邮件客户端选择一个最合适的版本来显示给用户。通常情况下,最好放入一个文本格式的版本,这样不支持MIME的邮件客户端也能正常读取。
; f+ [& |; U# d% ]
1 r' w" O' r6 B$ M8 X! \11.在类UNIX系统中,PHP依靠sendmail程序来处理邮件。而在Windows中,除非已有sendmail包装器,否则将使用服务器的SMTP配置来进行。答案是D。; d" n- w/ ^+ _

! |: y& T" K  `( K0 b" w/ v12.在普通文本邮件中使用htmlentities()不能防止跨站攻击,反而可能会让邮件内容变得不可读。强制使用POST传递变量只能让攻击变的困难,但并非绝对安全。确保E-Mail文本域(将变成To:的部分)中没有换行符,能够防止恶意用户把自己的邮件地址添加进收件人地址中。因此答案是C和E。
9 m( C* O% B0 `* f& V2 J% b* i7 I! k
3 D2 R  L' D9 H: q4 T+ O13.把数组序列化成一个字符串是传输这个数组的正确方式——第一步先让数组变得可以通过E-Mail网络传输。接下来你需要对它进行编码,以使得它能够安全传输。在PHP4中,最简单的方法是用base64_encode把它编码成每字符7bit的形式。答案是D。! F5 ]& e( E4 h' N# K9 V: d

) I* y) O' s3 ]3 R- C/ @14.要判断一个文件的MIME类型,最简单的方法是使用mime_content_type函数。答案是D。注意,虽然别的扩展库里有能更好的解决这个问题的函数(译者注:比如PECL的FileInfo),但在这里使用mime_content_type仍然是可以的。
' p+ E0 g, p0 b& A0 y
1 M  r9 m, P) T15.在头信息中添加From不能完全保证sendmail不会在邮件中重写你的发件人地址。事实上,你需要通过发送器向sendmail传递-f参数。除此之外,你还必须确保运行Apache的用户有修改头信息中的From内容的权限。因此答案是A,B和D。

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